refactor(agent): unify agent-scoped event signatures as payload objects

All agent/* and agent-loop/config-start-failed events take one payload
object carrying the agent subject; waterfall/serial payloads require a
signal and keep next as the final argument. PreStepContext and
RequestFailureContext are unfolded into payloads and retired.
goal/changed follows the same shape so agentEvents keeps its listener
error containment. ReactLoopAgent builds its scope carrier once in the
constructor. Regenerates scope resolvers, tool-cordis api catalog, and
docs catalogs; updates all affected listeners, tests, and the
core-data-structures docs (en + zh).
This commit is contained in:
_Kerman
2026-08-06 12:13:14 +08:00
parent bb53e25ed0
commit ccebba2349
91 changed files with 574 additions and 618 deletions
+10 -10
View File
@@ -243,20 +243,20 @@ export function apply(ctx: Context): void {
// One composite effect keeps the step fence installed until this
// plugin's own scheduling tasks settle.
ctx.effect(function* () {
ctx.on('agent/error', (agent) => {
ctx.on('agent/error', ({ agent }) => {
const state = stateFor(agent)
disarm(state)
})
ctx.on('agent/created', (agent) => { stateFor(agent) })
ctx.on('agent/disposed', (agent) => { states.delete(agent) })
ctx.on('agent/session-start', (agent) => {
ctx.on('agent/created', ({ agent }) => { stateFor(agent) })
ctx.on('agent/disposed', ({ agent }) => { states.delete(agent) })
ctx.on('agent/session-start', ({ agent }) => {
const state = stateFor(agent)
state.attempt = undefined
state.competingQueued = false
state.needsCheckpoint = false
})
ctx.on('agent/status', (agent, status) => {
ctx.on('agent/status', ({ agent, status }) => {
const state = stateFor(agent)
if (status === 'idle') {
state.competingQueued = false
@@ -275,13 +275,13 @@ export function apply(ctx: Context): void {
requestDrive(state)
}
})
ctx.on('goal/changed', (agent) => {
ctx.on('goal/changed', ({ agent }) => {
const state = stateFor(agent)
state.needsCheckpoint = true
requestDrive(state)
})
ctx.on('agent/inbox/inserted', (agent, { message }) => {
ctx.on('agent/inbox/inserted', ({ agent, message }) => {
if (!agent.inbox.nextTurn.some(candidate => candidate.id === message.id)) return
const state = stateFor(agent)
const attempt = state.attempt
@@ -289,14 +289,14 @@ export function apply(ctx: Context): void {
state.competingQueued = true
if (attempt?.phase === 'queued') attempt.stale = true
})
ctx.on('agent/inbox/claimed', (agent, { message }) => {
ctx.on('agent/inbox/claimed', ({ agent, message }) => {
const state = stateFor(agent)
const attempt = state.attempt
if (attempt !== undefined && sameQueued(message.content, message.source, attempt)) {
attempt.phase = 'claimed'
}
})
ctx.on('agent/inbox/discarded', (agent, { message }) => {
ctx.on('agent/inbox/discarded', ({ agent, message }) => {
const state = stateFor(agent)
const attempt = state.attempt
if (attempt !== undefined && sameQueued(message.content, message.source, attempt)) {
@@ -346,7 +346,7 @@ export function apply(ctx: Context): void {
&& source.round === goal.roundsStarted + 1
}
ctx.on('agent/pre-step', async (agent, messages, { signal }, next): Promise<PreStepDecision> => {
ctx.on('agent/pre-step', async ({ agent, messages, signal }, next): Promise<PreStepDecision> => {
const submitted = messages.find((message): message is UserMessage & { source: GoalMessageSource } =>
isGoalRoundSource(message.source))
if (submitted === undefined) return next()