dsh-lcx-codex 0.4.3-pre.2 → 0.4.3-pre.3
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/README.md +77 -109
- package/lib/client.js +40 -4
- package/lib/dsh-compat.js +8 -3
- package/lib/grok-native-search.js +317 -0
- package/lib/index.js +227 -71
- package/lib/responses-request.js +3 -0
- package/lib/responses-stream.js +248 -15
- package/lib/route.js +173 -5
- package/lib/transport.js +4 -2
- package/lib/types/dsh-compat.d.ts +1 -1
- package/lib/types/grok-native-search.d.ts +39 -0
- package/lib/types/responses-request.d.ts +1 -0
- package/lib/types/responses-stream.d.ts +14 -1
- package/lib/types/route.d.ts +22 -1
- package/lib/types/transport.d.ts +2 -1
- package/package.json +5 -1
package/lib/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import { WEB_SEARCH_MAX_QUERIES, applyWebSearchTool, } from "@deepseek-ai/dsh-tool-web";
|
|
2
3
|
import "@deepseek-ai/dsh-agent";
|
|
3
4
|
import "@deepseek-ai/dsh-tools";
|
|
4
5
|
import "@deepseek-ai/dsh-web";
|
|
@@ -6,9 +7,10 @@ import { randomUUID } from "node:crypto";
|
|
|
6
7
|
import { homedir } from "node:os";
|
|
7
8
|
import { join } from "node:path";
|
|
8
9
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
|
+
import { getSupportedThinkingLevels } from "@earendil-works/pi-ai";
|
|
9
11
|
import { fetchJsonWithRetry } from "./transport.js";
|
|
10
|
-
import { agentSessionId, agentUsesSession, compactionConfigState, compactionPatchCandidate, installCompactionPatch, patchCompactionConfig, patchToolResultPruner,
|
|
11
|
-
import { authenticatedHeaders, currentRoute, generationControlsFromSession, promptCacheKey, promptCacheRetention, promptCacheSessionId, resolveResponsesRouteConfig, routeFingerprint, } from "./route.js";
|
|
12
|
+
import { agentSessionId, agentUsesSession, compactionConfigState, compactionPatchCandidate, installCompactionPatch, patchCompactionConfig, patchToolResultPruner, readAgentRouteState, resolveAgentService, resolveContextService, resolveScopedService, restoreCompactionConfig, restoreCompactionPatches, restoreToolResultPruner, sessionFor, sessionFromAgent, scopedToolRuntime, tokenMeterTotal, toolResultPrunerState, } from "./dsh-compat.js";
|
|
13
|
+
import { authenticatedGrokHeaders, authenticatedHeaders, currentRoute, generationControlsFromSession, grokPromptCacheSessionId, promptCacheKey, promptCacheRetention, promptCacheSessionId, resolveGrokResponsesRouteConfig, resolveResponsesRouteConfig, routeFingerprint, } from "./route.js";
|
|
12
14
|
import { DEFAULT_MAX_REQUEST_IMAGE_BYTES, DEFAULT_REQUEST_IMAGE_PIXEL_BUDGET, DEFAULT_REQUEST_IMAGE_MAX_BYTES, hydrateNativeImageReferences, resolveModelImageSupport, responseInputItems, serializeDshMessages, } from "./dsh-responses.js";
|
|
13
15
|
import { mergeFeatureHeader, requestNativeCompaction } from "./compact-v2.js";
|
|
14
16
|
import { buildResponsesBody } from "./responses-request.js";
|
|
@@ -19,6 +21,7 @@ import { ALPHA_SCHEMA_FINGERPRINT, alphaRefRequiresStore, isAlphaContinuationUrl
|
|
|
19
21
|
import { AlphaCapabilityStore, alphaCapabilityFingerprint, alphaCapabilityUsable, } from "./web-search-capability.js";
|
|
20
22
|
import { AlphaRefStore } from "./web-search-ref-store.js";
|
|
21
23
|
import { ServiceMutex } from "./service-mutex.js";
|
|
24
|
+
import { GROK_NATIVE_SERVER_TOOL_TYPES, grokNativeSearchEnabled, grokVisibleFunctionTools, grokWireTools, restoreGrokNativeReplay, } from "./grok-native-search.js";
|
|
22
25
|
export const name = "lcx-codex";
|
|
23
26
|
export const inject = ["llm", "web", "sessions", "tools", "settings", "credentials", "attachments", "fs"];
|
|
24
27
|
const SETTINGS_NS = "lcx-codex";
|
|
@@ -53,6 +56,13 @@ function routeWithPolicies(route, config) {
|
|
|
53
56
|
webMaxResults: config.webMaxResults,
|
|
54
57
|
};
|
|
55
58
|
}
|
|
59
|
+
function grokReplayRoute(route, config) {
|
|
60
|
+
return {
|
|
61
|
+
...route,
|
|
62
|
+
apiKeyEnv: config.apiKeyEnv,
|
|
63
|
+
headers: config.headers,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
56
66
|
function isRecord(value) {
|
|
57
67
|
return value !== null && typeof value === "object";
|
|
58
68
|
}
|
|
@@ -106,6 +116,8 @@ const SettingsSchema = z.object({
|
|
|
106
116
|
webSearch: z.boolean().default(false),
|
|
107
117
|
advancedHostedSearch: z.boolean().default(false),
|
|
108
118
|
alphaSearch: z.boolean().default(false),
|
|
119
|
+
grokNativeWebSearch: z.boolean().default(false),
|
|
120
|
+
grokNativeXSearch: z.boolean().default(false),
|
|
109
121
|
});
|
|
110
122
|
function normalizeConfig(input = {}) {
|
|
111
123
|
return {
|
|
@@ -156,10 +168,10 @@ function activeAgentRoute(exec) {
|
|
|
156
168
|
function selectedAgentRoute(agent) {
|
|
157
169
|
const route = readAgentRouteState(agent);
|
|
158
170
|
return {
|
|
159
|
-
provider: stringValue(routeConfigValue(route.
|
|
160
|
-
routeConfigValue(route.
|
|
161
|
-
model: stringValue(routeConfigValue(route.
|
|
162
|
-
routeConfigValue(route.
|
|
171
|
+
provider: stringValue(routeConfigValue(route.requestConfig, "provider") ??
|
|
172
|
+
routeConfigValue(route.options, "provider"), ""),
|
|
173
|
+
model: stringValue(routeConfigValue(route.requestConfig, "model") ??
|
|
174
|
+
routeConfigValue(route.options, "model"), ""),
|
|
163
175
|
sessionId: route.sessionId,
|
|
164
176
|
};
|
|
165
177
|
}
|
|
@@ -228,6 +240,40 @@ class LcxResponsesSearchProvider {
|
|
|
228
240
|
};
|
|
229
241
|
}
|
|
230
242
|
}
|
|
243
|
+
function createScopedGptWebSearchTool(ctx, state, getConfig, provider, fetchEnabled) {
|
|
244
|
+
let definition;
|
|
245
|
+
const composition = {
|
|
246
|
+
web: {
|
|
247
|
+
search: (request, signal) => provider.search(request, signal),
|
|
248
|
+
},
|
|
249
|
+
tools: {
|
|
250
|
+
register(candidate) {
|
|
251
|
+
definition = candidate;
|
|
252
|
+
return () => { };
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
systemPrompt: {
|
|
256
|
+
getSectionOrder: () => 0,
|
|
257
|
+
section: () => () => { },
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
applyWebSearchTool(composition, getConfig().webMaxResults, WEB_SEARCH_MAX_QUERIES, WEB_SEARCH_TIMEOUT_MS, fetchEnabled);
|
|
261
|
+
if (!definition)
|
|
262
|
+
throw new Error("DSH web_search composition did not register a tool");
|
|
263
|
+
const execute = definition.execute.bind(definition);
|
|
264
|
+
return {
|
|
265
|
+
...definition,
|
|
266
|
+
async execute(args, exec) {
|
|
267
|
+
if (!state.enabled || !state.webSearch)
|
|
268
|
+
throw webError("web_search GPT Hosted Search is disabled", "LCX_WEB_DISABLED");
|
|
269
|
+
const active = activeAgentRoute(exec);
|
|
270
|
+
const route = resolveResponsesRouteConfig(ctx, active, getConfig());
|
|
271
|
+
if (!route)
|
|
272
|
+
throw webError("GPT Hosted Search requires the active GPT openai-responses route", "LCX_WEB_ROUTE_UNAVAILABLE");
|
|
273
|
+
return hostedSearchRouteContext.run(active, () => execute(args, exec));
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
231
277
|
function createAdvancedHostedTool(ctx, state, getConfig) {
|
|
232
278
|
return {
|
|
233
279
|
name: ADVANCED_HOSTED_TOOL,
|
|
@@ -249,6 +295,61 @@ function createAdvancedHostedTool(ctx, state, getConfig) {
|
|
|
249
295
|
},
|
|
250
296
|
};
|
|
251
297
|
}
|
|
298
|
+
function disposeGptToolsForAgent(agent, registrations) {
|
|
299
|
+
const registration = registrations.get(agent);
|
|
300
|
+
if (!registration)
|
|
301
|
+
return;
|
|
302
|
+
registration.dispose();
|
|
303
|
+
registrations.delete(agent);
|
|
304
|
+
}
|
|
305
|
+
function syncGptToolsForAgent(ctx, agent, state, getConfig, provider, registrations) {
|
|
306
|
+
const config = getConfig();
|
|
307
|
+
const active = selectedAgentRoute(agent);
|
|
308
|
+
const route = resolveResponsesRouteConfig(ctx, active, config);
|
|
309
|
+
const webSearch = state.enabled && state.webSearch && Boolean(route);
|
|
310
|
+
const advanced = webSearch && state.advancedHostedSearch;
|
|
311
|
+
if (!webSearch && !advanced) {
|
|
312
|
+
disposeGptToolsForAgent(agent, registrations);
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
const fingerprint = JSON.stringify({
|
|
316
|
+
provider: route?.provider,
|
|
317
|
+
model: route?.model,
|
|
318
|
+
baseURL: route?.baseURL,
|
|
319
|
+
webSearch,
|
|
320
|
+
advanced,
|
|
321
|
+
webMaxResults: config.webMaxResults,
|
|
322
|
+
});
|
|
323
|
+
if (registrations.get(agent)?.fingerprint === fingerprint)
|
|
324
|
+
return true;
|
|
325
|
+
disposeGptToolsForAgent(agent, registrations);
|
|
326
|
+
const scopedTools = scopedToolRuntime(agent);
|
|
327
|
+
if (!scopedTools)
|
|
328
|
+
return false;
|
|
329
|
+
const disposers = [];
|
|
330
|
+
try {
|
|
331
|
+
if (webSearch) {
|
|
332
|
+
const fetchEnabled = Boolean(scopedTools.get?.("web_fetch", agent));
|
|
333
|
+
disposers.push(scopedTools.register(createScopedGptWebSearchTool(ctx, state, getConfig, provider, fetchEnabled)));
|
|
334
|
+
}
|
|
335
|
+
if (advanced)
|
|
336
|
+
disposers.push(scopedTools.register(createAdvancedHostedTool(ctx, state, getConfig)));
|
|
337
|
+
registrations.set(agent, {
|
|
338
|
+
fingerprint,
|
|
339
|
+
dispose() {
|
|
340
|
+
for (const dispose of disposers.reverse())
|
|
341
|
+
dispose();
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
for (const dispose of disposers.reverse())
|
|
348
|
+
dispose();
|
|
349
|
+
ctx.logger?.warn?.(`[lcx-codex] GPT search tool composition unavailable: ${errorDetails(error).message ?? String(error)}`);
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
252
353
|
function alphaCapabilityFor(config, store) {
|
|
253
354
|
const fingerprint = alphaCapabilityFingerprint({
|
|
254
355
|
baseURL: config.baseURL,
|
|
@@ -433,14 +534,15 @@ async function serializeNativeAware(messages, route, routeConfig, ctx, options)
|
|
|
433
534
|
const flush = async () => {
|
|
434
535
|
if (!normal.length)
|
|
435
536
|
return;
|
|
436
|
-
const
|
|
537
|
+
const batch = normal;
|
|
538
|
+
normal = [];
|
|
539
|
+
const serialized = await serializeDshMessages(batch, ctx, serializeOptions());
|
|
437
540
|
nativeTools = serialized.tools ?? nativeTools;
|
|
438
541
|
nativeModel = serialized.model ?? nativeModel;
|
|
439
542
|
grammarToolInputProperties =
|
|
440
543
|
serialized.grammarToolInputProperties ?? grammarToolInputProperties;
|
|
441
|
-
input.push(...serialized.input);
|
|
544
|
+
input.push(...restoreGrokNativeReplay(serialized.input, batch, options.grokNativeReplayRoute));
|
|
442
545
|
mergeMap(imageMap, serialized.imageMap);
|
|
443
|
-
normal = [];
|
|
444
546
|
};
|
|
445
547
|
for (const message of messages ?? []) {
|
|
446
548
|
assertSupportedCheckpointMessage(message);
|
|
@@ -679,9 +781,6 @@ async function restoreCompactionPressure(records) {
|
|
|
679
781
|
await Promise.allSettled(entries.map((record) => record.mutex.close(reason)));
|
|
680
782
|
restoreCompactionPatches(records, entries);
|
|
681
783
|
}
|
|
682
|
-
function visibleWebSearchTimeout(state) {
|
|
683
|
-
return state.enabled && state.webSearch ? WEB_SEARCH_TIMEOUT_MS : undefined;
|
|
684
|
-
}
|
|
685
784
|
function messagesContainNativeCheckpoint(messages, session) {
|
|
686
785
|
return session !== undefined && messages.some((message) => checkpointStateForMessage(session, message));
|
|
687
786
|
}
|
|
@@ -731,6 +830,78 @@ async function* managedResponsesStream(options, routeConfig, ctx) {
|
|
|
731
830
|
yield managedFailureChunk(error, options.signal);
|
|
732
831
|
}
|
|
733
832
|
}
|
|
833
|
+
async function* managedGrokNativeSearchStream(options, routeConfig, nativeSearch, ctx) {
|
|
834
|
+
const route = currentRoute(options, routeConfig);
|
|
835
|
+
const nativeReplayRoute = grokReplayRoute(route, routeConfig);
|
|
836
|
+
try {
|
|
837
|
+
if (options.stop !== undefined)
|
|
838
|
+
throw Object.assign(new Error("LCX Responses does not support GenerateOptions.stop"), { code: "LCX_RESPONSES_UNSUPPORTED_OPTION" });
|
|
839
|
+
const visibleTools = grokVisibleFunctionTools(options.tools, nativeSearch);
|
|
840
|
+
const prepared = await serializeNativeAware(options.messages, route, routeConfig, ctx, {
|
|
841
|
+
signal: options.signal,
|
|
842
|
+
system: options.system,
|
|
843
|
+
tools: visibleTools,
|
|
844
|
+
grokNativeReplayRoute: nativeReplayRoute,
|
|
845
|
+
});
|
|
846
|
+
const cacheSessionId = grokPromptCacheSessionId(route, routeConfig);
|
|
847
|
+
const headers = await authenticatedGrokHeaders(ctx, routeConfig, cacheSessionId);
|
|
848
|
+
const model = {
|
|
849
|
+
...prepared.model,
|
|
850
|
+
...routeConfig.modelDefaults,
|
|
851
|
+
...routeConfig.modelControls,
|
|
852
|
+
id: route.model,
|
|
853
|
+
provider: route.provider,
|
|
854
|
+
baseUrl: routeConfig.baseURL,
|
|
855
|
+
api: "openai-responses",
|
|
856
|
+
};
|
|
857
|
+
const effectiveReasoning = options.reasoningEffort ?? routeConfig.profileReasoning;
|
|
858
|
+
if (effectiveReasoning !== undefined &&
|
|
859
|
+
!getSupportedThinkingLevels(model).some((level) => level === effectiveReasoning))
|
|
860
|
+
throw Object.assign(new Error(`Grok route does not support reasoning effort "${String(effectiveReasoning)}"`), { code: "LCX_RESPONSES_UNSUPPORTED_OPTION" });
|
|
861
|
+
const body = buildResponsesBody({
|
|
862
|
+
model,
|
|
863
|
+
input: prepared.input,
|
|
864
|
+
tools: grokWireTools(prepared.tools ?? visibleTools, nativeSearch),
|
|
865
|
+
sessionId: cacheSessionId,
|
|
866
|
+
promptCacheRetention: promptCacheRetention(routeConfig),
|
|
867
|
+
cacheRetention: routeConfig.cacheRetention,
|
|
868
|
+
reasoningEffort: effectiveReasoning,
|
|
869
|
+
temperature: options.temperature,
|
|
870
|
+
maxTokens: options.maxTokens,
|
|
871
|
+
});
|
|
872
|
+
if (nativeSearch.web) {
|
|
873
|
+
const include = new Set(Array.isArray(body.include) ? body.include : []);
|
|
874
|
+
include.add("web_search_call.action.sources");
|
|
875
|
+
body.include = [...include];
|
|
876
|
+
}
|
|
877
|
+
yield* streamResponsesRequest({
|
|
878
|
+
baseURL: routeConfig.baseURL,
|
|
879
|
+
provider: route.provider,
|
|
880
|
+
model: route.model,
|
|
881
|
+
piModel: model,
|
|
882
|
+
body,
|
|
883
|
+
grammarToolInputProperties: prepared.grammarToolInputProperties,
|
|
884
|
+
headers,
|
|
885
|
+
signal: options.signal,
|
|
886
|
+
timeoutMs: routeConfig.timeoutMs,
|
|
887
|
+
applyDefaultTimeout: false,
|
|
888
|
+
streamIdleTimeoutMs: routeConfig.streamIdleTimeoutMs,
|
|
889
|
+
maxAttempts: 1,
|
|
890
|
+
maxResponseBytes: routeConfig.maxResponseBytes,
|
|
891
|
+
serverToolTypes: GROK_NATIVE_SERVER_TOOL_TYPES,
|
|
892
|
+
nativeReplayRoute,
|
|
893
|
+
onServerToolUsage(usage) {
|
|
894
|
+
ctx.logger?.info?.(`[lcx-codex] Grok native search used ${usage.total} server-side tool call(s) (web=${usage.webSearchCalls}, x=${usage.xSearchCalls})`);
|
|
895
|
+
},
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
catch (error) {
|
|
899
|
+
yield managedFailureChunk(error, options.signal);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
function isGptLifecycleTarget(options) {
|
|
903
|
+
return /^gpt-/iu.test(String(options.model ?? ""));
|
|
904
|
+
}
|
|
734
905
|
async function* unavailableManagedRouteStream(options) {
|
|
735
906
|
yield managedFailureChunk(Object.assign(new Error("LCX is enabled but the selected DSH route cannot be resolved as an authenticated OpenAI Responses wire route"), { code: "LCX_RESPONSES_ROUTE_UNAVAILABLE" }), options.signal);
|
|
736
907
|
}
|
|
@@ -742,66 +913,45 @@ function installInjected(ctx, configInput = {}) {
|
|
|
742
913
|
webSearch: false,
|
|
743
914
|
advancedHostedSearch: false,
|
|
744
915
|
alphaSearch: false,
|
|
916
|
+
grokNativeWebSearch: false,
|
|
917
|
+
grokNativeXSearch: false,
|
|
745
918
|
};
|
|
746
|
-
const originalSearchProvider = readWebSearchProvider(ctx);
|
|
747
|
-
let warnedWebSelection = false;
|
|
748
919
|
const provider = new LcxResponsesSearchProvider(ctx, () => runtimeConfig, () => state.enabled && state.webSearch);
|
|
749
|
-
ctx.web.registerSearchProvider(provider);
|
|
750
|
-
const tools = ctx.tools;
|
|
751
|
-
let disposeAdvanced;
|
|
752
920
|
const capabilityStore = new AlphaCapabilityStore(baseConfig.alphaCapabilityPath);
|
|
753
921
|
const refStore = new AlphaRefStore(baseConfig.alphaRefPath);
|
|
754
|
-
const
|
|
922
|
+
const managedAgents = new Set();
|
|
923
|
+
const gptToolRegistrations = new Map();
|
|
755
924
|
const alphaToolRegistrations = new Map();
|
|
756
925
|
const compactionPatchRecords = new Map();
|
|
757
|
-
const
|
|
926
|
+
const syncAgentTools = (agent) => {
|
|
927
|
+
syncGptToolsForAgent(ctx, agent, state, () => runtimeConfig, provider, gptToolRegistrations);
|
|
928
|
+
syncAlphaToolForAgent(ctx, agent, state, () => runtimeConfig, capabilityStore, refStore, alphaToolRegistrations);
|
|
929
|
+
};
|
|
930
|
+
const refreshTools = () => {
|
|
931
|
+
for (const agent of managedAgents)
|
|
932
|
+
syncAgentTools(agent);
|
|
933
|
+
};
|
|
758
934
|
ctx.on("session/disposed", (session) => {
|
|
759
|
-
for (const agent of
|
|
935
|
+
for (const agent of managedAgents)
|
|
760
936
|
if (agentUsesSession(agent, session)) {
|
|
937
|
+
disposeGptToolsForAgent(agent, gptToolRegistrations);
|
|
761
938
|
disposeAlphaToolForAgent(agent, alphaToolRegistrations);
|
|
762
|
-
|
|
939
|
+
managedAgents.delete(agent);
|
|
763
940
|
}
|
|
764
941
|
}, { global: true });
|
|
765
942
|
ctx.on("session/event", (session, event) => {
|
|
766
943
|
if (event.type === "request/header")
|
|
767
|
-
for (const agent of
|
|
768
|
-
if (agentUsesSession(agent, session))
|
|
769
|
-
|
|
770
|
-
}
|
|
944
|
+
for (const agent of managedAgents)
|
|
945
|
+
if (agentUsesSession(agent, session))
|
|
946
|
+
syncAgentTools(agent);
|
|
771
947
|
}, { global: true });
|
|
772
|
-
const refreshTools = () => {
|
|
773
|
-
if (state.enabled &&
|
|
774
|
-
state.webSearch &&
|
|
775
|
-
state.advancedHostedSearch &&
|
|
776
|
-
!disposeAdvanced &&
|
|
777
|
-
tools?.register)
|
|
778
|
-
disposeAdvanced = tools.register(createAdvancedHostedTool(ctx, state, () => runtimeConfig));
|
|
779
|
-
if ((!state.enabled || !state.webSearch || !state.advancedHostedSearch) &&
|
|
780
|
-
disposeAdvanced) {
|
|
781
|
-
disposeAdvanced();
|
|
782
|
-
disposeAdvanced = undefined;
|
|
783
|
-
}
|
|
784
|
-
for (const agent of alphaAgents)
|
|
785
|
-
syncAlphaToolForAgent(ctx, agent, state, () => runtimeConfig, capabilityStore, refStore, alphaToolRegistrations);
|
|
786
|
-
if (ctx.web) {
|
|
787
|
-
const target = state.enabled && state.webSearch
|
|
788
|
-
? runtimeConfig.webSearchProvider
|
|
789
|
-
: originalSearchProvider;
|
|
790
|
-
const selected = writeWebSearchProvider(ctx, target);
|
|
791
|
-
if (!selected &&
|
|
792
|
-
state.enabled &&
|
|
793
|
-
state.webSearch &&
|
|
794
|
-
!warnedWebSelection) {
|
|
795
|
-
warnedWebSelection = true;
|
|
796
|
-
ctx.logger?.warn?.("[lcx-codex] DSH web provider selection could not be changed at runtime; websearch_gpt_advanced still works, but DSH web_search may remain on its configured provider. Pin web.searchProvider=lcx-responses in a profile overlay if this DSH version removes the runtime compatibility field.");
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
};
|
|
800
948
|
const settingsEntry = {
|
|
801
949
|
enabled: false,
|
|
802
950
|
webSearch: false,
|
|
803
951
|
advancedHostedSearch: false,
|
|
804
952
|
alphaSearch: false,
|
|
953
|
+
grokNativeWebSearch: false,
|
|
954
|
+
grokNativeXSearch: false,
|
|
805
955
|
};
|
|
806
956
|
let source = () => settingsEntry;
|
|
807
957
|
ctx.settings.installSection(ctx, SETTINGS_NS, SettingsSchema, settingsEntry, {
|
|
@@ -814,9 +964,10 @@ function installInjected(ctx, configInput = {}) {
|
|
|
814
964
|
state.webSearch = value.webSearch;
|
|
815
965
|
state.advancedHostedSearch = value.advancedHostedSearch;
|
|
816
966
|
state.alphaSearch = value.alphaSearch;
|
|
967
|
+
state.grokNativeWebSearch = value.grokNativeWebSearch;
|
|
968
|
+
state.grokNativeXSearch = value.grokNativeXSearch;
|
|
817
969
|
runtimeConfig = baseConfig;
|
|
818
970
|
refreshTools();
|
|
819
|
-
refreshVisibleWebSearchTimeouts(patchedWebSearchDefinitions, visibleWebSearchTimeout(state));
|
|
820
971
|
},
|
|
821
972
|
});
|
|
822
973
|
try {
|
|
@@ -826,6 +977,8 @@ function installInjected(ctx, configInput = {}) {
|
|
|
826
977
|
webSearch: Boolean(value.webSearch),
|
|
827
978
|
advancedHostedSearch: Boolean(value.advancedHostedSearch),
|
|
828
979
|
alphaSearch: Boolean(value.alphaSearch),
|
|
980
|
+
grokNativeWebSearch: Boolean(value.grokNativeWebSearch),
|
|
981
|
+
grokNativeXSearch: Boolean(value.grokNativeXSearch),
|
|
829
982
|
});
|
|
830
983
|
runtimeConfig = baseConfig;
|
|
831
984
|
}
|
|
@@ -834,17 +987,11 @@ function installInjected(ctx, configInput = {}) {
|
|
|
834
987
|
ctx.inject(["compaction"], (compactionCtx) => {
|
|
835
988
|
patchCompactionPressureService(resolveContextService(compactionCtx, "compaction"), state, () => runtimeConfig, ctx, compactionPatchRecords);
|
|
836
989
|
});
|
|
837
|
-
ctx.on("tools/execute", async (exec, next) => {
|
|
838
|
-
if (!state.enabled || !state.webSearch || exec.name !== "web_search")
|
|
839
|
-
return next();
|
|
840
|
-
const active = activeAgentRoute(exec);
|
|
841
|
-
return hostedSearchRouteContext.run(active, () => next());
|
|
842
|
-
});
|
|
843
990
|
ctx.on("agent/created", ({ agent }) => {
|
|
844
991
|
if (agent === null || typeof agent !== "object")
|
|
845
992
|
return;
|
|
846
|
-
|
|
847
|
-
|
|
993
|
+
managedAgents.add(agent);
|
|
994
|
+
syncAgentTools(agent);
|
|
848
995
|
const installed = patchCompactionPressureForAgent(agent, state, () => runtimeConfig, ctx, compactionPatchRecords);
|
|
849
996
|
if (installed)
|
|
850
997
|
ctx.logger?.info?.("[lcx-codex] pressure coordination installed through AgentPresets service resolver");
|
|
@@ -854,15 +1001,25 @@ function installInjected(ctx, configInput = {}) {
|
|
|
854
1001
|
agent === null ||
|
|
855
1002
|
typeof agent !== "object")
|
|
856
1003
|
return;
|
|
857
|
-
|
|
858
|
-
|
|
1004
|
+
managedAgents.add(agent);
|
|
1005
|
+
syncAgentTools(agent);
|
|
859
1006
|
const installed = patchCompactionPressureForAgent(agent, state, () => runtimeConfig, ctx, compactionPatchRecords);
|
|
860
1007
|
if (installed)
|
|
861
1008
|
ctx.logger?.info?.("[lcx-codex] pressure coordination installed through AgentPresets service resolver");
|
|
862
|
-
patchVisibleWebSearchTimeout(agent, () => visibleWebSearchTimeout(state), patchedWebSearchDefinitions);
|
|
863
1009
|
}, { global: true });
|
|
864
1010
|
ctx.on("llm/stream", (options, next) => {
|
|
865
|
-
if (
|
|
1011
|
+
if (options.purpose === "session-title")
|
|
1012
|
+
return next();
|
|
1013
|
+
const grokNativeSearch = {
|
|
1014
|
+
web: state.grokNativeWebSearch,
|
|
1015
|
+
x: state.grokNativeXSearch,
|
|
1016
|
+
};
|
|
1017
|
+
if (options.purpose === undefined && grokNativeSearchEnabled(grokNativeSearch)) {
|
|
1018
|
+
const grokRoute = resolveGrokResponsesRouteConfig(ctx, options, runtimeConfig);
|
|
1019
|
+
if (grokRoute)
|
|
1020
|
+
return managedGrokNativeSearchStream(options, routeWithPolicies(grokRoute, runtimeConfig), grokNativeSearch, ctx);
|
|
1021
|
+
}
|
|
1022
|
+
if (!state.enabled || !isGptLifecycleTarget(options))
|
|
866
1023
|
return next();
|
|
867
1024
|
const routeConfig = resolveResponsesRouteConfig(ctx, options, runtimeConfig);
|
|
868
1025
|
if (options.purpose === "compaction") {
|
|
@@ -875,13 +1032,12 @@ function installInjected(ctx, configInput = {}) {
|
|
|
875
1032
|
return managedResponsesStream(options, routeWithPolicies(routeConfig, runtimeConfig), ctx);
|
|
876
1033
|
});
|
|
877
1034
|
ctx.effect?.(() => async () => {
|
|
878
|
-
|
|
879
|
-
|
|
1035
|
+
for (const agent of managedAgents) {
|
|
1036
|
+
disposeGptToolsForAgent(agent, gptToolRegistrations);
|
|
880
1037
|
disposeAlphaToolForAgent(agent, alphaToolRegistrations);
|
|
881
|
-
|
|
1038
|
+
}
|
|
1039
|
+
managedAgents.clear();
|
|
882
1040
|
await restoreCompactionPressure(compactionPatchRecords);
|
|
883
|
-
restoreVisibleWebSearchTimeouts(patchedWebSearchDefinitions);
|
|
884
|
-
writeWebSearchProvider(ctx, originalSearchProvider);
|
|
885
1041
|
}, "lcx-codex cleanup");
|
|
886
1042
|
}
|
|
887
1043
|
export function apply(ctx, configInput = {}) {
|
package/lib/responses-request.js
CHANGED
|
@@ -33,6 +33,9 @@ export function responsesGenerationEnvelope({ model = "unknown", reasoningEffort
|
|
|
33
33
|
const descriptor = modelRecord(model);
|
|
34
34
|
const result = {};
|
|
35
35
|
if (descriptor.reasoning !== false) {
|
|
36
|
+
if (descriptor.provider === "xai" ||
|
|
37
|
+
descriptor.includeEncryptedReasoning === true)
|
|
38
|
+
result.include = ["reasoning.encrypted_content"];
|
|
36
39
|
if (reasoningEffort !== undefined && reasoningEffort !== "off") {
|
|
37
40
|
const requested = String(reasoningEffort);
|
|
38
41
|
const wire = descriptor.thinkingLevelMap?.[requested] ?? requested;
|