dsh-lcx-codex 0.4.2 → 0.4.3-pre.13

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 (39) hide show
  1. package/README.md +75 -224
  2. package/THIRD_PARTY_NOTICES.md +64 -0
  3. package/cordis.patch.yml +3 -20
  4. package/lib/auxiliary-usage.js +63 -0
  5. package/lib/client.js +1398 -167
  6. package/lib/compact-v2.js +218 -199
  7. package/lib/dsh-compat.js +294 -100
  8. package/lib/dsh-responses.js +512 -277
  9. package/lib/grok-native-search.js +391 -0
  10. package/lib/index.js +1066 -758
  11. package/lib/invocation-policy-scope.js +261 -0
  12. package/lib/json-store.js +57 -31
  13. package/lib/native-checkpoint.js +520 -194
  14. package/lib/pi-responses-runtime.js +1571 -0
  15. package/lib/responses-request.js +109 -121
  16. package/lib/responses-stream.js +1280 -447
  17. package/lib/route.js +425 -369
  18. package/lib/search-accounting.js +86 -0
  19. package/lib/search-usage.js +86 -0
  20. package/lib/service-mutex.js +73 -64
  21. package/lib/token-budget.js +176 -108
  22. package/lib/transport.js +308 -68
  23. package/lib/types/client/index.d.ts +18 -0
  24. package/lib/types/client/search-media.d.ts +16 -0
  25. package/lib/types/index.d.ts +83 -0
  26. package/lib/web-run-output.js +189 -18
  27. package/lib/web-search-alpha.js +1067 -163
  28. package/lib/web-search-capability.js +80 -65
  29. package/lib/web-search-hosted.js +321 -33
  30. package/lib/web-search-ref-store.js +145 -60
  31. package/package.json +112 -32
  32. package/ARCHITECTURE.md +0 -117
  33. package/CHANGELOG.md +0 -224
  34. package/README_EN.md +0 -277
  35. package/assets/dsh-lcx-codex-banner.jpg +0 -0
  36. package/lib/legacy-v3.js +0 -20
  37. package/lib/responses-replay.js +0 -68
  38. package/scripts/probe-alpha.mjs +0 -43
  39. package/scripts/validate-dsh-schema.mjs +0 -31
@@ -0,0 +1,391 @@
1
+ import { createHash } from "node:crypto";
2
+ export const GROK_NATIVE_SERVER_TOOL_TYPES = new Set([
3
+ "web_search_call",
4
+ "x_search_call",
5
+ ]);
6
+ const GROK_EXCLUDED_SEARCH_FUNCTIONS = new Set([
7
+ "web_search",
8
+ "websearch_gpt_advanced",
9
+ "websearch_alpha",
10
+ ]);
11
+ const GROK_NATIVE_X_EXTENSION_NAMES = new Set([
12
+ "x_user_search",
13
+ "x_keyword_search",
14
+ "x_semantic_search",
15
+ "x_thread_fetch",
16
+ ]);
17
+ const GROK_NATIVE_WEB_EXTENSION_NAMES = new Set(["browse_page"]);
18
+ const GROK_NATIVE_VISIBLE_ITEM_TYPES = new Set([
19
+ "message",
20
+ "reasoning",
21
+ "function_call",
22
+ "custom_tool_call",
23
+ ]);
24
+ const GROK_NATIVE_REPLAY_MAX_ITEMS = 256;
25
+ const GROK_NATIVE_REPLAY_MAX_CHARS = 8 * 1024 * 1024;
26
+ const GROK_RENDER_MARKER = /(?:\bstateless_invoke\s+)?\{?render_inline_citation(?:\s*\(\s*citation_id\s*=\s*\d+\s*\)|\s+with\s+citation_id\s+is\s+\d+)\}?[ \t]*/giu;
27
+ const GROK_CITATION_ID_MARKER = /([ \t]?)\{render_inline_citation:citation_id=(\d+)\}/giu;
28
+ const GROK_UI_CITATION_MARKER = /render_inline_citation[^\r\n]*[ \t]*/giu;
29
+ const GROK_PRIVATE_RENDER_MARKER = /[\uE000-\uF8FF]render_inline_citation[^\uE000-\uF8FF\r\n]*[\uE000-\uF8FF][ \t]*/giu;
30
+ const GROK_EOS_MARKER = /<\|eos\|>/giu;
31
+ function isRecord(value) {
32
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33
+ }
34
+ function citationId(annotation) {
35
+ const value = annotation.citation_id ?? annotation.citationId ?? annotation.id;
36
+ return typeof value === "string" || typeof value === "number"
37
+ ? String(value)
38
+ : undefined;
39
+ }
40
+ function citationUrl(annotation) {
41
+ if (annotation.type !== "url_citation" || typeof annotation.url !== "string")
42
+ return undefined;
43
+ try {
44
+ const parsed = new URL(annotation.url);
45
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
46
+ return undefined;
47
+ return annotation.url.replace(/\)/gu, "%29");
48
+ }
49
+ catch {
50
+ return undefined;
51
+ }
52
+ }
53
+ function stripTrailingSourcesList(value) {
54
+ const newline = value.includes("\r\n") ? "\r\n" : "\n";
55
+ const lines = value.split(/\r?\n/u);
56
+ let fence;
57
+ for (let index = 0; index < lines.length; index += 1) {
58
+ const fenceMatch = /^\s*(```|~~~)/u.exec(lines[index] ?? "");
59
+ if (fenceMatch) {
60
+ const marker = fenceMatch[1];
61
+ fence = fence === marker ? undefined : fence ?? marker;
62
+ continue;
63
+ }
64
+ if (fence !== undefined || !/^\s*Sources:[ \t]*$/iu.test(lines[index] ?? ""))
65
+ continue;
66
+ let sourceCount = 0;
67
+ let validTail = true;
68
+ for (const line of lines.slice(index + 1)) {
69
+ if (!line.trim())
70
+ continue;
71
+ if (/^\s*[-*][ \t]+.*https?:\/\/\S+/iu.test(line))
72
+ sourceCount += 1;
73
+ else {
74
+ validTail = false;
75
+ break;
76
+ }
77
+ }
78
+ if (validTail && sourceCount > 0)
79
+ return lines.slice(0, index).join(newline);
80
+ }
81
+ return value;
82
+ }
83
+ export function grokPendingSourcesStart(value) {
84
+ const lines = value.split(/(?<=\n)/u);
85
+ let offset = 0;
86
+ let fence;
87
+ let candidate;
88
+ for (const lineWithEnding of lines) {
89
+ const line = lineWithEnding.replace(/\r?\n$/u, "");
90
+ const fenceMatch = /^\s*(```|~~~)/u.exec(line);
91
+ if (fenceMatch) {
92
+ const marker = fenceMatch[1];
93
+ fence = fence === marker ? undefined : fence ?? marker;
94
+ }
95
+ else if (fence === undefined && /^\s*Sources:[ \t]*$/iu.test(line)) {
96
+ candidate = offset;
97
+ }
98
+ offset += lineWithEnding.length;
99
+ }
100
+ return candidate;
101
+ }
102
+ export function sanitizeGrokVisibleText(value, annotations = []) {
103
+ const citations = new Map();
104
+ for (const candidate of annotations) {
105
+ if (!isRecord(candidate))
106
+ continue;
107
+ const id = citationId(candidate);
108
+ const url = citationUrl(candidate);
109
+ if (id !== undefined && url !== undefined && !citations.has(id))
110
+ citations.set(id, url);
111
+ }
112
+ let text = value
113
+ .replace(GROK_CITATION_ID_MARKER, (_marker, leading, id) => {
114
+ const url = citations.get(id);
115
+ return url === undefined ? "" : `${leading}[[${id}]](${url})`;
116
+ })
117
+ .replace(GROK_RENDER_MARKER, "")
118
+ .replace(GROK_UI_CITATION_MARKER, "")
119
+ .replace(GROK_PRIVATE_RENDER_MARKER, "")
120
+ .replace(GROK_EOS_MARKER, "");
121
+ text = stripTrailingSourcesList(text);
122
+ return text.trimEnd();
123
+ }
124
+ function canonicalHeaders(headers) {
125
+ return Object.entries(headers ?? {})
126
+ .map(([name, value]) => [name.toLowerCase(), value])
127
+ .sort(([left], [right]) => left.localeCompare(right));
128
+ }
129
+ export function grokNativeReplayRouteFingerprint(route) {
130
+ return createHash("sha256")
131
+ .update(JSON.stringify({
132
+ provider: route.provider,
133
+ model: route.model,
134
+ sessionId: route.sessionId,
135
+ baseURL: route.baseURL.trim().replace(/\/+$/u, ""),
136
+ apiKeyEnv: route.apiKeyEnv,
137
+ headers: canonicalHeaders(route.headers),
138
+ }), "utf8")
139
+ .digest("hex");
140
+ }
141
+ export function grokNativeSearchEnabled(state) {
142
+ return state.web || state.x;
143
+ }
144
+ export function grokVisibleFunctionTools(tools, state = { web: false, x: false }) {
145
+ return tools?.filter((tool) => !GROK_EXCLUDED_SEARCH_FUNCTIONS.has(tool.name) &&
146
+ !(state.x && tool.name === "x_search"));
147
+ }
148
+ export function isGrokNativeServerToolItem(value, state, declaredToolNames) {
149
+ if (!isRecord(value) || typeof value.type !== "string")
150
+ return false;
151
+ if (GROK_NATIVE_SERVER_TOOL_TYPES.has(value.type))
152
+ return true;
153
+ if (value.type !== "custom_tool_call" || typeof value.name !== "string" ||
154
+ declaredToolNames.has(value.name) || typeof value.id !== "string" ||
155
+ !value.id.startsWith("ctc_") || typeof value.call_id !== "string")
156
+ return false;
157
+ if (state.x && GROK_NATIVE_X_EXTENSION_NAMES.has(value.name) &&
158
+ value.call_id.startsWith("xs_call-"))
159
+ return true;
160
+ return state.web && GROK_NATIVE_WEB_EXTENSION_NAMES.has(value.name) &&
161
+ (value.call_id.startsWith("ws_call-") || value.call_id.startsWith("web_search_call-"));
162
+ }
163
+ export function grokWireTools(tools, state) {
164
+ const nativeTypes = new Set(["web_search", "x_search"]);
165
+ const result = (tools ?? [])
166
+ .filter((tool) => {
167
+ if (!isRecord(tool))
168
+ return true;
169
+ if (nativeTypes.has(String(tool.type ?? "")))
170
+ return false;
171
+ return !(state.x && tool.type === "function" && tool.name === "x_search");
172
+ })
173
+ .map((tool) => structuredClone(tool))
174
+ .filter(isRecord);
175
+ if (state.web)
176
+ result.push({ type: "web_search" });
177
+ if (state.x)
178
+ result.push({ type: "x_search" });
179
+ return result;
180
+ }
181
+ function validVisibleItem(item) {
182
+ if (item.type === "message")
183
+ return typeof item.id === "string" && item.role === "assistant" &&
184
+ Array.isArray(item.content);
185
+ if (item.type === "reasoning")
186
+ return typeof item.id === "string" && Array.isArray(item.summary);
187
+ if (item.type === "function_call")
188
+ return typeof item.id === "string" && typeof item.call_id === "string" &&
189
+ typeof item.name === "string" && typeof item.arguments === "string";
190
+ if (item.type === "custom_tool_call")
191
+ return typeof item.id === "string" && typeof item.call_id === "string" &&
192
+ typeof item.name === "string" && typeof item.input === "string";
193
+ return false;
194
+ }
195
+ function readGrokNativeReplayEnvelope(value, route) {
196
+ if (!isRecord(value) ||
197
+ value.kind !== "xai-responses-native-search" ||
198
+ value.version !== 3)
199
+ return undefined;
200
+ if (value.provider !== route.provider ||
201
+ value.model !== route.model ||
202
+ value.sourceSessionId !== route.sessionId ||
203
+ value.routeAuthorityFingerprint !== grokNativeReplayRouteFingerprint(route) ||
204
+ !Array.isArray(value.output) ||
205
+ value.output.length === 0 ||
206
+ value.output.length > GROK_NATIVE_REPLAY_MAX_ITEMS)
207
+ return undefined;
208
+ let encoded;
209
+ try {
210
+ encoded = JSON.stringify(value.output);
211
+ }
212
+ catch {
213
+ return undefined;
214
+ }
215
+ if (encoded === undefined || encoded.length > GROK_NATIVE_REPLAY_MAX_CHARS)
216
+ return undefined;
217
+ const output = [];
218
+ const itemKinds = new Map();
219
+ const callIds = new Set();
220
+ if (value.serverSearchEchoCallIds !== undefined &&
221
+ (!Array.isArray(value.serverSearchEchoCallIds) ||
222
+ !value.serverSearchEchoCallIds.every((id) => typeof id === "string" && id.length > 0) ||
223
+ new Set(value.serverSearchEchoCallIds).size !== value.serverSearchEchoCallIds.length))
224
+ return undefined;
225
+ const serverSearchEchoCallIds = new Set(value.serverSearchEchoCallIds ?? []);
226
+ for (const candidate of value.output) {
227
+ if (!isRecord(candidate) || typeof candidate.type !== "string")
228
+ return undefined;
229
+ const item = candidate;
230
+ if (GROK_NATIVE_SERVER_TOOL_TYPES.has(item.type)) {
231
+ if (typeof item.id !== "string" || item.id.length === 0)
232
+ return undefined;
233
+ }
234
+ else if (!GROK_NATIVE_VISIBLE_ITEM_TYPES.has(item.type) || !validVisibleItem(item)) {
235
+ return undefined;
236
+ }
237
+ if (typeof item.id === "string") {
238
+ const previousKind = itemKinds.get(item.id);
239
+ // Compatible Grok gateways can repeat a reasoning ID around server tools.
240
+ // These are ordered opaque items, never executable client calls.
241
+ if (previousKind !== undefined &&
242
+ !(previousKind === "reasoning" && item.type === "reasoning"))
243
+ return undefined;
244
+ itemKinds.set(item.id, item.type);
245
+ }
246
+ if (item.type === "function_call" || item.type === "custom_tool_call") {
247
+ const callId = String(item.call_id);
248
+ if (callIds.has(callId))
249
+ return undefined;
250
+ callIds.add(callId);
251
+ }
252
+ output.push(structuredClone(item));
253
+ }
254
+ if (output.length === 0)
255
+ return undefined;
256
+ for (const id of serverSearchEchoCallIds)
257
+ if (!output.some((item) => item.type === "custom_tool_call" && item.call_id === id))
258
+ return undefined;
259
+ return {
260
+ kind: "xai-responses-native-search",
261
+ version: 3,
262
+ provider: route.provider,
263
+ model: route.model,
264
+ sourceSessionId: route.sessionId,
265
+ routeAuthorityFingerprint: grokNativeReplayRouteFingerprint(route),
266
+ ...(serverSearchEchoCallIds.size > 0 ? { serverSearchEchoCallIds: [...serverSearchEchoCallIds] } : {}),
267
+ output,
268
+ };
269
+ }
270
+ export function createGrokNativeReplayEnvelope(output, route, serverSearchEchoCallIds = []) {
271
+ if (!route || !Array.isArray(output))
272
+ return undefined;
273
+ return readGrokNativeReplayEnvelope({
274
+ kind: "xai-responses-native-search",
275
+ version: 3,
276
+ provider: route.provider,
277
+ model: route.model,
278
+ sourceSessionId: route.sessionId,
279
+ routeAuthorityFingerprint: grokNativeReplayRouteFingerprint(route),
280
+ ...(serverSearchEchoCallIds.length > 0 ? { serverSearchEchoCallIds: [...serverSearchEchoCallIds] } : {}),
281
+ output,
282
+ }, route);
283
+ }
284
+ function itemText(item, visible = false) {
285
+ if (item.type === "message")
286
+ return (Array.isArray(item.content) ? item.content : [])
287
+ .map((part) => {
288
+ if (!isRecord(part))
289
+ return "";
290
+ const text = String(part.text ?? part.refusal ?? "");
291
+ return visible
292
+ ? sanitizeGrokVisibleText(text, Array.isArray(part.annotations) ? part.annotations : [])
293
+ : text;
294
+ })
295
+ .join("");
296
+ if (item.type === "reasoning") {
297
+ const parts = Array.isArray(item.summary) && item.summary.length > 0
298
+ ? item.summary
299
+ : Array.isArray(item.content) ? item.content : [];
300
+ return parts.map((part) => isRecord(part) ? String(part.text ?? "") : "").join("\n\n");
301
+ }
302
+ return "";
303
+ }
304
+ function visibleItemMatchesBlock(item, block) {
305
+ if (item.type === "message")
306
+ return block.type === "text" && block.text === itemText(item, true);
307
+ if (item.type === "reasoning")
308
+ return block.type === "reasoning" && block.text === itemText(item);
309
+ if (item.type === "function_call")
310
+ return block.type === "tool-call" && block.id === `${String(item.call_id)}|${String(item.id)}` &&
311
+ block.name === item.name && block.arguments === item.arguments;
312
+ if (item.type === "custom_tool_call")
313
+ return block.type === "tool-call" && block.id === `${String(item.call_id)}|${String(item.id)}` &&
314
+ block.name === item.name;
315
+ return false;
316
+ }
317
+ function visibleItemMatchesInput(item, candidate) {
318
+ if (!isRecord(candidate) || candidate.type !== item.type)
319
+ return false;
320
+ if (candidate.id !== item.id)
321
+ return false;
322
+ if (item.type === "function_call" || item.type === "custom_tool_call")
323
+ return candidate.call_id === item.call_id;
324
+ return true;
325
+ }
326
+ function replayForMessage(message, route) {
327
+ if (message.role !== "assistant" || message.source.kind !== "model")
328
+ return undefined;
329
+ if (message.source.provider !== route.provider || message.source.model !== route.model)
330
+ return undefined;
331
+ const replayState = message.source.replayState;
332
+ if (!isRecord(replayState))
333
+ return undefined;
334
+ const envelope = readGrokNativeReplayEnvelope(replayState.grokNative, route);
335
+ if (!envelope)
336
+ return undefined;
337
+ const serverSearchEchoCallIds = new Set(envelope.serverSearchEchoCallIds ?? []);
338
+ const visible = envelope.output.filter((item) => !GROK_NATIVE_SERVER_TOOL_TYPES.has(item.type) &&
339
+ !(item.type === "custom_tool_call" && serverSearchEchoCallIds.has(String(item.call_id))));
340
+ if (visible.length === 0)
341
+ return undefined;
342
+ const reasoningCounts = new Map();
343
+ for (const item of visible)
344
+ if (item.type === "reasoning")
345
+ reasoningCounts.set(String(item.id), (reasoningCounts.get(String(item.id)) ?? 0) + 1);
346
+ const anchors = [];
347
+ let blockIndex = 0;
348
+ for (const item of visible) {
349
+ const block = message.content[blockIndex];
350
+ if (isRecord(block) && visibleItemMatchesBlock(item, block)) {
351
+ anchors.push(item);
352
+ blockIndex += 1;
353
+ }
354
+ else if (!(item.type === "reasoning" &&
355
+ (!itemText(item).trim() || (reasoningCounts.get(String(item.id)) ?? 0) > 1))) {
356
+ return undefined;
357
+ }
358
+ }
359
+ // Empty Grok reasoning has no UI block. Pi can coalesce repeated reasoning IDs
360
+ // in terminal-only gateway responses; every actual DSH-visible block must still match.
361
+ if (anchors.length === 0)
362
+ return undefined;
363
+ if (blockIndex !== message.content.length)
364
+ return undefined;
365
+ return { envelope, visible: anchors };
366
+ }
367
+ export function restoreGrokNativeReplay(input, messages, route) {
368
+ const restored = structuredClone(input);
369
+ if (!route)
370
+ return restored;
371
+ let cursor = 0;
372
+ for (const message of messages) {
373
+ const replay = replayForMessage(message, route);
374
+ if (!replay)
375
+ continue;
376
+ const { envelope, visible } = replay;
377
+ const replacedLength = visible.length;
378
+ let start = -1;
379
+ for (let index = cursor; index <= restored.length - replacedLength; index += 1) {
380
+ if (visible.every((item, offset) => visibleItemMatchesInput(item, restored[index + offset]))) {
381
+ start = index;
382
+ break;
383
+ }
384
+ }
385
+ if (start < 0)
386
+ continue;
387
+ restored.splice(start, replacedLength, ...structuredClone(envelope.output));
388
+ cursor = start + envelope.output.length;
389
+ }
390
+ return restored;
391
+ }