feat(coder): add hashline editing core + wire audit hooks into dispatch pipeline
Hashline editing: content-hash anchors for edit_file stale-patch detection.
Pure-JS xxHash32, line hash computation, validation with HashlineMismatchError,
256-entry hash dictionary. 6 files in apps/coder/src/services/hashline/.
Audit hooks: emitHook('tool.execute.after') wired in frame-emitter.ts for
completed/failed tool results. emitHook('turn.end') wired at terminal points
in dispatcher.ts (all 5 run functions: native, external, opencode, warm ACP,
claude SDK). Fire-and-forget, non-blocking.
This commit is contained in:
@@ -19,9 +19,10 @@
|
||||
import type { Broker } from '@boocode/server/broker';
|
||||
import type { WsFrame } from '@boocode/contracts/ws-frames';
|
||||
import type { AgentEvent } from './agent-backend.js';
|
||||
import { type AcpToolSnapshot, snapshotToWireToolCall } from './acp-tool-snapshot.js';
|
||||
import { type AcpToolSnapshot, snapshotToWireToolCall, mapToolLifecycleStatus } from './acp-tool-snapshot.js';
|
||||
import { mergeTaskCommands, getTaskCommands } from './agent-commands-cache.js';
|
||||
import type { DcpStreamStripper } from './dcp-strip.js';
|
||||
import { emitHook } from '../plugins/host.js';
|
||||
|
||||
export interface FrameEmitterOpts {
|
||||
broker?: Broker;
|
||||
@@ -91,8 +92,29 @@ export function makeFrameEmitter(opts: FrameEmitterOpts): FrameEmitter {
|
||||
}
|
||||
break;
|
||||
case 'tool_call':
|
||||
toolSnapshots.set(e.toolCall.toolCallId, e.toolCall);
|
||||
if (canStream()) {
|
||||
broker!.publishFrame(sessionId!, {
|
||||
type: 'tool_call',
|
||||
message_id: assistantId!,
|
||||
chat_id: chatId!,
|
||||
tool_call: snapshotToWireToolCall(e.toolCall),
|
||||
} as WsFrame);
|
||||
}
|
||||
break;
|
||||
case 'tool_update':
|
||||
toolSnapshots.set(e.toolCall.toolCallId, e.toolCall);
|
||||
{
|
||||
const lifecycle = mapToolLifecycleStatus(e.toolCall.status, e.toolCall.rawOutput);
|
||||
if (lifecycle === 'completed' || lifecycle === 'failed') {
|
||||
void emitHook('tool.execute.after', {
|
||||
toolName: e.toolCall.title,
|
||||
args: e.toolCall.rawInput,
|
||||
result: e.toolCall.rawOutput,
|
||||
duration: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (canStream()) {
|
||||
broker!.publishFrame(sessionId!, {
|
||||
type: 'tool_call',
|
||||
|
||||
Reference in New Issue
Block a user