@mininglamp-oss/octo-runtime 1.1.1 → 1.1.2

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.
Files changed (54) hide show
  1. package/apps/cli/dist/build-info.json +2 -2
  2. package/apps/cli/dist/manifest.json +5 -0
  3. package/node_modules/@mininglamp-oss/octo-runtime-acp-client/package.json +3 -3
  4. package/node_modules/@mininglamp-oss/octo-runtime-adapter-acp/package.json +4 -4
  5. package/node_modules/@mininglamp-oss/octo-runtime-adapter-antigravity/package.json +3 -3
  6. package/node_modules/@mininglamp-oss/octo-runtime-adapter-claude-code/package.json +3 -3
  7. package/node_modules/@mininglamp-oss/octo-runtime-adapter-codebuddy/package.json +4 -4
  8. package/node_modules/@mininglamp-oss/octo-runtime-adapter-codex/package.json +3 -3
  9. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.d.ts +54 -0
  10. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.js +399 -0
  11. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.d.ts +14 -0
  12. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.js +156 -0
  13. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.d.ts +29 -0
  14. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.js +273 -0
  15. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.d.ts +27 -0
  16. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.js +161 -0
  17. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/package.json +17 -0
  18. package/node_modules/@mininglamp-oss/octo-runtime-adapter-hermes/package.json +2 -2
  19. package/node_modules/@mininglamp-oss/octo-runtime-adapter-kimi-code/package.json +2 -2
  20. package/node_modules/@mininglamp-oss/octo-runtime-adapter-mcode/package.json +2 -2
  21. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.d.ts +24 -0
  22. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.js +181 -0
  23. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.d.ts +9 -0
  24. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.js +24 -8
  25. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/index.js +229 -225
  26. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/package.json +3 -3
  27. package/node_modules/@mininglamp-oss/octo-runtime-adapter-opencode/package.json +4 -4
  28. package/node_modules/@mininglamp-oss/octo-runtime-adapter-qodercli/package.json +2 -2
  29. package/node_modules/@mininglamp-oss/octo-runtime-adapter-qoderclicn/package.json +2 -2
  30. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.d.ts +4 -0
  31. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.js +5 -6
  32. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/package.json +2 -2
  33. package/node_modules/@mininglamp-oss/octo-runtime-adapter-zcode-gui/package.json +3 -3
  34. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/build-info.json +2 -2
  35. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/manifest.json +5 -0
  36. package/node_modules/@mininglamp-oss/octo-runtime-cli/package.json +23 -22
  37. package/node_modules/@mininglamp-oss/octo-runtime-cross-service/package.json +1 -1
  38. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.d.ts +1 -1
  39. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.js +13 -9
  40. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/package.json +3 -3
  41. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/package.json +4 -4
  42. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/application/im-channel.js +2 -1
  43. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/contracts.d.ts +1 -0
  44. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/execution/dispatcher.js +24 -0
  45. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/contexts.js +2 -2
  46. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.d.ts +5 -2
  47. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.js +19 -5
  48. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/normalize.js +1 -0
  49. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/package.json +6 -6
  50. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-wecom/package.json +5 -5
  51. package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/package.json +2 -2
  52. package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/package.json +4 -4
  53. package/node_modules/@mininglamp-oss/octo-runtime-protocol/package.json +1 -1
  54. package/package.json +27 -25
@@ -1,5 +1,5 @@
1
1
  {
2
- "commit": "20c377136288a55356300bd3d4a755d0f19a23ee",
2
+ "commit": "5c1921dced4b0852e41426f1c04582159082f482",
3
3
  "dirty": false,
4
- "buildTime": "2026-10-22T07:38:35.134Z"
4
+ "buildTime": "2026-10-22T12:44:46.791Z"
5
5
  }
@@ -16,6 +16,11 @@
16
16
  "module": "@mininglamp-oss/octo-runtime-adapter-codebuddy",
17
17
  "export": "codebuddyAdapter"
18
18
  },
19
+ {
20
+ "type": "grok-build",
21
+ "module": "@mininglamp-oss/octo-runtime-adapter-grok-build",
22
+ "export": "grokBuildAdapter"
23
+ },
19
24
  {
20
25
  "type": "hermes",
21
26
  "module": "@mininglamp-oss/octo-runtime-adapter-hermes",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-acp-client",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -9,7 +9,7 @@
9
9
  "dist"
10
10
  ],
11
11
  "dependencies": {
12
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.1",
13
- "@mininglamp-oss/octo-runtime-protocol": "1.1.1"
12
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2",
13
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2"
14
14
  }
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-acp",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -9,8 +9,8 @@
9
9
  "dist"
10
10
  ],
11
11
  "dependencies": {
12
- "@mininglamp-oss/octo-runtime-protocol": "1.1.1",
13
- "@mininglamp-oss/octo-runtime-acp-client": "1.1.1",
14
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.1"
12
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2",
13
+ "@mininglamp-oss/octo-runtime-acp-client": "1.1.2",
14
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2"
15
15
  }
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-antigravity",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -10,7 +10,7 @@
10
10
  "README.md"
11
11
  ],
12
12
  "dependencies": {
13
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.1",
14
- "@mininglamp-oss/octo-runtime-protocol": "1.1.1"
13
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2",
14
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2"
15
15
  }
16
16
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-claude-code",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
7
7
  "dependencies": {
8
- "@mininglamp-oss/octo-runtime-protocol": "1.1.1",
9
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.1"
8
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2",
9
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2"
10
10
  },
11
11
  "types": "./dist/index.d.ts",
12
12
  "files": [
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-codebuddy",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
7
7
  "dependencies": {
8
- "@mininglamp-oss/octo-runtime-protocol": "1.1.1",
9
- "@mininglamp-oss/octo-runtime-acp-client": "1.1.1",
10
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.1"
8
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2",
9
+ "@mininglamp-oss/octo-runtime-acp-client": "1.1.2",
10
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2"
11
11
  },
12
12
  "types": "./dist/index.d.ts",
13
13
  "files": [
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-codex",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
7
7
  "dependencies": {
8
- "@mininglamp-oss/octo-runtime-protocol": "1.1.1",
9
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.1"
8
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2",
9
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2"
10
10
  },
11
11
  "types": "./dist/index.d.ts",
12
12
  "files": [
@@ -0,0 +1,54 @@
1
+ import { spawnGrokBuildAcpClient as spawnAcpClient, type SpawnGrokBuildClientOptions as SpawnAcpClientOptions } from "./client.js";
2
+ import { GrokBuildInteractionBridge as AcpApprovalBridge } from "./interactions.js";
3
+ import { acpActmodeSelectionRequest } from "@mininglamp-oss/octo-runtime-adapter-acp";
4
+ import { type AcpClient, type AcpUpdate } from "@mininglamp-oss/octo-runtime-acp-client";
5
+ import { type ProbeResult, type ReasoningLevelMap, type AdapterInvocationContext, type CanonicalEvent, type InvokeRequest } from "@mininglamp-oss/octo-runtime-adapter-sdk";
6
+ import { type InteractionResponse } from "@mininglamp-oss/octo-runtime-protocol";
7
+ type JsonRecord = Record<string, unknown>;
8
+ export interface AcpAdapterDefinition {
9
+ type: string;
10
+ provider: string;
11
+ command: string;
12
+ args?: readonly string[] | ((request: InvokeRequest) => readonly string[]);
13
+ env?: (request: InvokeRequest) => NodeJS.ProcessEnv;
14
+ protocolVersion?: string | number;
15
+ emptyLoadResultMeansMissing?: boolean;
16
+ probe?: () => Promise<ProbeResult>;
17
+ /** Grok Build 专用的握手、会话配置与交互策略,只在本包消费。 */
18
+ initialize?: (client: AcpClient, initialization: JsonRecord, request: InvokeRequest, env: NodeJS.ProcessEnv) => Promise<void>;
19
+ sessionParams?: (params: JsonRecord, request: InvokeRequest, fresh: boolean) => JsonRecord;
20
+ isMissingSessionError?: (error: unknown) => boolean;
21
+ configureSession?: (client: AcpClient, session: JsonRecord, sessionId: string, request: InvokeRequest) => AsyncIterable<CanonicalEvent>;
22
+ selectActmode?: typeof acpActmodeSelectionRequest;
23
+ controlInstructions?: "session";
24
+ reasoningLevels?: ReasoningLevelMap;
25
+ clientOptions?: (request: InvokeRequest, bridge: AcpApprovalBridge) => Pick<SpawnAcpClientOptions, "requestHandler" | "onRequestResponseWritten" | "onRequestResponseFailed">;
26
+ validatePromptResult?: (update: StandardAcpUpdate) => CanonicalEvent[];
27
+ }
28
+ export interface StandardAcpUpdate extends AcpUpdate {
29
+ sessionUpdate?: string;
30
+ content?: unknown;
31
+ text?: string;
32
+ toolCallId?: string;
33
+ name?: string;
34
+ title?: string;
35
+ rawInput?: unknown;
36
+ input?: unknown;
37
+ rawOutput?: unknown;
38
+ output?: unknown;
39
+ status?: string;
40
+ }
41
+ export declare function createGrokBuildAcpAdapter(definition: AcpAdapterDefinition, { acpClientFactory, command }?: {
42
+ acpClientFactory?: typeof spawnAcpClient;
43
+ command?: string;
44
+ }): Readonly<{
45
+ metadata: {
46
+ mcp: true;
47
+ type: string;
48
+ agentSources: "provisioned"[];
49
+ };
50
+ probe: () => Promise<ProbeResult>;
51
+ respondInteraction(invocationId: string, response: InteractionResponse): Promise<void>;
52
+ invoke(request: InvokeRequest, context?: AdapterInvocationContext): AsyncGenerator<CanonicalEvent>;
53
+ }>;
54
+ export {};
@@ -0,0 +1,399 @@
1
+ import { spawnGrokBuildAcpClient as spawnAcpClient } from "./client.js";
2
+ import { GrokBuildInteractionBridge as AcpApprovalBridge } from "./interactions.js";
3
+ import { acpModelSelectionRequest, acpActmodeSelectionRequest, normalizeAcpUpdate } from "@mininglamp-oss/octo-runtime-adapter-acp";
4
+ import { acpLoadSessionParams, acpNewSessionParams, acpPromptParams } from "@mininglamp-oss/octo-runtime-acp-client";
5
+ import { initialControlInstructions, actmodeEvidence, AcpTurnNormalizer, defineAdapter, invocationEnvironment, invocationMcpServers, assertMcpOptions, probeCommand } from "@mininglamp-oss/octo-runtime-adapter-sdk";
6
+ import { canonicalTerminalStatus, contextActmode, providerInputParts } from "@mininglamp-oss/octo-runtime-protocol";
7
+ function sessionModel(session) {
8
+ const modelOption = arrayField(session, "configOptions")
9
+ .map(recordValue)
10
+ .find((option) => stringField(option, "id") === "model" || stringField(option, "category") === "model");
11
+ return (stringField(modelOption ?? {}, "currentValue") ??
12
+ stringField(recordValue(session.models), "currentModelId") ??
13
+ stringField(session, "model"));
14
+ }
15
+ export function createGrokBuildAcpAdapter(definition, { acpClientFactory = spawnAcpClient, command = definition.command } = {}) {
16
+ const responders = new Map();
17
+ return defineAdapter({
18
+ metadata: {
19
+ mcp: true,
20
+ type: definition.type,
21
+ agentSources: ["provisioned"]
22
+ },
23
+ probe: definition.probe ?? (() => probeCommand(command)),
24
+ async respondInteraction(invocationId, response) {
25
+ const bridge = responders.get(invocationId);
26
+ if (!bridge)
27
+ throw new Error("INTERACTION_NOT_ACTIVE");
28
+ await bridge.respond(response);
29
+ },
30
+ async *invoke(request, context) {
31
+ if (request.approvalMode !== "ask" && request.approvalMode !== "full_access")
32
+ throw new Error("APPROVAL_MODE_UNSUPPORTED: this ACP adapter has no assisted policy");
33
+ if (responders.has(request.invocationId))
34
+ throw new Error("INVOCATION_ALREADY_ACTIVE");
35
+ const bridge = new AcpApprovalBridge(request);
36
+ responders.set(request.invocationId, bridge);
37
+ try {
38
+ yield* bridge.stream(execute(request, bridge, context));
39
+ }
40
+ finally {
41
+ bridge.close("execution_lost");
42
+ responders.delete(request.invocationId);
43
+ }
44
+ }
45
+ }, definition.reasoningLevels ?? null);
46
+ async function* execute(request, bridge, context) {
47
+ const args = typeof definition.args === "function"
48
+ ? definition.args(request)
49
+ : (definition.args ?? ["acp"]);
50
+ const runEnv = invocationEnvironment(request, definition.env?.(request));
51
+ const mcp = invocationMcpServers(request, runEnv);
52
+ assertMcpOptions(mcp, definition.type, []);
53
+ const servers = Object.entries(mcp).map(([name, server]) => server.type === "stdio"
54
+ ? {
55
+ name,
56
+ command: server.command,
57
+ args: server.args ?? [],
58
+ env: Object.entries(server.env ?? {}).map(([name, value]) => ({ name, value }))
59
+ }
60
+ : {
61
+ name,
62
+ type: "http",
63
+ url: server.url,
64
+ headers: Object.entries(server.headers ?? {}).map(([name, value]) => ({ name, value }))
65
+ });
66
+ const client = acpClientFactory({
67
+ command,
68
+ args: [...args],
69
+ env: runEnv,
70
+ cwd: request.workdir,
71
+ ...definition.clientOptions?.(request, bridge),
72
+ permissionHandler: (params) => bridge.requestPermission(params),
73
+ onPermissionResponseWritten: (params) => bridge.responseWritten(params),
74
+ onPermissionResponseFailed: (params, error) => bridge.responseFailed(params, error),
75
+ ...(context?.streamLimits ? { streamLimits: context.streamLimits } : {})
76
+ });
77
+ let sessionId;
78
+ let terminal = false;
79
+ let abortClose;
80
+ const closeAfterAbort = () => {
81
+ // 审批桥和 signal 共用关闭过程,先给取消通知留出发送窗口,再回收进程。
82
+ abortClose ??= (async () => {
83
+ if (sessionId)
84
+ client.cancel(sessionId);
85
+ await new Promise((resolve) => setTimeout(resolve, 250));
86
+ await client.close();
87
+ })();
88
+ return abortClose;
89
+ };
90
+ bridge.bindTransport(() => (request.signal?.aborted ? closeAfterAbort() : client.close()));
91
+ const abort = () => {
92
+ void closeAfterAbort().catch(() => undefined);
93
+ };
94
+ if (request.signal?.aborted)
95
+ abort();
96
+ else
97
+ request.signal?.addEventListener("abort", abort, { once: true });
98
+ try {
99
+ const initialization = recordValue(await client.initialize({ protocolVersion: definition.protocolVersion ?? 1 }));
100
+ await definition.initialize?.(client, initialization, request, runEnv);
101
+ if (servers.some((server) => server.type === "http") &&
102
+ recordValue(recordValue(initialization.agentCapabilities).mcpCapabilities).http !== true)
103
+ throw new Error(`MCP_TRANSPORT_UNSUPPORTED: ${definition.type}: http`);
104
+ const imageSupported = recordValue(recordValue(initialization.agentCapabilities).promptCapabilities).image ===
105
+ true;
106
+ const inputs = [
107
+ providerInputParts(request),
108
+ ...(request.providerSession ? [providerInputParts(request, true)] : [])
109
+ ];
110
+ if (!imageSupported && inputs.some((parts) => parts.some((part) => part.type === "image"))) {
111
+ throw new Error("UNSUPPORTED_INPUT_MODALITY: ACP agent did not advertise promptCapabilities.image");
112
+ }
113
+ const requestedSessionId = request.providerSession?.sessionId;
114
+ let providerModel;
115
+ let resumeFallback;
116
+ let sessionMethod = requestedSessionId ? "session/load" : "session/new";
117
+ let sessionParams = requestedSessionId
118
+ ? acpLoadSessionParams(requestedSessionId, { cwd: request.workdir })
119
+ : acpNewSessionParams({ cwd: request.workdir });
120
+ sessionParams.mcpServers = servers;
121
+ sessionParams =
122
+ definition.sessionParams?.(sessionParams, request, !requestedSessionId) ?? sessionParams;
123
+ let sessionRequestId = client.reserveRequestId();
124
+ let sessionResult = {};
125
+ let result = await client
126
+ .request(sessionMethod, sessionParams, {
127
+ requestId: sessionRequestId,
128
+ ...(requestedSessionId ? { timeoutMs: 600_000 } : {})
129
+ })
130
+ .catch((error) => {
131
+ if (requestedSessionId && definition.isMissingSessionError?.(error))
132
+ return null;
133
+ throw error;
134
+ });
135
+ const initialSessionId = requestedSessionId ?? (isRecord(result) ? stringField(result, "sessionId") : undefined);
136
+ if (!initialSessionId)
137
+ throw new Error("ACP session/new returned no sessionId");
138
+ const missingLoadedSession = requestedSessionId &&
139
+ (result === null ||
140
+ (definition.emptyLoadResultMeansMissing === true &&
141
+ isRecord(result) &&
142
+ Object.keys(result).length === 0));
143
+ if (missingLoadedSession) {
144
+ resumeFallback = "session_load_not_found";
145
+ sessionMethod = "session/new";
146
+ sessionParams = acpNewSessionParams({ cwd: request.workdir });
147
+ sessionParams.mcpServers = servers;
148
+ sessionParams = definition.sessionParams?.(sessionParams, request, true) ?? sessionParams;
149
+ sessionRequestId = client.reserveRequestId();
150
+ result = await client.request(sessionMethod, sessionParams, {
151
+ requestId: sessionRequestId
152
+ });
153
+ const freshSessionId = stringField(result, "sessionId");
154
+ if (!freshSessionId)
155
+ throw new Error("ACP session/new returned no sessionId");
156
+ }
157
+ sessionResult = isRecord(result) ? result : {};
158
+ sessionId = resumeFallback
159
+ ? stringField(sessionResult, "sessionId")
160
+ : (requestedSessionId ?? stringField(sessionResult, "sessionId"));
161
+ if (!sessionId)
162
+ throw new Error("ACP session/new returned no sessionId");
163
+ const requestedMode = contextActmode(request.context);
164
+ if (requestedMode !== undefined) {
165
+ const selection = (definition.selectActmode ?? acpActmodeSelectionRequest)(sessionResult, sessionId, requestedMode);
166
+ if (!selection.unchanged)
167
+ await client.request(selection.method, selection.params);
168
+ yield actmodeEvidence({
169
+ requested: requestedMode,
170
+ effective: selection.effective,
171
+ nativeMode: selection.nativeMode,
172
+ status: selection.effective === requestedMode ? "applied" : "fallback",
173
+ ...(selection.effective !== requestedMode
174
+ ? { reason: "provider_unsupported" }
175
+ : {})
176
+ });
177
+ }
178
+ const requestedModel = nonEmptyString(request.agentConfig?.model);
179
+ if (requestedModel) {
180
+ const selection = acpModelSelectionRequest(sessionResult, sessionId, requestedModel);
181
+ if (selection) {
182
+ const selectionRequestId = client.reserveRequestId();
183
+ const selected = recordValue(await client.request(selection.method, selection.params, {
184
+ requestId: selectionRequestId
185
+ }));
186
+ if (Array.isArray(selected.configOptions))
187
+ sessionResult.configOptions = selected.configOptions;
188
+ }
189
+ providerModel = requestedModel;
190
+ }
191
+ else {
192
+ providerModel = sessionModel(sessionResult);
193
+ }
194
+ if (definition.configureSession)
195
+ yield* definition.configureSession(client, sessionResult, sessionId, request);
196
+ yield {
197
+ protocolVersion: 2,
198
+ type: "session.update",
199
+ payload: {
200
+ providerSession: {
201
+ sessionId,
202
+ resumable: true,
203
+ ...(resumeFallback
204
+ ? {
205
+ resumeOutcome: "fresh_fallback",
206
+ resumeFallback,
207
+ contextInputVariant: request.freshFallbackModelInputParts || request.freshFallbackModelInput
208
+ ? "recovery"
209
+ : "primary"
210
+ }
211
+ : {}),
212
+ ...(providerModel ? { model: providerModel } : {})
213
+ }
214
+ }
215
+ };
216
+ const input = providerInputParts(request, resumeFallback !== undefined);
217
+ const instructions = definition.controlInstructions === "session"
218
+ ? ""
219
+ : initialControlInstructions(request, !requestedSessionId || resumeFallback !== undefined);
220
+ // Preserve the legacy text call while mixed prompts retain every block's position.
221
+ const prompt = input.length === 1 && input[0]?.type === "text"
222
+ ? `${input[0].text}${instructions ? `\n\n${instructions}` : ""}`
223
+ : [
224
+ ...input,
225
+ ...(instructions
226
+ ? [
227
+ {
228
+ type: "text",
229
+ text: instructions
230
+ }
231
+ ]
232
+ : [])
233
+ ];
234
+ const promptParams = acpPromptParams(sessionId, prompt);
235
+ const promptRequestId = client.reserveRequestId();
236
+ let stopReason;
237
+ let finishReason;
238
+ let promptResultPublicText;
239
+ let producedFinalOutput = false;
240
+ const activeTools = new Set();
241
+ const turn = new AcpTurnNormalizer(definition.provider);
242
+ for await (const update of client.prompt(sessionId, prompt, {
243
+ requestId: promptRequestId,
244
+ params: promptParams
245
+ })) {
246
+ if (update.type === "prompt_result") {
247
+ for (const event of definition.validatePromptResult?.(update) ?? [])
248
+ yield event;
249
+ stopReason = update.stopReason;
250
+ finishReason = update.finishReason;
251
+ promptResultPublicText = promptResultText(update);
252
+ continue;
253
+ }
254
+ const standardUpdate = update;
255
+ const events = turn.normalize(standardUpdate.sessionUpdate ?? standardUpdate.type, normalizeAcpUpdate(standardUpdate, definition.provider));
256
+ for (const event of events) {
257
+ const id = stringField(event.payload, "id");
258
+ if (event.type === "message.delta" &&
259
+ event.payload.channel !== "analysis" &&
260
+ typeof event.payload.text === "string" &&
261
+ event.payload.text.length > 0) {
262
+ producedFinalOutput = true;
263
+ }
264
+ if (event.type === "tool_call.create" && id)
265
+ activeTools.add(id);
266
+ if (event.type === "tool_call.update" && id && isTerminalToolStatus(event.payload.status))
267
+ activeTools.delete(id);
268
+ yield event;
269
+ }
270
+ }
271
+ const cancelled = request.signal?.aborted || isCancelledStopReason(stopReason);
272
+ if (!cancelled && !producedFinalOutput && promptResultPublicText) {
273
+ const fallbackEvents = turn.normalize("agent_message_chunk", normalizeAcpUpdate({
274
+ type: "prompt_result",
275
+ sessionUpdate: "agent_message_chunk",
276
+ content: { text: promptResultPublicText }
277
+ }, definition.provider));
278
+ for (const event of fallbackEvents)
279
+ yield event;
280
+ producedFinalOutput = true;
281
+ }
282
+ if (cancelled) {
283
+ for (const id of activeTools)
284
+ yield {
285
+ protocolVersion: 2,
286
+ type: "tool_call.update",
287
+ payload: { id, status: canonicalTerminalStatus("cancelled") }
288
+ };
289
+ }
290
+ if (!cancelled && !producedFinalOutput) {
291
+ for (const event of turn.finish("no-final-output", "failed"))
292
+ yield event;
293
+ yield {
294
+ protocolVersion: 2,
295
+ type: "message.update",
296
+ payload: { role: "assistant", status: "failed" }
297
+ };
298
+ terminal = true;
299
+ yield {
300
+ protocolVersion: 2,
301
+ type: "run.failed",
302
+ payload: {
303
+ code: "ACP_NO_FINAL_OUTPUT",
304
+ message: `${definition.provider} completed without assistant output`,
305
+ adapterType: definition.type
306
+ }
307
+ };
308
+ return;
309
+ }
310
+ for (const event of turn.finish(stopReason ?? finishReason, cancelled ? "stopped" : "completed"))
311
+ yield event;
312
+ yield {
313
+ protocolVersion: 2,
314
+ type: "message.update",
315
+ payload: { role: "assistant", status: cancelled ? "stopped" : "completed" }
316
+ };
317
+ terminal = true;
318
+ yield cancelled
319
+ ? {
320
+ protocolVersion: 2,
321
+ type: "run.cancelled",
322
+ payload: {
323
+ reason: stopReason ?? String(request.signal?.reason ?? "cancelled"),
324
+ ...(finishReason ? { finishReason } : {})
325
+ }
326
+ }
327
+ : { protocolVersion: 2, type: "run.completed", payload: {} };
328
+ }
329
+ catch (error) {
330
+ if (!terminal && request.signal?.aborted) {
331
+ yield {
332
+ protocolVersion: 2,
333
+ type: "run.cancelled",
334
+ payload: { reason: String(request.signal.reason ?? "cancelled") }
335
+ };
336
+ }
337
+ else {
338
+ throw error;
339
+ }
340
+ }
341
+ finally {
342
+ request.signal?.removeEventListener("abort", abort);
343
+ if (request.signal?.aborted)
344
+ await closeAfterAbort();
345
+ else
346
+ await client.close();
347
+ }
348
+ }
349
+ }
350
+ function contentText(value) {
351
+ if (isRecord(value) && typeof value.text === "string")
352
+ return value.text;
353
+ if (!Array.isArray(value))
354
+ return undefined;
355
+ const text = value
356
+ .filter(isRecord)
357
+ .map((item) => (typeof item.text === "string" ? item.text : ""))
358
+ .join("");
359
+ return text || undefined;
360
+ }
361
+ function promptResultText(update) {
362
+ for (const value of [
363
+ update.text,
364
+ update.content,
365
+ update.output,
366
+ update.response,
367
+ update.message
368
+ ]) {
369
+ if (typeof value === "string" && value)
370
+ return value;
371
+ const text = contentText(value);
372
+ if (text)
373
+ return text;
374
+ }
375
+ return undefined;
376
+ }
377
+ function isTerminalToolStatus(status) {
378
+ return (typeof status === "string" &&
379
+ ["completed", "failed", "error", "cancelled", "canceled", "stopped"].includes(status.toLowerCase()));
380
+ }
381
+ function isCancelledStopReason(reason) {
382
+ return (typeof reason === "string" &&
383
+ ["cancelled", "canceled", "interrupted", "aborted"].includes(reason.toLowerCase()));
384
+ }
385
+ function isRecord(value) {
386
+ return value !== null && typeof value === "object" && !Array.isArray(value);
387
+ }
388
+ function recordValue(value) {
389
+ return isRecord(value) ? value : {};
390
+ }
391
+ function arrayField(value, key) {
392
+ return Array.isArray(value[key]) ? value[key] : [];
393
+ }
394
+ function nonEmptyString(value) {
395
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
396
+ }
397
+ function stringField(value, key) {
398
+ return typeof value[key] === "string" ? value[key] : undefined;
399
+ }
@@ -0,0 +1,14 @@
1
+ import { AcpClient, type SpawnAcpClientOptions } from "@mininglamp-oss/octo-runtime-acp-client";
2
+ type JsonRecord = Record<string, unknown>;
3
+ export interface SpawnGrokBuildClientOptions extends SpawnAcpClientOptions {
4
+ requestHandler?: (method: string, params: JsonRecord) => unknown;
5
+ onRequestResponseWritten?: (params: JsonRecord) => void;
6
+ onRequestResponseFailed?: (params: JsonRecord, error: Error) => void;
7
+ }
8
+ export declare class GrokBuildRpcError extends Error {
9
+ readonly code: unknown;
10
+ readonly data: unknown;
11
+ constructor(error: JsonRecord);
12
+ }
13
+ export declare function spawnGrokBuildAcpClient(options: SpawnGrokBuildClientOptions): AcpClient;
14
+ export {};