Merge goal tool fixes and align same-session blockers
This commit is contained in:
@@ -143,11 +143,8 @@ export function apply(ctx: Context): void {
|
||||
case 'pause':
|
||||
ctx.goals.pause(state.agent, ref)
|
||||
return
|
||||
case 'usage-limited':
|
||||
ctx.goals.markUsageLimited(state.agent, ref)
|
||||
return
|
||||
case 'blocked':
|
||||
ctx.goals.block(state.agent, ref)
|
||||
ctx.goals.block(state.agent, ref, { code: outcome.code, message: outcome.message })
|
||||
return
|
||||
case 'disarm':
|
||||
ctx.goals.disarm(state.agent)
|
||||
@@ -190,7 +187,7 @@ export function apply(ctx: Context): void {
|
||||
if (goal !== undefined && goal.id === attempt.goalId && goal.revision === attempt.revision
|
||||
&& goal.phase === 'active' && goal.activation === 'armed') {
|
||||
const outcome = attempt.phase === 'queued' && attempt.rejectedReason !== undefined && !attempt.stale
|
||||
? { kind: 'blocked', reason: 'rejected', detail: attempt.rejectedReason } as const
|
||||
? { kind: 'blocked', code: 'prompt-rejected', message: attempt.rejectedReason } as const
|
||||
: classifyGoalRound(attempt.reason, durable)
|
||||
if (!attempt.stale) applyOutcome(state, goal, outcome)
|
||||
}
|
||||
@@ -200,7 +197,10 @@ export function apply(ctx: Context): void {
|
||||
const goal = currentGoal(state)
|
||||
if (goal === undefined || goal.phase !== 'active' || goal.activation !== 'armed') return
|
||||
if (goal.roundsStarted >= goal.maxGoalRounds) {
|
||||
ctx.goals.markBudgetLimited(agent, goalRef(goal))
|
||||
ctx.goals.block(agent, goalRef(goal), {
|
||||
code: 'round-limit',
|
||||
message: `Goal reached its configured limit of ${goal.maxGoalRounds} rounds.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -228,7 +228,10 @@ export function apply(ctx: Context): void {
|
||||
const latest = currentGoal(state)
|
||||
if (latest !== undefined && latest.id === goal.id && latest.revision === goal.revision
|
||||
&& latest.phase === 'active' && latest.activation === 'armed') {
|
||||
ctx.goals.block(agent, goalRef(latest))
|
||||
ctx.goals.block(agent, goalRef(latest), {
|
||||
code: 'queue-failed',
|
||||
message: `Could not queue goal round ${round}: ${renderThrown(error)}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,10 @@ import type { TurnEndReason } from '@deepseek-ai/dsh-session'
|
||||
export type GoalRoundOutcome =
|
||||
| { readonly kind: 'continue' }
|
||||
| { readonly kind: 'pause'; readonly reason: string }
|
||||
| { readonly kind: 'usage-limited'; readonly message: string }
|
||||
| {
|
||||
readonly kind: 'blocked'
|
||||
readonly reason: 'error' | 'max-tokens' | 'rejected' | 'unknown'
|
||||
readonly detail: string
|
||||
readonly code: 'usage-limited' | 'turn-error' | 'max-tokens' | 'prompt-rejected' | 'unknown-turn-outcome'
|
||||
readonly message: string
|
||||
}
|
||||
| { readonly kind: 'disarm'; readonly reason: 'durability-failed' | 'disposed' | 'interrupted' }
|
||||
|
||||
@@ -30,12 +29,12 @@ export function classifyGoalRound(reason: TurnEndReason, durable: boolean): Goal
|
||||
return { kind: 'pause', reason: reason.reason ?? 'cancelled' }
|
||||
case 'error':
|
||||
return reason.code === 'RATE_LIMIT'
|
||||
? { kind: 'usage-limited', message: reason.message }
|
||||
: { kind: 'blocked', reason: 'error', detail: reason.message }
|
||||
? { kind: 'blocked', code: 'usage-limited', message: reason.message }
|
||||
: { kind: 'blocked', code: 'turn-error', message: reason.message }
|
||||
case 'max-tokens':
|
||||
return { kind: 'blocked', reason: 'max-tokens', detail: 'model output reached max tokens' }
|
||||
return { kind: 'blocked', code: 'max-tokens', message: 'model output reached max tokens' }
|
||||
case 'rejected':
|
||||
return { kind: 'blocked', reason: 'rejected', detail: reason.reason }
|
||||
return { kind: 'blocked', code: 'prompt-rejected', message: reason.reason }
|
||||
case 'disposed':
|
||||
return { kind: 'disarm', reason: 'disposed' }
|
||||
case 'interrupted':
|
||||
@@ -43,6 +42,10 @@ export function classifyGoalRound(reason: TurnEndReason, durable: boolean): Goal
|
||||
// TurnEndReason is merge-extensible. An unknown producer cannot opt into
|
||||
// automatic retry merely by adding a tag; stop for inspection instead.
|
||||
default:
|
||||
return { kind: 'blocked', reason: 'unknown', detail: `unknown turn outcome: ${extensibleReason.kind}` }
|
||||
return {
|
||||
kind: 'blocked',
|
||||
code: 'unknown-turn-outcome',
|
||||
message: `unknown turn outcome: ${extensibleReason.kind}`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user