@ai-sdk/harness-grok-build 1.0.43 → 1.0.45

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 CHANGED
@@ -1,5 +1,28 @@
1
1
  # @ai-sdk/harness-grok-build
2
2
 
3
+ ## 1.0.45
4
+
5
+ ### Patch Changes
6
+
7
+ - cdc12a1: feat(harness): add support for using adapter-native subscriptions where available
8
+ - Updated dependencies [4d1bf28]
9
+ - Updated dependencies [cdc12a1]
10
+ - Updated dependencies [d70a334]
11
+ - Updated dependencies [81ba84c]
12
+ - Updated dependencies [813bb36]
13
+ - Updated dependencies [c43e4b7]
14
+ - @ai-sdk/harness@1.0.108
15
+ - @ai-sdk/harness-acp@1.0.46
16
+ - @ai-sdk/provider-utils@5.0.40
17
+
18
+ ## 1.0.44
19
+
20
+ ### Patch Changes
21
+
22
+ - @ai-sdk/harness@1.0.107
23
+ - @ai-sdk/provider-utils@5.0.39
24
+ - @ai-sdk/harness-acp@1.0.45
25
+
3
26
  ## 1.0.43
4
27
 
5
28
  ### Patch Changes
package/dist/index.js CHANGED
@@ -9,7 +9,125 @@ import { tool } from "@ai-sdk/provider-utils";
9
9
  import { z as z2 } from "zod/v4";
10
10
 
11
11
  // src/version.ts
12
- var VERSION = true ? "1.0.43" : "0.0.0-test";
12
+ var VERSION = true ? "1.0.45" : "0.0.0-test";
13
+
14
+ // src/grok-build-subscription.ts
15
+ import { chmod, readFile, rename, writeFile } from "fs/promises";
16
+ import { homedir } from "os";
17
+ import { join, resolve } from "path";
18
+ import {
19
+ isAccessTokenExpiringSoon,
20
+ isHarnessAuthenticationEnvironment,
21
+ refreshOAuthAccessToken,
22
+ shouldResolveNativeSubscription
23
+ } from "@ai-sdk/harness/utils";
24
+ import { isRecord, safeParseJSON } from "@ai-sdk/provider-utils";
25
+ var XAI_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
26
+ var GROK_SUBSCRIPTION_BASE_URL = "https://cli-chat-proxy.grok.com/v1";
27
+ async function resolveGrokBuildSubscriptionEnvironment({
28
+ auth,
29
+ env
30
+ }) {
31
+ if (isHarnessAuthenticationEnvironment(auth)) return auth;
32
+ if (!shouldResolveNativeSubscription({
33
+ auth,
34
+ env,
35
+ hasDirectCredential: env.XAI_API_KEY != null
36
+ })) {
37
+ return env;
38
+ }
39
+ const subscription = await readGrokBuildSubscription({ env });
40
+ return subscription == null ? env : { ...env, ...subscription };
41
+ }
42
+ async function readGrokBuildSubscription({
43
+ env = process.env,
44
+ homeDirectory = homedir(),
45
+ fetch
46
+ } = {}) {
47
+ const grokHome = resolve(env.GROK_HOME ?? join(homeDirectory, ".grok"));
48
+ const authPath = join(grokHome, "auth.json");
49
+ const text = await readFile(authPath, "utf8").catch(() => void 0);
50
+ if (text == null) return void 0;
51
+ const parsed = await safeParseJSON({ text });
52
+ if (!parsed.success || !isRecord(parsed.value)) return void 0;
53
+ const selected = selectOAuthRecord(parsed.value);
54
+ if (selected == null) return void 0;
55
+ let accessToken = selected.record.key;
56
+ if (isAccessTokenExpiringSoon({ expiresAt: selected.record.expiresAt })) {
57
+ const discoveryResponse = await (fetch ?? globalThis.fetch)(
58
+ `${selected.issuer.replace(/\/+$/, "")}/.well-known/openid-configuration`
59
+ );
60
+ if (!discoveryResponse.ok) {
61
+ throw new Error(
62
+ `Grok OAuth discovery failed with status ${discoveryResponse.status}.`
63
+ );
64
+ }
65
+ const discovery = await safeParseJSON({
66
+ text: await discoveryResponse.text()
67
+ });
68
+ if (!discovery.success || !isRecord(discovery.value) || typeof discovery.value.token_endpoint !== "string") {
69
+ throw new Error("Grok OAuth discovery returned no token endpoint.");
70
+ }
71
+ const refreshed = await refreshOAuthAccessToken({
72
+ tokenUrl: discovery.value.token_endpoint,
73
+ clientId: XAI_CLIENT_ID,
74
+ refreshToken: selected.record.refreshToken,
75
+ ...fetch == null ? {} : { fetch }
76
+ });
77
+ accessToken = refreshed.accessToken;
78
+ const originalRecord = parsed.value[selected.scope];
79
+ parsed.value[selected.scope] = {
80
+ ...isRecord(originalRecord) ? originalRecord : {},
81
+ key: refreshed.accessToken,
82
+ refresh_token: refreshed.refreshToken ?? selected.record.refreshToken,
83
+ expires_at: refreshed.expiresAt
84
+ };
85
+ const temporaryPath = `${authPath}.${process.pid}.tmp`;
86
+ await writeFile(
87
+ temporaryPath,
88
+ `${JSON.stringify(parsed.value, null, 2)}
89
+ `,
90
+ {
91
+ mode: 384
92
+ }
93
+ );
94
+ await chmod(temporaryPath, 384);
95
+ await rename(temporaryPath, authPath);
96
+ }
97
+ return {
98
+ XAI_API_KEY: accessToken,
99
+ GROK_XAI_API_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,
100
+ GROK_MODELS_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,
101
+ GROK_CLI_CHAT_PROXY_BASE_URL: GROK_SUBSCRIPTION_BASE_URL
102
+ };
103
+ }
104
+ function selectOAuthRecord(value) {
105
+ for (const [scope, candidate] of Object.entries(value)) {
106
+ if (!isRecord(candidate)) continue;
107
+ const key = candidate.key;
108
+ const refreshToken = candidate.refresh_token;
109
+ const expiresAt = normalizeExpiresAt(candidate.expires_at);
110
+ const separator = scope.lastIndexOf("::");
111
+ if (typeof key === "string" && typeof refreshToken === "string" && expiresAt != null && separator > 0 && scope.slice(separator + 2) === XAI_CLIENT_ID) {
112
+ return {
113
+ scope,
114
+ issuer: scope.slice(0, separator),
115
+ record: { key, refreshToken, expiresAt }
116
+ };
117
+ }
118
+ }
119
+ return void 0;
120
+ }
121
+ function normalizeExpiresAt(value) {
122
+ if (typeof value === "number" && Number.isFinite(value)) {
123
+ return value < 1e10 ? value * 1e3 : value;
124
+ }
125
+ if (typeof value === "string") {
126
+ const parsed = Date.parse(value);
127
+ return Number.isFinite(parsed) ? parsed : void 0;
128
+ }
129
+ return void 0;
130
+ }
13
131
 
14
132
  // src/grok-build-question-tool.ts
15
133
  import {
@@ -357,6 +475,8 @@ function createGrokBuild(settings = {}) {
357
475
  const clientAppVersion = clientAppSegments.pop();
358
476
  return createACP({
359
477
  auth: settings.auth,
478
+ resolveAuthenticationEnvironment: resolveGrokBuildSubscriptionEnvironment,
479
+ authentication: { methodId: "xai.api_key" },
360
480
  credentialForwarding: settings.credentialForwarding,
361
481
  port: settings.port,
362
482
  portEndpoint: settings.portEndpoint,
@@ -368,7 +488,7 @@ function createGrokBuild(settings = {}) {
368
488
  },
369
489
  isMcpToolCall: (toolCall) => {
370
490
  const metadata = toolCall._meta?.["x.ai/tool"];
371
- return isRecord(metadata) && metadata.namespace === "mcp";
491
+ return isRecord2(metadata) && metadata.namespace === "mcp";
372
492
  },
373
493
  mintBridgeToken: settings.mintBridgeToken,
374
494
  version: "v1",
@@ -391,6 +511,11 @@ function createGrokBuild(settings = {}) {
391
511
  ...settings.reasoningEffort == null ? [] : ["--reasoning-effort", settings.reasoningEffort],
392
512
  "stdio"
393
513
  ],
514
+ forwardEnv: [
515
+ "GROK_XAI_API_BASE_URL",
516
+ "GROK_MODELS_BASE_URL",
517
+ "GROK_CLI_CHAT_PROXY_BASE_URL"
518
+ ],
394
519
  credentialEnv: ["XAI_API_KEY"],
395
520
  credentialBrokering: ({ env, sandboxEnv, headers }) => {
396
521
  if (!env.XAI_API_KEY || !sandboxEnv?.XAI_API_KEY) return [];
@@ -402,7 +527,8 @@ function createGrokBuild(settings = {}) {
402
527
  },
403
528
  transformHeaders: {
404
529
  ...headers,
405
- Authorization: `Bearer ${env.XAI_API_KEY}`
530
+ Authorization: `Bearer ${env.XAI_API_KEY}`,
531
+ ...env.GROK_CLI_CHAT_PROXY_BASE_URL == null ? {} : { "X-XAI-Token-Auth": "xai-grok-cli" }
406
532
  }
407
533
  })
408
534
  ];
@@ -434,7 +560,7 @@ function createGrokBuild(settings = {}) {
434
560
  }
435
561
  });
436
562
  }
437
- function isRecord(value) {
563
+ function isRecord2(value) {
438
564
  return value != null && typeof value === "object" && !Array.isArray(value);
439
565
  }
440
566
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/grok-build-harness.ts","../src/version.ts","../src/grok-build-question-tool.ts","../src/index.ts"],"sourcesContent":["import {\n HARNESS_V1_BUILTIN_TOOLS,\n commonTool,\n type HarnessV1,\n type HarnessV1BuiltinTool,\n type HarnessV1CredentialForwarding,\n type HarnessV1MintBridgeTokenCallback,\n type HarnessV1PortEndpoint,\n} from '@ai-sdk/harness';\nimport { createCredentialRequestTransformation } from '@ai-sdk/harness/utils';\nimport { createACP, type ACPAuthenticationMode } from '@ai-sdk/harness-acp';\nimport { tool } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport { VERSION } from './version';\nimport { grokBuildAskUserQuestions } from './grok-build-question-tool';\n\ndeclare const __GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON__: string;\ndeclare const __GROK_BUILD_IMPLEMENTATION_PNPM_LOCK_YAML__: string;\ndeclare const __GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE_YAML__: string;\n\nconst GROK_BUILD_CLIENT_APP = `ai-sdk/harness-grok-build/${VERSION}`;\nconst GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON =\n __GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON__;\nconst GROK_BUILD_IMPLEMENTATION_PNPM_LOCK =\n __GROK_BUILD_IMPLEMENTATION_PNPM_LOCK_YAML__;\nconst GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE =\n __GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE_YAML__;\n\nexport type GrokBuildAuthenticationMode = ACPAuthenticationMode;\n\nexport type GrokBuildHarnessSettings = {\n /**\n * Selects direct xAI or AI Gateway authentication. Defaults to automatic\n * environment-based selection.\n */\n readonly auth?: GrokBuildAuthenticationMode;\n /**\n * Customizes each credential value before it is forwarded into a sandbox\n * process. This does not restrict which credentials the harness adapter can\n * discover, read, or otherwise access in the host process.\n */\n readonly credentialForwarding?: HarnessV1CredentialForwarding;\n /**\n * Reasoning effort for reasoning-capable models. Leaving this unset defers\n * to Grok Build's default.\n */\n readonly reasoningEffort?:\n | 'none'\n | 'minimal'\n | 'low'\n | 'medium'\n | 'high'\n | 'xhigh'\n | 'max';\n /**\n * Overrides the sandbox port used by the ACP bridge.\n */\n readonly port?: number;\n /**\n * Override the host endpoint used to connect to the sandbox bridge. Required\n * together with `port` when using a basic sandbox session.\n */\n readonly portEndpoint?: HarnessV1PortEndpoint;\n /**\n * Maximum milliseconds to wait for the ACP bridge to start.\n */\n readonly startupTimeoutMs?: number;\n /**\n * MCP server definitions keyed by server name. Each definition uses the\n * underlying runtime's native MCP server configuration format.\n */\n readonly mcpServers?: Record<string, unknown>;\n /**\n * Creates the authentication token used by the sandbox bridge. Defaults to\n * a random 32-byte hexadecimal token.\n */\n readonly mintBridgeToken?: HarnessV1MintBridgeTokenCallback;\n};\n\n/*\n * Tool names and inputs were captured from the model request produced by\n * @xai-official/grok 0.2.111, the version used by the pinned Grok Build ACP\n * implementation.\n */\nconst GROK_BUILD_BUILTIN_TOOLS = {\n askUserQuestions: HARNESS_V1_BUILTIN_TOOLS.askUserQuestions,\n bash: commonTool('bash', {\n nativeName: 'run_terminal_command',\n toolUseKind: 'bash',\n inputSchema: z.looseObject({\n command: z.string(),\n timeout: z.number().int().min(0).max(36_000_000).nullable().optional(),\n description: z.string().optional(),\n background: z.boolean().optional(),\n }),\n }),\n edit: commonTool('edit', {\n nativeName: 'search_replace',\n toolUseKind: 'edit',\n inputSchema: z.looseObject({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n inputSchema: z.looseObject({\n pattern: z.string(),\n path: z.string().nullable().optional(),\n glob: z.string().nullable().optional(),\n '-B': z.number().int().optional(),\n '-A': z.number().int().optional(),\n '-C': z.number().int().optional(),\n '-i': z.boolean().optional(),\n type: z.string().nullable().optional(),\n head_limit: z.number().int().optional(),\n multiline: z.boolean().optional(),\n }),\n }),\n webSearch: commonTool('webSearch', {\n nativeName: 'web_search',\n toolUseKind: 'readonly',\n inputSchema: z.looseObject({\n query: z.string(),\n allowed_domains: z.array(z.string()).nullable().optional(),\n }),\n }),\n write: commonTool('write', {\n nativeName: 'write',\n toolUseKind: 'edit',\n inputSchema: z.looseObject({\n file_path: z.string(),\n content: z.string(),\n }),\n }),\n read_file: {\n ...tool({\n inputSchema: z.looseObject({\n target_file: z.string(),\n offset: z.number().int().optional(),\n limit: z.number().int().optional(),\n pages: z.string().nullable().optional(),\n format: z.string().nullable().optional(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n list_dir: {\n ...tool({\n inputSchema: z.looseObject({\n target_directory: z.string(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n kill_command_or_subagent: tool({\n inputSchema: z.looseObject({\n task_id: z.string(),\n }),\n }),\n todo_write: tool({\n inputSchema: z.looseObject({\n merge: z.boolean().optional(),\n todos: z.array(\n z.looseObject({\n id: z.string(),\n content: z.string().nullable().optional(),\n status: z\n .enum(['pending', 'in_progress', 'completed', 'cancelled'])\n .nullable()\n .optional(),\n }),\n ),\n }),\n }),\n get_command_or_subagent_output: {\n ...tool({\n inputSchema: z.looseObject({\n task_ids: z.array(z.string()).optional(),\n timeout_ms: z.number().int().nonnegative().nullable().optional(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n spawn_subagent: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n description: z.string(),\n subagent_type: z.string().optional(),\n background: z.boolean().optional(),\n capability_mode: z\n .enum(['read-only', 'read-write', 'execute', 'all'])\n .nullable()\n .optional(),\n isolation: z.enum(['none', 'worktree']).nullable().optional(),\n resume_from: z.string().nullable().optional(),\n cwd: z.string().nullable().optional(),\n model: z.string().nullable().optional(),\n }),\n }),\n scheduler_create: tool({\n inputSchema: z.looseObject({\n task_id: z.string().nullable().optional(),\n interval: z.string().nullable().optional(),\n prompt: z.string().nullable().optional(),\n durable: z.boolean().nullable().optional(),\n foreground: z.boolean().nullable().optional(),\n fire_immediately: z.boolean().optional(),\n }),\n }),\n scheduler_delete: tool({\n inputSchema: z.looseObject({ id: z.string() }),\n }),\n scheduler_list: {\n ...tool({ inputSchema: z.looseObject({}) }),\n toolUseKind: 'readonly',\n },\n monitor: tool({\n inputSchema: z.looseObject({\n command: z.string(),\n description: z.string(),\n timeout_ms: z.number().int().nonnegative().nullable().optional(),\n persistent: z.boolean().optional(),\n }),\n }),\n search_tool: {\n ...tool({\n inputSchema: z.looseObject({\n query: z.string(),\n limit: z.number().int().min(0).max(255).nullable().optional(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n use_tool: tool({\n inputSchema: z.looseObject({\n tool_name: z.string(),\n tool_input: z.looseObject({}),\n }),\n }),\n workflow: tool({\n inputSchema: z.looseObject({\n agent_budget: z.number().int().min(1).max(1024).nullable().optional(),\n name: z.string().nullable().optional(),\n script: z.string().nullable().optional(),\n script_path: z.string().nullable().optional(),\n args: z.unknown().optional(),\n resume_from_run_id: z.string().nullable().optional(),\n validate_only: z.boolean().optional(),\n }),\n }),\n enter_plan_mode: tool({ inputSchema: z.looseObject({}) }),\n exit_plan_mode: tool({ inputSchema: z.looseObject({}) }),\n image_gen: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n aspect_ratio: z.string().optional(),\n }),\n }),\n image_edit: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n image: z.array(z.string()),\n aspect_ratio: z.string().optional(),\n }),\n }),\n image_to_video: tool({\n inputSchema: z.looseObject({\n prompt: z.string().nullable().optional(),\n image: z.string(),\n duration: z.number().int().nonnegative().nullable().optional(),\n resolution_name: z.string().optional(),\n }),\n }),\n reference_to_video: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n images: z.array(z.string()),\n aspect_ratio: z.string(),\n duration: z.number().int().nonnegative().nullable().optional(),\n resolution_name: z.string().optional(),\n }),\n }),\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\nexport function createGrokBuild(\n settings: GrokBuildHarnessSettings = {},\n): HarnessV1<typeof GROK_BUILD_BUILTIN_TOOLS> {\n const clientAppSegments = GROK_BUILD_CLIENT_APP.split('/');\n const clientAppVersion = clientAppSegments.pop()!;\n return createACP({\n auth: settings.auth,\n credentialForwarding: settings.credentialForwarding,\n port: settings.port,\n portEndpoint: settings.portEndpoint,\n startupTimeoutMs: settings.startupTimeoutMs,\n mcpServers: settings.mcpServers,\n modelMapping: {\n type: 'session-model',\n path: 'modelId',\n },\n isMcpToolCall: toolCall => {\n const metadata = toolCall._meta?.['x.ai/tool'];\n return isRecord(metadata) && metadata.namespace === 'mcp';\n },\n mintBridgeToken: settings.mintBridgeToken,\n version: 'v1',\n harnessId: 'grok-build',\n builtinTools: GROK_BUILD_BUILTIN_TOOLS,\n askUserQuestions: grokBuildAskUserQuestions,\n clientApp: {\n name: clientAppSegments.join('/'),\n version: clientAppVersion,\n },\n source: {\n type: 'npm-locked',\n packageJson: GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON,\n pnpmLockYaml: GROK_BUILD_IMPLEMENTATION_PNPM_LOCK,\n pnpmWorkspaceYaml: GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE,\n },\n executable: 'grok',\n args: [\n 'agent',\n ...(settings.reasoningEffort == null\n ? []\n : ['--reasoning-effort', settings.reasoningEffort]),\n 'stdio',\n ],\n credentialEnv: ['XAI_API_KEY'],\n credentialBrokering: ({ env, sandboxEnv, headers }) => {\n if (!env.XAI_API_KEY || !sandboxEnv?.XAI_API_KEY) return [];\n return [\n createCredentialRequestTransformation({\n matchUrl: env.GROK_XAI_API_BASE_URL ?? 'https://api.x.ai/v1',\n matchHeaders: {\n Authorization: `Bearer ${sandboxEnv.XAI_API_KEY}`,\n },\n transformHeaders: {\n ...headers,\n Authorization: `Bearer ${env.XAI_API_KEY}`,\n },\n }),\n ];\n },\n instructionMapping: {\n type: 'filesystem',\n path: '.grok/AGENTS.md',\n },\n outputSchemaMapping: {\n type: 'session-prompt-meta',\n path: ['outputSchema'],\n },\n providerAuthentication: {\n gateway: {\n env: {\n GROK_CLIENT_NAME: { $source: 'client-app-name' },\n GROK_CLIENT_VERSION: { $source: 'client-app-version' },\n XAI_API_KEY: { $source: 'gateway-api-key' },\n GROK_XAI_API_BASE_URL: {\n $source: 'gateway-base-url',\n ensureSuffix: '/v1',\n },\n GROK_MODELS_BASE_URL: {\n $source: 'gateway-base-url',\n ensureSuffix: '/v1',\n },\n },\n },\n },\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n","declare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import {\n harnessV1QuestionsToolOutputSchema,\n type HarnessV1QuestionsToolInput,\n} from '@ai-sdk/harness';\nimport type { ACPAskUserQuestionsSettings } from '@ai-sdk/harness-acp';\nimport type { ToolResultPart } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nconst grokBuildQuestionRequestSchema = z.object({\n sessionId: z.string(),\n toolCallId: z.string(),\n questions: z.array(\n z.object({\n question: z.string(),\n options: z.array(\n z.object({\n label: z.string(),\n description: z.string(),\n preview: z.string().nullable().optional(),\n }),\n ),\n multi_select: z.boolean().nullable().optional(),\n }),\n ),\n mode: z.enum(['default', 'plan']),\n});\n\ntype GrokBuildQuestionRequest = z.infer<typeof grokBuildQuestionRequestSchema>;\n\nexport const grokBuildAskUserQuestions = {\n requestMethod: '_x.ai/ask_user_question',\n fromNativeRequest: ({ nativeRequest }) => {\n const parsed = grokBuildQuestionRequestSchema.safeParse(nativeRequest);\n if (!parsed.success) return null;\n return {\n type: 'tool-call',\n toolCallId: parsed.data.toolCallId,\n toolName: 'askUserQuestions',\n nativeName: 'ask_user_question',\n input: JSON.stringify(toHarnessQuestionsInput(parsed.data)),\n providerExecuted: false,\n };\n },\n toNativeResponse: ({ nativeRequest, toolResult }) => {\n const request = grokBuildQuestionRequestSchema.parse(nativeRequest);\n const output = parseQuestionsOutput(toolResult);\n if (output.action === 'cancelled') {\n return { outcome: 'cancelled' };\n }\n\n const nativeAnswers =\n output.action === 'declined'\n ? { answers: {}, annotations: {} }\n : toNativeAnswers({ request, output });\n const requestedOutcome =\n toolResult.providerOptions?.['grok-build']?.outcome;\n if (\n requestedOutcome === 'chat_about_this' ||\n requestedOutcome === 'skip_interview'\n ) {\n return {\n outcome: requestedOutcome,\n partial_answers: Object.fromEntries(\n Object.entries(nativeAnswers.answers).map(([question, answers]) => [\n question,\n answers.join(', '),\n ]),\n ),\n };\n }\n if (output.action === 'declined') {\n return { outcome: 'skip_interview', partial_answers: {} };\n }\n return {\n outcome: 'accepted',\n answers: nativeAnswers.answers,\n ...(Object.keys(nativeAnswers.annotations).length === 0\n ? {}\n : { annotations: nativeAnswers.annotations }),\n };\n },\n matchesNativeRequest: ({ previousNativeRequest, nativeRequest }) => {\n const previous = grokBuildQuestionRequestSchema.safeParse(\n previousNativeRequest,\n );\n const current = grokBuildQuestionRequestSchema.safeParse(nativeRequest);\n return (\n previous.success &&\n current.success &&\n questionFingerprint(previous.data) === questionFingerprint(current.data)\n );\n },\n} satisfies ACPAskUserQuestionsSettings;\n\nfunction toHarnessQuestionsInput(\n request: GrokBuildQuestionRequest,\n): HarnessV1QuestionsToolInput {\n return {\n allowPartialAnswers: true,\n questions: request.questions.map((question, questionIndex) => ({\n id: questionId(questionIndex),\n question: question.question,\n options: question.options.map((option, optionIndex) => ({\n id: optionId(optionIndex),\n label: option.label,\n description: option.description,\n ...(option.preview == null ? {} : { preview: option.preview }),\n })),\n ...(question.multi_select == null\n ? {}\n : { allowMultiple: question.multi_select }),\n allowFreeForm: true,\n })),\n };\n}\n\nfunction toNativeAnswers({\n request,\n output,\n}: {\n request: GrokBuildQuestionRequest;\n output: Extract<\n ReturnType<typeof parseQuestionsOutput>,\n { action: 'answered' | 'partially-answered' }\n >;\n}): {\n answers: Record<string, string[]>;\n annotations: Record<string, { preview?: string; notes?: string }>;\n} {\n const answers: Record<string, string[]> = {};\n const annotations: Record<string, { preview?: string; notes?: string }> = {};\n request.questions.forEach((question, questionIndex) => {\n const answer = output.answers[questionId(questionIndex)];\n if (answer == null) return;\n const labels = answer.optionIds.flatMap(id => {\n const optionIndex = positionalIdIndex({ id, prefix: 'option-' });\n const option =\n optionIndex == null ? undefined : question.options[optionIndex];\n return option == null ? [] : [option.label];\n });\n if (answer.freeform != null) {\n labels.push('Other');\n annotations[question.question] = { notes: answer.freeform };\n }\n answers[question.question] = labels;\n });\n return { answers, annotations };\n}\n\nfunction parseQuestionsOutput(toolResult: ToolResultPart) {\n if (\n toolResult.output.type !== 'json' &&\n toolResult.output.type !== 'error-json'\n ) {\n throw new Error('Grok Build askUserQuestions requires a JSON tool result.');\n }\n return harnessV1QuestionsToolOutputSchema.parse(toolResult.output.value);\n}\n\nfunction questionId(index: number): string {\n return `question-${index + 1}`;\n}\n\nfunction optionId(index: number): string {\n return `option-${index + 1}`;\n}\n\nfunction positionalIdIndex({\n id,\n prefix,\n}: {\n id: string;\n prefix: string;\n}): number | undefined {\n if (!id.startsWith(prefix)) return undefined;\n const index = Number(id.slice(prefix.length)) - 1;\n return Number.isInteger(index) && index >= 0 ? index : undefined;\n}\n\nfunction questionFingerprint(request: GrokBuildQuestionRequest): string {\n return JSON.stringify({\n questions: request.questions,\n mode: request.mode,\n });\n}\n","import { createGrokBuild } from './grok-build-harness';\n\n/**\n * Default Grok Build harness instance. Equivalent to `createGrokBuild()`.\n */\nexport const grokBuild = createGrokBuild();\n\nexport { createGrokBuild } from './grok-build-harness';\nexport type {\n GrokBuildAuthenticationMode,\n GrokBuildHarnessSettings,\n} from './grok-build-harness';\nexport { VERSION } from './version';\n"],"mappings":"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","names":["z","z"]}
1
+ {"version":3,"sources":["../src/grok-build-harness.ts","../src/version.ts","../src/grok-build-subscription.ts","../src/grok-build-question-tool.ts","../src/index.ts"],"sourcesContent":["import {\n HARNESS_V1_BUILTIN_TOOLS,\n commonTool,\n type HarnessV1,\n type HarnessV1BuiltinTool,\n type HarnessV1CredentialForwarding,\n type HarnessV1MintBridgeTokenCallback,\n type HarnessV1PortEndpoint,\n} from '@ai-sdk/harness';\nimport { createCredentialRequestTransformation } from '@ai-sdk/harness/utils';\nimport { createACP, type ACPAuthenticationMode } from '@ai-sdk/harness-acp';\nimport { tool } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport { VERSION } from './version';\nimport { resolveGrokBuildSubscriptionEnvironment } from './grok-build-subscription';\nimport { grokBuildAskUserQuestions } from './grok-build-question-tool';\n\ndeclare const __GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON__: string;\ndeclare const __GROK_BUILD_IMPLEMENTATION_PNPM_LOCK_YAML__: string;\ndeclare const __GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE_YAML__: string;\n\nconst GROK_BUILD_CLIENT_APP = `ai-sdk/harness-grok-build/${VERSION}`;\nconst GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON =\n __GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON__;\nconst GROK_BUILD_IMPLEMENTATION_PNPM_LOCK =\n __GROK_BUILD_IMPLEMENTATION_PNPM_LOCK_YAML__;\nconst GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE =\n __GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE_YAML__;\n\nexport type GrokBuildAuthenticationMode = ACPAuthenticationMode;\n\nexport type GrokBuildHarnessSettings = {\n /**\n * Selects direct xAI or AI Gateway authentication. Defaults to automatic\n * environment-based selection.\n */\n readonly auth?: GrokBuildAuthenticationMode;\n /**\n * Customizes each credential value before it is forwarded into a sandbox\n * process. This does not restrict which credentials the harness adapter can\n * discover, read, or otherwise access in the host process.\n */\n readonly credentialForwarding?: HarnessV1CredentialForwarding;\n /**\n * Reasoning effort for reasoning-capable models. Leaving this unset defers\n * to Grok Build's default.\n */\n readonly reasoningEffort?:\n | 'none'\n | 'minimal'\n | 'low'\n | 'medium'\n | 'high'\n | 'xhigh'\n | 'max';\n /**\n * Overrides the sandbox port used by the ACP bridge.\n */\n readonly port?: number;\n /**\n * Override the host endpoint used to connect to the sandbox bridge. Required\n * together with `port` when using a basic sandbox session.\n */\n readonly portEndpoint?: HarnessV1PortEndpoint;\n /**\n * Maximum milliseconds to wait for the ACP bridge to start.\n */\n readonly startupTimeoutMs?: number;\n /**\n * MCP server definitions keyed by server name. Each definition uses the\n * underlying runtime's native MCP server configuration format.\n */\n readonly mcpServers?: Record<string, unknown>;\n /**\n * Creates the authentication token used by the sandbox bridge. Defaults to\n * a random 32-byte hexadecimal token.\n */\n readonly mintBridgeToken?: HarnessV1MintBridgeTokenCallback;\n};\n\n/*\n * Tool names and inputs were captured from the model request produced by\n * @xai-official/grok 0.2.111, the version used by the pinned Grok Build ACP\n * implementation.\n */\nconst GROK_BUILD_BUILTIN_TOOLS = {\n askUserQuestions: HARNESS_V1_BUILTIN_TOOLS.askUserQuestions,\n bash: commonTool('bash', {\n nativeName: 'run_terminal_command',\n toolUseKind: 'bash',\n inputSchema: z.looseObject({\n command: z.string(),\n timeout: z.number().int().min(0).max(36_000_000).nullable().optional(),\n description: z.string().optional(),\n background: z.boolean().optional(),\n }),\n }),\n edit: commonTool('edit', {\n nativeName: 'search_replace',\n toolUseKind: 'edit',\n inputSchema: z.looseObject({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n inputSchema: z.looseObject({\n pattern: z.string(),\n path: z.string().nullable().optional(),\n glob: z.string().nullable().optional(),\n '-B': z.number().int().optional(),\n '-A': z.number().int().optional(),\n '-C': z.number().int().optional(),\n '-i': z.boolean().optional(),\n type: z.string().nullable().optional(),\n head_limit: z.number().int().optional(),\n multiline: z.boolean().optional(),\n }),\n }),\n webSearch: commonTool('webSearch', {\n nativeName: 'web_search',\n toolUseKind: 'readonly',\n inputSchema: z.looseObject({\n query: z.string(),\n allowed_domains: z.array(z.string()).nullable().optional(),\n }),\n }),\n write: commonTool('write', {\n nativeName: 'write',\n toolUseKind: 'edit',\n inputSchema: z.looseObject({\n file_path: z.string(),\n content: z.string(),\n }),\n }),\n read_file: {\n ...tool({\n inputSchema: z.looseObject({\n target_file: z.string(),\n offset: z.number().int().optional(),\n limit: z.number().int().optional(),\n pages: z.string().nullable().optional(),\n format: z.string().nullable().optional(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n list_dir: {\n ...tool({\n inputSchema: z.looseObject({\n target_directory: z.string(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n kill_command_or_subagent: tool({\n inputSchema: z.looseObject({\n task_id: z.string(),\n }),\n }),\n todo_write: tool({\n inputSchema: z.looseObject({\n merge: z.boolean().optional(),\n todos: z.array(\n z.looseObject({\n id: z.string(),\n content: z.string().nullable().optional(),\n status: z\n .enum(['pending', 'in_progress', 'completed', 'cancelled'])\n .nullable()\n .optional(),\n }),\n ),\n }),\n }),\n get_command_or_subagent_output: {\n ...tool({\n inputSchema: z.looseObject({\n task_ids: z.array(z.string()).optional(),\n timeout_ms: z.number().int().nonnegative().nullable().optional(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n spawn_subagent: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n description: z.string(),\n subagent_type: z.string().optional(),\n background: z.boolean().optional(),\n capability_mode: z\n .enum(['read-only', 'read-write', 'execute', 'all'])\n .nullable()\n .optional(),\n isolation: z.enum(['none', 'worktree']).nullable().optional(),\n resume_from: z.string().nullable().optional(),\n cwd: z.string().nullable().optional(),\n model: z.string().nullable().optional(),\n }),\n }),\n scheduler_create: tool({\n inputSchema: z.looseObject({\n task_id: z.string().nullable().optional(),\n interval: z.string().nullable().optional(),\n prompt: z.string().nullable().optional(),\n durable: z.boolean().nullable().optional(),\n foreground: z.boolean().nullable().optional(),\n fire_immediately: z.boolean().optional(),\n }),\n }),\n scheduler_delete: tool({\n inputSchema: z.looseObject({ id: z.string() }),\n }),\n scheduler_list: {\n ...tool({ inputSchema: z.looseObject({}) }),\n toolUseKind: 'readonly',\n },\n monitor: tool({\n inputSchema: z.looseObject({\n command: z.string(),\n description: z.string(),\n timeout_ms: z.number().int().nonnegative().nullable().optional(),\n persistent: z.boolean().optional(),\n }),\n }),\n search_tool: {\n ...tool({\n inputSchema: z.looseObject({\n query: z.string(),\n limit: z.number().int().min(0).max(255).nullable().optional(),\n }),\n }),\n toolUseKind: 'readonly',\n },\n use_tool: tool({\n inputSchema: z.looseObject({\n tool_name: z.string(),\n tool_input: z.looseObject({}),\n }),\n }),\n workflow: tool({\n inputSchema: z.looseObject({\n agent_budget: z.number().int().min(1).max(1024).nullable().optional(),\n name: z.string().nullable().optional(),\n script: z.string().nullable().optional(),\n script_path: z.string().nullable().optional(),\n args: z.unknown().optional(),\n resume_from_run_id: z.string().nullable().optional(),\n validate_only: z.boolean().optional(),\n }),\n }),\n enter_plan_mode: tool({ inputSchema: z.looseObject({}) }),\n exit_plan_mode: tool({ inputSchema: z.looseObject({}) }),\n image_gen: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n aspect_ratio: z.string().optional(),\n }),\n }),\n image_edit: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n image: z.array(z.string()),\n aspect_ratio: z.string().optional(),\n }),\n }),\n image_to_video: tool({\n inputSchema: z.looseObject({\n prompt: z.string().nullable().optional(),\n image: z.string(),\n duration: z.number().int().nonnegative().nullable().optional(),\n resolution_name: z.string().optional(),\n }),\n }),\n reference_to_video: tool({\n inputSchema: z.looseObject({\n prompt: z.string(),\n images: z.array(z.string()),\n aspect_ratio: z.string(),\n duration: z.number().int().nonnegative().nullable().optional(),\n resolution_name: z.string().optional(),\n }),\n }),\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\nexport function createGrokBuild(\n settings: GrokBuildHarnessSettings = {},\n): HarnessV1<typeof GROK_BUILD_BUILTIN_TOOLS> {\n const clientAppSegments = GROK_BUILD_CLIENT_APP.split('/');\n const clientAppVersion = clientAppSegments.pop()!;\n return createACP({\n auth: settings.auth,\n resolveAuthenticationEnvironment: resolveGrokBuildSubscriptionEnvironment,\n authentication: { methodId: 'xai.api_key' },\n credentialForwarding: settings.credentialForwarding,\n port: settings.port,\n portEndpoint: settings.portEndpoint,\n startupTimeoutMs: settings.startupTimeoutMs,\n mcpServers: settings.mcpServers,\n modelMapping: {\n type: 'session-model',\n path: 'modelId',\n },\n isMcpToolCall: toolCall => {\n const metadata = toolCall._meta?.['x.ai/tool'];\n return isRecord(metadata) && metadata.namespace === 'mcp';\n },\n mintBridgeToken: settings.mintBridgeToken,\n version: 'v1',\n harnessId: 'grok-build',\n builtinTools: GROK_BUILD_BUILTIN_TOOLS,\n askUserQuestions: grokBuildAskUserQuestions,\n clientApp: {\n name: clientAppSegments.join('/'),\n version: clientAppVersion,\n },\n source: {\n type: 'npm-locked',\n packageJson: GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON,\n pnpmLockYaml: GROK_BUILD_IMPLEMENTATION_PNPM_LOCK,\n pnpmWorkspaceYaml: GROK_BUILD_IMPLEMENTATION_PNPM_WORKSPACE,\n },\n executable: 'grok',\n args: [\n 'agent',\n ...(settings.reasoningEffort == null\n ? []\n : ['--reasoning-effort', settings.reasoningEffort]),\n 'stdio',\n ],\n forwardEnv: [\n 'GROK_XAI_API_BASE_URL',\n 'GROK_MODELS_BASE_URL',\n 'GROK_CLI_CHAT_PROXY_BASE_URL',\n ],\n credentialEnv: ['XAI_API_KEY'],\n credentialBrokering: ({ env, sandboxEnv, headers }) => {\n if (!env.XAI_API_KEY || !sandboxEnv?.XAI_API_KEY) return [];\n return [\n createCredentialRequestTransformation({\n matchUrl: env.GROK_XAI_API_BASE_URL ?? 'https://api.x.ai/v1',\n matchHeaders: {\n Authorization: `Bearer ${sandboxEnv.XAI_API_KEY}`,\n },\n transformHeaders: {\n ...headers,\n Authorization: `Bearer ${env.XAI_API_KEY}`,\n ...(env.GROK_CLI_CHAT_PROXY_BASE_URL == null\n ? {}\n : { 'X-XAI-Token-Auth': 'xai-grok-cli' }),\n },\n }),\n ];\n },\n instructionMapping: {\n type: 'filesystem',\n path: '.grok/AGENTS.md',\n },\n outputSchemaMapping: {\n type: 'session-prompt-meta',\n path: ['outputSchema'],\n },\n providerAuthentication: {\n gateway: {\n env: {\n GROK_CLIENT_NAME: { $source: 'client-app-name' },\n GROK_CLIENT_VERSION: { $source: 'client-app-version' },\n XAI_API_KEY: { $source: 'gateway-api-key' },\n GROK_XAI_API_BASE_URL: {\n $source: 'gateway-base-url',\n ensureSuffix: '/v1',\n },\n GROK_MODELS_BASE_URL: {\n $source: 'gateway-base-url',\n ensureSuffix: '/v1',\n },\n },\n },\n },\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n","declare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { chmod, readFile, rename, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport type { ACPAuthenticationMode } from '@ai-sdk/harness-acp';\nimport {\n isAccessTokenExpiringSoon,\n isHarnessAuthenticationEnvironment,\n refreshOAuthAccessToken,\n shouldResolveNativeSubscription,\n} from '@ai-sdk/harness/utils';\nimport { isRecord, safeParseJSON } from '@ai-sdk/provider-utils';\n\nconst XAI_CLIENT_ID = 'b1a00492-073a-47ea-816f-4c329264a828';\nconst GROK_SUBSCRIPTION_BASE_URL = 'https://cli-chat-proxy.grok.com/v1';\n\nexport async function resolveGrokBuildSubscriptionEnvironment({\n auth,\n env,\n}: {\n auth: ACPAuthenticationMode | undefined;\n env: Readonly<Record<string, string | undefined>>;\n}): Promise<Readonly<Record<string, string | undefined>>> {\n if (isHarnessAuthenticationEnvironment(auth)) return auth;\n if (\n !shouldResolveNativeSubscription({\n auth,\n env,\n hasDirectCredential: env.XAI_API_KEY != null,\n })\n ) {\n return env;\n }\n\n const subscription = await readGrokBuildSubscription({ env });\n return subscription == null ? env : { ...env, ...subscription };\n}\n\nexport async function readGrokBuildSubscription({\n env = process.env,\n homeDirectory = homedir(),\n fetch,\n}: {\n env?: Readonly<Record<string, string | undefined>>;\n homeDirectory?: string;\n fetch?: typeof globalThis.fetch;\n} = {}): Promise<Record<string, string> | undefined> {\n const grokHome = resolve(env.GROK_HOME ?? join(homeDirectory, '.grok'));\n const authPath = join(grokHome, 'auth.json');\n const text = await readFile(authPath, 'utf8').catch(() => undefined);\n if (text == null) return undefined;\n const parsed = await safeParseJSON({ text });\n if (!parsed.success || !isRecord(parsed.value)) return undefined;\n\n const selected = selectOAuthRecord(parsed.value);\n if (selected == null) return undefined;\n let accessToken = selected.record.key;\n if (isAccessTokenExpiringSoon({ expiresAt: selected.record.expiresAt })) {\n const discoveryResponse = await (fetch ?? globalThis.fetch)(\n `${selected.issuer.replace(/\\/+$/, '')}/.well-known/openid-configuration`,\n );\n if (!discoveryResponse.ok) {\n throw new Error(\n `Grok OAuth discovery failed with status ${discoveryResponse.status}.`,\n );\n }\n const discovery = await safeParseJSON({\n text: await discoveryResponse.text(),\n });\n if (\n !discovery.success ||\n !isRecord(discovery.value) ||\n typeof discovery.value.token_endpoint !== 'string'\n ) {\n throw new Error('Grok OAuth discovery returned no token endpoint.');\n }\n const refreshed = await refreshOAuthAccessToken({\n tokenUrl: discovery.value.token_endpoint,\n clientId: XAI_CLIENT_ID,\n refreshToken: selected.record.refreshToken,\n ...(fetch == null ? {} : { fetch }),\n });\n accessToken = refreshed.accessToken;\n const originalRecord = parsed.value[selected.scope];\n parsed.value[selected.scope] = {\n ...(isRecord(originalRecord) ? originalRecord : {}),\n key: refreshed.accessToken,\n refresh_token: refreshed.refreshToken ?? selected.record.refreshToken,\n expires_at: refreshed.expiresAt,\n };\n const temporaryPath = `${authPath}.${process.pid}.tmp`;\n await writeFile(\n temporaryPath,\n `${JSON.stringify(parsed.value, null, 2)}\\n`,\n {\n mode: 0o600,\n },\n );\n await chmod(temporaryPath, 0o600);\n await rename(temporaryPath, authPath);\n }\n\n return {\n XAI_API_KEY: accessToken,\n GROK_XAI_API_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,\n GROK_MODELS_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,\n GROK_CLI_CHAT_PROXY_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,\n };\n}\n\nfunction selectOAuthRecord(value: Record<string, unknown>):\n | {\n scope: string;\n issuer: string;\n record: {\n key: string;\n refreshToken: string;\n expiresAt: number;\n };\n }\n | undefined {\n for (const [scope, candidate] of Object.entries(value)) {\n if (!isRecord(candidate)) continue;\n const key = candidate.key;\n const refreshToken = candidate.refresh_token;\n const expiresAt = normalizeExpiresAt(candidate.expires_at);\n const separator = scope.lastIndexOf('::');\n if (\n typeof key === 'string' &&\n typeof refreshToken === 'string' &&\n expiresAt != null &&\n separator > 0 &&\n scope.slice(separator + 2) === XAI_CLIENT_ID\n ) {\n return {\n scope,\n issuer: scope.slice(0, separator),\n record: { key, refreshToken, expiresAt },\n };\n }\n }\n return undefined;\n}\n\nfunction normalizeExpiresAt(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value < 10_000_000_000 ? value * 1000 : value;\n }\n if (typeof value === 'string') {\n const parsed = Date.parse(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n}\n","import {\n harnessV1QuestionsToolOutputSchema,\n type HarnessV1QuestionsToolInput,\n} from '@ai-sdk/harness';\nimport type { ACPAskUserQuestionsSettings } from '@ai-sdk/harness-acp';\nimport type { ToolResultPart } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nconst grokBuildQuestionRequestSchema = z.object({\n sessionId: z.string(),\n toolCallId: z.string(),\n questions: z.array(\n z.object({\n question: z.string(),\n options: z.array(\n z.object({\n label: z.string(),\n description: z.string(),\n preview: z.string().nullable().optional(),\n }),\n ),\n multi_select: z.boolean().nullable().optional(),\n }),\n ),\n mode: z.enum(['default', 'plan']),\n});\n\ntype GrokBuildQuestionRequest = z.infer<typeof grokBuildQuestionRequestSchema>;\n\nexport const grokBuildAskUserQuestions = {\n requestMethod: '_x.ai/ask_user_question',\n fromNativeRequest: ({ nativeRequest }) => {\n const parsed = grokBuildQuestionRequestSchema.safeParse(nativeRequest);\n if (!parsed.success) return null;\n return {\n type: 'tool-call',\n toolCallId: parsed.data.toolCallId,\n toolName: 'askUserQuestions',\n nativeName: 'ask_user_question',\n input: JSON.stringify(toHarnessQuestionsInput(parsed.data)),\n providerExecuted: false,\n };\n },\n toNativeResponse: ({ nativeRequest, toolResult }) => {\n const request = grokBuildQuestionRequestSchema.parse(nativeRequest);\n const output = parseQuestionsOutput(toolResult);\n if (output.action === 'cancelled') {\n return { outcome: 'cancelled' };\n }\n\n const nativeAnswers =\n output.action === 'declined'\n ? { answers: {}, annotations: {} }\n : toNativeAnswers({ request, output });\n const requestedOutcome =\n toolResult.providerOptions?.['grok-build']?.outcome;\n if (\n requestedOutcome === 'chat_about_this' ||\n requestedOutcome === 'skip_interview'\n ) {\n return {\n outcome: requestedOutcome,\n partial_answers: Object.fromEntries(\n Object.entries(nativeAnswers.answers).map(([question, answers]) => [\n question,\n answers.join(', '),\n ]),\n ),\n };\n }\n if (output.action === 'declined') {\n return { outcome: 'skip_interview', partial_answers: {} };\n }\n return {\n outcome: 'accepted',\n answers: nativeAnswers.answers,\n ...(Object.keys(nativeAnswers.annotations).length === 0\n ? {}\n : { annotations: nativeAnswers.annotations }),\n };\n },\n matchesNativeRequest: ({ previousNativeRequest, nativeRequest }) => {\n const previous = grokBuildQuestionRequestSchema.safeParse(\n previousNativeRequest,\n );\n const current = grokBuildQuestionRequestSchema.safeParse(nativeRequest);\n return (\n previous.success &&\n current.success &&\n questionFingerprint(previous.data) === questionFingerprint(current.data)\n );\n },\n} satisfies ACPAskUserQuestionsSettings;\n\nfunction toHarnessQuestionsInput(\n request: GrokBuildQuestionRequest,\n): HarnessV1QuestionsToolInput {\n return {\n allowPartialAnswers: true,\n questions: request.questions.map((question, questionIndex) => ({\n id: questionId(questionIndex),\n question: question.question,\n options: question.options.map((option, optionIndex) => ({\n id: optionId(optionIndex),\n label: option.label,\n description: option.description,\n ...(option.preview == null ? {} : { preview: option.preview }),\n })),\n ...(question.multi_select == null\n ? {}\n : { allowMultiple: question.multi_select }),\n allowFreeForm: true,\n })),\n };\n}\n\nfunction toNativeAnswers({\n request,\n output,\n}: {\n request: GrokBuildQuestionRequest;\n output: Extract<\n ReturnType<typeof parseQuestionsOutput>,\n { action: 'answered' | 'partially-answered' }\n >;\n}): {\n answers: Record<string, string[]>;\n annotations: Record<string, { preview?: string; notes?: string }>;\n} {\n const answers: Record<string, string[]> = {};\n const annotations: Record<string, { preview?: string; notes?: string }> = {};\n request.questions.forEach((question, questionIndex) => {\n const answer = output.answers[questionId(questionIndex)];\n if (answer == null) return;\n const labels = answer.optionIds.flatMap(id => {\n const optionIndex = positionalIdIndex({ id, prefix: 'option-' });\n const option =\n optionIndex == null ? undefined : question.options[optionIndex];\n return option == null ? [] : [option.label];\n });\n if (answer.freeform != null) {\n labels.push('Other');\n annotations[question.question] = { notes: answer.freeform };\n }\n answers[question.question] = labels;\n });\n return { answers, annotations };\n}\n\nfunction parseQuestionsOutput(toolResult: ToolResultPart) {\n if (\n toolResult.output.type !== 'json' &&\n toolResult.output.type !== 'error-json'\n ) {\n throw new Error('Grok Build askUserQuestions requires a JSON tool result.');\n }\n return harnessV1QuestionsToolOutputSchema.parse(toolResult.output.value);\n}\n\nfunction questionId(index: number): string {\n return `question-${index + 1}`;\n}\n\nfunction optionId(index: number): string {\n return `option-${index + 1}`;\n}\n\nfunction positionalIdIndex({\n id,\n prefix,\n}: {\n id: string;\n prefix: string;\n}): number | undefined {\n if (!id.startsWith(prefix)) return undefined;\n const index = Number(id.slice(prefix.length)) - 1;\n return Number.isInteger(index) && index >= 0 ? index : undefined;\n}\n\nfunction questionFingerprint(request: GrokBuildQuestionRequest): string {\n return JSON.stringify({\n questions: request.questions,\n mode: request.mode,\n });\n}\n","import { createGrokBuild } from './grok-build-harness';\n\n/**\n * Default Grok Build harness instance. Equivalent to `createGrokBuild()`.\n */\nexport const grokBuild = createGrokBuild();\n\nexport { createGrokBuild } from './grok-build-harness';\nexport type {\n GrokBuildAuthenticationMode,\n GrokBuildHarnessSettings,\n} from './grok-build-harness';\nexport { VERSION } from './version';\n"],"mappings":"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","names":["z","z","isRecord"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/harness-grok-build",
3
- "version": "1.0.43",
3
+ "version": "1.0.45",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -26,9 +26,9 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@ai-sdk/harness": "1.0.106",
30
- "@ai-sdk/harness-acp": "1.0.44",
31
- "@ai-sdk/provider-utils": "5.0.38"
29
+ "@ai-sdk/harness": "1.0.108",
30
+ "@ai-sdk/harness-acp": "1.0.46",
31
+ "@ai-sdk/provider-utils": "5.0.40"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "zod": "^3.25.76 || ^4.1.8"
@@ -12,6 +12,7 @@ import { createACP, type ACPAuthenticationMode } from '@ai-sdk/harness-acp';
12
12
  import { tool } from '@ai-sdk/provider-utils';
13
13
  import { z } from 'zod/v4';
14
14
  import { VERSION } from './version';
15
+ import { resolveGrokBuildSubscriptionEnvironment } from './grok-build-subscription';
15
16
  import { grokBuildAskUserQuestions } from './grok-build-question-tool';
16
17
 
17
18
  declare const __GROK_BUILD_IMPLEMENTATION_PACKAGE_JSON__: string;
@@ -293,6 +294,8 @@ export function createGrokBuild(
293
294
  const clientAppVersion = clientAppSegments.pop()!;
294
295
  return createACP({
295
296
  auth: settings.auth,
297
+ resolveAuthenticationEnvironment: resolveGrokBuildSubscriptionEnvironment,
298
+ authentication: { methodId: 'xai.api_key' },
296
299
  credentialForwarding: settings.credentialForwarding,
297
300
  port: settings.port,
298
301
  portEndpoint: settings.portEndpoint,
@@ -329,6 +332,11 @@ export function createGrokBuild(
329
332
  : ['--reasoning-effort', settings.reasoningEffort]),
330
333
  'stdio',
331
334
  ],
335
+ forwardEnv: [
336
+ 'GROK_XAI_API_BASE_URL',
337
+ 'GROK_MODELS_BASE_URL',
338
+ 'GROK_CLI_CHAT_PROXY_BASE_URL',
339
+ ],
332
340
  credentialEnv: ['XAI_API_KEY'],
333
341
  credentialBrokering: ({ env, sandboxEnv, headers }) => {
334
342
  if (!env.XAI_API_KEY || !sandboxEnv?.XAI_API_KEY) return [];
@@ -341,6 +349,9 @@ export function createGrokBuild(
341
349
  transformHeaders: {
342
350
  ...headers,
343
351
  Authorization: `Bearer ${env.XAI_API_KEY}`,
352
+ ...(env.GROK_CLI_CHAT_PROXY_BASE_URL == null
353
+ ? {}
354
+ : { 'X-XAI-Token-Auth': 'xai-grok-cli' }),
344
355
  },
345
356
  }),
346
357
  ];
@@ -0,0 +1,153 @@
1
+ import { chmod, readFile, rename, writeFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import { join, resolve } from 'node:path';
4
+ import type { ACPAuthenticationMode } from '@ai-sdk/harness-acp';
5
+ import {
6
+ isAccessTokenExpiringSoon,
7
+ isHarnessAuthenticationEnvironment,
8
+ refreshOAuthAccessToken,
9
+ shouldResolveNativeSubscription,
10
+ } from '@ai-sdk/harness/utils';
11
+ import { isRecord, safeParseJSON } from '@ai-sdk/provider-utils';
12
+
13
+ const XAI_CLIENT_ID = 'b1a00492-073a-47ea-816f-4c329264a828';
14
+ const GROK_SUBSCRIPTION_BASE_URL = 'https://cli-chat-proxy.grok.com/v1';
15
+
16
+ export async function resolveGrokBuildSubscriptionEnvironment({
17
+ auth,
18
+ env,
19
+ }: {
20
+ auth: ACPAuthenticationMode | undefined;
21
+ env: Readonly<Record<string, string | undefined>>;
22
+ }): Promise<Readonly<Record<string, string | undefined>>> {
23
+ if (isHarnessAuthenticationEnvironment(auth)) return auth;
24
+ if (
25
+ !shouldResolveNativeSubscription({
26
+ auth,
27
+ env,
28
+ hasDirectCredential: env.XAI_API_KEY != null,
29
+ })
30
+ ) {
31
+ return env;
32
+ }
33
+
34
+ const subscription = await readGrokBuildSubscription({ env });
35
+ return subscription == null ? env : { ...env, ...subscription };
36
+ }
37
+
38
+ export async function readGrokBuildSubscription({
39
+ env = process.env,
40
+ homeDirectory = homedir(),
41
+ fetch,
42
+ }: {
43
+ env?: Readonly<Record<string, string | undefined>>;
44
+ homeDirectory?: string;
45
+ fetch?: typeof globalThis.fetch;
46
+ } = {}): Promise<Record<string, string> | undefined> {
47
+ const grokHome = resolve(env.GROK_HOME ?? join(homeDirectory, '.grok'));
48
+ const authPath = join(grokHome, 'auth.json');
49
+ const text = await readFile(authPath, 'utf8').catch(() => undefined);
50
+ if (text == null) return undefined;
51
+ const parsed = await safeParseJSON({ text });
52
+ if (!parsed.success || !isRecord(parsed.value)) return undefined;
53
+
54
+ const selected = selectOAuthRecord(parsed.value);
55
+ if (selected == null) return undefined;
56
+ let accessToken = selected.record.key;
57
+ if (isAccessTokenExpiringSoon({ expiresAt: selected.record.expiresAt })) {
58
+ const discoveryResponse = await (fetch ?? globalThis.fetch)(
59
+ `${selected.issuer.replace(/\/+$/, '')}/.well-known/openid-configuration`,
60
+ );
61
+ if (!discoveryResponse.ok) {
62
+ throw new Error(
63
+ `Grok OAuth discovery failed with status ${discoveryResponse.status}.`,
64
+ );
65
+ }
66
+ const discovery = await safeParseJSON({
67
+ text: await discoveryResponse.text(),
68
+ });
69
+ if (
70
+ !discovery.success ||
71
+ !isRecord(discovery.value) ||
72
+ typeof discovery.value.token_endpoint !== 'string'
73
+ ) {
74
+ throw new Error('Grok OAuth discovery returned no token endpoint.');
75
+ }
76
+ const refreshed = await refreshOAuthAccessToken({
77
+ tokenUrl: discovery.value.token_endpoint,
78
+ clientId: XAI_CLIENT_ID,
79
+ refreshToken: selected.record.refreshToken,
80
+ ...(fetch == null ? {} : { fetch }),
81
+ });
82
+ accessToken = refreshed.accessToken;
83
+ const originalRecord = parsed.value[selected.scope];
84
+ parsed.value[selected.scope] = {
85
+ ...(isRecord(originalRecord) ? originalRecord : {}),
86
+ key: refreshed.accessToken,
87
+ refresh_token: refreshed.refreshToken ?? selected.record.refreshToken,
88
+ expires_at: refreshed.expiresAt,
89
+ };
90
+ const temporaryPath = `${authPath}.${process.pid}.tmp`;
91
+ await writeFile(
92
+ temporaryPath,
93
+ `${JSON.stringify(parsed.value, null, 2)}\n`,
94
+ {
95
+ mode: 0o600,
96
+ },
97
+ );
98
+ await chmod(temporaryPath, 0o600);
99
+ await rename(temporaryPath, authPath);
100
+ }
101
+
102
+ return {
103
+ XAI_API_KEY: accessToken,
104
+ GROK_XAI_API_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,
105
+ GROK_MODELS_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,
106
+ GROK_CLI_CHAT_PROXY_BASE_URL: GROK_SUBSCRIPTION_BASE_URL,
107
+ };
108
+ }
109
+
110
+ function selectOAuthRecord(value: Record<string, unknown>):
111
+ | {
112
+ scope: string;
113
+ issuer: string;
114
+ record: {
115
+ key: string;
116
+ refreshToken: string;
117
+ expiresAt: number;
118
+ };
119
+ }
120
+ | undefined {
121
+ for (const [scope, candidate] of Object.entries(value)) {
122
+ if (!isRecord(candidate)) continue;
123
+ const key = candidate.key;
124
+ const refreshToken = candidate.refresh_token;
125
+ const expiresAt = normalizeExpiresAt(candidate.expires_at);
126
+ const separator = scope.lastIndexOf('::');
127
+ if (
128
+ typeof key === 'string' &&
129
+ typeof refreshToken === 'string' &&
130
+ expiresAt != null &&
131
+ separator > 0 &&
132
+ scope.slice(separator + 2) === XAI_CLIENT_ID
133
+ ) {
134
+ return {
135
+ scope,
136
+ issuer: scope.slice(0, separator),
137
+ record: { key, refreshToken, expiresAt },
138
+ };
139
+ }
140
+ }
141
+ return undefined;
142
+ }
143
+
144
+ function normalizeExpiresAt(value: unknown): number | undefined {
145
+ if (typeof value === 'number' && Number.isFinite(value)) {
146
+ return value < 10_000_000_000 ? value * 1000 : value;
147
+ }
148
+ if (typeof value === 'string') {
149
+ const parsed = Date.parse(value);
150
+ return Number.isFinite(parsed) ? parsed : undefined;
151
+ }
152
+ return undefined;
153
+ }