import test from 'node:test' import assert from 'node:assert/strict' import { buildHermesAgentRuntimeConfigValues, mergeHermesAgentRuntimeConfig, } from '../scripts/dev-api.js' test('Hermes Agent 长跑保护配置读取会提供上游默认值', () => { const values = buildHermesAgentRuntimeConfigValues({}) assert.deepEqual(values, { agentMaxTurns: 90, gatewayTimeout: 1800, restartDrainTimeout: 180, apiMaxRetries: 3, gatewayTimeoutWarning: 900, clarifyTimeout: 600, gatewayNotifyInterval: 180, gatewayAutoContinueFreshness: 3600, imageInputMode: 'auto', }) }) test('Hermes Agent 长跑保护配置读取会回显 YAML 字段', () => { const values = buildHermesAgentRuntimeConfigValues({ agent: { max_turns: 240, gateway_timeout: 7200, restart_drain_timeout: 600, api_max_retries: 5, gateway_timeout_warning: 1200, clarify_timeout: 900, gateway_notify_interval: 240, gateway_auto_continue_freshness: 5400, image_input_mode: 'native', }, }) assert.equal(values.agentMaxTurns, 240) assert.equal(values.gatewayTimeout, 7200) assert.equal(values.restartDrainTimeout, 600) assert.equal(values.apiMaxRetries, 5) assert.equal(values.gatewayTimeoutWarning, 1200) assert.equal(values.clarifyTimeout, 900) assert.equal(values.gatewayNotifyInterval, 240) assert.equal(values.gatewayAutoContinueFreshness, 5400) assert.equal(values.imageInputMode, 'native') }) test('Hermes Agent 长跑保护配置保存会保留未知字段并写入 agent', () => { const next = mergeHermesAgentRuntimeConfig({ model: { provider: 'anthropic' }, agent: { max_turns: 90, disabled_toolsets: ['terminal'], custom_flag: 'keep-agent', }, streaming: { enabled: true }, }, { agentMaxTurns: '180', gatewayTimeout: '3600', restartDrainTimeout: '300', apiMaxRetries: '2', gatewayTimeoutWarning: '600', clarifyTimeout: '300', gatewayNotifyInterval: '120', gatewayAutoContinueFreshness: '1800', imageInputMode: 'text', }) assert.deepEqual(next.model, { provider: 'anthropic' }) assert.deepEqual(next.streaming, { enabled: true }) assert.equal(next.agent.max_turns, 180) assert.equal(next.agent.gateway_timeout, 3600) assert.equal(next.agent.restart_drain_timeout, 300) assert.equal(next.agent.api_max_retries, 2) assert.equal(next.agent.gateway_timeout_warning, 600) assert.equal(next.agent.clarify_timeout, 300) assert.equal(next.agent.gateway_notify_interval, 120) assert.equal(next.agent.gateway_auto_continue_freshness, 1800) assert.equal(next.agent.image_input_mode, 'text') assert.deepEqual(next.agent.disabled_toolsets, ['terminal']) assert.equal(next.agent.custom_flag, 'keep-agent') }) test('Hermes Agent 长跑保护配置保存允许 0 表示关闭或无限制', () => { const next = mergeHermesAgentRuntimeConfig({}, { gatewayTimeout: '0', restartDrainTimeout: '0', gatewayTimeoutWarning: '0', gatewayNotifyInterval: '0', gatewayAutoContinueFreshness: '0', }) assert.equal(next.agent.gateway_timeout, 0) assert.equal(next.agent.restart_drain_timeout, 0) assert.equal(next.agent.gateway_timeout_warning, 0) assert.equal(next.agent.gateway_notify_interval, 0) assert.equal(next.agent.gateway_auto_continue_freshness, 0) }) test('Hermes Agent 长跑保护配置保存会拒绝非法枚举和越界值', () => { assert.throws( () => mergeHermesAgentRuntimeConfig({}, { imageInputMode: 'pixel' }), /agent\.image_input_mode/, ) assert.throws( () => mergeHermesAgentRuntimeConfig({}, { agentMaxTurns: '0' }), /agent\.max_turns/, ) assert.throws( () => mergeHermesAgentRuntimeConfig({}, { apiMaxRetries: '0' }), /agent\.api_max_retries/, ) assert.throws( () => mergeHermesAgentRuntimeConfig({}, { clarifyTimeout: '-1' }), /agent\.clarify_timeout/, ) })