feat(agent): unify send(target × wakeup), coalesce context/message into user/message
Replace send/steer/inject with one Agent.send primitive over the (target × wakeup) matrix; followup/steer/inject become fixed-preset alias methods on the now-abstract Agent class. Coalesce context/message into user/message (injected context is a non-user source). Replace agent/queued with agent/inbox/enqueue/dequeue/discard, add cancel keepInbox, and add a FIFO-conservation invariant.
This commit is contained in:
@@ -42,7 +42,7 @@ function buildAlphaLog(): SessionEvent[] {
|
||||
push({ type: 'turn/start', data: { turn, trigger: { kind: 'message', source: { kind: 'user' } } } })
|
||||
push({ type: 'user/message', surfaceOp: 'append', data: { content: text(`问题 ${turn}:fixture 历史消息,用于翻页与渲染验收。`), source: { kind: 'user' } } })
|
||||
if (turn % 9 === 4) {
|
||||
push({ type: 'context/message', surfaceOp: 'append', data: { content: text(`[fixture] 上下文注入(turn ${turn})`), source: { kind: 'plugin', plugin: 'fixture' } } })
|
||||
push({ type: 'user/message', surfaceOp: 'append', data: { content: text(`[fixture] 上下文注入(turn ${turn})`), source: { kind: 'plugin', plugin: 'fixture' } } })
|
||||
}
|
||||
push({ type: 'step/start', data: { turn, step: 0 } })
|
||||
const withTool = turn % 5 === 2
|
||||
|
||||
@@ -38,6 +38,14 @@ function materializeNode(
|
||||
): ConversationNode {
|
||||
switch (event.type) {
|
||||
case 'user/message':
|
||||
// Injected context (plugin/goal source) folds to a context node, not a
|
||||
// user message; only a direct human prompt is a user node.
|
||||
if (event.data.source.kind !== 'user') {
|
||||
return {
|
||||
kind: 'context', seq: event.seq, content: event.data.content, source: event.data.source,
|
||||
meta: event.data.meta,
|
||||
}
|
||||
}
|
||||
return { kind: 'user', seq: event.seq, content: event.data.content, source: event.data.source }
|
||||
case 'assistant/message':
|
||||
return {
|
||||
@@ -46,11 +54,6 @@ function materializeNode(
|
||||
}
|
||||
case 'steering/message':
|
||||
return { kind: 'steering', seq: event.seq, turn: event.data.turn, content: event.data.content, source: event.data.source }
|
||||
case 'context/message':
|
||||
return {
|
||||
kind: 'context', seq: event.seq, content: event.data.content, source: event.data.source,
|
||||
meta: event.data.meta,
|
||||
}
|
||||
case 'tool/result': {
|
||||
const call = callIndex.get(String(event.data.callId))
|
||||
return {
|
||||
@@ -63,7 +66,7 @@ function materializeNode(
|
||||
resultView,
|
||||
}
|
||||
}
|
||||
/* v8 ignore next 2 -- defensive arm: fold output only carries the five
|
||||
/* v8 ignore next 2 -- defensive arm: fold output only carries the four
|
||||
surface-eligible types, and each has a case above; reachable only if core
|
||||
adds an eligible type. */
|
||||
default:
|
||||
|
||||
@@ -40,7 +40,7 @@ describe('FoldAdapter', () => {
|
||||
ev.user(0, '用户'),
|
||||
ev.assistant(1, 0, '助手'),
|
||||
at(2, { type: 'steering/message', surfaceOp: 'append', data: { turn: 0, content: [{ type: 'text', text: '插话' }], source: { kind: 'user' } } }),
|
||||
at(3, { type: 'context/message', surfaceOp: 'append', data: { content: [{ type: 'text', text: '上下文' }], source: { kind: 'plugin', plugin: 'p' } } }),
|
||||
at(3, { type: 'user/message', surfaceOp: 'append', data: { content: [{ type: 'text', text: '上下文' }], source: { kind: 'plugin', plugin: 'p' } } }),
|
||||
ev.toolCall(4, 0, 'c1', 'echo', '{"x":1}'),
|
||||
ev.toolResult(5, 0, 'c1', '结果'),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user