@astrosheep/keiyaku 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms_v2.js +103 -0
- package/build/agents/harness/activity-values.js +54 -0
- package/build/agents/harness/event-channel.js +55 -20
- package/build/agents/harness/events.js +47 -1
- package/build/agents/harness/execution-handle.js +292 -61
- package/build/agents/harness/index.js +103 -121
- package/build/agents/harness/pump.js +36 -47
- package/build/agents/harness/runtime.js +3 -0
- package/build/agents/launch-snapshot_v2.js +348 -0
- package/build/agents/opencode-sdk.js +42 -169
- package/build/agents/providers/claude-agent-sdk.js +240 -79
- package/build/agents/providers/codex-app-server.js +280 -72
- package/build/agents/providers/codex-sdk.js +159 -41
- package/build/agents/providers/event-type-tail.js +16 -0
- package/build/agents/providers/opencode-sdk.js +165 -59
- package/build/agents/providers/pi.js +254 -42
- package/build/agents/selector_v2.js +122 -0
- package/build/cli/commands/akuma.js +120 -42
- package/build/cli/completion.js +6 -7
- package/build/cli/flags.js +36 -10
- package/build/cli/help.js +29 -24
- package/build/cli/index.js +225 -93
- package/build/cli/parse.js +194 -75
- package/build/cli/projection-address.js +11 -0
- package/build/cli/render/address.js +88 -0
- package/build/cli/render/arc.js +10 -10
- package/build/cli/render/call.js +59 -0
- package/build/cli/render/compact-text.js +3 -0
- package/build/cli/render/errors.js +4 -2
- package/build/cli/render/format.js +6 -0
- package/build/cli/render/line-width.js +70 -0
- package/build/cli/render/misc.js +7 -4
- package/build/cli/render/petition.js +4 -3
- package/build/cli/render/projection-activity.js +201 -0
- package/build/cli/render/shared.js +46 -12
- package/build/cli/render/status.js +59 -10
- package/build/cli/render/tool-ledger-rollup.js +74 -0
- package/build/cli/render/tool-presentation.js +97 -0
- package/build/cli/render/wait.js +229 -0
- package/build/cli/skills-install.js +42 -24
- package/build/cli/subagent-guard.js +1 -1
- package/build/config/akuma-loader_v2.js +222 -0
- package/build/config/env-keys.js +0 -4
- package/build/config/env.js +0 -6
- package/build/config/settings.js +325 -12
- package/build/core/addressing.js +224 -0
- package/build/core/amend.js +30 -47
- package/build/core/arc.js +68 -60
- package/build/core/bind.js +105 -25
- package/build/core/call-persist.js +69 -0
- package/build/core/call.js +658 -0
- package/build/core/claim.js +72 -44
- package/build/core/command-io.js +19 -19
- package/build/core/context.js +11 -36
- package/build/core/draft.js +2 -3
- package/build/core/entry.js +101 -6
- package/build/core/execution-coordinate.js +62 -0
- package/build/core/execution-pact.js +141 -0
- package/build/core/forfeit.js +2 -3
- package/build/core/hints.js +10 -10
- package/build/core/ids.js +6 -0
- package/build/core/ledger.js +16 -1
- package/build/core/petition-claim-gates.js +14 -12
- package/build/core/petition-claim.js +1 -0
- package/build/core/petition-run.js +6 -2
- package/build/core/petition.js +63 -21
- package/build/core/places.js +106 -13
- package/build/core/projection/generation.js +412 -0
- package/build/core/projection/heart.js +316 -0
- package/build/core/projection/identity.js +81 -0
- package/build/core/projection/leash.js +87 -0
- package/build/core/projection/mint.js +154 -0
- package/build/core/projection-activity.js +219 -0
- package/build/core/projection-coordinate.js +35 -0
- package/build/core/projection-core.js +69 -463
- package/build/core/projection-generation-continuation.js +31 -0
- package/build/core/projection-generation-execution.js +148 -0
- package/build/core/projection-generation-identity.js +17 -0
- package/build/core/projection-generation-launcher.js +90 -0
- package/build/core/projection-generation-process.js +43 -0
- package/build/core/projection-generation-runner.js +144 -0
- package/build/core/projection-generation-runtime.js +15 -0
- package/build/core/projection-generation-store.js +707 -0
- package/build/core/projection-identity.js +11 -0
- package/build/core/projection-life-observer.js +87 -0
- package/build/core/projection-life-protocol.js +95 -0
- package/build/core/projection-mint.js +96 -24
- package/build/core/projection-runner-lock.js +230 -0
- package/build/core/projection-status.js +207 -107
- package/build/core/projection-tells.js +401 -0
- package/build/core/projection-wait.js +155 -0
- package/build/core/projection-wake.js +109 -231
- package/build/core/queue_v2.js +342 -0
- package/build/core/registry.js +6 -3
- package/build/core/render.js +63 -1
- package/build/core/renew.js +80 -53
- package/build/core/scope.js +186 -137
- package/build/core/seal.js +16 -19
- package/build/core/status.js +88 -25
- package/build/core/stored-agent-event.js +101 -0
- package/build/core/transcripts.js +214 -228
- package/build/core/verdict.js +27 -15
- package/build/core/worktree-bootstrap.js +187 -0
- package/build/core/worktree-path.js +72 -18
- package/build/flow-error.js +4 -6
- package/build/generated/version.js +1 -1
- package/build/git/branches.js +6 -1
- package/build/index.js +8 -5
- package/build/keiyaku.js +1 -3
- package/package.json +6 -5
- package/skills/keiyaku/SKILL.md +6 -47
- package/skills/keiyaku-akuma/SKILL.md +75 -0
- package/build/agents/effective-policy.js +0 -32
- package/build/agents/index.js +0 -114
- package/build/agents/selector.js +0 -28
- package/build/cli/render/summon.js +0 -17
- package/build/cli/render/tell.js +0 -11
- package/build/config/akuma-loader.js +0 -268
- package/build/core/queue.js +0 -73
- package/build/core/summon-persist.js +0 -73
- package/build/core/summon.js +0 -377
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { appendDebugLog } from "../../telemetry/debug-log.js";
|
|
3
3
|
import { SUBAGENT_SESSION_VERSION } from "../session.js";
|
|
4
|
-
import { coerceString } from "../index.js";
|
|
5
4
|
import { createProjectionDriver } from "../harness/execution-handle.js";
|
|
6
|
-
import {
|
|
5
|
+
import { activityCallFromNamedTool, boundActivityExcerpt } from "../harness/activity-values.js";
|
|
6
|
+
import { buildSubagentEnv, coerceString, createAbortError, emitProviderEvidence, linkAbortSignal, sha256Utf8 } from "../harness/runtime.js";
|
|
7
|
+
import { AGENT_PLAN_ITEM_TEXT_MAX_CHARS, AGENT_PLAN_MAX_ITEMS, AGENT_THOUGHT_TEXT_MAX_CHARS, } from "../harness/events.js";
|
|
8
|
+
const CLAUDE_MAPPED = new Set(["assistant", "user", "result", "system", "fallback"]);
|
|
9
|
+
const CLAUDE_ACKNOWLEDGED_UNPERSISTED = new Set([
|
|
10
|
+
"stream_event",
|
|
11
|
+
"rate_limit_event",
|
|
12
|
+
"control_cancel_request",
|
|
13
|
+
"control_request",
|
|
14
|
+
"control_response",
|
|
15
|
+
"conversation_reset",
|
|
16
|
+
"keep_alive",
|
|
17
|
+
"local",
|
|
18
|
+
"prompt_suggestion",
|
|
19
|
+
"tool_progress",
|
|
20
|
+
"tool_use_summary",
|
|
21
|
+
"auth_status",
|
|
22
|
+
]);
|
|
23
|
+
function claudeIngressDisposition(type) {
|
|
24
|
+
if (CLAUDE_MAPPED.has(type))
|
|
25
|
+
return "mapped";
|
|
26
|
+
if (CLAUDE_ACKNOWLEDGED_UNPERSISTED.has(type))
|
|
27
|
+
return "acknowledged-unpersisted";
|
|
28
|
+
return "unknown";
|
|
29
|
+
}
|
|
30
|
+
function toClaudeSdkEffort(effort) {
|
|
31
|
+
return effort; // opacity boundary
|
|
32
|
+
}
|
|
7
33
|
export const claudeSessionSchema = z.object({ sessionId: z.string().trim().min(1) });
|
|
8
34
|
const CLAUDE_AGENT_SDK_PROVIDER = "claude-agent-sdk";
|
|
9
35
|
let claudeAgentSdkLoader;
|
|
@@ -31,6 +57,119 @@ function extractAssistantMessage(event) {
|
|
|
31
57
|
function extractAssistantMessageModel(event) {
|
|
32
58
|
return coerceString(event.message.model);
|
|
33
59
|
}
|
|
60
|
+
function claudeActivityCall(name, input) {
|
|
61
|
+
if (!isRecord(input))
|
|
62
|
+
return { kind: "other", display: name };
|
|
63
|
+
return activityCallFromNamedTool(name, {
|
|
64
|
+
...(typeof input.command === "string" ? { command: input.command } : {}),
|
|
65
|
+
...(typeof input.description === "string" ? { description: input.description } : {}),
|
|
66
|
+
...(typeof input.file_path === "string" ? { path: input.file_path } : {}),
|
|
67
|
+
...(typeof input.offset === "number" && Number.isFinite(input.offset) ? { offset: input.offset } : {}),
|
|
68
|
+
...(typeof input.limit === "number" && Number.isFinite(input.limit) ? { limit: input.limit } : {}),
|
|
69
|
+
...(typeof input.query === "string" ? { query: input.query } : {}),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function claudeResultMessage(content) {
|
|
73
|
+
if (typeof content === "string")
|
|
74
|
+
return content ? boundActivityExcerpt(content) : undefined;
|
|
75
|
+
if (!Array.isArray(content))
|
|
76
|
+
return undefined;
|
|
77
|
+
const text = content.flatMap((entry) => {
|
|
78
|
+
if (!isRecord(entry) || entry.type !== "text" || typeof entry.text !== "string")
|
|
79
|
+
return [];
|
|
80
|
+
return [entry.text];
|
|
81
|
+
}).join("\n");
|
|
82
|
+
return text ? boundActivityExcerpt(text) : undefined;
|
|
83
|
+
}
|
|
84
|
+
function emitClaudeToolStarts(builder, event, seenToolUses) {
|
|
85
|
+
if (!Array.isArray(event.message.content))
|
|
86
|
+
return;
|
|
87
|
+
for (const block of event.message.content) {
|
|
88
|
+
if (!isRecord(block) || block.type !== "tool_use")
|
|
89
|
+
continue;
|
|
90
|
+
const id = coerceString(block.id);
|
|
91
|
+
const name = coerceString(block.name);
|
|
92
|
+
if (!id || !name)
|
|
93
|
+
continue;
|
|
94
|
+
const call = claudeActivityCall(name, block.input);
|
|
95
|
+
seenToolUses.set(id, { tool: name, call });
|
|
96
|
+
builder.emit({
|
|
97
|
+
type: "activity",
|
|
98
|
+
phase: "started",
|
|
99
|
+
id,
|
|
100
|
+
tool: name,
|
|
101
|
+
call,
|
|
102
|
+
});
|
|
103
|
+
if (name === "TodoWrite" && isRecord(block.input) && Array.isArray(block.input.todos)) {
|
|
104
|
+
const items = block.input.todos.slice(0, AGENT_PLAN_MAX_ITEMS).flatMap((todo) => {
|
|
105
|
+
if (!isRecord(todo) || typeof todo.content !== "string" || typeof todo.status !== "string") {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
return [{
|
|
109
|
+
text: todo.content.slice(0, AGENT_PLAN_ITEM_TEXT_MAX_CHARS),
|
|
110
|
+
done: todo.status === "completed",
|
|
111
|
+
...(todo.status === "in_progress" ? { active: true } : {}),
|
|
112
|
+
}];
|
|
113
|
+
});
|
|
114
|
+
builder.emit({ type: "plan", id, items });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function emitClaudeThoughts(builder, event) {
|
|
119
|
+
if (!Array.isArray(event.message.content))
|
|
120
|
+
return;
|
|
121
|
+
event.message.content.forEach((block, blockIndex) => {
|
|
122
|
+
if (!isRecord(block) || block.type !== "thinking" || typeof block.thinking !== "string")
|
|
123
|
+
return;
|
|
124
|
+
const truncated = block.thinking.length > AGENT_THOUGHT_TEXT_MAX_CHARS;
|
|
125
|
+
builder.emit({
|
|
126
|
+
type: "thought",
|
|
127
|
+
id: `${event.uuid}:${blockIndex}`,
|
|
128
|
+
text: block.thinking.slice(0, AGENT_THOUGHT_TEXT_MAX_CHARS),
|
|
129
|
+
final: true,
|
|
130
|
+
...(truncated ? { truncated: true } : {}),
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function emitClaudeToolResults(builder, event, seenToolUses) {
|
|
135
|
+
const content = event.message.content;
|
|
136
|
+
if (!Array.isArray(content))
|
|
137
|
+
return;
|
|
138
|
+
for (const block of content) {
|
|
139
|
+
if (!isRecord(block) || block.type !== "tool_result")
|
|
140
|
+
continue;
|
|
141
|
+
const id = coerceString(block.tool_use_id);
|
|
142
|
+
if (!id)
|
|
143
|
+
continue;
|
|
144
|
+
const observed = seenToolUses.get(id);
|
|
145
|
+
if (!observed)
|
|
146
|
+
continue;
|
|
147
|
+
seenToolUses.delete(id);
|
|
148
|
+
const message = claudeResultMessage(block.content);
|
|
149
|
+
builder.emit({
|
|
150
|
+
type: "activity",
|
|
151
|
+
phase: "completed",
|
|
152
|
+
id,
|
|
153
|
+
tool: observed.tool,
|
|
154
|
+
call: observed.call,
|
|
155
|
+
result: {
|
|
156
|
+
status: block.is_error === true ? "error" : "ok",
|
|
157
|
+
...(message ? { message } : {}),
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function emitClaudeUsage(builder, event, model) {
|
|
163
|
+
const usage = event.usage;
|
|
164
|
+
builder.emit({
|
|
165
|
+
type: "usage",
|
|
166
|
+
inputTokens: usage.input_tokens,
|
|
167
|
+
outputTokens: usage.output_tokens,
|
|
168
|
+
cachedInputTokens: usage.cache_read_input_tokens,
|
|
169
|
+
...(typeof event.total_cost_usd === "number" ? { costUsd: event.total_cost_usd } : {}),
|
|
170
|
+
...(model ? { model } : {}),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
34
173
|
function isRecord(value) {
|
|
35
174
|
return typeof value === "object" && value !== null;
|
|
36
175
|
}
|
|
@@ -253,6 +392,7 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
253
392
|
let completedResultOrdinal = 0;
|
|
254
393
|
let openSteerCount = 0;
|
|
255
394
|
let sawSuccessfulResult = false;
|
|
395
|
+
let emitTurnStarted;
|
|
256
396
|
const activeWaiters = new Set();
|
|
257
397
|
const notifyActive = () => {
|
|
258
398
|
for (const resolve of [...activeWaiters]) {
|
|
@@ -305,7 +445,7 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
305
445
|
throw new Error(`${CLAUDE_AGENT_SDK_PROVIDER} cannot enqueue: query ended before yield`);
|
|
306
446
|
}
|
|
307
447
|
if (message.effort) {
|
|
308
|
-
await liveQuery.applyFlagSettings({ effortLevel: message.effort
|
|
448
|
+
await liveQuery.applyFlagSettings({ effortLevel: toClaudeSdkEffort(message.effort) });
|
|
309
449
|
}
|
|
310
450
|
// The pump calls enqueue at a successful result checkpoint. Push now;
|
|
311
451
|
// waiting for another result before pushing would deadlock the next turn.
|
|
@@ -313,6 +453,7 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
313
453
|
const submitted = inputStream.push(toUserMessage(message.text));
|
|
314
454
|
// submitted = NEXT source next() after this tell is yielded (not the yield pull itself).
|
|
315
455
|
await submitted.waitSubmitted();
|
|
456
|
+
emitTurnStarted?.();
|
|
316
457
|
// 落账:记录提交时越过的 result ordinal(generation fence 落点)。
|
|
317
458
|
const submittedAfterResultOrdinal = completedResultOrdinal;
|
|
318
459
|
if (options.onEvidence)
|
|
@@ -326,7 +467,9 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
326
467
|
};
|
|
327
468
|
return createProjectionDriver({
|
|
328
469
|
steerMode: "mid-execution",
|
|
470
|
+
initialTurn: options.initialTurn,
|
|
329
471
|
enqueue,
|
|
472
|
+
onIngress: options.onIngress,
|
|
330
473
|
async abort() {
|
|
331
474
|
queryEnded = true;
|
|
332
475
|
queryActive = false;
|
|
@@ -343,6 +486,7 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
343
486
|
},
|
|
344
487
|
async run(builder) {
|
|
345
488
|
builderDiagnostic = (text) => builder.emit({ type: "diagnostic", text });
|
|
489
|
+
emitTurnStarted = () => builder.emit({ type: "turn", phase: "started" });
|
|
346
490
|
while (pendingEvidenceDiagnostics > 0) {
|
|
347
491
|
pendingEvidenceDiagnostics -= 1;
|
|
348
492
|
builderDiagnostic("provider evidence callback failed");
|
|
@@ -366,12 +510,10 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
366
510
|
emitProviderEvidence(options.onEvidence, { type: "outbound", provider: CLAUDE_AGENT_SDK_PROVIDER, direction: "input", kind: "steer", ...sha256Utf8(text) }, (text) => builder.emit({ type: "diagnostic", text }));
|
|
367
511
|
});
|
|
368
512
|
inputStream.push(initialMessage);
|
|
513
|
+
builder.emit({ type: "turn", phase: "started" });
|
|
369
514
|
const queryOptions = {
|
|
370
515
|
cwd,
|
|
371
516
|
model: options.model,
|
|
372
|
-
permissionMode: options.permissionMode,
|
|
373
|
-
allowDangerouslySkipPermissions: options.permissionMode === "bypassPermissions",
|
|
374
|
-
settingSources: [...options.settingSources],
|
|
375
517
|
resume: sessionId,
|
|
376
518
|
env: buildSubagentEnv(),
|
|
377
519
|
abortController: queryAbortController,
|
|
@@ -381,10 +523,22 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
381
523
|
builder.emit({ type: "diagnostic", text: data });
|
|
382
524
|
},
|
|
383
525
|
};
|
|
526
|
+
if (options.permissionMode !== undefined) {
|
|
527
|
+
queryOptions.permissionMode = options.permissionMode;
|
|
528
|
+
if (options.permissionMode === "bypassPermissions") {
|
|
529
|
+
queryOptions.allowDangerouslySkipPermissions = true;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (options.settingSources !== undefined) {
|
|
533
|
+
queryOptions.settingSources = [...options.settingSources];
|
|
534
|
+
}
|
|
535
|
+
if (options.disallowedTools !== undefined) {
|
|
536
|
+
queryOptions.disallowedTools = [...options.disallowedTools];
|
|
537
|
+
}
|
|
384
538
|
const execPathKey = `pathToClaudeCode${"Ex"}ecutable`;
|
|
385
539
|
queryOptions[execPathKey] = options.executable;
|
|
386
540
|
if (options.effort !== undefined) {
|
|
387
|
-
queryOptions.effort = options.effort;
|
|
541
|
+
queryOptions.effort = toClaudeSdkEffort(options.effort);
|
|
388
542
|
}
|
|
389
543
|
// Long-lived push-AsyncIterable: one stream for the whole Query lifetime (Tier 1).
|
|
390
544
|
// Never mount short per-tell streams (that would endInput and break stdin).
|
|
@@ -400,87 +554,94 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
|
|
|
400
554
|
let resumedSessionId = sessionId;
|
|
401
555
|
let finalMessage;
|
|
402
556
|
let latestAssistantMessageModel;
|
|
557
|
+
const seenToolUses = new Map();
|
|
403
558
|
for await (const event of query) {
|
|
404
|
-
builder.
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
if (isClaudeModelRefusalFallbackEvent(event)) {
|
|
411
|
-
builder.emit({
|
|
412
|
-
type: "warning",
|
|
413
|
-
warning: {
|
|
414
|
-
reason: "refusal",
|
|
415
|
-
originalModel: event.original_model,
|
|
416
|
-
fallbackModel: event.fallback_model,
|
|
417
|
-
direction: event.direction,
|
|
418
|
-
requestId: event.request_id,
|
|
419
|
-
...(latestAssistantMessageModel ? { signerModel: latestAssistantMessageModel } : {}),
|
|
420
|
-
},
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
else if (isClaudeModelRefusalNoFallbackEvent(event)) {
|
|
424
|
-
builder.emit({
|
|
425
|
-
type: "warning",
|
|
426
|
-
warning: {
|
|
427
|
-
reason: "refusal",
|
|
428
|
-
originalModel: event.original_model,
|
|
429
|
-
requestId: event.request_id,
|
|
430
|
-
...(latestAssistantMessageModel ? { signerModel: latestAssistantMessageModel } : {}),
|
|
431
|
-
},
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
switch (event.type) {
|
|
435
|
-
case "assistant": {
|
|
436
|
-
latestAssistantMessageModel = extractAssistantMessageModel(event) ?? latestAssistantMessageModel;
|
|
437
|
-
finalMessage = extractAssistantMessage(event) ?? finalMessage;
|
|
438
|
-
if (finalMessage) {
|
|
439
|
-
builder.emit({ type: "message", text: finalMessage });
|
|
440
|
-
}
|
|
441
|
-
break;
|
|
559
|
+
builder.ingress(CLAUDE_AGENT_SDK_PROVIDER, event.type, event, claudeIngressDisposition(event.type), () => {
|
|
560
|
+
resumedSessionId = extractResumeToken(event) ?? resumedSessionId;
|
|
561
|
+
const overloadWarning = extractOverloadFallbackWarning(event);
|
|
562
|
+
if (overloadWarning) {
|
|
563
|
+
builder.emit({ type: "warning", warning: overloadWarning });
|
|
442
564
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
565
|
+
if (isClaudeModelRefusalFallbackEvent(event)) {
|
|
566
|
+
builder.emit({
|
|
567
|
+
type: "warning",
|
|
568
|
+
warning: {
|
|
569
|
+
reason: "refusal",
|
|
570
|
+
originalModel: event.original_model,
|
|
571
|
+
fallbackModel: event.fallback_model,
|
|
572
|
+
direction: event.direction,
|
|
573
|
+
requestId: event.request_id,
|
|
574
|
+
...(latestAssistantMessageModel ? { signerModel: latestAssistantMessageModel } : {}),
|
|
575
|
+
},
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
else if (isClaudeModelRefusalNoFallbackEvent(event)) {
|
|
579
|
+
builder.emit({
|
|
580
|
+
type: "warning",
|
|
581
|
+
warning: {
|
|
582
|
+
reason: "refusal",
|
|
583
|
+
originalModel: event.original_model,
|
|
584
|
+
requestId: event.request_id,
|
|
585
|
+
...(latestAssistantMessageModel ? { signerModel: latestAssistantMessageModel } : {}),
|
|
586
|
+
},
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
switch (event.type) {
|
|
590
|
+
case "assistant": {
|
|
591
|
+
latestAssistantMessageModel = extractAssistantMessageModel(event) ?? latestAssistantMessageModel;
|
|
592
|
+
emitClaudeThoughts(builder, event);
|
|
593
|
+
emitClaudeToolStarts(builder, event, seenToolUses);
|
|
594
|
+
finalMessage = extractAssistantMessage(event) ?? finalMessage;
|
|
447
595
|
if (finalMessage) {
|
|
448
596
|
builder.emit({ type: "message", text: finalMessage });
|
|
449
597
|
}
|
|
450
|
-
sawSuccessfulResult = true;
|
|
451
|
-
// Advance generation fence BEFORE maybe-ending the stream so gated tells can yield.
|
|
452
|
-
bumpResultOrdinal();
|
|
453
|
-
const checkpoint = {
|
|
454
|
-
fence: { kind: "ordinal", ordinal: completedResultOrdinal },
|
|
455
|
-
};
|
|
456
|
-
// Record the native result before the synchronous pump can
|
|
457
|
-
// consume any tell fenced to an earlier result.
|
|
458
|
-
if (options.onEvidence) {
|
|
459
|
-
emitProviderEvidence(options.onEvidence, {
|
|
460
|
-
type: "checkpoint",
|
|
461
|
-
provider: CLAUDE_AGENT_SDK_PROVIDER,
|
|
462
|
-
...checkpoint,
|
|
463
|
-
source: "response",
|
|
464
|
-
}, (text) => builder.emit({ type: "diagnostic", text }));
|
|
465
|
-
}
|
|
466
|
-
// Sync checkpoint: claim inbox tells and deliver them via steer control.
|
|
467
|
-
options.onSyncCheckpoint?.({ enqueue }, checkpoint);
|
|
468
|
-
// Defer end so concurrent enqueue after this result can register openSteerCount.
|
|
469
|
-
queueMicrotask(() => maybeEndInputStream());
|
|
470
598
|
break;
|
|
471
599
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
600
|
+
case "user": {
|
|
601
|
+
emitClaudeToolResults(builder, event, seenToolUses);
|
|
602
|
+
break;
|
|
475
603
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
604
|
+
case "result": {
|
|
605
|
+
const resultText = extractResultText(event);
|
|
606
|
+
if (event.subtype === "success") {
|
|
607
|
+
finalMessage = resultText ?? finalMessage;
|
|
608
|
+
emitClaudeUsage(builder, event, latestAssistantMessageModel);
|
|
609
|
+
builder.emit({ type: "turn", phase: "completed" });
|
|
610
|
+
sawSuccessfulResult = true;
|
|
611
|
+
// Advance generation fence BEFORE maybe-ending the stream so gated tells can yield.
|
|
612
|
+
bumpResultOrdinal();
|
|
613
|
+
const checkpoint = {
|
|
614
|
+
fence: { kind: "ordinal", ordinal: completedResultOrdinal },
|
|
615
|
+
};
|
|
616
|
+
// Record the native result before the synchronous pump can
|
|
617
|
+
// consume any tell fenced to an earlier result.
|
|
618
|
+
if (options.onEvidence) {
|
|
619
|
+
emitProviderEvidence(options.onEvidence, {
|
|
620
|
+
type: "checkpoint",
|
|
621
|
+
provider: CLAUDE_AGENT_SDK_PROVIDER,
|
|
622
|
+
...checkpoint,
|
|
623
|
+
source: "response",
|
|
624
|
+
}, (text) => builder.emit({ type: "diagnostic", text }));
|
|
625
|
+
}
|
|
626
|
+
// Sync checkpoint: claim inbox tells and deliver them via steer control.
|
|
627
|
+
options.onSyncCheckpoint?.({ enqueue }, checkpoint);
|
|
628
|
+
// Defer end so concurrent enqueue after this result can register openSteerCount.
|
|
629
|
+
queueMicrotask(() => maybeEndInputStream());
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
632
|
+
bumpResultOrdinal();
|
|
633
|
+
if (resultText) {
|
|
634
|
+
builder.emit({ type: "diagnostic", text: resultText });
|
|
635
|
+
}
|
|
636
|
+
const message = resultText ?? `${CLAUDE_AGENT_SDK_PROVIDER} exec failed`;
|
|
637
|
+
builder.emit({ type: "fail", message });
|
|
638
|
+
inputStream?.end();
|
|
639
|
+
throw new Error(message);
|
|
640
|
+
}
|
|
641
|
+
default:
|
|
642
|
+
break;
|
|
480
643
|
}
|
|
481
|
-
|
|
482
|
-
break;
|
|
483
|
-
}
|
|
644
|
+
});
|
|
484
645
|
}
|
|
485
646
|
if (queryAbortController.signal.aborted) {
|
|
486
647
|
throw createAbortError(`${CLAUDE_AGENT_SDK_PROVIDER} exec cancelled by client`);
|