mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-07-21 12:42:53 +08:00
feat(hermes): add execution limits config form
This commit is contained in:
@@ -52,12 +52,35 @@ test('Hermes 配置页会暴露网关流式结构化配置字段', () => {
|
||||
}
|
||||
})
|
||||
|
||||
test('Hermes 配置页会暴露执行与委派限制结构化配置字段', () => {
|
||||
for (const id of [
|
||||
'hm-execution-limits-save',
|
||||
'hm-code-execution-mode',
|
||||
'hm-code-execution-timeout',
|
||||
'hm-code-execution-max-tool-calls',
|
||||
'hm-delegation-max-iterations',
|
||||
'hm-delegation-child-timeout-seconds',
|
||||
'hm-delegation-max-concurrent-children',
|
||||
'hm-delegation-max-spawn-depth',
|
||||
'hm-delegation-orchestrator-enabled',
|
||||
'hm-delegation-subagent-auto-approve',
|
||||
'hm-delegation-inherit-mcp-toolsets',
|
||||
]) {
|
||||
assert.match(source, new RegExp(`id="${id}"`), `缺少 ${id}`)
|
||||
}
|
||||
})
|
||||
|
||||
test('Hermes 配置页数值输入会保留 0 值显示', () => {
|
||||
assert.doesNotMatch(source, /String\(value \|\| ''\)/, 'esc(value) 不能把合法 0 渲染为空字符串')
|
||||
})
|
||||
|
||||
test('Hermes 配置页新增结构化配置不会暴露翻译 key', () => {
|
||||
const keys = new Set(extractEngineKeys().filter(key => key.includes('ToolGuardrails') || key.includes('MemoryConfig') || key.includes('StreamingConfig')))
|
||||
const keys = new Set(extractEngineKeys().filter(key => (
|
||||
key.includes('ToolGuardrails') ||
|
||||
key.includes('MemoryConfig') ||
|
||||
key.includes('StreamingConfig') ||
|
||||
key.includes('ExecutionLimits')
|
||||
)))
|
||||
|
||||
assert.ok(keys.size > 0, '应能提取新增结构化配置用到的 engine 翻译 key')
|
||||
for (const key of keys) {
|
||||
|
||||
121
tests/hermes-execution-limits-config.test.js
Normal file
121
tests/hermes-execution-limits-config.test.js
Normal file
@@ -0,0 +1,121 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import {
|
||||
buildHermesExecutionLimitsConfigValues,
|
||||
mergeHermesExecutionLimitsConfig,
|
||||
} from '../scripts/dev-api.js'
|
||||
|
||||
test('Hermes 执行与委派限制读取会提供上游默认值', () => {
|
||||
const values = buildHermesExecutionLimitsConfigValues({})
|
||||
|
||||
assert.deepEqual(values, {
|
||||
codeExecutionMode: 'project',
|
||||
codeExecutionTimeout: 300,
|
||||
codeExecutionMaxToolCalls: 50,
|
||||
delegationMaxIterations: 50,
|
||||
delegationChildTimeoutSeconds: 600,
|
||||
delegationMaxConcurrentChildren: 3,
|
||||
delegationMaxSpawnDepth: 1,
|
||||
delegationOrchestratorEnabled: true,
|
||||
delegationSubagentAutoApprove: false,
|
||||
delegationInheritMcpToolsets: true,
|
||||
})
|
||||
})
|
||||
|
||||
test('Hermes 执行与委派限制读取会回显 YAML 字段', () => {
|
||||
const values = buildHermesExecutionLimitsConfigValues({
|
||||
code_execution: {
|
||||
mode: 'strict',
|
||||
timeout: 120,
|
||||
max_tool_calls: 12,
|
||||
},
|
||||
delegation: {
|
||||
max_iterations: 30,
|
||||
child_timeout_seconds: 900,
|
||||
max_concurrent_children: 5,
|
||||
max_spawn_depth: 2,
|
||||
orchestrator_enabled: false,
|
||||
subagent_auto_approve: true,
|
||||
inherit_mcp_toolsets: false,
|
||||
},
|
||||
})
|
||||
|
||||
assert.equal(values.codeExecutionMode, 'strict')
|
||||
assert.equal(values.codeExecutionTimeout, 120)
|
||||
assert.equal(values.codeExecutionMaxToolCalls, 12)
|
||||
assert.equal(values.delegationMaxIterations, 30)
|
||||
assert.equal(values.delegationChildTimeoutSeconds, 900)
|
||||
assert.equal(values.delegationMaxConcurrentChildren, 5)
|
||||
assert.equal(values.delegationMaxSpawnDepth, 2)
|
||||
assert.equal(values.delegationOrchestratorEnabled, false)
|
||||
assert.equal(values.delegationSubagentAutoApprove, true)
|
||||
assert.equal(values.delegationInheritMcpToolsets, false)
|
||||
})
|
||||
|
||||
test('Hermes 执行与委派限制保存会保留未知字段并写入上游结构', () => {
|
||||
const next = mergeHermesExecutionLimitsConfig({
|
||||
model: { provider: 'anthropic' },
|
||||
code_execution: {
|
||||
mode: 'project',
|
||||
custom_flag: 'keep-code',
|
||||
},
|
||||
delegation: {
|
||||
model: 'child-model',
|
||||
provider: 'openrouter',
|
||||
custom_flag: 'keep-delegation',
|
||||
},
|
||||
streaming: { enabled: true },
|
||||
}, {
|
||||
codeExecutionMode: 'strict',
|
||||
codeExecutionTimeout: '180',
|
||||
codeExecutionMaxToolCalls: '25',
|
||||
delegationMaxIterations: '40',
|
||||
delegationChildTimeoutSeconds: '1200',
|
||||
delegationMaxConcurrentChildren: '4',
|
||||
delegationMaxSpawnDepth: '2',
|
||||
delegationOrchestratorEnabled: false,
|
||||
delegationSubagentAutoApprove: true,
|
||||
delegationInheritMcpToolsets: false,
|
||||
})
|
||||
|
||||
assert.deepEqual(next.model, { provider: 'anthropic' })
|
||||
assert.deepEqual(next.streaming, { enabled: true })
|
||||
assert.equal(next.code_execution.mode, 'strict')
|
||||
assert.equal(next.code_execution.timeout, 180)
|
||||
assert.equal(next.code_execution.max_tool_calls, 25)
|
||||
assert.equal(next.code_execution.custom_flag, 'keep-code')
|
||||
assert.equal(next.delegation.max_iterations, 40)
|
||||
assert.equal(next.delegation.child_timeout_seconds, 1200)
|
||||
assert.equal(next.delegation.max_concurrent_children, 4)
|
||||
assert.equal(next.delegation.max_spawn_depth, 2)
|
||||
assert.equal(next.delegation.orchestrator_enabled, false)
|
||||
assert.equal(next.delegation.subagent_auto_approve, true)
|
||||
assert.equal(next.delegation.inherit_mcp_toolsets, false)
|
||||
assert.equal(next.delegation.model, 'child-model')
|
||||
assert.equal(next.delegation.provider, 'openrouter')
|
||||
assert.equal(next.delegation.custom_flag, 'keep-delegation')
|
||||
})
|
||||
|
||||
test('Hermes 执行与委派限制保存会拒绝非法模式和越界值', () => {
|
||||
assert.throws(
|
||||
() => mergeHermesExecutionLimitsConfig({}, { codeExecutionMode: 'unsafe' }),
|
||||
/code_execution\.mode/,
|
||||
)
|
||||
assert.throws(
|
||||
() => mergeHermesExecutionLimitsConfig({}, { codeExecutionTimeout: '0' }),
|
||||
/code_execution\.timeout/,
|
||||
)
|
||||
assert.throws(
|
||||
() => mergeHermesExecutionLimitsConfig({}, { delegationMaxConcurrentChildren: '0' }),
|
||||
/delegation\.max_concurrent_children/,
|
||||
)
|
||||
assert.throws(
|
||||
() => mergeHermesExecutionLimitsConfig({}, { delegationMaxSpawnDepth: '4' }),
|
||||
/delegation\.max_spawn_depth/,
|
||||
)
|
||||
assert.throws(
|
||||
() => mergeHermesExecutionLimitsConfig({}, { delegationChildTimeoutSeconds: '29' }),
|
||||
/delegation\.child_timeout_seconds/,
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user