lody 0.85.0 → 0.86.0
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/chunks/{directory-handle-OPjjCl3O.js → directory-handle-Bp47LF5g.js} +37 -35
- package/dist/chunks/{index-ddMw90Gr.js → index-Dd0J9MIK.js} +173 -210
- package/dist/chunks/methods-CvEDMahD.js +19 -0
- package/dist/chunks/{review-viewer-oYzxdgq4.js → review-viewer-DE7MFi1P.js} +5 -4
- package/dist/chunks/runtime-manifest-ByWJfM07.js +9 -0
- package/dist/claude-acp.js +347 -160
- package/dist/codex-acp.js +1 -1
- package/dist/deepseek-acp.js +39 -1
- package/dist/file-index-scan-worker.js +1 -1
- package/dist/grok-acp.js +236 -44
- package/dist/index.js +2424 -936
- package/package.json +2 -2
- package/dist/chunks/runtime-manifest-Fr5DEH54.js +0 -9
package/dist/codex-acp.js
CHANGED
package/dist/deepseek-acp.js
CHANGED
|
@@ -15,6 +15,9 @@ const inject = [
|
|
|
15
15
|
"sessionPersistence",
|
|
16
16
|
"sessionQuery"
|
|
17
17
|
];
|
|
18
|
+
const LODY_CAPABILITIES = {
|
|
19
|
+
compaction: { version: 1 }
|
|
20
|
+
};
|
|
18
21
|
const MODEL_CONFIG_ID = "model";
|
|
19
22
|
const MODE_CONFIG_ID = "mode";
|
|
20
23
|
const REASONING_EFFORT_CONFIG_ID = "reasoning_effort";
|
|
@@ -518,6 +521,40 @@ function apply(ctx, rawConfig) {
|
|
|
518
521
|
});
|
|
519
522
|
}
|
|
520
523
|
}
|
|
524
|
+
} else if (event.type === "compaction/start" && event.data.compactionId) {
|
|
525
|
+
const activity = {
|
|
526
|
+
version: 1,
|
|
527
|
+
kind: "context_compaction",
|
|
528
|
+
automatic: event.data.turn !== null
|
|
529
|
+
};
|
|
530
|
+
notify({
|
|
531
|
+
sessionId: record.agent.session.id,
|
|
532
|
+
update: {
|
|
533
|
+
sessionUpdate: "tool_call",
|
|
534
|
+
toolCallId: `context-compaction:${event.data.compactionId}`,
|
|
535
|
+
title: "Compacting context",
|
|
536
|
+
kind: "think",
|
|
537
|
+
status: "in_progress",
|
|
538
|
+
_meta: { lody: { activity } }
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
} else if (event.type === "compaction/end" && event.data.compactionId) {
|
|
542
|
+
const activity = {
|
|
543
|
+
version: 1,
|
|
544
|
+
kind: "context_compaction",
|
|
545
|
+
automatic: event.data.turn !== null,
|
|
546
|
+
...event.data.error ? { failureReason: event.data.error } : {}
|
|
547
|
+
};
|
|
548
|
+
notify({
|
|
549
|
+
sessionId: record.agent.session.id,
|
|
550
|
+
update: {
|
|
551
|
+
sessionUpdate: "tool_call_update",
|
|
552
|
+
toolCallId: `context-compaction:${event.data.compactionId}`,
|
|
553
|
+
title: event.data.error ? "Context compaction failed" : "Context compacted",
|
|
554
|
+
status: event.data.error ? "failed" : "completed",
|
|
555
|
+
_meta: { lody: { activity } }
|
|
556
|
+
}
|
|
557
|
+
});
|
|
521
558
|
}
|
|
522
559
|
} finally {
|
|
523
560
|
const inflight = record.inflight;
|
|
@@ -616,7 +653,8 @@ function apply(ctx, rawConfig) {
|
|
|
616
653
|
embeddedContext: false
|
|
617
654
|
},
|
|
618
655
|
mcpCapabilities: { http: true },
|
|
619
|
-
sessionCapabilities: { close: {} }
|
|
656
|
+
sessionCapabilities: { close: {} },
|
|
657
|
+
_meta: { lody: LODY_CAPABILITIES }
|
|
620
658
|
},
|
|
621
659
|
authMethods: []
|
|
622
660
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { opendir } from "node:fs/promises";
|
|
2
2
|
import path__default from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { z as buildCodeCollabFileIndexState, F as scanGitDirectoryEntries, H as joinWorkspacePath, I as isInsideGitWorktree, D as computeAllChanges, J as pathSegmentComparisonKey, G as closeDirectoryQuietly } from "./chunks/directory-handle-Bp47LF5g.js";
|
|
4
4
|
import "./chunks/schemas-Du3qLZPS.js";
|
|
5
5
|
import "node:child_process";
|
|
6
6
|
import "node:util";
|
package/dist/grok-acp.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createInterface } from "node:readline";
|
|
2
|
-
import { r as runtimeManifest } from "./chunks/runtime-manifest-
|
|
2
|
+
import { r as runtimeManifest } from "./chunks/runtime-manifest-ByWJfM07.js";
|
|
3
|
+
import { L as LODY_EXTENSION_METHODS } from "./chunks/methods-CvEDMahD.js";
|
|
3
4
|
import { spawn } from "node:child_process";
|
|
4
5
|
const contract = runtimeManifest.privateWireContract;
|
|
5
6
|
const PERMISSION_MODES = {
|
|
@@ -16,12 +17,17 @@ const INTERACTION_FROM_RUNTIME = { default: "agent", plan: "plan", ask: "plan" }
|
|
|
16
17
|
const LEGACY_INTERACTION_ALIASES = { ask: "plan" };
|
|
17
18
|
const INTERNAL_REQUESTS = {
|
|
18
19
|
context: { contractKey: "sessionInfoRequest", params: (sessionId) => ({ sessionId }) },
|
|
19
|
-
billing: { contractKey: "billingRequest", params: () => ({}) }
|
|
20
|
+
billing: { contractKey: "billingRequest", params: () => ({}) },
|
|
21
|
+
rateLimits: { contractKey: "billingRequest", params: () => ({}) }
|
|
20
22
|
};
|
|
21
23
|
const USD_TICKS_PER_USD = 1e10;
|
|
22
24
|
const MAX_TRACKED_PROMPTS = 256;
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
+
const GROK_LODY_CAPABILITIES = {
|
|
26
|
+
usage: { version: 1 },
|
|
27
|
+
rateLimits: { version: 1, query: true }
|
|
28
|
+
};
|
|
29
|
+
const SEVEN_DAY_WINDOW_SECONDS = 7 * 24 * 60 * 60;
|
|
30
|
+
const GROK_MODEL_SNAPSHOT_SETTLE_TIMEOUT_MS = 2e3;
|
|
25
31
|
function logicalExtensionMethod(method) {
|
|
26
32
|
return typeof method === "string" && method.startsWith("_") ? method.slice(1) : method;
|
|
27
33
|
}
|
|
@@ -31,6 +37,9 @@ function wireExtensionMethod(method) {
|
|
|
31
37
|
function extensionNotification(contractKey, params) {
|
|
32
38
|
return { jsonrpc: "2.0", method: wireExtensionMethod(contract[contractKey]), params };
|
|
33
39
|
}
|
|
40
|
+
function lodyNotification(method, params) {
|
|
41
|
+
return { jsonrpc: "2.0", method, params };
|
|
42
|
+
}
|
|
34
43
|
function optionalNonnegativeNumber(value) {
|
|
35
44
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
36
45
|
}
|
|
@@ -53,20 +62,18 @@ function billingUsagePercent(config, period) {
|
|
|
53
62
|
if (hasOfficialZeroUsage) return 0;
|
|
54
63
|
return void 0;
|
|
55
64
|
}
|
|
56
|
-
function rateLimitsPayload(planName, window) {
|
|
57
|
-
const isFiveHour = window?.windowDurationMins === FIVE_HOUR_WINDOW_MINS;
|
|
58
|
-
const isSevenDay = window?.windowDurationMins === SEVEN_DAY_WINDOW_MINS;
|
|
65
|
+
function rateLimitsPayload(planName, window, now = Date.now()) {
|
|
59
66
|
return {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
rateLimits: window ? [
|
|
68
|
+
{
|
|
69
|
+
limitId: "grok",
|
|
70
|
+
scope: { providerId: "grok" },
|
|
71
|
+
planName,
|
|
72
|
+
limitName: "Grok Build",
|
|
73
|
+
windows: [window]
|
|
74
|
+
}
|
|
75
|
+
] : [],
|
|
76
|
+
fetchedAtEpochSeconds: Math.floor(now / 1e3)
|
|
70
77
|
};
|
|
71
78
|
}
|
|
72
79
|
function normalizeUsageModel(usage, usageIsIncomplete) {
|
|
@@ -105,9 +112,9 @@ function normalizePromptUsage(promptUsage) {
|
|
|
105
112
|
...Object.keys(modelUsage).length ? { modelUsage } : {}
|
|
106
113
|
};
|
|
107
114
|
}
|
|
108
|
-
function usageNotification(promptUsage) {
|
|
115
|
+
function usageNotification(sessionId, promptUsage) {
|
|
109
116
|
const params = normalizePromptUsage(promptUsage);
|
|
110
|
-
return params &&
|
|
117
|
+
return params && lodyNotification(LODY_EXTENSION_METHODS.sessionUsageUpdate, { sessionId, ...params });
|
|
111
118
|
}
|
|
112
119
|
function normalizeBillingRateLimits(billing) {
|
|
113
120
|
if (!billing || typeof billing !== "object") return void 0;
|
|
@@ -121,20 +128,25 @@ function normalizeBillingRateLimits(billing) {
|
|
|
121
128
|
const end = period?.end ?? period?.billingPeriodEnd ?? config.billingPeriodEnd;
|
|
122
129
|
const startMs = typeof start === "string" ? Date.parse(start) : Number.NaN;
|
|
123
130
|
const endMs = typeof end === "string" ? Date.parse(end) : Number.NaN;
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
const
|
|
131
|
+
const measuredWindowDurationSeconds = Number.isFinite(startMs) && Number.isFinite(endMs) && endMs > startMs ? Math.round((endMs - startMs) / 1e3) : null;
|
|
132
|
+
const windowDurationSeconds = period?.type === contract.weeklyUsagePeriodType ? SEVEN_DAY_WINDOW_SECONDS : measuredWindowDurationSeconds;
|
|
133
|
+
const resetsAtEpochSeconds = Number.isFinite(endMs) ? Math.floor(endMs / 1e3) : null;
|
|
127
134
|
const tier = billing.subscriptionTier ?? billing.subscription_tier;
|
|
128
135
|
const planName = typeof tier === "string" && tier.trim() ? tier : null;
|
|
129
136
|
if (usedPercent === void 0) {
|
|
130
|
-
if (!planName &&
|
|
137
|
+
if (!planName && windowDurationSeconds === null && resetsAtEpochSeconds === null)
|
|
138
|
+
return void 0;
|
|
131
139
|
return rateLimitsPayload(planName, null);
|
|
132
140
|
}
|
|
133
|
-
return rateLimitsPayload(planName, {
|
|
141
|
+
return rateLimitsPayload(planName, {
|
|
142
|
+
usedPercent,
|
|
143
|
+
windowDurationSeconds,
|
|
144
|
+
resetsAtEpochSeconds
|
|
145
|
+
});
|
|
134
146
|
}
|
|
135
147
|
function rateLimitsNotification(billing) {
|
|
136
148
|
const params = normalizeBillingRateLimits(billing);
|
|
137
|
-
return params &&
|
|
149
|
+
return params && lodyNotification(LODY_EXTENSION_METHODS.rateLimitsUpdate, params);
|
|
138
150
|
}
|
|
139
151
|
function contextUsageNotification(sessionId, context) {
|
|
140
152
|
const size = nonnegativeNumber(context?.total);
|
|
@@ -184,6 +196,24 @@ function readReasoningEfforts(model) {
|
|
|
184
196
|
if (!Array.isArray(raw)) return [];
|
|
185
197
|
return raw.map((item) => typeof item === "string" ? item : item?.id ?? item?.reasoningEffort).filter((item) => typeof item === "string");
|
|
186
198
|
}
|
|
199
|
+
function readModelSnapshot(params) {
|
|
200
|
+
if (!params || typeof params !== "object" || !Array.isArray(params.availableModels)) {
|
|
201
|
+
return void 0;
|
|
202
|
+
}
|
|
203
|
+
if (params.availableModels.length === 0 || params.availableModels.some(
|
|
204
|
+
(model) => !model || typeof model !== "object" || typeof model.modelId !== "string"
|
|
205
|
+
)) {
|
|
206
|
+
return void 0;
|
|
207
|
+
}
|
|
208
|
+
const currentModelId = params.currentModelId;
|
|
209
|
+
if (typeof currentModelId !== "string" || !params.availableModels.some((model) => model.modelId === currentModelId)) {
|
|
210
|
+
return void 0;
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
currentModelId,
|
|
214
|
+
availableModels: params.availableModels
|
|
215
|
+
};
|
|
216
|
+
}
|
|
187
217
|
function selectOption(id, name, description, currentValue, options, category) {
|
|
188
218
|
return {
|
|
189
219
|
id,
|
|
@@ -240,17 +270,107 @@ function translateSessionStart(message) {
|
|
|
240
270
|
};
|
|
241
271
|
}
|
|
242
272
|
class GrokAcpCompatibilityProxy {
|
|
243
|
-
constructor() {
|
|
273
|
+
constructor({ deferSessionResponseUntilModelSnapshot = false } = {}) {
|
|
244
274
|
this.sessions = /* @__PURE__ */ new Map();
|
|
245
275
|
this.pending = /* @__PURE__ */ new Map();
|
|
276
|
+
this.pendingSessionResponses = /* @__PURE__ */ new Map();
|
|
277
|
+
this.clientVisibleSessions = /* @__PURE__ */ new Set();
|
|
278
|
+
this.latestModelSnapshot = void 0;
|
|
279
|
+
this.latestModelSnapshotFingerprint = void 0;
|
|
280
|
+
this.deferSessionResponseUntilModelSnapshot = deferSessionResponseUntilModelSnapshot;
|
|
246
281
|
this.permissionModes = /* @__PURE__ */ new Map();
|
|
247
282
|
this.nextInternalRequestId = Number.MAX_SAFE_INTEGER;
|
|
248
283
|
}
|
|
249
|
-
|
|
284
|
+
applyModelSnapshot(state, snapshot) {
|
|
285
|
+
const previousModelId = state.currentModelId;
|
|
286
|
+
const previousReasoningEffort = state.reasoningEffort;
|
|
287
|
+
const currentModel = snapshot.availableModels.find(
|
|
288
|
+
(model) => model.modelId === snapshot.currentModelId
|
|
289
|
+
);
|
|
290
|
+
const reasoningEfforts = readReasoningEfforts(currentModel);
|
|
291
|
+
const metadataReasoningEffort = currentModel?._meta?.reasoningEffort ?? currentModel?._meta?.reasoning_effort;
|
|
292
|
+
state.currentModelId = snapshot.currentModelId;
|
|
293
|
+
state.models = snapshot.availableModels;
|
|
294
|
+
state.reasoningEfforts = reasoningEfforts;
|
|
295
|
+
state.reasoningEffort = previousModelId === snapshot.currentModelId && reasoningEfforts.includes(previousReasoningEffort) ? previousReasoningEffort : typeof metadataReasoningEffort === "string" && reasoningEfforts.includes(metadataReasoningEffort) ? metadataReasoningEffort : reasoningEfforts[0];
|
|
296
|
+
}
|
|
297
|
+
sessionResponseWithState(message, state) {
|
|
298
|
+
const models = typeof state.currentModelId === "string" && state.models.length > 0 ? {
|
|
299
|
+
currentModelId: state.currentModelId,
|
|
300
|
+
availableModels: state.models
|
|
301
|
+
} : message.result?.models;
|
|
302
|
+
return {
|
|
303
|
+
...message,
|
|
304
|
+
result: {
|
|
305
|
+
...message.result,
|
|
306
|
+
...models ? { models } : {},
|
|
307
|
+
configOptions: this.configOptions(state)
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
exposePendingSessionResponse(id) {
|
|
312
|
+
const pending = this.pendingSessionResponses.get(id);
|
|
313
|
+
if (!pending) return { toRuntime: [], toClient: [] };
|
|
314
|
+
this.pendingSessionResponses.delete(id);
|
|
315
|
+
const state = this.sessions.get(pending.sessionId);
|
|
316
|
+
if (!state) return { toRuntime: [], toClient: [pending.message] };
|
|
317
|
+
this.clientVisibleSessions.add(pending.sessionId);
|
|
318
|
+
return {
|
|
319
|
+
toRuntime: [],
|
|
320
|
+
toClient: [this.sessionResponseWithState(pending.message, state)]
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
flushPendingSessionResponse(id) {
|
|
324
|
+
return this.exposePendingSessionResponse(id);
|
|
325
|
+
}
|
|
326
|
+
handleModelSnapshot(message) {
|
|
327
|
+
const snapshot = readModelSnapshot(message.params);
|
|
328
|
+
if (!snapshot) return { toRuntime: [], toClient: [message] };
|
|
329
|
+
const fingerprint = JSON.stringify(snapshot);
|
|
330
|
+
if (fingerprint === this.latestModelSnapshotFingerprint) {
|
|
331
|
+
return { toRuntime: [], toClient: [] };
|
|
332
|
+
}
|
|
333
|
+
this.latestModelSnapshot = snapshot;
|
|
334
|
+
this.latestModelSnapshotFingerprint = fingerprint;
|
|
335
|
+
for (const state of this.sessions.values()) {
|
|
336
|
+
this.applyModelSnapshot(state, snapshot);
|
|
337
|
+
}
|
|
338
|
+
const toClient = [];
|
|
339
|
+
const pendingSessionIds = /* @__PURE__ */ new Set();
|
|
340
|
+
const settledSessionResponseIds = [];
|
|
341
|
+
for (const id of [...this.pendingSessionResponses.keys()]) {
|
|
342
|
+
const pending = this.pendingSessionResponses.get(id);
|
|
343
|
+
if (pending) pendingSessionIds.add(pending.sessionId);
|
|
344
|
+
toClient.push(...this.exposePendingSessionResponse(id).toClient);
|
|
345
|
+
settledSessionResponseIds.push(id);
|
|
346
|
+
}
|
|
347
|
+
for (const sessionId of this.clientVisibleSessions) {
|
|
348
|
+
if (pendingSessionIds.has(sessionId)) continue;
|
|
349
|
+
const state = this.sessions.get(sessionId);
|
|
350
|
+
if (!state) continue;
|
|
351
|
+
toClient.push({
|
|
352
|
+
jsonrpc: "2.0",
|
|
353
|
+
method: "session/update",
|
|
354
|
+
params: {
|
|
355
|
+
sessionId,
|
|
356
|
+
update: {
|
|
357
|
+
sessionUpdate: "config_option_update",
|
|
358
|
+
configOptions: this.configOptions(state)
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
toRuntime: [],
|
|
365
|
+
toClient,
|
|
366
|
+
...settledSessionResponseIds.length > 0 ? { settledSessionResponseIds } : {}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
internalRequest(kind, sessionId, responseId) {
|
|
250
370
|
while (this.pending.has(this.nextInternalRequestId)) this.nextInternalRequestId -= 1;
|
|
251
371
|
const id = this.nextInternalRequestId;
|
|
252
372
|
this.nextInternalRequestId -= 1;
|
|
253
|
-
this.pending.set(id, { kind, sessionId });
|
|
373
|
+
this.pending.set(id, { kind, sessionId, responseId });
|
|
254
374
|
const { contractKey, params } = INTERNAL_REQUESTS[kind];
|
|
255
375
|
return {
|
|
256
376
|
jsonrpc: "2.0",
|
|
@@ -267,7 +387,7 @@ class GrokAcpCompatibilityProxy {
|
|
|
267
387
|
return this.usageRefreshRequests(state.sessionId);
|
|
268
388
|
}
|
|
269
389
|
usageForPrompt(state, promptId, promptUsage) {
|
|
270
|
-
const notification = usageNotification(promptUsage);
|
|
390
|
+
const notification = usageNotification(state.sessionId, promptUsage);
|
|
271
391
|
if (!notification) return void 0;
|
|
272
392
|
if (!rememberPrompt(state.usagePromptIds, promptId)) return void 0;
|
|
273
393
|
return notification;
|
|
@@ -275,6 +395,16 @@ class GrokAcpCompatibilityProxy {
|
|
|
275
395
|
handleClient(message) {
|
|
276
396
|
if (!message || typeof message !== "object") return { toRuntime: [message], toClient: [] };
|
|
277
397
|
const params = message.params ?? {};
|
|
398
|
+
if (message.method === "initialize" && message.id !== void 0) {
|
|
399
|
+
this.pending.set(message.id, { kind: "initialize" });
|
|
400
|
+
return { toRuntime: [message], toClient: [] };
|
|
401
|
+
}
|
|
402
|
+
if (message.method === LODY_EXTENSION_METHODS.rateLimitsGet) {
|
|
403
|
+
return {
|
|
404
|
+
toRuntime: [this.internalRequest("rateLimits", void 0, message.id)],
|
|
405
|
+
toClient: []
|
|
406
|
+
};
|
|
407
|
+
}
|
|
278
408
|
if (message.method === "session/new" || message.method === "session/load" || message.method === "session/resume" || message.method === "session/fork") {
|
|
279
409
|
const clientIdentifier = params._meta?.clientIdentifier;
|
|
280
410
|
const translated2 = translateSessionStart(message);
|
|
@@ -404,27 +534,68 @@ class GrokAcpCompatibilityProxy {
|
|
|
404
534
|
};
|
|
405
535
|
}
|
|
406
536
|
if (pending.kind === "billing") {
|
|
407
|
-
const notification = message.error ?
|
|
537
|
+
const notification = message.error ? lodyNotification(LODY_EXTENSION_METHODS.rateLimitsUpdate, rateLimitsPayload(null, null)) : rateLimitsNotification(unwrapExtensionResult(message.result));
|
|
408
538
|
return {
|
|
409
539
|
toRuntime: [],
|
|
410
540
|
toClient: notification ? [notification] : []
|
|
411
541
|
};
|
|
412
542
|
}
|
|
543
|
+
if (pending.kind === "rateLimits") {
|
|
544
|
+
const result = message.error ? rateLimitsPayload(null, null) : normalizeBillingRateLimits(unwrapExtensionResult(message.result)) ?? rateLimitsPayload(null, null);
|
|
545
|
+
return {
|
|
546
|
+
toRuntime: [],
|
|
547
|
+
toClient: [{ jsonrpc: "2.0", id: pending.responseId, result }]
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
if (pending.kind === "initialize") {
|
|
551
|
+
if (message.error) return { toRuntime: [], toClient: [message] };
|
|
552
|
+
const result = message.result ?? {};
|
|
553
|
+
const agentCapabilities = result.agentCapabilities ?? {};
|
|
554
|
+
return {
|
|
555
|
+
toRuntime: [],
|
|
556
|
+
toClient: [
|
|
557
|
+
{
|
|
558
|
+
...message,
|
|
559
|
+
result: {
|
|
560
|
+
...result,
|
|
561
|
+
agentCapabilities: {
|
|
562
|
+
...agentCapabilities,
|
|
563
|
+
_meta: {
|
|
564
|
+
...agentCapabilities._meta ?? {},
|
|
565
|
+
lody: GROK_LODY_CAPABILITIES
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
]
|
|
571
|
+
};
|
|
572
|
+
}
|
|
413
573
|
if (message.error) return { toRuntime: [], toClient: [message] };
|
|
414
574
|
if (pending.kind === "session") {
|
|
415
575
|
const result = message.result ?? {};
|
|
416
576
|
const sessionId = result.sessionId ?? pending.sessionId;
|
|
417
577
|
if (!sessionId) return { toRuntime: [], toClient: [message] };
|
|
418
578
|
const state2 = this.stateFromSessionResponse(sessionId, pending.clientIdentifier, result);
|
|
579
|
+
if (this.latestModelSnapshot) {
|
|
580
|
+
this.applyModelSnapshot(state2, this.latestModelSnapshot);
|
|
581
|
+
}
|
|
419
582
|
this.sessions.set(sessionId, state2);
|
|
583
|
+
const sessionResponse = this.sessionResponseWithState(message, state2);
|
|
584
|
+
if (this.deferSessionResponseUntilModelSnapshot && !this.latestModelSnapshot && message.id !== void 0) {
|
|
585
|
+
this.pendingSessionResponses.set(message.id, {
|
|
586
|
+
message: sessionResponse,
|
|
587
|
+
sessionId
|
|
588
|
+
});
|
|
589
|
+
return {
|
|
590
|
+
toRuntime: this.usageRefreshRequests(sessionId),
|
|
591
|
+
toClient: [],
|
|
592
|
+
deferredSessionResponseIds: [message.id]
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
this.clientVisibleSessions.add(sessionId);
|
|
420
596
|
return {
|
|
421
597
|
toRuntime: this.usageRefreshRequests(sessionId),
|
|
422
|
-
toClient: [
|
|
423
|
-
{
|
|
424
|
-
...message,
|
|
425
|
-
result: { ...result, configOptions: this.configOptions(state2) }
|
|
426
|
-
}
|
|
427
|
-
]
|
|
598
|
+
toClient: [sessionResponse]
|
|
428
599
|
};
|
|
429
600
|
}
|
|
430
601
|
if (pending.kind === "prompt") {
|
|
@@ -456,11 +627,14 @@ class GrokAcpCompatibilityProxy {
|
|
|
456
627
|
}
|
|
457
628
|
handleRuntimeMethod(message) {
|
|
458
629
|
const passthrough = { toRuntime: [], toClient: [message] };
|
|
630
|
+
const logicalMethod = logicalExtensionMethod(message.method);
|
|
631
|
+
if (logicalMethod === contract.modelsUpdateNotification) {
|
|
632
|
+
return this.handleModelSnapshot(message);
|
|
633
|
+
}
|
|
459
634
|
const sessionId = message.params?.sessionId;
|
|
460
635
|
const update = message.params?.update;
|
|
461
636
|
const state = this.sessions.get(sessionId);
|
|
462
637
|
if (!state) return passthrough;
|
|
463
|
-
const logicalMethod = logicalExtensionMethod(message.method);
|
|
464
638
|
if (logicalMethod === contract.sessionUpdateNotification && update?.sessionUpdate === contract.turnCompletedUpdate) {
|
|
465
639
|
if (message.params?._meta?.isReplay === true) return passthrough;
|
|
466
640
|
const promptId = update.prompt_id ?? update.promptId;
|
|
@@ -611,16 +785,36 @@ if (!grokPath) {
|
|
|
611
785
|
process.exit(1);
|
|
612
786
|
}
|
|
613
787
|
const child = spawnGrokRuntime(grokPath);
|
|
614
|
-
const proxy = new GrokAcpCompatibilityProxy(
|
|
788
|
+
const proxy = new GrokAcpCompatibilityProxy({
|
|
789
|
+
deferSessionResponseUntilModelSnapshot: true
|
|
790
|
+
});
|
|
791
|
+
const deferredResponseTimers = /* @__PURE__ */ new Map();
|
|
615
792
|
function write(stream, message) {
|
|
616
793
|
stream.write(`${JSON.stringify(message)}
|
|
617
794
|
`);
|
|
618
795
|
}
|
|
796
|
+
function dispatch(output) {
|
|
797
|
+
for (const id of output.settledSessionResponseIds ?? []) {
|
|
798
|
+
const timer = deferredResponseTimers.get(id);
|
|
799
|
+
if (timer) clearTimeout(timer);
|
|
800
|
+
deferredResponseTimers.delete(id);
|
|
801
|
+
}
|
|
802
|
+
for (const message of output.toRuntime) write(child.stdin, message);
|
|
803
|
+
for (const message of output.toClient) write(process.stdout, message);
|
|
804
|
+
for (const id of output.deferredSessionResponseIds ?? []) {
|
|
805
|
+
const existingTimer = deferredResponseTimers.get(id);
|
|
806
|
+
if (existingTimer) clearTimeout(existingTimer);
|
|
807
|
+
const timer = setTimeout(() => {
|
|
808
|
+
deferredResponseTimers.delete(id);
|
|
809
|
+
dispatch(proxy.flushPendingSessionResponse(id));
|
|
810
|
+
}, GROK_MODEL_SNAPSHOT_SETTLE_TIMEOUT_MS);
|
|
811
|
+
deferredResponseTimers.set(id, timer);
|
|
812
|
+
timer.unref();
|
|
813
|
+
}
|
|
814
|
+
}
|
|
619
815
|
createInterface({ input: process.stdin }).on("line", (line) => {
|
|
620
816
|
try {
|
|
621
|
-
|
|
622
|
-
for (const message of output.toRuntime) write(child.stdin, message);
|
|
623
|
-
for (const message of output.toClient) write(process.stdout, message);
|
|
817
|
+
dispatch(proxy.handleClient(JSON.parse(line)));
|
|
624
818
|
} catch (error) {
|
|
625
819
|
console.error(
|
|
626
820
|
`Invalid ACP client message: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -629,9 +823,7 @@ createInterface({ input: process.stdin }).on("line", (line) => {
|
|
|
629
823
|
});
|
|
630
824
|
createInterface({ input: child.stdout }).on("line", (line) => {
|
|
631
825
|
try {
|
|
632
|
-
|
|
633
|
-
for (const message of output.toRuntime) write(child.stdin, message);
|
|
634
|
-
for (const message of output.toClient) write(process.stdout, message);
|
|
826
|
+
dispatch(proxy.handleRuntime(JSON.parse(line)));
|
|
635
827
|
} catch (error) {
|
|
636
828
|
console.error(
|
|
637
829
|
`Invalid Grok runtime message: ${error instanceof Error ? error.message : String(error)}`
|