refactor(agent): unify sourced message delivery

This commit is contained in:
_Kerman
2026-07-24 22:38:50 +08:00
parent 009d113e0e
commit 992cf894af
197 changed files with 1890 additions and 2132 deletions

View File

@@ -221,13 +221,13 @@ export function apply(ctx: Context, config: Config): void {
ctx.tasks.onTaskDone((snapshot, owner) => {
if (snapshot.reported || owner === undefined) return
try {
owner.inject(
[{
owner.inject({
content: [{
type: 'text',
text: fitCompletionNotice(snapshot),
}],
{ source: { kind: 'plugin', plugin: 'tool-tasks' } },
)
source: { kind: 'plugin', plugin: 'tool-tasks' },
})
} catch (error: unknown) {
// Disposal may win the race after settlement; other injection failures surface.
if (error instanceof Error && error.message.includes('is disposed')) return

View File

@@ -455,10 +455,10 @@ describe('completion notices', () => {
p.settle({ status: 'completed', detail: 'exit code: 0' })
await tick()
expect(inject).toHaveBeenCalledTimes(1)
expect(inject).toHaveBeenCalledWith(
[{ type: 'text', text: 'background task bash-1 (bash: pnpm test) finished [status: completed, exit code: 0]. Read its output with task_output.' }],
{ source: { kind: 'plugin', plugin: 'tool-tasks' } },
)
expect(inject).toHaveBeenCalledWith({
content: [{ type: 'text', text: 'background task bash-1 (bash: pnpm test) finished [status: completed, exit code: 0]. Read its output with task_output.' }],
source: { kind: 'plugin', plugin: 'tool-tasks' },
})
})
it('preserves task ids and collection guidance in bounded completion notices', async () => {
@@ -477,8 +477,10 @@ describe('completion notices', () => {
expect(inject).toHaveBeenNthCalledWith(
1,
[{ type: 'text', text: 'background task subagent-1\n[notice truncated]\nDone; task_output.' }],
{ source: { kind: 'plugin', plugin: 'tool-tasks' } },
{
content: [{ type: 'text', text: 'background task subagent-1\n[notice truncated]\nDone; task_output.' }],
source: { kind: 'plugin', plugin: 'tool-tasks' },
},
)
const second = producer({
@@ -491,7 +493,7 @@ describe('completion notices', () => {
second.settle({ status: 'completed', detail: 'd'.repeat(1_000) })
await tick()
const content = inject.mock.calls[1]?.[0] as Array<{ type: string; text?: string }> | undefined
const content = (inject.mock.calls[1]?.[0] as { content?: Array<{ type: string; text?: string }> } | undefined)?.content
const notice = content?.[0]?.text ?? ''
expect(Buffer.byteLength(notice)).toBeLessThanOrEqual(80)
expect(notice).toContain('background task subagent-2 (subagent: xxxx')
@@ -518,7 +520,7 @@ describe('completion notices', () => {
target.settle({ status: 'completed', detail: 'd'.repeat(1_000) })
await tick()
const content = inject.mock.calls[0]?.[0] as Array<{ type: string; text?: string }> | undefined
const content = (inject.mock.calls[0]?.[0] as { content?: Array<{ type: string; text?: string }> } | undefined)?.content
const notice = content?.[0]?.text ?? ''
expect(Buffer.byteLength(notice)).toBeLessThanOrEqual(64)
expect(notice).toBe('background task pty-send-100\nDone; task_output.')
@@ -537,8 +539,8 @@ describe('completion notices', () => {
short.settle({ status: 'completed' })
await tick()
const tinyNotice = (inject.mock.calls[0]?.[0] as Array<{ text?: string }> | undefined)?.[0]?.text ?? ''
const shortNotice = (inject.mock.calls[1]?.[0] as Array<{ text?: string }> | undefined)?.[0]?.text ?? ''
const tinyNotice = (inject.mock.calls[0]?.[0] as { content?: Array<{ text?: string }> } | undefined)?.content?.[0]?.text ?? ''
const shortNotice = (inject.mock.calls[1]?.[0] as { content?: Array<{ text?: string }> } | undefined)?.content?.[0]?.text ?? ''
expect(Buffer.byteLength(tinyNotice)).toBeLessThanOrEqual(8)
expect(tinyNotice).toBe('_output.')
expect(Buffer.byteLength(shortNotice)).toBeLessThanOrEqual(32)