@ai-sdk/harness-claude-code 1.0.75 → 1.0.76
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 +10 -0
- package/dist/bridge/index.mjs +43 -28
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/bridge/create-emit-stream-event.ts +10 -0
- package/src/bridge/index.ts +23 -0
- package/src/bridge/json-schema-to-zod.ts +8 -21
- package/src/claude-code-harness.ts +26 -0
package/src/bridge/index.ts
CHANGED
|
@@ -348,6 +348,15 @@ async function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {
|
|
|
348
348
|
systemPrompt: createClaudeCodeSystemPrompt(start.instructions),
|
|
349
349
|
thinking: start.thinking,
|
|
350
350
|
...(start.effort !== undefined ? { effort: start.effort } : {}),
|
|
351
|
+
...(start.responseFormat?.type === 'json' &&
|
|
352
|
+
start.responseFormat.schema != null
|
|
353
|
+
? {
|
|
354
|
+
outputFormat: {
|
|
355
|
+
type: 'json_schema' as const,
|
|
356
|
+
schema: start.responseFormat.schema,
|
|
357
|
+
},
|
|
358
|
+
}
|
|
359
|
+
: {}),
|
|
351
360
|
includePartialMessages: true,
|
|
352
361
|
// The `PostCompact` hook carries the compaction summary, which the
|
|
353
362
|
// `compact_boundary` system message does not. Latch it for the unified
|
|
@@ -425,6 +434,20 @@ async function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {
|
|
|
425
434
|
if (typeof msg.total_cost_usd === 'number') {
|
|
426
435
|
totalCostUsd = (totalCostUsd ?? 0) + msg.total_cost_usd;
|
|
427
436
|
}
|
|
437
|
+
if (
|
|
438
|
+
start.responseFormat?.type === 'json' &&
|
|
439
|
+
msg.structured_output !== undefined
|
|
440
|
+
) {
|
|
441
|
+
const id = randomUUID();
|
|
442
|
+
emit({ type: 'text-start', id });
|
|
443
|
+
emit({
|
|
444
|
+
type: 'text-delta',
|
|
445
|
+
id,
|
|
446
|
+
delta: JSON.stringify(msg.structured_output),
|
|
447
|
+
});
|
|
448
|
+
emit({ type: 'text-end', id });
|
|
449
|
+
streamEventState.stepOpen = true;
|
|
450
|
+
}
|
|
428
451
|
if (streamEventState.stepOpen) {
|
|
429
452
|
emitFinishStep({
|
|
430
453
|
state: streamEventState,
|
|
@@ -43,7 +43,7 @@ function toZodType(schema: JsonSchemaObject | undefined): z.ZodTypeAny {
|
|
|
43
43
|
let zType =
|
|
44
44
|
zodForConst(schema) ??
|
|
45
45
|
zodForEnum(schema) ??
|
|
46
|
-
|
|
46
|
+
zodForUnion(schema) ??
|
|
47
47
|
zodForType(schema);
|
|
48
48
|
|
|
49
49
|
if (isNullable(schema)) zType = zType.nullable();
|
|
@@ -90,16 +90,16 @@ function zodForEnum(schema: JsonSchemaObject): z.ZodTypeAny | undefined {
|
|
|
90
90
|
return zodForLiterals(schema.enum);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
function
|
|
94
|
-
schema: JsonSchemaObject,
|
|
95
|
-
): z.ZodTypeAny | undefined {
|
|
93
|
+
function zodForUnion(schema: JsonSchemaObject): z.ZodTypeAny | undefined {
|
|
96
94
|
const unionSchemas = schema.anyOf ?? schema.oneOf;
|
|
97
95
|
if (!unionSchemas || unionSchemas.length < 2) return undefined;
|
|
98
96
|
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
const options = unionSchemas.map(item => toZodType(item)) as unknown as [
|
|
98
|
+
z.ZodTypeAny,
|
|
99
|
+
z.ZodTypeAny,
|
|
100
|
+
...z.ZodTypeAny[],
|
|
101
|
+
];
|
|
102
|
+
return z.union(options);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
function zodForLiterals(values: JsonLiteral[]): z.ZodTypeAny {
|
|
@@ -127,19 +127,6 @@ function isNullable(schema: JsonSchemaObject): boolean {
|
|
|
127
127
|
);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
function isNullOnlySchema(schema: JsonSchemaObject): boolean {
|
|
131
|
-
return (
|
|
132
|
-
schema.type === 'null' ||
|
|
133
|
-
(Array.isArray(schema.type) &&
|
|
134
|
-
schema.type.length === 1 &&
|
|
135
|
-
schema.type[0] === 'null') ||
|
|
136
|
-
schema.const === null ||
|
|
137
|
-
(Array.isArray(schema.enum) &&
|
|
138
|
-
schema.enum.length === 1 &&
|
|
139
|
-
schema.enum[0] === null)
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
130
|
function isJsonSchemaObject(input: unknown): input is JsonSchemaObject {
|
|
144
131
|
return input != null && typeof input === 'object' && !Array.isArray(input);
|
|
145
132
|
}
|
|
@@ -1540,6 +1540,16 @@ function createSession({
|
|
|
1540
1540
|
isResume,
|
|
1541
1541
|
modelId: model,
|
|
1542
1542
|
doPromptTurn: async promptOpts => {
|
|
1543
|
+
if (
|
|
1544
|
+
promptOpts.responseFormat?.type === 'json' &&
|
|
1545
|
+
promptOpts.responseFormat.schema == null
|
|
1546
|
+
) {
|
|
1547
|
+
throw new HarnessCapabilityUnsupportedError({
|
|
1548
|
+
message:
|
|
1549
|
+
"Harness 'claude-code' requires a JSON schema for structured output.",
|
|
1550
|
+
harnessId: 'claude-code',
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1543
1553
|
const control = wireTurn({
|
|
1544
1554
|
emit: promptOpts.emit,
|
|
1545
1555
|
abortSignal: promptOpts.abortSignal,
|
|
@@ -1553,6 +1563,9 @@ function createSession({
|
|
|
1553
1563
|
description: t.description,
|
|
1554
1564
|
inputSchema: t.inputSchema,
|
|
1555
1565
|
})),
|
|
1566
|
+
...(promptOpts.responseFormat == null
|
|
1567
|
+
? {}
|
|
1568
|
+
: { responseFormat: promptOpts.responseFormat }),
|
|
1556
1569
|
...(promptOpts.instructions
|
|
1557
1570
|
? { instructions: promptOpts.instructions }
|
|
1558
1571
|
: {}),
|
|
@@ -1576,6 +1589,16 @@ function createSession({
|
|
|
1576
1589
|
return control;
|
|
1577
1590
|
},
|
|
1578
1591
|
doContinueTurn: async continueOpts => {
|
|
1592
|
+
if (
|
|
1593
|
+
continueOpts.responseFormat?.type === 'json' &&
|
|
1594
|
+
continueOpts.responseFormat.schema == null
|
|
1595
|
+
) {
|
|
1596
|
+
throw new HarnessCapabilityUnsupportedError({
|
|
1597
|
+
message:
|
|
1598
|
+
"Harness 'claude-code' requires a JSON schema for structured output.",
|
|
1599
|
+
harnessId: 'claude-code',
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1579
1602
|
const control = wireTurn({
|
|
1580
1603
|
emit: continueOpts.emit,
|
|
1581
1604
|
abortSignal: continueOpts.abortSignal,
|
|
@@ -1611,6 +1634,9 @@ function createSession({
|
|
|
1611
1634
|
description: t.description,
|
|
1612
1635
|
inputSchema: t.inputSchema,
|
|
1613
1636
|
})),
|
|
1637
|
+
...(continueOpts.responseFormat == null
|
|
1638
|
+
? {}
|
|
1639
|
+
: { responseFormat: continueOpts.responseFormat }),
|
|
1614
1640
|
...(continueOpts.instructions
|
|
1615
1641
|
? { instructions: continueOpts.instructions }
|
|
1616
1642
|
: {}),
|