@ai-sdk/harness-claude-code 1.0.136 → 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 +26 -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 -1968
- 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 +31 -4
- 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(),
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
import {
|
|
28
28
|
applyCredentialForwarding,
|
|
29
29
|
classifyDiskLog,
|
|
30
|
-
|
|
30
|
+
resolveSandboxCredentialEnvironment,
|
|
31
31
|
createBridgeToken,
|
|
32
32
|
experimental_createBridgeUserMessageSubmitter,
|
|
33
33
|
createBridgeErrorHandler,
|
|
@@ -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.
|
|
@@ -887,13 +897,14 @@ export function createClaudeCode(
|
|
|
887
897
|
sandboxSession.addRequestTransformations != null
|
|
888
898
|
) {
|
|
889
899
|
sandboxCredentialEnvironment =
|
|
890
|
-
|
|
891
|
-
(await createSandboxCredentialEnvironment({
|
|
900
|
+
await resolveSandboxCredentialEnvironment({
|
|
892
901
|
environment: claudeEnvironment,
|
|
893
902
|
credentialEnvironmentVariables:
|
|
894
903
|
CLAUDE_CODE_CREDENTIAL_ENVIRONMENT_VARIABLES,
|
|
895
904
|
credentialForwarding: settings.credentialForwarding,
|
|
896
|
-
|
|
905
|
+
previousSandboxCredentialEnvironment:
|
|
906
|
+
resumeData?.sandboxCredentialEnvironment,
|
|
907
|
+
});
|
|
897
908
|
sandboxClaudeEnvironment = {
|
|
898
909
|
...claudeEnvironment,
|
|
899
910
|
...sandboxCredentialEnvironment,
|
|
@@ -1035,6 +1046,8 @@ export function createClaudeCode(
|
|
|
1035
1046
|
// sandbox is left running, stopped, or destroyed.
|
|
1036
1047
|
proc: undefined,
|
|
1037
1048
|
maxTurns: settings.maxTurns,
|
|
1049
|
+
agentProgressSummaries: settings.agentProgressSummaries,
|
|
1050
|
+
forwardSubagentText: settings.forwardSubagentText,
|
|
1038
1051
|
env: sandboxClaudeEnvironment,
|
|
1039
1052
|
thinking,
|
|
1040
1053
|
effort: settings.effort,
|
|
@@ -1196,6 +1209,8 @@ export function createClaudeCode(
|
|
|
1196
1209
|
finishListenerAttachment,
|
|
1197
1210
|
proc,
|
|
1198
1211
|
maxTurns: settings.maxTurns,
|
|
1212
|
+
agentProgressSummaries: settings.agentProgressSummaries,
|
|
1213
|
+
forwardSubagentText: settings.forwardSubagentText,
|
|
1199
1214
|
env: sandboxClaudeEnvironment,
|
|
1200
1215
|
thinking,
|
|
1201
1216
|
effort: settings.effort,
|
|
@@ -1512,6 +1527,8 @@ function createSession({
|
|
|
1512
1527
|
finishListenerAttachment,
|
|
1513
1528
|
proc,
|
|
1514
1529
|
maxTurns,
|
|
1530
|
+
agentProgressSummaries,
|
|
1531
|
+
forwardSubagentText,
|
|
1515
1532
|
env,
|
|
1516
1533
|
thinking,
|
|
1517
1534
|
effort,
|
|
@@ -1537,6 +1554,8 @@ function createSession({
|
|
|
1537
1554
|
/** Undefined on `attach` — the live bridge was spawned by another process. */
|
|
1538
1555
|
proc: Experimental_SandboxProcess | undefined;
|
|
1539
1556
|
maxTurns: number | undefined;
|
|
1557
|
+
agentProgressSummaries: boolean | undefined;
|
|
1558
|
+
forwardSubagentText: boolean | undefined;
|
|
1540
1559
|
env: Readonly<Record<string, string>> | undefined;
|
|
1541
1560
|
thinking: ClaudeCodeThinkingConfig;
|
|
1542
1561
|
effort: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | undefined;
|
|
@@ -1810,6 +1829,10 @@ function createSession({
|
|
|
1810
1829
|
: {}),
|
|
1811
1830
|
model: promptOpts.model,
|
|
1812
1831
|
maxTurns,
|
|
1832
|
+
...(agentProgressSummaries !== undefined
|
|
1833
|
+
? { agentProgressSummaries }
|
|
1834
|
+
: {}),
|
|
1835
|
+
...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
|
|
1813
1836
|
...(env !== undefined ? { env } : {}),
|
|
1814
1837
|
thinking,
|
|
1815
1838
|
...(effort !== undefined ? { effort } : {}),
|
|
@@ -1874,6 +1897,10 @@ function createSession({
|
|
|
1874
1897
|
: {}),
|
|
1875
1898
|
model: continueOpts.model,
|
|
1876
1899
|
maxTurns,
|
|
1900
|
+
...(agentProgressSummaries !== undefined
|
|
1901
|
+
? { agentProgressSummaries }
|
|
1902
|
+
: {}),
|
|
1903
|
+
...(forwardSubagentText !== undefined ? { forwardSubagentText } : {}),
|
|
1877
1904
|
...(env !== undefined ? { env } : {}),
|
|
1878
1905
|
thinking,
|
|
1879
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';
|