refactor(agent-loop): simplify observable state machine
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import type { Context } from 'cordis'
|
||||
import z from 'schemastery'
|
||||
import type { AdditionalContext, Agent, ContinuationDecision, PromptDecision } from '@deepseek-ai/dsh-agent'
|
||||
import type { AdditionalContext, Agent, PromptDecision } from '@deepseek-ai/dsh-agent'
|
||||
import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm'
|
||||
import type {} from '@deepseek-ai/dsh-session-persistence'
|
||||
import type { PostToolDecision, PreToolDecision, ToolExecution, ToolExecutionResult } from '@deepseek-ai/dsh-tools'
|
||||
@@ -236,11 +236,12 @@ export function apply(ctx: Context, config: Config): void {
|
||||
}
|
||||
})
|
||||
|
||||
// Stop → ContinuationDecision. A blocking Stop hook forces continuation.
|
||||
// A blocking Stop hook steers at the stopping boundary, which makes the
|
||||
// machine observe pending input and run another step.
|
||||
// TODO(stop-loop-guard): Codex supplies `stop_hook_active` so a Stop hook can
|
||||
// avoid continuing the same turn indefinitely. It is always false here, so an
|
||||
// unconditionally blocking hook force-continues every step until it self-limits.
|
||||
ctx.on('agent/turn-continuation', async (agent, turn, _default, signal, next): Promise<ContinuationDecision> => {
|
||||
ctx.on('agent/stopping', async (agent, turn, signal): Promise<void> => {
|
||||
const merged = await runPoint('Stop', '', { ...turnBase(ctx, agent, 'Stop', model), stop_hook_active: false, last_assistant_message: null }, { agent, turn, signal })
|
||||
/* jscpd:ignore-end */
|
||||
if (merged.decision === 'deny') {
|
||||
@@ -248,9 +249,8 @@ export function apply(ctx: Context, config: Config): void {
|
||||
// empty stderr) still forces it — fall back to a generic steering line
|
||||
// rather than letting the turn stop.
|
||||
const text = merged.reason ?? 'continue: blocked by Stop hook'
|
||||
return { action: 'continue', reason: { content: [{ type: 'text', text }], source: PLUGIN_SOURCE } }
|
||||
agent.steer([{ type: 'text', text }], { source: PLUGIN_SOURCE })
|
||||
}
|
||||
return next()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user