@ai-sdk/harness-claude-code 1.0.137 → 1.0.138
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/CHANGELOG.md +15 -0
- package/README.md +5 -0
- package/dist/bridge/index.mjs +1619 -1792
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +25747 -25734
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1697 -1969
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
- package/src/bridge/create-emit-stream-event.ts +49 -2
- package/src/bridge/index.ts +8 -2
- package/src/claude-code-bridge-protocol.ts +2 -0
- package/src/claude-code-harness.ts +26 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness-claude-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.138",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ai-sdk/harness": "1.0.
|
|
30
|
-
"@ai-sdk/provider
|
|
29
|
+
"@ai-sdk/harness": "1.0.134",
|
|
30
|
+
"@ai-sdk/provider": "4.0.20",
|
|
31
|
+
"@ai-sdk/provider-utils": "5.0.52",
|
|
31
32
|
"ws": "^8.21.0"
|
|
32
33
|
},
|
|
33
34
|
"peerDependencies": {
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
"@types/node": "22.19.19",
|
|
40
41
|
"@types/ws": "^8.5.13",
|
|
41
42
|
"@vercel/ai-tsconfig": "0.0.0",
|
|
42
|
-
"
|
|
43
|
+
"tsdown": "^0.23.0",
|
|
43
44
|
"typescript": "5.8.3",
|
|
44
45
|
"zod": "3.25.76"
|
|
45
46
|
},
|
|
@@ -65,9 +66,9 @@
|
|
|
65
66
|
"claude-code"
|
|
66
67
|
],
|
|
67
68
|
"scripts": {
|
|
68
|
-
"build": "pnpm clean &&
|
|
69
|
-
"build:watch": "pnpm clean &&
|
|
70
|
-
"clean": "del-cli
|
|
69
|
+
"build": "pnpm clean && tsdown && pnpm copy-bridge-assets",
|
|
70
|
+
"build:watch": "pnpm clean && tsdown --watch",
|
|
71
|
+
"clean": "del-cli *.tsbuildinfo",
|
|
71
72
|
"copy-bridge-assets": "node -e \"import('node:fs/promises').then(async fs => { await fs.copyFile('src/bridge/package.json', 'dist/bridge/package.json'); await fs.copyFile('src/bridge/pnpm-lock.yaml', 'dist/bridge/pnpm-lock.yaml'); await fs.copyFile('src/bridge/pnpm-workspace.yaml', 'dist/bridge/pnpm-workspace.yaml'); })\"",
|
|
72
73
|
"type-check": "tsc --build",
|
|
73
74
|
"test": "pnpm test:node",
|
|
@@ -22,6 +22,9 @@ export type ClaudeMessage = {
|
|
|
22
22
|
type?: string;
|
|
23
23
|
index?: number;
|
|
24
24
|
usage?: Record<string, unknown>;
|
|
25
|
+
message?: {
|
|
26
|
+
usage?: Record<string, unknown>;
|
|
27
|
+
};
|
|
25
28
|
content_block?: {
|
|
26
29
|
type?: string;
|
|
27
30
|
id?: string;
|
|
@@ -76,6 +79,7 @@ export type ClaudeStreamEventState = {
|
|
|
76
79
|
pendingStepAssistantUsage: Record<string, unknown> | undefined;
|
|
77
80
|
pendingStepDeltaUsage: Record<string, unknown> | undefined;
|
|
78
81
|
pendingStepUsage: Record<string, unknown> | undefined;
|
|
82
|
+
pendingResponseUsage: Record<string, unknown> | undefined;
|
|
79
83
|
stepOpen: boolean;
|
|
80
84
|
/*
|
|
81
85
|
* Tool-use ids that originated from the MCP server hosting user-supplied
|
|
@@ -103,6 +107,7 @@ export function createClaudeStreamEventState(): ClaudeStreamEventState {
|
|
|
103
107
|
pendingStepAssistantUsage: undefined,
|
|
104
108
|
pendingStepDeltaUsage: undefined,
|
|
105
109
|
pendingStepUsage: undefined,
|
|
110
|
+
pendingResponseUsage: undefined,
|
|
106
111
|
stepOpen: false,
|
|
107
112
|
mcpToolUseIds: new Set(),
|
|
108
113
|
externalMcpToolUseIds: new Set(),
|
|
@@ -113,6 +118,13 @@ export function createClaudeStreamEventState(): ClaudeStreamEventState {
|
|
|
113
118
|
|
|
114
119
|
const UNRECOVERABLE_API_RETRY_STATUSES = new Set([401, 403, 404]);
|
|
115
120
|
const HOST_TOOL_PREFIX = 'mcp__harness-tools__';
|
|
121
|
+
const RAW_TASK_MESSAGE_SUBTYPES = new Set([
|
|
122
|
+
'background_tasks_changed',
|
|
123
|
+
'task_started',
|
|
124
|
+
'task_progress',
|
|
125
|
+
'task_updated',
|
|
126
|
+
'task_notification',
|
|
127
|
+
]);
|
|
116
128
|
|
|
117
129
|
export function isExternalMcpTool(nativeName: string): boolean {
|
|
118
130
|
return (
|
|
@@ -215,16 +227,28 @@ export function createEmitStreamEvent({
|
|
|
215
227
|
return;
|
|
216
228
|
}
|
|
217
229
|
|
|
230
|
+
if (
|
|
231
|
+
type === 'tool_progress' ||
|
|
232
|
+
(type === 'system' &&
|
|
233
|
+
msg.subtype != null &&
|
|
234
|
+
RAW_TASK_MESSAGE_SUBTYPES.has(msg.subtype))
|
|
235
|
+
) {
|
|
236
|
+
emit({ type: 'raw', rawValue: msg });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
218
240
|
// Messages emitted by a Task-tool subagent carry the parent tool-use id.
|
|
219
|
-
//
|
|
220
|
-
//
|
|
241
|
+
// Forward them for correlation and nested rendering, but do not map them
|
|
242
|
+
// into regular stream parts or let them affect the parent step.
|
|
221
243
|
if (msg.parent_tool_use_id != null) {
|
|
244
|
+
emit({ type: 'raw', rawValue: msg });
|
|
222
245
|
return;
|
|
223
246
|
}
|
|
224
247
|
|
|
225
248
|
if (type === 'stream_event') {
|
|
226
249
|
handleStreamEvent({
|
|
227
250
|
event: msg.event,
|
|
251
|
+
message: msg,
|
|
228
252
|
state,
|
|
229
253
|
send: emit,
|
|
230
254
|
toCommonName,
|
|
@@ -414,20 +438,31 @@ function formatApiRetryWarning(msg: ClaudeMessage): string {
|
|
|
414
438
|
|
|
415
439
|
function handleStreamEvent({
|
|
416
440
|
event,
|
|
441
|
+
message,
|
|
417
442
|
state,
|
|
418
443
|
send,
|
|
419
444
|
toCommonName,
|
|
420
445
|
}: {
|
|
421
446
|
event: ClaudeMessage['event'] | undefined;
|
|
447
|
+
message: ClaudeMessage;
|
|
422
448
|
state: ClaudeStreamEventState;
|
|
423
449
|
send: Emit;
|
|
424
450
|
toCommonName: (nativeName: string) => string;
|
|
425
451
|
}): void {
|
|
426
452
|
if (!event) return;
|
|
427
453
|
|
|
454
|
+
if (event.type === 'message_start') {
|
|
455
|
+
state.pendingResponseUsage = toUsageRecord(event.message?.usage);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
428
459
|
if (event.type === 'message_delta') {
|
|
429
460
|
const usage = toUsageRecord(event.usage);
|
|
430
461
|
if (usage) {
|
|
462
|
+
state.pendingResponseUsage = mergeNonNullUsage(
|
|
463
|
+
state.pendingResponseUsage,
|
|
464
|
+
usage,
|
|
465
|
+
);
|
|
431
466
|
state.pendingStepDeltaUsage = mergeNonNullUsage(
|
|
432
467
|
state.pendingStepDeltaUsage,
|
|
433
468
|
usage,
|
|
@@ -437,6 +472,18 @@ function handleStreamEvent({
|
|
|
437
472
|
return;
|
|
438
473
|
}
|
|
439
474
|
|
|
475
|
+
if (event.type === 'message_stop') {
|
|
476
|
+
send({
|
|
477
|
+
type: 'raw',
|
|
478
|
+
rawValue: {
|
|
479
|
+
...message,
|
|
480
|
+
usage: state.pendingResponseUsage ?? {},
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
state.pendingResponseUsage = undefined;
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
|
|
440
487
|
if (typeof event.index !== 'number') return;
|
|
441
488
|
const index = event.index;
|
|
442
489
|
const partialBlocks = state.partialBlocks;
|
package/src/bridge/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { argv, env as procEnv, stdout } from 'node:process';
|
|
|
19
19
|
/*
|
|
20
20
|
* CONSTRAINT — the third-party imports below are NEVER bundled into the
|
|
21
21
|
* compiled `bridge/index.mjs`. They are declared `external` in
|
|
22
|
-
*
|
|
22
|
+
* tsdown.config.ts and resolved at runtime from the node_modules that this
|
|
23
23
|
* bridge installs *inside the sandbox* from `src/bridge/package.json` (and
|
|
24
24
|
* its pinned `pnpm-lock.yaml`). That bridge package.json — NOT this host
|
|
25
25
|
* package — is the single source of truth for these packages and their
|
|
@@ -30,7 +30,7 @@ import { argv, env as procEnv, stdout } from 'node:process';
|
|
|
30
30
|
* in sync, or the bridge will either get the dependency bundled in or fail
|
|
31
31
|
* to resolve it in the sandbox:
|
|
32
32
|
* 1. the import statement below,
|
|
33
|
-
* 2. the `external` array in
|
|
33
|
+
* 2. the `external` array in tsdown.config.ts, and
|
|
34
34
|
* 3. the dependency entry in `src/bridge/package.json`.
|
|
35
35
|
*/
|
|
36
36
|
import * as claudeAgentSdk from '@anthropic-ai/claude-agent-sdk';
|
|
@@ -484,6 +484,12 @@ async function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {
|
|
|
484
484
|
options: {
|
|
485
485
|
...(start.model ? { model: start.model } : {}),
|
|
486
486
|
...(start.maxTurns !== undefined ? { maxTurns: start.maxTurns } : {}),
|
|
487
|
+
...(start.agentProgressSummaries !== undefined
|
|
488
|
+
? { agentProgressSummaries: start.agentProgressSummaries }
|
|
489
|
+
: {}),
|
|
490
|
+
...(start.forwardSubagentText !== undefined
|
|
491
|
+
? { forwardSubagentText: start.forwardSubagentText }
|
|
492
|
+
: {}),
|
|
487
493
|
...(start.env !== undefined ? { env: { ...procEnv, ...start.env } } : {}),
|
|
488
494
|
...(skillsOption ? { skills: skillsOption } : {}),
|
|
489
495
|
...(nativeTools !== undefined ? { tools: nativeTools } : {}),
|
|
@@ -35,6 +35,8 @@ export const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
|
|
|
35
35
|
thinking: thinkingSchema,
|
|
36
36
|
effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
|
|
37
37
|
maxTurns: z.number().optional(),
|
|
38
|
+
agentProgressSummaries: z.boolean().optional(),
|
|
39
|
+
forwardSubagentText: z.boolean().optional(),
|
|
38
40
|
env: z.record(z.string(), z.string()).optional(),
|
|
39
41
|
skills: z.array(z.string()).optional(),
|
|
40
42
|
mcpServers: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -102,6 +102,16 @@ export type ClaudeCodeHarnessSettings = {
|
|
|
102
102
|
* back to the caller. Unset means the CLI's default.
|
|
103
103
|
*/
|
|
104
104
|
readonly maxTurns?: number;
|
|
105
|
+
/**
|
|
106
|
+
* Enables periodic AI-generated progress summaries for running subagents.
|
|
107
|
+
* The summaries are forwarded in raw `task_progress` stream parts.
|
|
108
|
+
*/
|
|
109
|
+
readonly agentProgressSummaries?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Forwards subagent text and thinking messages in addition to tool activity.
|
|
112
|
+
* Subagent messages are exposed as raw stream parts.
|
|
113
|
+
*/
|
|
114
|
+
readonly forwardSubagentText?: boolean;
|
|
105
115
|
/**
|
|
106
116
|
* Environment variables for the Claude Code process. These values are
|
|
107
117
|
* merged over the sandbox bridge process environment.
|
|
@@ -1036,6 +1046,8 @@ export function createClaudeCode(
|
|
|
1036
1046
|
// sandbox is left running, stopped, or destroyed.
|
|
1037
1047
|
proc: undefined,
|
|
1038
1048
|
maxTurns: settings.maxTurns,
|
|
1049
|
+
agentProgressSummaries: settings.agentProgressSummaries,
|
|
1050
|
+
forwardSubagentText: settings.forwardSubagentText,
|
|
1039
1051
|
env: sandboxClaudeEnvironment,
|
|
1040
1052
|
thinking,
|
|
1041
1053
|
effort: settings.effort,
|
|
@@ -1197,6 +1209,8 @@ export function createClaudeCode(
|
|
|
1197
1209
|
finishListenerAttachment,
|
|
1198
1210
|
proc,
|
|
1199
1211
|
maxTurns: settings.maxTurns,
|
|
1212
|
+
agentProgressSummaries: settings.agentProgressSummaries,
|
|
1213
|
+
forwardSubagentText: settings.forwardSubagentText,
|
|
1200
1214
|
env: sandboxClaudeEnvironment,
|
|
1201
1215
|
thinking,
|
|
1202
1216
|
effort: settings.effort,
|
|
@@ -1513,6 +1527,8 @@ function createSession({
|
|
|
1513
1527
|
finishListenerAttachment,
|
|
1514
1528
|
proc,
|
|
1515
1529
|
maxTurns,
|
|
1530
|
+
agentProgressSummaries,
|
|
1531
|
+
forwardSubagentText,
|
|
1516
1532
|
env,
|
|
1517
1533
|
thinking,
|
|
1518
1534
|
effort,
|
|
@@ -1538,6 +1554,8 @@ function createSession({
|
|
|
1538
1554
|
/** Undefined on `attach` — the live bridge was spawned by another process. */
|
|
1539
1555
|
proc: Experimental_SandboxProcess | undefined;
|
|
1540
1556
|
maxTurns: number | undefined;
|
|
1557
|
+
agentProgressSummaries: boolean | undefined;
|
|
1558
|
+
forwardSubagentText: boolean | undefined;
|
|
1541
1559
|
env: Readonly<Record<string, string>> | undefined;
|
|
1542
1560
|
thinking: ClaudeCodeThinkingConfig;
|
|
1543
1561
|
effort: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | undefined;
|
|
@@ -1811,6 +1829,10 @@ function createSession({
|
|
|
1811
1829
|
: {}),
|
|
1812
1830
|
model: promptOpts.model,
|
|
1813
1831
|
maxTurns,
|
|
1832
|
+
...(agentProgressSummaries !== undefined
|
|
1833
|
+
? { agentProgressSummaries }
|
|
1834
|
+
: {}),
|
|
1835
|
+
...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
|
|
1814
1836
|
...(env !== undefined ? { env } : {}),
|
|
1815
1837
|
thinking,
|
|
1816
1838
|
...(effort !== undefined ? { effort } : {}),
|
|
@@ -1875,6 +1897,10 @@ function createSession({
|
|
|
1875
1897
|
: {}),
|
|
1876
1898
|
model: continueOpts.model,
|
|
1877
1899
|
maxTurns,
|
|
1900
|
+
...(agentProgressSummaries !== undefined
|
|
1901
|
+
? { agentProgressSummaries }
|
|
1902
|
+
: {}),
|
|
1903
|
+
...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
|
|
1878
1904
|
...(env !== undefined ? { env } : {}),
|
|
1879
1905
|
thinking,
|
|
1880
1906
|
...(effort !== undefined ? { effort } : {}),
|
package/src/index.ts
CHANGED
|
@@ -12,3 +12,4 @@ export { VERSION } from './version';
|
|
|
12
12
|
export type { ClaudeCodeHarnessSettings } from './claude-code-harness';
|
|
13
13
|
export type { ClaudeCodeAuthenticationMode } from './claude-code-auth';
|
|
14
14
|
export type { ClaudeCodeThinkingConfig } from './claude-code-thinking';
|
|
15
|
+
export type { JSONObject } from '@ai-sdk/provider';
|