@ai-sdk/harness-claude-code 1.0.104 → 1.0.106

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/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as _ai_sdk_provider from '@ai-sdk/provider';
2
2
  import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
3
3
  import { Experimental_SandboxSession } from '@ai-sdk/provider-utils';
4
4
  import * as _ai_sdk_harness from '@ai-sdk/harness';
5
- import { HarnessV1Authentication, HarnessV1CredentialForwarding, HarnessV1PortEndpoint, HarnessV1, HarnessV1BuiltinTool } from '@ai-sdk/harness';
5
+ import { HarnessV1Authentication, HarnessV1CredentialForwarding, HarnessV1PortEndpoint, HarnessV1, HarnessV1BuiltinTool, HARNESS_V1_BUILTIN_TOOLS } from '@ai-sdk/harness';
6
6
 
7
7
  type ClaudeCodeAuthenticationMode = HarnessV1Authentication;
8
8
 
@@ -3245,26 +3245,10 @@ declare const CLAUDE_CODE_BUILTIN_TOOLS: {
3245
3245
  action: "keep" | "remove";
3246
3246
  discard_changes?: boolean | undefined;
3247
3247
  }, any, any>;
3248
- readonly AskUserQuestion: _ai_sdk_provider_utils.Tool<{
3249
- questions: {
3250
- question: string;
3251
- header: string;
3252
- options: {
3253
- label: string;
3254
- description: string;
3255
- preview?: string | undefined;
3256
- }[];
3257
- multiSelect: boolean;
3258
- }[];
3259
- answers?: Record<string, string> | undefined;
3260
- annotations?: Record<string, {
3261
- preview?: string | undefined;
3262
- notes?: string | undefined;
3263
- }> | undefined;
3264
- metadata?: {
3265
- source?: string | undefined;
3266
- } | undefined;
3267
- }, any, any>;
3248
+ readonly askUserQuestions: typeof HARNESS_V1_BUILTIN_TOOLS.askUserQuestions & {
3249
+ readonly nativeName: "AskUserQuestion";
3250
+ readonly toolUseKind: "readonly";
3251
+ };
3268
3252
  readonly Skill: {
3269
3253
  readonly toolUseKind: "readonly";
3270
3254
  readonly title?: string;
@@ -15928,26 +15912,43 @@ declare const claudeCode: _ai_sdk_harness.HarnessV1<{
15928
15912
  action: "keep" | "remove";
15929
15913
  discard_changes?: boolean | undefined;
15930
15914
  }, any, any>;
15931
- readonly AskUserQuestion: _ai_sdk_provider_utils.Tool<{
15915
+ readonly askUserQuestions: _ai_sdk_provider_utils.FunctionTool<{
15916
+ allowPartialAnswers: boolean;
15932
15917
  questions: {
15918
+ id: string;
15933
15919
  question: string;
15934
- header: string;
15935
- options: {
15920
+ header?: string | undefined;
15921
+ options?: {
15922
+ id: string;
15936
15923
  label: string;
15937
- description: string;
15924
+ description?: string | undefined;
15938
15925
  preview?: string | undefined;
15939
- }[];
15940
- multiSelect: boolean;
15926
+ }[] | undefined;
15927
+ allowMultiple?: boolean | undefined;
15928
+ allowFreeForm?: boolean | {
15929
+ secret: boolean;
15930
+ } | undefined;
15941
15931
  }[];
15942
- answers?: Record<string, string> | undefined;
15943
- annotations?: Record<string, {
15944
- preview?: string | undefined;
15945
- notes?: string | undefined;
15946
- }> | undefined;
15947
- metadata?: {
15948
- source?: string | undefined;
15949
- } | undefined;
15950
- }, any, any>;
15932
+ }, {
15933
+ action: "answered";
15934
+ answers: Record<string, {
15935
+ optionIds: string[];
15936
+ freeform?: string | undefined;
15937
+ }>;
15938
+ } | {
15939
+ action: "partially-answered";
15940
+ answers: Record<string, {
15941
+ optionIds: string[];
15942
+ freeform?: string | undefined;
15943
+ }>;
15944
+ } | {
15945
+ action: "declined";
15946
+ } | {
15947
+ action: "cancelled";
15948
+ }> & {
15949
+ readonly nativeName: "AskUserQuestion";
15950
+ readonly toolUseKind: "readonly";
15951
+ };
15951
15952
  readonly Skill: {
15952
15953
  readonly toolUseKind: "readonly";
15953
15954
  readonly title?: string;
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { posix } from "path";
3
3
  import {
4
4
  commonTool,
5
+ HARNESS_V1_BUILTIN_TOOLS,
5
6
  harnessV1DiagnosticFromBridgeFrame,
6
7
  HarnessCapabilityUnsupportedError
7
8
  } from "@ai-sdk/harness";
@@ -24,7 +25,7 @@ import {
24
25
  warnCredentialBrokeringUnavailable,
25
26
  waitForBridgeReady,
26
27
  withBridgeToken,
27
- writeSkills as writeHarnessSkills
28
+ writeSkills
28
29
  } from "@ai-sdk/harness/utils";
29
30
  import {
30
31
  safeParseJSON,
@@ -260,7 +261,7 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
260
261
  ]);
261
262
 
262
263
  // src/version.ts
263
- var VERSION = true ? "1.0.104" : "0.0.0-test";
264
+ var VERSION = true ? "1.0.106" : "0.0.0-test";
264
265
 
265
266
  // src/claude-code-harness.ts
266
267
  var CLAUDE_CODE_CLIENT_APP = `ai-sdk/harness-claude-code/${VERSION}`;
@@ -563,34 +564,11 @@ var CLAUDE_CODE_BUILTIN_TOOLS = {
563
564
  discard_changes: z2.boolean().optional()
564
565
  })
565
566
  }),
566
- AskUserQuestion: tool({
567
- description: "Ask the user multiple-choice questions via a structured UI",
568
- inputSchema: z2.object({
569
- questions: z2.array(
570
- z2.object({
571
- question: z2.string(),
572
- header: z2.string(),
573
- options: z2.array(
574
- z2.object({
575
- label: z2.string(),
576
- description: z2.string(),
577
- preview: z2.string().optional()
578
- })
579
- ),
580
- multiSelect: z2.boolean()
581
- })
582
- ).min(1).max(4),
583
- answers: z2.record(z2.string(), z2.string()).optional(),
584
- annotations: z2.record(
585
- z2.string(),
586
- z2.object({
587
- preview: z2.string().optional(),
588
- notes: z2.string().optional()
589
- })
590
- ).optional(),
591
- metadata: z2.object({ source: z2.string().optional() }).optional()
592
- })
593
- }),
567
+ askUserQuestions: {
568
+ ...HARNESS_V1_BUILTIN_TOOLS.askUserQuestions,
569
+ nativeName: "AskUserQuestion",
570
+ toolUseKind: "readonly"
571
+ },
594
572
  Skill: {
595
573
  ...tool({
596
574
  description: "Activate a skill by name",
@@ -933,7 +911,10 @@ function createClaudeCode(settings = {}) {
933
911
  * `User-Agent`, so this is the attribution path for AI Gateway.
934
912
  */
935
913
  ...resolvedAuthEnvironment.AI_GATEWAY_BASE_URL ? { CLAUDE_AGENT_SDK_CLIENT_APP: CLAUDE_CODE_CLIENT_APP } : {},
936
- ...settings.env
914
+ ...settings.env,
915
+ ...startOpts.headers != null ? {
916
+ ANTHROPIC_CUSTOM_HEADERS: Object.entries(startOpts.headers).map(([name, value]) => `${name}: ${value}`).join("\n")
917
+ } : {}
937
918
  };
938
919
  let sandboxClaudeEnvironment = claudeEnvironment;
939
920
  let sandboxCredentialEnvironment;
@@ -1216,22 +1197,6 @@ async function resolveBridgeEndpoint({
1216
1197
  message: "The Claude Code harness requires an explicit `portEndpoint` when using a basic sandbox session."
1217
1198
  });
1218
1199
  }
1219
- async function writeClaudeCodeSkills({
1220
- sandbox,
1221
- homeDir,
1222
- skills,
1223
- abortSignal
1224
- }) {
1225
- await writeHarnessSkills({
1226
- sandbox,
1227
- rootDir: `${homeDir}/.claude/skills`,
1228
- skills,
1229
- abortSignal,
1230
- invalidSkillNameMessage: ({ name }) => `Invalid Claude Code skill name: ${name}`,
1231
- invalidSkillFilePathMessage: ({ skillName, filePath }) => `Invalid Claude Code skill file path for ${skillName}: ${filePath}`,
1232
- trailingNewline: true
1233
- });
1234
- }
1235
1200
  function openWebSocketAndWaitForBridgeHello({
1236
1201
  endpoint,
1237
1202
  openTimeoutMs,
@@ -1523,7 +1488,8 @@ function createSession({
1523
1488
  type: "tool-result",
1524
1489
  toolCallId: input.toolCallId,
1525
1490
  output: input.output,
1526
- isError: input.isError
1491
+ isError: input.isError,
1492
+ ...input.toolResult !== void 0 ? { toolResult: input.toolResult } : {}
1527
1493
  });
1528
1494
  },
1529
1495
  submitToolApproval: async (input) => {
@@ -1542,26 +1508,33 @@ function createSession({
1542
1508
  done
1543
1509
  };
1544
1510
  };
1511
+ const prepareTurn = async (turnOpts) => {
1512
+ if (turnOpts.responseFormat?.type === "json" && turnOpts.responseFormat.schema == null) {
1513
+ throw new HarnessCapabilityUnsupportedError({
1514
+ message: "Harness 'claude-code' requires a JSON schema for structured output.",
1515
+ harnessId: "claude-code"
1516
+ });
1517
+ }
1518
+ await writeSkills({
1519
+ sandbox,
1520
+ homePath: sandboxHomeDir,
1521
+ skillsDir: ".claude/skills",
1522
+ skills: turnOpts.skills,
1523
+ abortSignal: turnOpts.abortSignal,
1524
+ invalidSkillNameMessage: ({ name }) => `Invalid Claude Code skill name: ${name}`,
1525
+ invalidSkillFilePathMessage: ({ skillName, filePath }) => `Invalid Claude Code skill file path for ${skillName}: ${filePath}`,
1526
+ trailingNewline: true
1527
+ });
1528
+ return wireTurn({
1529
+ emit: turnOpts.emit,
1530
+ abortSignal: turnOpts.abortSignal
1531
+ });
1532
+ };
1545
1533
  return {
1546
1534
  sessionId,
1547
1535
  isResume,
1548
1536
  doPromptTurn: async (promptOpts) => {
1549
- if (promptOpts.responseFormat?.type === "json" && promptOpts.responseFormat.schema == null) {
1550
- throw new HarnessCapabilityUnsupportedError({
1551
- message: "Harness 'claude-code' requires a JSON schema for structured output.",
1552
- harnessId: "claude-code"
1553
- });
1554
- }
1555
- await writeClaudeCodeSkills({
1556
- sandbox,
1557
- homeDir: sandboxHomeDir,
1558
- skills: promptOpts.skills,
1559
- abortSignal: promptOpts.abortSignal
1560
- });
1561
- const control = wireTurn({
1562
- emit: promptOpts.emit,
1563
- abortSignal: promptOpts.abortSignal
1564
- });
1537
+ const control = await prepareTurn(promptOpts);
1565
1538
  if (promptOpts.abortSignal?.aborted) {
1566
1539
  return control;
1567
1540
  }
@@ -1592,22 +1565,7 @@ function createSession({
1592
1565
  return control;
1593
1566
  },
1594
1567
  doContinueTurn: async (continueOpts) => {
1595
- if (continueOpts.responseFormat?.type === "json" && continueOpts.responseFormat.schema == null) {
1596
- throw new HarnessCapabilityUnsupportedError({
1597
- message: "Harness 'claude-code' requires a JSON schema for structured output.",
1598
- harnessId: "claude-code"
1599
- });
1600
- }
1601
- await writeClaudeCodeSkills({
1602
- sandbox,
1603
- homeDir: sandboxHomeDir,
1604
- skills: continueOpts.skills,
1605
- abortSignal: continueOpts.abortSignal
1606
- });
1607
- const control = wireTurn({
1608
- emit: continueOpts.emit,
1609
- abortSignal: continueOpts.abortSignal
1610
- });
1568
+ const control = await prepareTurn(continueOpts);
1611
1569
  if (rerunContinue && !continueOpts.abortSignal?.aborted) {
1612
1570
  pendingResumeFlag = false;
1613
1571
  channel.send({