refactor(agent): publish agent/inbox/claimed from Inbox.claim
Move the claimed-message notification loop out of the loop's pre-step into Inbox.claim(target, turn), so the step-boundary operation publishes its own claimed notifications like insertions and discards do.
This commit is contained in:
@@ -40,7 +40,7 @@ function sessionAgent(session: Session, id = 'agent'): Agent {
|
||||
id: SessionId(id),
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'running',
|
||||
ctx: new Context(),
|
||||
send: () => {},
|
||||
|
||||
@@ -96,7 +96,7 @@ function sessionAgent(session: Session, id = 'agent'): Agent {
|
||||
id: SessionId(id),
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'running',
|
||||
ctx: new Context(),
|
||||
send: () => {},
|
||||
|
||||
@@ -175,7 +175,7 @@ function stubAgent(cwd?: string, seed: SessionEvent[] = []): Agent {
|
||||
id: SessionId('a1'),
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
send: () => {},
|
||||
followup: () => {},
|
||||
@@ -230,7 +230,7 @@ function baselineEvents(agent: Agent): SessionEvent[] {
|
||||
async function appendAdditionalContexts(ctx: Context, agent: Agent): Promise<number | undefined> {
|
||||
await syncedWorkspaceContext(ctx, agent)
|
||||
let lastSeq: number | undefined
|
||||
for (const claimed of agent.inbox.claim('next-step')) {
|
||||
for (const claimed of agent.inbox.claim('next-step', 1)) {
|
||||
if (claimed.source.kind !== 'workspace-instructions') continue
|
||||
const event = agent.session.append('user/message', claimed, { surfaceOp: 'append' })
|
||||
ctx.emit('session/event', agent.session, event)
|
||||
@@ -249,7 +249,7 @@ async function composeBaselinePrefix(ctx: Context, agent: Agent): Promise<Messag
|
||||
{ turn: 1, step: 1, signal },
|
||||
() => Promise.resolve({ kind: 'enter' as const, messages: [] }),
|
||||
)
|
||||
const claimed = agent.inbox.claim('next-step')
|
||||
const claimed = agent.inbox.claim('next-step', 1)
|
||||
const decision = await agentEvents(ctx, agent).waterfall(
|
||||
'agent/pre-step',
|
||||
claimed,
|
||||
@@ -979,7 +979,7 @@ describe('workspace context request injection', () => {
|
||||
await ctx.plugin(workspaceContext, { dshHome: home, maxBytes: 65536 })
|
||||
const resumed = stubAgent(root, [...original.session.events])
|
||||
agentEvents(ctx, resumed).emit('agent/session-start', 'resume')
|
||||
const claimed = resumed.inbox.claim('next-step')
|
||||
const claimed = resumed.inbox.claim('next-step', 1)
|
||||
const decision = await agentEvents(ctx, resumed).waterfall(
|
||||
'agent/pre-step',
|
||||
claimed,
|
||||
@@ -1027,7 +1027,7 @@ describe('workspace context request injection', () => {
|
||||
await ctx.plugin(workspaceContext, { dshHome: home, maxBytes: 65536 })
|
||||
const resumed = stubAgent(root, [...original.session.events])
|
||||
agentEvents(ctx, resumed).emit('agent/session-start', 'resume')
|
||||
const staleClaim = resumed.inbox.claim('next-step')
|
||||
const staleClaim = resumed.inbox.claim('next-step', 1)
|
||||
const staleDecision = await agentEvents(ctx, resumed).waterfall(
|
||||
'agent/pre-step',
|
||||
staleClaim,
|
||||
@@ -1082,7 +1082,7 @@ describe('workspace context request injection', () => {
|
||||
await resumedCtx.plugin(workspaceContext, { dshHome: home, maxBytes })
|
||||
const resumed = stubAgent(root, [...original.session.events])
|
||||
agentEvents(resumedCtx, resumed).emit('agent/session-start', 'resume')
|
||||
const claimed = resumed.inbox.claim('next-step')
|
||||
const claimed = resumed.inbox.claim('next-step', 1)
|
||||
const decision = await agentEvents(resumedCtx, resumed).waterfall(
|
||||
'agent/pre-step',
|
||||
claimed,
|
||||
@@ -3966,7 +3966,7 @@ describe('workspace context inbox synchronization', () => {
|
||||
await mountFileToolsAndWorkspaceContext(ctx, { dshHome: home, maxBytes: 65536 })
|
||||
const agent = stubAgent(join(root, 'pkg'))
|
||||
await syncedWorkspaceContext(ctx, agent)
|
||||
const claimed = agent.inbox.claim('next-step')
|
||||
const claimed = agent.inbox.claim('next-step', 1)
|
||||
await write(join(root, 'pkg/AGENTS.md'), 'new claimed rule with more detail')
|
||||
const downstream = { kind: 'enter' as const, messages: claimed }
|
||||
|
||||
|
||||
@@ -2007,11 +2007,11 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
},
|
||||
{
|
||||
name: 'Inbox',
|
||||
declaration: 'export class Inbox {\n constructor(private readonly session: Session, private readonly notifications: InboxNotifications);\n get nextTurn(): readonly UserMessage[];\n get nextStep(): readonly UserMessage[];\n get hasPending(): boolean;\n clear(): void;\n claim(target: InboxTarget): UserMessage[];\n append(target: InboxTarget, message: UserMessage): void;\n prepend(target: InboxTarget, message: UserMessage): void;\n replace(messageId: MessageId, newMessage: UserMessage): boolean;\n remove(messageId: MessageId): boolean;\n splice(target: InboxTarget, start: number, deleteCount: number, inserted: UserMessage[]): UserMessage[];\n}',
|
||||
declaration: 'export class Inbox {\n constructor(private readonly session: Session, private readonly notifications: InboxNotifications);\n get nextTurn(): readonly UserMessage[];\n get nextStep(): readonly UserMessage[];\n get hasPending(): boolean;\n clear(): void;\n claim(target: InboxTarget, turn: number): UserMessage[];\n append(target: InboxTarget, message: UserMessage): void;\n prepend(target: InboxTarget, message: UserMessage): void;\n replace(messageId: MessageId, newMessage: UserMessage): boolean;\n remove(messageId: MessageId): boolean;\n splice(target: InboxTarget, start: number, deleteCount: number, inserted: UserMessage[]): UserMessage[];\n}',
|
||||
},
|
||||
{
|
||||
name: 'InboxNotifications',
|
||||
declaration: 'export interface InboxNotifications {\n inserted(message: UserMessage): void;\n discarded(message: UserMessage): void;\n}',
|
||||
declaration: 'export interface InboxNotifications {\n inserted(message: UserMessage): void;\n discarded(message: UserMessage): void;\n claimed(message: UserMessage, turn: number): void;\n}',
|
||||
},
|
||||
{
|
||||
name: 'InboxTarget',
|
||||
|
||||
@@ -81,6 +81,7 @@ export class ReactLoopAgent implements Agent {
|
||||
this.inbox = new Inbox(session, {
|
||||
inserted: (message) => { emitAgentEvent(loopCtx, this, 'agent/inbox/inserted', { message }) },
|
||||
discarded: (message) => { emitAgentEvent(loopCtx, this, 'agent/inbox/discarded', { message }) },
|
||||
claimed: (message, turn) => { emitAgentEvent(loopCtx, this, 'agent/inbox/claimed', { message, turn }) },
|
||||
})
|
||||
const lastTurn = session.events.findLast(event => event.type === 'turn/start')?.data.turn ?? 0
|
||||
this.phase = { kind: 'idle', lastTurn }
|
||||
@@ -198,10 +199,7 @@ export class ReactLoopAgent implements Agent {
|
||||
/* v8 ignore next -- private callers establish the running phase before proposing a step */
|
||||
if (this.phase.kind !== 'running') throw new Error(`agent "${this.id}": pre-step outside running phase`)
|
||||
const signal = this.phase.abort.signal
|
||||
const claimed = this.inbox.claim(target)
|
||||
for (const message of claimed) {
|
||||
emitAgentEvent(this.loopCtx, this, 'agent/inbox/claimed', { message, turn: position.turn })
|
||||
}
|
||||
const claimed = this.inbox.claim(target, position.turn)
|
||||
const assembly = await this.loopCtx.systemPrompt.assemble(assembleContextFor(this, signal))
|
||||
signal.throwIfAborted()
|
||||
const context = this.runtimeContext.project(renderContextSnapshot(assembly))
|
||||
|
||||
@@ -19,6 +19,8 @@ export interface InboxNotifications {
|
||||
inserted(message: UserMessage): void
|
||||
/** Publish one discarded message. */
|
||||
discarded(message: UserMessage): void
|
||||
/** Publish one claimed message inside its owning turn. */
|
||||
claimed(message: UserMessage, turn: number): void
|
||||
}
|
||||
|
||||
/** A replay-once projection that incrementally consumes later inbox splices. */
|
||||
@@ -61,17 +63,19 @@ export class Inbox {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and return the complete batch proposed for one step. The durable
|
||||
* splices are pure deletions; the caller publishes claimed notifications.
|
||||
* Remove and return the complete batch proposed for one step, publishing
|
||||
* each claimed message. The durable splices are pure deletions.
|
||||
* @param target - whether this boundary also consumes one queued turn.
|
||||
* @param turn - turn that will own the claimed batch.
|
||||
* @returns next-step input followed by the queued turn, when requested.
|
||||
* @internal - the agent loop's step-boundary operation, not a plugin seam.
|
||||
*/
|
||||
claim(target: InboxTarget): UserMessage[] {
|
||||
claim(target: InboxTarget, turn: number): UserMessage[] {
|
||||
const claimed = this.mutate('next-step', 0, this.nextStep.length, [], false)
|
||||
if (target === 'next-turn') {
|
||||
claimed.push(...this.mutate('next-turn', 0, 1, [], false))
|
||||
}
|
||||
for (const message of claimed) this.notifications.claimed(message, turn)
|
||||
return claimed
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ function stubAgent(rawId: string, overrides: Partial<Agent> = {}): Agent {
|
||||
id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: new Context(),
|
||||
send: () => {},
|
||||
@@ -45,7 +45,7 @@ describe('Inbox', () => {
|
||||
inserted: [],
|
||||
})
|
||||
|
||||
expect(() => new Inbox(session, { inserted: () => {}, discarded: () => {} }))
|
||||
expect(() => new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }))
|
||||
.toThrow('invalid persisted inbox splice at session seq 0')
|
||||
})
|
||||
|
||||
@@ -54,6 +54,7 @@ describe('Inbox', () => {
|
||||
const inserted: UserMessage[] = []
|
||||
const discarded: UserMessage[] = []
|
||||
const inbox = new Inbox(session, {
|
||||
claimed: () => {},
|
||||
inserted: message => void inserted.push(message),
|
||||
discarded: message => void discarded.push(message),
|
||||
})
|
||||
@@ -92,7 +93,7 @@ describe('Inbox', () => {
|
||||
|
||||
it('normalizes splice coordinates, rejects duplicate identities, and reports missing removals', () => {
|
||||
const session = Session.create(SessionId('splice-inbox'))
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {} })
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} })
|
||||
const first = createUserMessage({
|
||||
content: [{ type: 'text', text: 'first' }],
|
||||
source: { kind: 'user' },
|
||||
@@ -113,6 +114,7 @@ describe('Inbox', () => {
|
||||
const session = Session.create(SessionId('clear-inbox'))
|
||||
const discarded: UserMessage[] = []
|
||||
const inbox = new Inbox(session, {
|
||||
claimed: () => {},
|
||||
inserted: () => {},
|
||||
discarded: message => void discarded.push(message),
|
||||
})
|
||||
|
||||
@@ -33,7 +33,7 @@ function agent(ctx: Context, cwd: string): Agent {
|
||||
id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: scope.ctx,
|
||||
send: () => {},
|
||||
|
||||
@@ -20,7 +20,7 @@ interface Harness {
|
||||
function stubAgent(ctx: Context, id: string): { agent: Agent; session: Session } {
|
||||
// Store-created: the command executor durably logs lifecycle events on it.
|
||||
const session = ctx.sessions.create(SessionId(id))
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {} })
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} })
|
||||
let status: AgentStatus = 'idle'
|
||||
const agent: Agent = {
|
||||
id: session.id,
|
||||
|
||||
@@ -24,13 +24,13 @@ function nextTurn(session: Session): number {
|
||||
|
||||
/** Mirror the public Agent.inject contract for domain tests. */
|
||||
function appendInjection(session: Session, input: UserMessage): void {
|
||||
new Inbox(session, { inserted: () => {}, discarded: () => {} }).append('next-step', input)
|
||||
new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }).append('next-step', input)
|
||||
}
|
||||
|
||||
/** Build a registry-compatible agent around one concrete session. */
|
||||
function stubAgentForSession(session: Session): StubAgent {
|
||||
const id = session.id
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {} })
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} })
|
||||
const agent: Agent = {
|
||||
id,
|
||||
options: {},
|
||||
@@ -554,7 +554,7 @@ describe('goal replay validation', () => {
|
||||
content: [{ type: 'text', text: 'unrelated pending context' }],
|
||||
source: { kind: 'plugin', plugin: 'test' },
|
||||
})
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {} })
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} })
|
||||
inbox.append('next-step', message)
|
||||
expect(inbox.remove(message.id)).toBe(true)
|
||||
expect(foldGoal(session.events)).toMatchObject({ goal: { id: change.goal.id, revision: 1 } })
|
||||
|
||||
@@ -31,7 +31,7 @@ interface Bench {
|
||||
/** Register a minimal registry-compatible live agent over a store session. */
|
||||
function liveAgent(ctx: Context, session: Session): Agent {
|
||||
const status: AgentStatus = 'idle'
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {} })
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} })
|
||||
const agent: Agent = {
|
||||
id: session.id,
|
||||
options: {},
|
||||
|
||||
@@ -29,7 +29,7 @@ function stubAgent(rawId: string, supplied?: Session): StubAgent {
|
||||
id: session.id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
get status() { return status },
|
||||
ctx: new Context(),
|
||||
send: () => {},
|
||||
@@ -55,7 +55,7 @@ function openTurn(stub: StubAgent, source: MessageSource, text = 'prompt'): numb
|
||||
source,
|
||||
})
|
||||
stub.agent.inbox.append('next-turn', message)
|
||||
const claimed = stub.agent.inbox.claim('next-turn')
|
||||
const claimed = stub.agent.inbox.claim('next-turn', turn)
|
||||
if (claimed.length === 0) throw new Error('expected queued turn input')
|
||||
stub.session.append('turn/start', { turn })
|
||||
for (const admitted of claimed) {
|
||||
|
||||
@@ -63,7 +63,7 @@ async function harness(options: { commands?: boolean; skills?: boolean } = {}):
|
||||
/** Register a live structural agent stub (api-proxy-view precedent: only id/session/status/ctx are read). */
|
||||
function stubAgent(ctx: Context, sessionId?: SessionId): Agent {
|
||||
const session = ctx.sessions.create(sessionId)
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {} })
|
||||
const inbox = new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} })
|
||||
const agent = {
|
||||
id: session.id,
|
||||
session,
|
||||
|
||||
@@ -54,7 +54,7 @@ async function harness(withRegistry: boolean): Promise<{ ctx: Context; session:
|
||||
if (withRegistry) await ctx.plugin(SessionProjectionRegistry)
|
||||
const session = ctx.sessions.create()
|
||||
// The gateway reads both the session and durable inbox baseline.
|
||||
ctx.agents.register({ id: session.id, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }), status: 'idle', ctx } as Agent)
|
||||
ctx.agents.register({ id: session.id, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }), status: 'idle', ctx } as Agent)
|
||||
return { ctx, session }
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ function stubAgent(session: Session): Agent {
|
||||
id: session.id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: new Context(),
|
||||
send: () => {},
|
||||
|
||||
@@ -42,8 +42,9 @@ function agent(ctx: Context, cwd?: string): Agent {
|
||||
const id = SessionId('agent')
|
||||
const session = Session.create(id, undefined, { version: 0, id, createdAt: 0, ...cwd === undefined ? {} : { cwd } })
|
||||
return {
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
status: 'idle', ctx,
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx,
|
||||
send: () => {},
|
||||
followup: () => {}, steer: () => {}, inject: () => {}, cancel() {},
|
||||
runMaintenance: task => task(new AbortController().signal),
|
||||
@@ -259,8 +260,9 @@ describe('pty-local plugin shape', () => {
|
||||
const session = ctx.sessions.create(SessionId('mode-owner'))
|
||||
const ownerFiber = await ctx.plugin(() => {})
|
||||
const owner: Agent = {
|
||||
id: session.id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
status: 'idle', ctx: ownerFiber.ctx,
|
||||
id: session.id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: ownerFiber.ctx,
|
||||
send: () => {},
|
||||
followup: () => {}, steer: () => {}, inject: () => {}, cancel() {},
|
||||
runMaintenance: task => task(new AbortController().signal),
|
||||
@@ -306,8 +308,9 @@ describe('pty-local plugin shape', () => {
|
||||
const session = ctx.sessions.create(SessionId('pending-mode-owner'))
|
||||
const ownerFiber = await ctx.plugin(() => {})
|
||||
const owner: Agent = {
|
||||
id: session.id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
status: 'idle', ctx: ownerFiber.ctx,
|
||||
id: session.id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: ownerFiber.ctx,
|
||||
send: () => {},
|
||||
followup: () => {}, steer: () => {}, inject: () => {}, cancel() {},
|
||||
runMaintenance: task => task(new AbortController().signal),
|
||||
|
||||
@@ -35,8 +35,9 @@ function stubAgent(ctx: Context, rawId: string): Agent {
|
||||
const scope = ctx.plugin(() => {})
|
||||
const session = Session.create(id)
|
||||
return {
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
status: 'idle', ctx: scope.ctx,
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: scope.ctx,
|
||||
send: () => {},
|
||||
followup: () => {}, steer: () => {}, inject: () => {}, cancel() {},
|
||||
runMaintenance: task => task(new AbortController().signal),
|
||||
|
||||
@@ -26,7 +26,7 @@ function stubAgent(ctx: Context, rawId: string): Agent {
|
||||
id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: scopeFiber.ctx,
|
||||
send: () => {},
|
||||
|
||||
@@ -43,7 +43,7 @@ function agent(ctx: Context, cwd: string): Agent {
|
||||
id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: scope.ctx,
|
||||
send: () => {},
|
||||
|
||||
@@ -39,7 +39,7 @@ function agent(ctx: Context, cwd: string | undefined): Agent {
|
||||
id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: scope.ctx,
|
||||
send: () => {},
|
||||
|
||||
@@ -40,8 +40,9 @@ function agent(ctx: Context): Agent {
|
||||
const id = SessionId('pty-loader-agent')
|
||||
const session = Session.create(id)
|
||||
const value: Agent = {
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
status: 'idle', ctx: scope.ctx,
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: scope.ctx,
|
||||
send: () => {},
|
||||
followup: () => {}, steer: () => {}, inject: () => {}, cancel() {},
|
||||
runMaintenance: task => task(new AbortController().signal),
|
||||
|
||||
@@ -18,8 +18,9 @@ function fakeAgent(ctx: Context, rawId: string): Agent {
|
||||
const id = SessionId(rawId)
|
||||
const session = Session.create(id)
|
||||
const agent: Agent = {
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
status: 'idle', ctx: scope.ctx,
|
||||
id, options: {}, session, inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
ctx: scope.ctx,
|
||||
send: () => {},
|
||||
followup: () => {}, steer: () => {}, inject: () => {}, cancel() {},
|
||||
runMaintenance: task => task(new AbortController().signal),
|
||||
|
||||
@@ -44,7 +44,7 @@ function agentForCwd(cwd: string): Agent {
|
||||
id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle',
|
||||
send: () => {},
|
||||
followup: () => {},
|
||||
@@ -61,7 +61,7 @@ function sessionAgent(session: Session, id = 'tool-skill-agent'): Agent {
|
||||
id: SessionId(id),
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'running',
|
||||
ctx: new Context(),
|
||||
send: () => {},
|
||||
|
||||
@@ -23,7 +23,7 @@ function stubAgent(ctx: Context, rawId: string): Agent {
|
||||
id,
|
||||
options: {},
|
||||
session,
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {} }),
|
||||
inbox: new Inbox(session, { inserted: () => {}, discarded: () => {}, claimed: () => {} }),
|
||||
status: 'idle' as const,
|
||||
ctx: scopeFiber.ctx,
|
||||
send: () => {},
|
||||
|
||||
Reference in New Issue
Block a user