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.
- package/README.md +75 -224
- package/THIRD_PARTY_NOTICES.md +64 -0
- package/cordis.patch.yml +3 -20
- package/lib/auxiliary-usage.js +63 -0
- package/lib/client.js +1398 -167
- package/lib/compact-v2.js +218 -199
- package/lib/dsh-compat.js +294 -100
- package/lib/dsh-responses.js +512 -277
- package/lib/grok-native-search.js +391 -0
- package/lib/index.js +1066 -758
- package/lib/invocation-policy-scope.js +261 -0
- package/lib/json-store.js +57 -31
- package/lib/native-checkpoint.js +520 -194
- package/lib/pi-responses-runtime.js +1571 -0
- package/lib/responses-request.js +109 -121
- package/lib/responses-stream.js +1280 -447
- package/lib/route.js +425 -369
- package/lib/search-accounting.js +86 -0
- package/lib/search-usage.js +86 -0
- package/lib/service-mutex.js +73 -64
- package/lib/token-budget.js +176 -108
- package/lib/transport.js +308 -68
- package/lib/types/client/index.d.ts +18 -0
- package/lib/types/client/search-media.d.ts +16 -0
- package/lib/types/index.d.ts +83 -0
- package/lib/web-run-output.js +189 -18
- package/lib/web-search-alpha.js +1067 -163
- package/lib/web-search-capability.js +80 -65
- package/lib/web-search-hosted.js +321 -33
- package/lib/web-search-ref-store.js +145 -60
- package/package.json +112 -32
- package/ARCHITECTURE.md +0 -117
- package/CHANGELOG.md +0 -224
- package/README_EN.md +0 -277
- package/assets/dsh-lcx-codex-banner.jpg +0 -0
- package/lib/legacy-v3.js +0 -20
- package/lib/responses-replay.js +0 -68
- package/scripts/probe-alpha.mjs +0 -43
- package/scripts/validate-dsh-schema.mjs +0 -31
package/lib/compact-v2.js
CHANGED
|
@@ -1,184 +1,158 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { buildCompactionResponsesBody, responsesGenerationEnvelope as standardGenerationEnvelope } from './responses-request.js'
|
|
5
|
-
|
|
6
|
-
/** @typedef {Record<string, unknown>} UnknownRecord */
|
|
7
|
-
/** @typedef {Record<string, string>} HeaderMap */
|
|
8
|
-
/** @typedef {Error & { code?: string, status?: number, providerCode?: string, providerType?: string, providerParam?: string }} LcxError */
|
|
9
|
-
/** @typedef {{ type: 'compaction', encrypted_content: string }} CompactionItem */
|
|
10
|
-
/** @typedef {{ type: 'function_call', call_id: string }} FunctionCallItem */
|
|
11
|
-
/** @typedef {{ type: 'function_call_output', call_id: string }} FunctionCallOutputItem */
|
|
12
|
-
/** @typedef {CompactionItem | FunctionCallItem | FunctionCallOutputItem | { type: string }} ValidatedOutputItem */
|
|
13
|
-
/** @typedef {{ inputTokens: number, outputTokens: number, cacheReadTokens?: number, cacheWriteTokens?: number, reasoningTokens?: number }} CanonicalUsage */
|
|
14
|
-
/** @typedef {{ reasoningEffort?: unknown, temperature?: unknown, maxTokens?: unknown }} GenerationControls */
|
|
15
|
-
/** @typedef {{ reasoning?: { effort: string, summary: 'auto' }, include?: string[], temperature?: number, max_output_tokens?: number }} GenerationEnvelope */
|
|
16
|
-
/**
|
|
17
|
-
* @typedef {object} NativeCompactionBodyOptions
|
|
18
|
-
* @property {string} model
|
|
19
|
-
* @property {unknown} [modelDescriptor]
|
|
20
|
-
* @property {unknown[]} input
|
|
21
|
-
* @property {string} [instructions]
|
|
22
|
-
* @property {unknown} [tools]
|
|
23
|
-
* @property {string} [promptCacheKey]
|
|
24
|
-
* @property {string} [promptCacheRetention]
|
|
25
|
-
* @property {'none' | 'short' | 'long'} [cacheRetention]
|
|
26
|
-
* @property {unknown} [reasoningEffort]
|
|
27
|
-
* @property {unknown} [temperature]
|
|
28
|
-
* @property {unknown} [maxTokens]
|
|
29
|
-
*/
|
|
30
|
-
/**
|
|
31
|
-
* @typedef {object} NativeCompactionBody
|
|
32
|
-
* @property {string} model
|
|
33
|
-
* @property {unknown[]} input
|
|
34
|
-
* @property {true} stream
|
|
35
|
-
* @property {false} store
|
|
36
|
-
* @property {'auto'} tool_choice
|
|
37
|
-
* @property {true} parallel_tool_calls
|
|
38
|
-
* @property {string} [instructions]
|
|
39
|
-
* @property {unknown[]} [tools]
|
|
40
|
-
* @property {string} [prompt_cache_key]
|
|
41
|
-
* @property {string} [prompt_cache_retention]
|
|
42
|
-
* @property {{ mode?: 'explicit', ttl?: '30m' }} [prompt_cache_options]
|
|
43
|
-
* @property {{ effort: string, summary: 'auto' }} [reasoning]
|
|
44
|
-
* @property {string[]} [include]
|
|
45
|
-
* @property {number} [temperature]
|
|
46
|
-
* @property {number} [max_output_tokens]
|
|
47
|
-
*/
|
|
48
|
-
/**
|
|
49
|
-
* @typedef {NativeCompactionBodyOptions & {
|
|
50
|
-
* baseURL: string,
|
|
51
|
-
* idempotencyKey?: string,
|
|
52
|
-
* headers?: HeaderMap,
|
|
53
|
-
* signal?: AbortSignal,
|
|
54
|
-
* timeoutMs?: number,
|
|
55
|
-
* maxAttempts?: number,
|
|
56
|
-
* maxResponseBytes?: number
|
|
57
|
-
* }} NativeCompactionRequestOptions
|
|
58
|
-
*/
|
|
59
|
-
/** @typedef {{ signal?: AbortSignal, maxResponseBytes?: number }} SseParseOptions */
|
|
60
|
-
/** @typedef {{ object: unknown, id?: string, output: ValidatedOutputItem[], compaction: CompactionItem, usage?: CanonicalUsage }} NativeCompactionResult */
|
|
61
|
-
|
|
62
|
-
export const REMOTE_COMPACTION_V2_FEATURE = 'remote_compaction_v2'
|
|
63
|
-
|
|
1
|
+
import { consumeSse, fetchSseWithRetry } from "./transport.js";
|
|
2
|
+
import { buildCompactionResponsesBody, responsesGenerationEnvelope as standardGenerationEnvelope, } from "./responses-request.js";
|
|
3
|
+
export const REMOTE_COMPACTION_V2_FEATURE = "remote_compaction_v2";
|
|
64
4
|
/**
|
|
65
5
|
* @param {unknown} value
|
|
66
6
|
* @returns {value is UnknownRecord}
|
|
67
7
|
*/
|
|
68
|
-
function isObject(value) {
|
|
8
|
+
function isObject(value) {
|
|
9
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10
|
+
}
|
|
69
11
|
/**
|
|
70
12
|
* @param {string} message
|
|
71
13
|
* @param {string} [code]
|
|
72
14
|
* @returns {LcxError}
|
|
73
15
|
*/
|
|
74
|
-
function fail(message, code =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return e
|
|
16
|
+
function fail(message, code = "LCX_COMPACT_INVALID_RESPONSE") {
|
|
17
|
+
const e = new Error(message);
|
|
18
|
+
e.code = code;
|
|
19
|
+
return e;
|
|
79
20
|
}
|
|
80
21
|
/** @param {unknown} value */
|
|
81
22
|
function safeMachineField(value) {
|
|
82
|
-
|
|
83
|
-
|
|
23
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 96)
|
|
24
|
+
return undefined;
|
|
25
|
+
return /^[A-Za-z0-9_.:\[\]-]+$/u.test(value) ? value : undefined;
|
|
84
26
|
}
|
|
85
|
-
|
|
86
27
|
/**
|
|
87
28
|
* @param {HeaderMap} [headers]
|
|
88
29
|
* @returns {HeaderMap}
|
|
89
30
|
*/
|
|
90
31
|
export function mergeFeatureHeader(headers = {}) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
32
|
+
const result = { ...headers };
|
|
33
|
+
const key = Object.keys(result).find((name) => name.toLowerCase() === "x-codex-beta-features");
|
|
34
|
+
const values = String(key ? (result[key] ?? "") : "")
|
|
35
|
+
.split(",")
|
|
36
|
+
.map((x) => x.trim())
|
|
37
|
+
.filter(Boolean);
|
|
38
|
+
if (!values.includes(REMOTE_COMPACTION_V2_FEATURE))
|
|
39
|
+
values.push(REMOTE_COMPACTION_V2_FEATURE);
|
|
40
|
+
result[key ?? "x-codex-beta-features"] = values.join(",");
|
|
41
|
+
return result;
|
|
97
42
|
}
|
|
98
|
-
|
|
99
43
|
/**
|
|
100
44
|
* @param {GenerationControls} [controls]
|
|
101
45
|
* @returns {GenerationEnvelope}
|
|
102
46
|
*/
|
|
103
47
|
export function responsesGenerationEnvelope(controls = {}) {
|
|
104
|
-
|
|
48
|
+
return standardGenerationEnvelope({
|
|
49
|
+
model: "unknown",
|
|
50
|
+
reasoningEffort: controls.reasoningEffort,
|
|
51
|
+
temperature: controls.temperature,
|
|
52
|
+
maxTokens: controls.maxTokens,
|
|
53
|
+
});
|
|
105
54
|
}
|
|
106
|
-
|
|
107
55
|
/**
|
|
108
56
|
* @param {NativeCompactionBodyOptions} options
|
|
109
57
|
* @returns {NativeCompactionBody}
|
|
110
58
|
*/
|
|
111
|
-
export function buildNativeCompactionBody({ model, modelDescriptor, input,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
59
|
+
export function buildNativeCompactionBody({ model, modelDescriptor, input, tools, promptCacheKey, promptCacheRetention, cacheRetention, reasoningEffort, temperature, maxTokens, }) {
|
|
60
|
+
return buildCompactionResponsesBody({
|
|
61
|
+
model: modelDescriptor ?? model,
|
|
62
|
+
input,
|
|
63
|
+
tools,
|
|
64
|
+
promptCacheKey,
|
|
65
|
+
promptCacheRetention,
|
|
66
|
+
cacheRetention: cacheRetention ??
|
|
67
|
+
(promptCacheKey ? (promptCacheRetention ? "long" : "short") : "none"),
|
|
68
|
+
reasoningEffort,
|
|
69
|
+
temperature,
|
|
70
|
+
maxTokens,
|
|
71
|
+
});
|
|
124
72
|
}
|
|
125
|
-
|
|
126
73
|
/**
|
|
127
74
|
* Provider usage stays unknown until the object guard and numeric normalization.
|
|
128
75
|
* @param {unknown} raw
|
|
129
76
|
* @returns {CanonicalUsage | undefined}
|
|
130
77
|
*/
|
|
131
78
|
function usageFrom(raw) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
79
|
+
if (!isObject(raw))
|
|
80
|
+
return undefined;
|
|
81
|
+
const inputTotal = Number(raw.input_tokens ?? 0);
|
|
82
|
+
const output = Number(raw.output_tokens ?? 0);
|
|
83
|
+
const detailsValue = raw.input_tokens_details ?? raw.input_token_details ?? raw.prompt_tokens_details;
|
|
84
|
+
const details = isObject(detailsValue) ? detailsValue : {};
|
|
85
|
+
const cacheRead = Number(details.cached_tokens ?? 0);
|
|
86
|
+
const cacheWrite = Number(details.cache_write_tokens ?? 0);
|
|
87
|
+
const result = {
|
|
88
|
+
inputTokens: Math.max(0, Number.isFinite(inputTotal)
|
|
89
|
+
? inputTotal -
|
|
90
|
+
(Number.isFinite(cacheRead) ? cacheRead : 0) -
|
|
91
|
+
(Number.isFinite(cacheWrite) ? cacheWrite : 0)
|
|
92
|
+
: 0),
|
|
93
|
+
outputTokens: Number.isFinite(output) && output > 0 ? output : 0,
|
|
94
|
+
};
|
|
95
|
+
if (Number.isFinite(cacheRead) && cacheRead > 0)
|
|
96
|
+
result.cacheReadTokens = cacheRead;
|
|
97
|
+
if (Number.isFinite(cacheWrite) && cacheWrite > 0)
|
|
98
|
+
result.cacheWriteTokens = cacheWrite;
|
|
99
|
+
const outputDetails = isObject(raw.output_tokens_details)
|
|
100
|
+
? raw.output_tokens_details
|
|
101
|
+
: isObject(raw.output_token_details)
|
|
102
|
+
? raw.output_token_details
|
|
103
|
+
: {};
|
|
104
|
+
const reasoning = Number(outputDetails.reasoning_tokens ?? 0);
|
|
105
|
+
if (Number.isFinite(reasoning) && reasoning > 0)
|
|
106
|
+
result.reasoningTokens = reasoning;
|
|
107
|
+
return Object.values(result).some((v) => Number(v) > 0) ? result : undefined;
|
|
148
108
|
}
|
|
149
|
-
|
|
150
109
|
/**
|
|
151
110
|
* @param {unknown} output
|
|
152
111
|
* @returns {{ output: ValidatedOutputItem[], compaction: CompactionItem }}
|
|
153
112
|
*/
|
|
154
113
|
function validateOutput(output) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
114
|
+
if (!Array.isArray(output) || output.length === 0)
|
|
115
|
+
throw fail("native compaction output is empty");
|
|
116
|
+
const compactions = output.filter((item) => isObject(item) && item.type === "compaction");
|
|
117
|
+
if (compactions.length !== 1)
|
|
118
|
+
throw fail(`native compaction must return exactly one compaction item, got ${compactions.length}`);
|
|
119
|
+
const compact = compactions[0];
|
|
120
|
+
if (typeof compact.encrypted_content !== "string" ||
|
|
121
|
+
compact.encrypted_content.length === 0)
|
|
122
|
+
throw fail("native compaction item has no encrypted_content");
|
|
123
|
+
/** @type {Set<string>} */
|
|
124
|
+
const calls = new Set();
|
|
125
|
+
/** @type {Set<string>} */
|
|
126
|
+
const results = new Set();
|
|
127
|
+
for (const item of output) {
|
|
128
|
+
if (!isObject(item) || typeof item.type !== "string")
|
|
129
|
+
throw fail("native compaction output contains a malformed item");
|
|
130
|
+
if (item.type === "function_call") {
|
|
131
|
+
if (typeof item.call_id !== "string" ||
|
|
132
|
+
!item.call_id ||
|
|
133
|
+
calls.has(item.call_id))
|
|
134
|
+
throw fail("native compaction output contains an invalid function_call");
|
|
135
|
+
calls.add(item.call_id);
|
|
136
|
+
}
|
|
137
|
+
else if (item.type === "function_call_output") {
|
|
138
|
+
if (typeof item.call_id !== "string" ||
|
|
139
|
+
!item.call_id ||
|
|
140
|
+
results.has(item.call_id))
|
|
141
|
+
throw fail("native compaction output contains an invalid function_call_output");
|
|
142
|
+
results.add(item.call_id);
|
|
143
|
+
}
|
|
172
144
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
145
|
+
for (const id of calls)
|
|
146
|
+
if (!results.has(id))
|
|
147
|
+
throw fail(`native compaction output has orphan function_call ${id}`);
|
|
148
|
+
for (const id of results)
|
|
149
|
+
if (!calls.has(id))
|
|
150
|
+
throw fail(`native compaction output has orphan function_call_output ${id}`);
|
|
151
|
+
return {
|
|
152
|
+
output: structuredClone(output),
|
|
153
|
+
compaction: structuredClone(compact),
|
|
154
|
+
};
|
|
180
155
|
}
|
|
181
|
-
|
|
182
156
|
/**
|
|
183
157
|
* Provider SSE events enter as unknown; response.completed remains authoritative.
|
|
184
158
|
* @param {Response} response
|
|
@@ -186,70 +160,115 @@ function validateOutput(output) {
|
|
|
186
160
|
* @returns {Promise<NativeCompactionResult>}
|
|
187
161
|
*/
|
|
188
162
|
export async function parseNativeCompactionSse(response, options = {}) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
163
|
+
const byIndex = new Map();
|
|
164
|
+
const byId = new Map();
|
|
165
|
+
let terminal;
|
|
166
|
+
const mergeItem = (event) => {
|
|
167
|
+
if (!isObject(event.item))
|
|
168
|
+
return;
|
|
169
|
+
const index = Number.isInteger(event.output_index)
|
|
170
|
+
? Number(event.output_index)
|
|
171
|
+
: undefined;
|
|
172
|
+
const id = typeof event.item.id === "string"
|
|
173
|
+
? event.item.id
|
|
174
|
+
: typeof event.item_id === "string"
|
|
175
|
+
? event.item_id
|
|
176
|
+
: undefined;
|
|
177
|
+
let record = (index !== undefined ? byIndex.get(index) : undefined) ??
|
|
178
|
+
(id ? byId.get(id) : undefined);
|
|
179
|
+
if (!record)
|
|
180
|
+
record = {};
|
|
181
|
+
const encrypted = record.encrypted_content;
|
|
182
|
+
Object.assign(record, structuredClone(event.item));
|
|
183
|
+
if (typeof record.encrypted_content !== "string" &&
|
|
184
|
+
typeof encrypted === "string")
|
|
185
|
+
record.encrypted_content = encrypted;
|
|
186
|
+
if (index !== undefined)
|
|
187
|
+
byIndex.set(index, record);
|
|
188
|
+
if (id)
|
|
189
|
+
byId.set(id, record);
|
|
190
|
+
};
|
|
191
|
+
await consumeSse(response, (event) => {
|
|
192
|
+
if (!isObject(event))
|
|
193
|
+
return;
|
|
194
|
+
if (event.type === "error" ||
|
|
195
|
+
event.type === "response.failed" ||
|
|
196
|
+
event.type === "response.incomplete") {
|
|
197
|
+
const upstreamValue = event.type === "response.failed"
|
|
198
|
+
? isObject(event.response)
|
|
199
|
+
? event.response.error
|
|
200
|
+
: undefined
|
|
201
|
+
: event.error;
|
|
202
|
+
const upstream = isObject(upstreamValue) ? upstreamValue : {};
|
|
203
|
+
const providerCode = safeMachineField(upstream.code);
|
|
204
|
+
const providerType = safeMachineField(upstream.type);
|
|
205
|
+
const providerParam = safeMachineField(upstream.param);
|
|
206
|
+
const diagnostics = [
|
|
207
|
+
providerCode ? `providerCode=${providerCode}` : "",
|
|
208
|
+
providerType ? `providerType=${providerType}` : "",
|
|
209
|
+
providerParam ? `providerParam=${providerParam}` : "",
|
|
210
|
+
]
|
|
211
|
+
.filter(Boolean)
|
|
212
|
+
.join(" ");
|
|
213
|
+
const e = fail(`native compaction ended with ${event.type}${diagnostics ? ` ${diagnostics}` : ""}`, "LCX_COMPACT_UPSTREAM_ERROR");
|
|
214
|
+
if (Number.isInteger(upstream.status ?? (isObject(event.error) ? event.error.status : undefined)))
|
|
215
|
+
e.status = Number(upstream.status ?? (isObject(event.error) ? event.error.status : undefined));
|
|
216
|
+
if (providerCode)
|
|
217
|
+
e.providerCode = providerCode;
|
|
218
|
+
if (providerType)
|
|
219
|
+
e.providerType = providerType;
|
|
220
|
+
if (providerParam)
|
|
221
|
+
e.providerParam = providerParam;
|
|
222
|
+
throw e;
|
|
223
|
+
}
|
|
224
|
+
if (event.type === "response.output_item.added" ||
|
|
225
|
+
event.type === "response.output_item.done")
|
|
226
|
+
mergeItem(event);
|
|
227
|
+
if (event.type === "response.completed")
|
|
228
|
+
terminal = isObject(event.response) ? event.response : undefined;
|
|
229
|
+
}, options);
|
|
230
|
+
if (!isObject(terminal))
|
|
231
|
+
throw fail("native compaction stream ended without response.completed", "LCX_COMPACT_INCOMPLETE_SSE");
|
|
232
|
+
if (terminal.status !== "completed")
|
|
233
|
+
throw fail("native compaction response.completed did not carry completed status", "LCX_COMPACT_INCOMPLETE_SSE");
|
|
234
|
+
const eventItems = [...new Set([...byIndex.values(), ...byId.values()])];
|
|
235
|
+
const output = Array.isArray(terminal.output) && terminal.output.length > 0
|
|
236
|
+
? terminal.output
|
|
237
|
+
: eventItems;
|
|
238
|
+
const normalized = validateOutput(output);
|
|
239
|
+
return {
|
|
240
|
+
object: terminal.object ?? "response.compaction",
|
|
241
|
+
...(typeof terminal.id === "string" ? { id: terminal.id } : {}),
|
|
242
|
+
...normalized,
|
|
243
|
+
usage: usageFrom(terminal.usage),
|
|
244
|
+
};
|
|
242
245
|
}
|
|
243
|
-
|
|
244
246
|
/**
|
|
245
247
|
* @param {NativeCompactionRequestOptions} options
|
|
246
248
|
*/
|
|
247
|
-
export async function requestNativeCompaction({ baseURL, model, modelDescriptor, input,
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
249
|
+
export async function requestNativeCompaction({ baseURL, model, modelDescriptor, input, tools, promptCacheKey, promptCacheRetention, cacheRetention, reasoningEffort, temperature, maxTokens, idempotencyKey, headers, signal, timeoutMs, maxAttempts, maxResponseBytes, }) {
|
|
250
|
+
const body = buildNativeCompactionBody({
|
|
251
|
+
model,
|
|
252
|
+
modelDescriptor,
|
|
253
|
+
input,
|
|
254
|
+
tools,
|
|
255
|
+
promptCacheKey,
|
|
256
|
+
promptCacheRetention,
|
|
257
|
+
cacheRetention,
|
|
258
|
+
reasoningEffort,
|
|
259
|
+
temperature,
|
|
260
|
+
maxTokens,
|
|
261
|
+
});
|
|
262
|
+
const requestHeaders = mergeFeatureHeader({
|
|
263
|
+
...headers,
|
|
264
|
+
...(idempotencyKey ? { "idempotency-key": String(idempotencyKey) } : {}),
|
|
265
|
+
});
|
|
266
|
+
return fetchSseWithRetry(`${String(baseURL).replace(/\/+$/u, "")}/responses`, body, requestHeaders, signal, timeoutMs, {
|
|
267
|
+
maxAttempts,
|
|
268
|
+
maxResponseBytes,
|
|
269
|
+
consume: (response, consumeOptions) => parseNativeCompactionSse(response, {
|
|
270
|
+
signal: consumeOptions.requestSignal ?? signal,
|
|
271
|
+
maxResponseBytes,
|
|
272
|
+
}),
|
|
273
|
+
});
|
|
255
274
|
}
|