@opengeni/runtime 0.11.0 → 0.13.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/{chunk-YUAFQEFY.js → chunk-65UDUFUO.js} +729 -118
- package/dist/chunk-65UDUFUO.js.map +1 -0
- package/dist/chunk-HAN5D27J.js +292 -0
- package/dist/chunk-HAN5D27J.js.map +1 -0
- package/dist/{index-D6yi-JcU.d.ts → index-DGUrY_yR.d.ts} +37 -7
- package/dist/index.d.ts +81 -10
- package/dist/index.js +696 -93
- package/dist/index.js.map +1 -1
- package/dist/mcp-network.d.ts +78 -0
- package/dist/mcp-network.js +62 -0
- package/dist/mcp-network.js.map +1 -0
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.js +1 -1
- package/package.json +9 -4
- package/src/codex-tool-search.ts +20 -1
- package/src/index.ts +487 -83
- package/src/mcp-network.ts +330 -0
- package/src/sandbox/channel-a.ts +3 -28
- package/src/sandbox/display-stack.ts +860 -23
- package/src/sandbox/exec-banner.ts +67 -0
- package/src/sandbox/index.ts +7 -0
- package/src/sandbox/providers/modal.ts +29 -2
- package/src/sandbox-computer.ts +3 -1
- package/src/usage-telemetry.ts +495 -51
- package/dist/chunk-YUAFQEFY.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -153,13 +153,28 @@ import {
|
|
|
153
153
|
withToolspaceTokenClient,
|
|
154
154
|
withToolspaceTokenEnvironment,
|
|
155
155
|
withToolspaceTokenSession
|
|
156
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-65UDUFUO.js";
|
|
157
157
|
import {
|
|
158
158
|
getSkillLibraryEntry,
|
|
159
159
|
isSkillLibraryEntryId,
|
|
160
160
|
listSkillLibraryEntries,
|
|
161
161
|
loadSkillLibrarySkill
|
|
162
162
|
} from "./chunk-DPULLAJG.js";
|
|
163
|
+
import {
|
|
164
|
+
MCP_MAX_CONCURRENT_SERVER_OPERATIONS,
|
|
165
|
+
MCP_MAX_TOOL_DEFINITION_BYTES,
|
|
166
|
+
MCP_MAX_TOOL_RESULT_BYTES,
|
|
167
|
+
MCP_MAX_TOOL_SEARCH_DISCLOSURE_BYTES,
|
|
168
|
+
McpAggregateToolListBudget,
|
|
169
|
+
assertMcpPayloadWithinBytes,
|
|
170
|
+
assertMcpServerSelectionWithinBounds,
|
|
171
|
+
assertMcpToolListWithinBounds,
|
|
172
|
+
boundedParallelMap,
|
|
173
|
+
cancelMcpResponseBody,
|
|
174
|
+
guardedMcpFetch,
|
|
175
|
+
mcpSerializedSizeBytes,
|
|
176
|
+
undiciFetch
|
|
177
|
+
} from "./chunk-HAN5D27J.js";
|
|
163
178
|
import {
|
|
164
179
|
MemorySession,
|
|
165
180
|
connectMcpServers
|
|
@@ -225,6 +240,7 @@ import {
|
|
|
225
240
|
import {
|
|
226
241
|
approvalIdentifier,
|
|
227
242
|
CAPABILITY_DESCRIPTORS as CAPABILITY_DESCRIPTORS2,
|
|
243
|
+
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
|
|
228
244
|
assertUniqueResourceMountPaths,
|
|
229
245
|
gitCredentialBindingIdForRepository,
|
|
230
246
|
gitCredentialProviderForRepository,
|
|
@@ -6372,6 +6388,7 @@ import {
|
|
|
6372
6388
|
CODEX_APPS_MCP_SERVER_ID,
|
|
6373
6389
|
CODEX_MODEL_ID_PREFIX,
|
|
6374
6390
|
CODEX_ORIGINATOR,
|
|
6391
|
+
CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS,
|
|
6375
6392
|
boundModelToolOutputItems as boundModelToolOutputItems2,
|
|
6376
6393
|
codexAppsSanitizingFetch,
|
|
6377
6394
|
codexRequestStorage,
|
|
@@ -6972,7 +6989,21 @@ function codexToolSearchExecutor(args) {
|
|
|
6972
6989
|
const deferred = (args.availableTools ?? []).filter(isCodexAppsFunctionTool);
|
|
6973
6990
|
if (deferred.length === 0) return [];
|
|
6974
6991
|
const { query, limit } = parseSearchArgs(args.toolCall?.arguments);
|
|
6975
|
-
|
|
6992
|
+
const ranked = bm25RankTools(deferred, query, limit);
|
|
6993
|
+
const bounded = [];
|
|
6994
|
+
let disclosedBytes = 0;
|
|
6995
|
+
for (const tool2 of ranked) {
|
|
6996
|
+
const toolBytes = mcpSerializedSizeBytes(tool2);
|
|
6997
|
+
if (toolBytes > MCP_MAX_TOOL_DEFINITION_BYTES) {
|
|
6998
|
+
continue;
|
|
6999
|
+
}
|
|
7000
|
+
if (disclosedBytes + toolBytes > MCP_MAX_TOOL_SEARCH_DISCLOSURE_BYTES) {
|
|
7001
|
+
break;
|
|
7002
|
+
}
|
|
7003
|
+
disclosedBytes += toolBytes;
|
|
7004
|
+
bounded.push(tool2);
|
|
7005
|
+
}
|
|
7006
|
+
return bounded;
|
|
6976
7007
|
}
|
|
6977
7008
|
var NO_NAMESPACES = /* @__PURE__ */ new Set();
|
|
6978
7009
|
function hasConnectorSources(connectorNamespaces) {
|
|
@@ -8963,7 +8994,9 @@ var ComputerUseCapability = class extends Capability {
|
|
|
8963
8994
|
// any computer-use-only recording. One SandboxComputer instance caches
|
|
8964
8995
|
// this for the rest of the turn.
|
|
8965
8996
|
prepare: async (preparedSession) => {
|
|
8966
|
-
await ensureDisplayStack(preparedSession
|
|
8997
|
+
await ensureDisplayStack(preparedSession, {
|
|
8998
|
+
telemetryContext: { callerKind: "computer" }
|
|
8999
|
+
});
|
|
8967
9000
|
await this.args.onReady?.(preparedSession);
|
|
8968
9001
|
}
|
|
8969
9002
|
});
|
|
@@ -9008,43 +9041,351 @@ var ComputerUseCapability = class extends Capability {
|
|
|
9008
9041
|
};
|
|
9009
9042
|
|
|
9010
9043
|
// src/usage-telemetry.ts
|
|
9011
|
-
|
|
9044
|
+
var MAX_MODEL_USAGE_TOKEN_COUNT = 1e9;
|
|
9045
|
+
function modelUsageTokenCountOrNull(value) {
|
|
9046
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= MAX_MODEL_USAGE_TOKEN_COUNT ? value : null;
|
|
9047
|
+
}
|
|
9048
|
+
function normalizeModelCallUsage(usage) {
|
|
9049
|
+
const rejectedFields = /* @__PURE__ */ new Set();
|
|
9050
|
+
if (!usage) {
|
|
9051
|
+
return {
|
|
9052
|
+
telemetry: {
|
|
9053
|
+
inputTokens: null,
|
|
9054
|
+
outputTokens: null,
|
|
9055
|
+
cachedTokens: null,
|
|
9056
|
+
cacheWriteTokens: null,
|
|
9057
|
+
reasoningTokens: null
|
|
9058
|
+
},
|
|
9059
|
+
totalTokens: null,
|
|
9060
|
+
rejectedFields: []
|
|
9061
|
+
};
|
|
9062
|
+
}
|
|
9063
|
+
const requestEntries = requestUsageEntries(usage.requestUsageEntries, rejectedFields);
|
|
9064
|
+
const topLevelInputTokens = reportedTokenCount(usage.inputTokens, "inputTokens", rejectedFields);
|
|
9065
|
+
const topLevelOutputTokens = reportedTokenCount(
|
|
9066
|
+
usage.outputTokens,
|
|
9067
|
+
"outputTokens",
|
|
9068
|
+
rejectedFields
|
|
9069
|
+
);
|
|
9070
|
+
const topLevelTotalTokens = reportedTokenCount(usage.totalTokens, "totalTokens", rejectedFields);
|
|
9071
|
+
const requestInputTokens = completeRequestTokenAggregate(
|
|
9072
|
+
requestEntries,
|
|
9073
|
+
["inputTokens", "input_tokens"],
|
|
9074
|
+
"inputTokens.requestUsageEntries",
|
|
9075
|
+
rejectedFields
|
|
9076
|
+
);
|
|
9077
|
+
const requestOutputTokens = completeRequestTokenAggregate(
|
|
9078
|
+
requestEntries,
|
|
9079
|
+
["outputTokens", "output_tokens"],
|
|
9080
|
+
"outputTokens.requestUsageEntries",
|
|
9081
|
+
rejectedFields
|
|
9082
|
+
);
|
|
9083
|
+
let requestTotalTokens = completeRequestTokenAggregate(
|
|
9084
|
+
requestEntries,
|
|
9085
|
+
["totalTokens", "total_tokens"],
|
|
9086
|
+
"totalTokens.requestUsageEntries",
|
|
9087
|
+
rejectedFields
|
|
9088
|
+
);
|
|
9089
|
+
if (rejectInconsistentRequestTotals(requestEntries, rejectedFields)) {
|
|
9090
|
+
requestTotalTokens = { ...requestTotalTokens, status: "invalid", value: null };
|
|
9091
|
+
}
|
|
9092
|
+
const inputTokens = canonicalTokenDimension({
|
|
9093
|
+
topLevel: topLevelInputTokens,
|
|
9094
|
+
topLevelReported: isReported(usage.inputTokens),
|
|
9095
|
+
topLevelPath: "inputTokens",
|
|
9096
|
+
requestAggregate: requestInputTokens,
|
|
9097
|
+
rejectedFields
|
|
9098
|
+
});
|
|
9099
|
+
const outputTokens = canonicalTokenDimension({
|
|
9100
|
+
topLevel: topLevelOutputTokens,
|
|
9101
|
+
topLevelReported: isReported(usage.outputTokens),
|
|
9102
|
+
topLevelPath: "outputTokens",
|
|
9103
|
+
requestAggregate: requestOutputTokens,
|
|
9104
|
+
rejectedFields
|
|
9105
|
+
});
|
|
9106
|
+
const totalTokens = canonicalTotalTokens({
|
|
9107
|
+
inputTokens,
|
|
9108
|
+
outputTokens,
|
|
9109
|
+
topLevel: topLevelTotalTokens,
|
|
9110
|
+
topLevelReported: isReported(usage.totalTokens),
|
|
9111
|
+
requestAggregate: requestTotalTokens,
|
|
9112
|
+
rejectedFields
|
|
9113
|
+
});
|
|
9114
|
+
const inputDetailSource = preferredDetailSource(
|
|
9115
|
+
usage.inputTokensDetails,
|
|
9116
|
+
"inputTokensDetails",
|
|
9117
|
+
requestEntries,
|
|
9118
|
+
["inputTokensDetails", "input_tokens_details"]
|
|
9119
|
+
);
|
|
9120
|
+
const outputDetailSource = preferredDetailSource(
|
|
9121
|
+
usage.outputTokensDetails,
|
|
9122
|
+
"outputTokensDetails",
|
|
9123
|
+
requestEntries,
|
|
9124
|
+
["outputTokensDetails", "output_tokens_details"]
|
|
9125
|
+
);
|
|
9012
9126
|
return {
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9127
|
+
telemetry: {
|
|
9128
|
+
inputTokens,
|
|
9129
|
+
outputTokens,
|
|
9130
|
+
cachedTokens: aggregateDetailTokenCount(
|
|
9131
|
+
inputDetailSource,
|
|
9132
|
+
["cached_tokens", "cachedInputTokens", "cached_input_tokens"],
|
|
9133
|
+
"cachedTokens",
|
|
9134
|
+
rejectedFields
|
|
9135
|
+
),
|
|
9136
|
+
cacheWriteTokens: aggregateDetailTokenCount(
|
|
9137
|
+
inputDetailSource,
|
|
9138
|
+
["cache_write_tokens", "cacheWriteTokens"],
|
|
9139
|
+
"cacheWriteTokens",
|
|
9140
|
+
rejectedFields
|
|
9141
|
+
),
|
|
9142
|
+
reasoningTokens: aggregateDetailTokenCount(
|
|
9143
|
+
outputDetailSource,
|
|
9144
|
+
["reasoning_tokens", "reasoningTokens", "reasoning_output_tokens"],
|
|
9145
|
+
"reasoningTokens",
|
|
9146
|
+
rejectedFields
|
|
9147
|
+
)
|
|
9148
|
+
},
|
|
9149
|
+
totalTokens,
|
|
9150
|
+
rejectedFields: [...rejectedFields].slice(0, 32)
|
|
9025
9151
|
};
|
|
9026
9152
|
}
|
|
9027
|
-
function
|
|
9028
|
-
|
|
9153
|
+
function modelCallUsageTelemetry(usage) {
|
|
9154
|
+
return normalizeModelCallUsage(usage).telemetry;
|
|
9155
|
+
}
|
|
9156
|
+
function requestUsageEntries(value, rejectedFields) {
|
|
9157
|
+
if (value === void 0) {
|
|
9158
|
+
return [];
|
|
9159
|
+
}
|
|
9160
|
+
if (!Array.isArray(value)) {
|
|
9161
|
+
rejectField(rejectedFields, "requestUsageEntries");
|
|
9162
|
+
return [];
|
|
9163
|
+
}
|
|
9164
|
+
const entries = [];
|
|
9165
|
+
for (const [index, entry] of value.entries()) {
|
|
9166
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
9167
|
+
rejectField(rejectedFields, `requestUsageEntries[${index}]`);
|
|
9168
|
+
entries.push({});
|
|
9169
|
+
continue;
|
|
9170
|
+
}
|
|
9171
|
+
entries.push(entry);
|
|
9172
|
+
}
|
|
9173
|
+
return entries;
|
|
9174
|
+
}
|
|
9175
|
+
function completeRequestTokenAggregate(requestEntries, requestKeys, aggregatePath, rejectedFields) {
|
|
9176
|
+
if (requestEntries.length === 0) {
|
|
9177
|
+
return { status: "absent", value: null };
|
|
9178
|
+
}
|
|
9179
|
+
const values = [];
|
|
9180
|
+
let incomplete = false;
|
|
9181
|
+
let invalid = false;
|
|
9182
|
+
for (const [index, entry] of requestEntries.entries()) {
|
|
9183
|
+
const selected = firstPresentEntry(entry, requestKeys);
|
|
9184
|
+
if (!selected || selected.value === null) {
|
|
9185
|
+
incomplete = true;
|
|
9186
|
+
continue;
|
|
9187
|
+
}
|
|
9188
|
+
const parsed = reportedTokenCount(
|
|
9189
|
+
selected.value,
|
|
9190
|
+
`requestUsageEntries[${index}].${selected.key}`,
|
|
9191
|
+
rejectedFields
|
|
9192
|
+
);
|
|
9193
|
+
if (parsed === null) invalid = true;
|
|
9194
|
+
values.push(parsed);
|
|
9195
|
+
}
|
|
9196
|
+
if (invalid) {
|
|
9197
|
+
return { status: "invalid", value: null };
|
|
9198
|
+
}
|
|
9199
|
+
if (incomplete) {
|
|
9200
|
+
return { status: "incomplete", value: null };
|
|
9201
|
+
}
|
|
9202
|
+
const value = boundedTokenSum(values, aggregatePath, rejectedFields);
|
|
9203
|
+
return value === null ? { status: "invalid", value: null } : { status: "complete", value };
|
|
9204
|
+
}
|
|
9205
|
+
function canonicalTokenDimension(input) {
|
|
9206
|
+
if (input.requestAggregate.status === "complete") {
|
|
9207
|
+
if (input.topLevelReported && input.topLevel !== null && input.topLevel !== input.requestAggregate.value) {
|
|
9208
|
+
rejectField(input.rejectedFields, input.topLevelPath);
|
|
9209
|
+
}
|
|
9210
|
+
return input.requestAggregate.value;
|
|
9211
|
+
}
|
|
9212
|
+
if (input.requestAggregate.status === "invalid") {
|
|
9213
|
+
if (input.topLevelReported) {
|
|
9214
|
+
rejectField(input.rejectedFields, input.topLevelPath);
|
|
9215
|
+
}
|
|
9029
9216
|
return null;
|
|
9030
9217
|
}
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9218
|
+
return input.topLevel;
|
|
9219
|
+
}
|
|
9220
|
+
function canonicalTotalTokens(input) {
|
|
9221
|
+
if (input.inputTokens !== null && input.outputTokens !== null) {
|
|
9222
|
+
const derived = boundedTokenSum(
|
|
9223
|
+
[input.inputTokens, input.outputTokens],
|
|
9224
|
+
"totalTokens.aggregate",
|
|
9225
|
+
input.rejectedFields
|
|
9226
|
+
);
|
|
9227
|
+
if (derived === null) {
|
|
9228
|
+
if (input.topLevelReported) rejectField(input.rejectedFields, "totalTokens");
|
|
9229
|
+
if (input.requestAggregate.status === "complete") {
|
|
9230
|
+
rejectField(input.rejectedFields, "totalTokens.requestUsageEntries");
|
|
9038
9231
|
}
|
|
9039
|
-
|
|
9040
|
-
|
|
9232
|
+
return null;
|
|
9233
|
+
}
|
|
9234
|
+
if (input.topLevelReported && input.topLevel !== null && input.topLevel !== derived) {
|
|
9235
|
+
rejectField(input.rejectedFields, "totalTokens");
|
|
9236
|
+
}
|
|
9237
|
+
if (input.requestAggregate.status === "complete" && input.requestAggregate.value !== derived) {
|
|
9238
|
+
rejectField(input.rejectedFields, "totalTokens.requestUsageEntries");
|
|
9239
|
+
}
|
|
9240
|
+
return derived;
|
|
9241
|
+
}
|
|
9242
|
+
if (input.requestAggregate.status === "complete") {
|
|
9243
|
+
const requestTotal = input.requestAggregate.value;
|
|
9244
|
+
if (requestTotal === null || !totalCoversKnownComponents(requestTotal, input.inputTokens, input.outputTokens)) {
|
|
9245
|
+
rejectField(input.rejectedFields, "totalTokens.requestUsageEntries");
|
|
9246
|
+
if (input.topLevelReported) rejectField(input.rejectedFields, "totalTokens");
|
|
9247
|
+
return null;
|
|
9248
|
+
}
|
|
9249
|
+
if (input.topLevelReported && input.topLevel !== null && input.topLevel !== requestTotal) {
|
|
9250
|
+
rejectField(input.rejectedFields, "totalTokens");
|
|
9251
|
+
}
|
|
9252
|
+
return requestTotal;
|
|
9253
|
+
}
|
|
9254
|
+
if (input.requestAggregate.status === "invalid") {
|
|
9255
|
+
if (input.topLevelReported) rejectField(input.rejectedFields, "totalTokens");
|
|
9256
|
+
return null;
|
|
9257
|
+
}
|
|
9258
|
+
if (input.topLevel !== null && !totalCoversKnownComponents(input.topLevel, input.inputTokens, input.outputTokens)) {
|
|
9259
|
+
rejectField(input.rejectedFields, "totalTokens");
|
|
9260
|
+
return null;
|
|
9261
|
+
}
|
|
9262
|
+
return input.topLevel;
|
|
9263
|
+
}
|
|
9264
|
+
function totalCoversKnownComponents(total, inputTokens, outputTokens) {
|
|
9265
|
+
return (inputTokens === null || total >= inputTokens) && (outputTokens === null || total >= outputTokens);
|
|
9266
|
+
}
|
|
9267
|
+
function rejectInconsistentRequestTotals(requestEntries, rejectedFields) {
|
|
9268
|
+
let inconsistent = false;
|
|
9269
|
+
for (const [index, entry] of requestEntries.entries()) {
|
|
9270
|
+
const record = entry;
|
|
9271
|
+
const selectedInput = firstPresentEntry(record, ["inputTokens", "input_tokens"]);
|
|
9272
|
+
const selectedOutput = firstPresentEntry(record, ["outputTokens", "output_tokens"]);
|
|
9273
|
+
const selectedTotal = firstPresentEntry(record, ["totalTokens", "total_tokens"]);
|
|
9274
|
+
if (!selectedInput || !selectedOutput || !selectedTotal) continue;
|
|
9275
|
+
const inputTokens = modelUsageTokenCountOrNull(selectedInput.value);
|
|
9276
|
+
const outputTokens = modelUsageTokenCountOrNull(selectedOutput.value);
|
|
9277
|
+
const totalTokens = modelUsageTokenCountOrNull(selectedTotal.value);
|
|
9278
|
+
if (inputTokens === null || outputTokens === null || totalTokens === null) continue;
|
|
9279
|
+
const derived = inputTokens <= MAX_MODEL_USAGE_TOKEN_COUNT - outputTokens ? inputTokens + outputTokens : null;
|
|
9280
|
+
if (derived === null || totalTokens !== derived) {
|
|
9281
|
+
rejectField(rejectedFields, `requestUsageEntries[${index}].${selectedTotal.key}`);
|
|
9282
|
+
inconsistent = true;
|
|
9283
|
+
}
|
|
9284
|
+
}
|
|
9285
|
+
return inconsistent;
|
|
9286
|
+
}
|
|
9287
|
+
function isReported(value) {
|
|
9288
|
+
return value !== void 0 && value !== null;
|
|
9289
|
+
}
|
|
9290
|
+
function preferredDetailSource(aggregateDetails, aggregatePath, requestEntries, requestKeys) {
|
|
9291
|
+
const requestDetails = [];
|
|
9292
|
+
let sawRequestDetails = false;
|
|
9293
|
+
for (const [index, entry] of requestEntries.entries()) {
|
|
9294
|
+
const selected = firstPresentEntry(entry, requestKeys);
|
|
9295
|
+
if (!selected) {
|
|
9296
|
+
requestDetails.push({
|
|
9297
|
+
details: void 0,
|
|
9298
|
+
path: `requestUsageEntries[${index}].${requestKeys[0]}`,
|
|
9299
|
+
missing: true
|
|
9300
|
+
});
|
|
9301
|
+
continue;
|
|
9302
|
+
}
|
|
9303
|
+
sawRequestDetails = true;
|
|
9304
|
+
requestDetails.push({
|
|
9305
|
+
details: selected.value,
|
|
9306
|
+
path: `requestUsageEntries[${index}].${selected.key}`
|
|
9307
|
+
});
|
|
9308
|
+
}
|
|
9309
|
+
return sawRequestDetails ? requestDetails : aggregateDetails === void 0 ? [] : [{ details: aggregateDetails, path: aggregatePath }];
|
|
9310
|
+
}
|
|
9311
|
+
function aggregateDetailTokenCount(sources, keys, field, rejectedFields) {
|
|
9312
|
+
const values = [];
|
|
9313
|
+
let sawReportedValue = false;
|
|
9314
|
+
let sawMissingValue = false;
|
|
9315
|
+
for (const source of sources) {
|
|
9316
|
+
if (source.missing) {
|
|
9317
|
+
sawMissingValue = true;
|
|
9318
|
+
continue;
|
|
9319
|
+
}
|
|
9320
|
+
const details = detailRecords(source.details, source.path, rejectedFields);
|
|
9321
|
+
if (!details.complete) {
|
|
9322
|
+
sawMissingValue = true;
|
|
9323
|
+
}
|
|
9324
|
+
for (const detail of details.records) {
|
|
9325
|
+
const selected = firstPresentEntry(detail.record, keys);
|
|
9326
|
+
if (!selected) {
|
|
9327
|
+
sawMissingValue = true;
|
|
9328
|
+
continue;
|
|
9041
9329
|
}
|
|
9330
|
+
sawReportedValue = true;
|
|
9331
|
+
values.push(
|
|
9332
|
+
reportedTokenCount(selected.value, `${detail.path}.${selected.key}`, rejectedFields)
|
|
9333
|
+
);
|
|
9334
|
+
}
|
|
9335
|
+
}
|
|
9336
|
+
return sawReportedValue && !sawMissingValue ? boundedTokenSum(values, `${field}.aggregate`, rejectedFields) : null;
|
|
9337
|
+
}
|
|
9338
|
+
function detailRecords(details, path, rejectedFields) {
|
|
9339
|
+
const entries = Array.isArray(details) ? details : [details];
|
|
9340
|
+
const records = [];
|
|
9341
|
+
let complete = true;
|
|
9342
|
+
for (const [index, entry] of entries.entries()) {
|
|
9343
|
+
const entryPath = Array.isArray(details) ? `${path}[${index}]` : path;
|
|
9344
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
9345
|
+
rejectField(rejectedFields, entryPath);
|
|
9346
|
+
complete = false;
|
|
9347
|
+
continue;
|
|
9348
|
+
}
|
|
9349
|
+
records.push({ record: entry, path: entryPath });
|
|
9350
|
+
}
|
|
9351
|
+
return { records, complete };
|
|
9352
|
+
}
|
|
9353
|
+
function firstPresentEntry(record, keys) {
|
|
9354
|
+
for (const key of keys) {
|
|
9355
|
+
if (Object.prototype.hasOwnProperty.call(record, key) && record[key] !== void 0) {
|
|
9356
|
+
return { key, value: record[key] };
|
|
9357
|
+
}
|
|
9358
|
+
}
|
|
9359
|
+
return null;
|
|
9360
|
+
}
|
|
9361
|
+
function reportedTokenCount(value, field, rejectedFields) {
|
|
9362
|
+
if (value === void 0 || value === null) {
|
|
9363
|
+
return null;
|
|
9364
|
+
}
|
|
9365
|
+
const normalized = modelUsageTokenCountOrNull(value);
|
|
9366
|
+
if (normalized === null) {
|
|
9367
|
+
rejectField(rejectedFields, field);
|
|
9368
|
+
}
|
|
9369
|
+
return normalized;
|
|
9370
|
+
}
|
|
9371
|
+
function boundedTokenSum(values, field, rejectedFields) {
|
|
9372
|
+
if (values.length === 0 || values.some((value) => value === null)) {
|
|
9373
|
+
return null;
|
|
9374
|
+
}
|
|
9375
|
+
let total = 0;
|
|
9376
|
+
for (const value of values) {
|
|
9377
|
+
if (value > MAX_MODEL_USAGE_TOKEN_COUNT - total) {
|
|
9378
|
+
rejectField(rejectedFields, field);
|
|
9379
|
+
return null;
|
|
9042
9380
|
}
|
|
9381
|
+
total += value;
|
|
9043
9382
|
}
|
|
9044
|
-
return
|
|
9383
|
+
return total;
|
|
9045
9384
|
}
|
|
9046
|
-
function
|
|
9047
|
-
|
|
9385
|
+
function rejectField(rejectedFields, field) {
|
|
9386
|
+
if (rejectedFields.size < 32) {
|
|
9387
|
+
rejectedFields.add(field);
|
|
9388
|
+
}
|
|
9048
9389
|
}
|
|
9049
9390
|
|
|
9050
9391
|
// src/index.ts
|
|
@@ -9154,6 +9495,10 @@ function buildProviderClient(provider, settings) {
|
|
|
9154
9495
|
// SDK retries on network/5xx/partial streams can replay provider work
|
|
9155
9496
|
// or external tool side effects without a durable checkpoint.
|
|
9156
9497
|
maxRetries: 0,
|
|
9498
|
+
// The Codex transport owns finer headers/idle/whole deadlines and
|
|
9499
|
+
// emits typed durable evidence. Keep the SDK's opaque envelope beyond
|
|
9500
|
+
// that whole-response budget so `Request timed out.` cannot win first.
|
|
9501
|
+
timeout: CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS,
|
|
9157
9502
|
fetch: codexSubscriptionFetch(instrumentedModelFetch(provider.id, globalThis.fetch))
|
|
9158
9503
|
})
|
|
9159
9504
|
) : (
|
|
@@ -9184,7 +9529,7 @@ function resolveTurnModel(settings, modelId) {
|
|
|
9184
9529
|
return {
|
|
9185
9530
|
provider: resolved.provider,
|
|
9186
9531
|
client,
|
|
9187
|
-
model: buildModelInstance(resolved.provider, client, resolved.model.
|
|
9532
|
+
model: buildModelInstance(resolved.provider, client, resolved.model.upstreamModelId),
|
|
9188
9533
|
configured: resolved.model
|
|
9189
9534
|
};
|
|
9190
9535
|
}
|
|
@@ -9834,7 +10179,7 @@ function maybeInstallCodexToolSearch(agent, settings, options) {
|
|
|
9834
10179
|
}
|
|
9835
10180
|
}
|
|
9836
10181
|
function mcpToolRequiresApproval(policy, unprefixedName) {
|
|
9837
|
-
return policy === true ||
|
|
10182
|
+
return policy === true || policy !== false && policy.has(unprefixedName);
|
|
9838
10183
|
}
|
|
9839
10184
|
function installMcpApprovalPolicy(agent, policies) {
|
|
9840
10185
|
const listMcpTools = agent.getMcpTools.bind(agent);
|
|
@@ -9866,7 +10211,7 @@ function applyMcpApprovalPolicy(agent, settings) {
|
|
|
9866
10211
|
(server) => server.requireApproval === true || Array.isArray(server.requireApproval) && server.requireApproval.length > 0
|
|
9867
10212
|
).map((server) => ({
|
|
9868
10213
|
prefix: prefixedMcpToolName(server.id, ""),
|
|
9869
|
-
requireApproval: server.requireApproval
|
|
10214
|
+
requireApproval: server.requireApproval === true ? true : new Set(server.requireApproval)
|
|
9870
10215
|
})).sort((a, b) => b.prefix.length - a.prefix.length);
|
|
9871
10216
|
if (policies.length === 0) {
|
|
9872
10217
|
return;
|
|
@@ -9966,22 +10311,76 @@ function buildAgentCapabilities(settings, packSkills, options = {}) {
|
|
|
9966
10311
|
function sandboxRunAs(_settings) {
|
|
9967
10312
|
return void 0;
|
|
9968
10313
|
}
|
|
10314
|
+
async function connectMcpServersInBatches(servers, options) {
|
|
10315
|
+
assertMcpServerSelectionWithinBounds(servers);
|
|
10316
|
+
const batches = [];
|
|
10317
|
+
try {
|
|
10318
|
+
for (let offset = 0; offset < servers.length; offset += MCP_MAX_CONCURRENT_SERVER_OPERATIONS) {
|
|
10319
|
+
batches.push(
|
|
10320
|
+
await connectMcpServers(
|
|
10321
|
+
servers.slice(offset, offset + MCP_MAX_CONCURRENT_SERVER_OPERATIONS),
|
|
10322
|
+
{
|
|
10323
|
+
connectInParallel: true,
|
|
10324
|
+
strict: options.strict
|
|
10325
|
+
}
|
|
10326
|
+
)
|
|
10327
|
+
);
|
|
10328
|
+
}
|
|
10329
|
+
} catch (error) {
|
|
10330
|
+
await closeMcpServerBatches(batches).catch(() => void 0);
|
|
10331
|
+
throw error;
|
|
10332
|
+
}
|
|
10333
|
+
const errors = /* @__PURE__ */ new Map();
|
|
10334
|
+
for (const batch of batches) {
|
|
10335
|
+
for (const [server, error] of batch.errors) errors.set(server, error);
|
|
10336
|
+
}
|
|
10337
|
+
return {
|
|
10338
|
+
active: batches.flatMap((batch) => batch.active),
|
|
10339
|
+
failed: batches.flatMap((batch) => batch.failed),
|
|
10340
|
+
errors,
|
|
10341
|
+
close: async () => {
|
|
10342
|
+
await closeMcpServerBatches(batches);
|
|
10343
|
+
}
|
|
10344
|
+
};
|
|
10345
|
+
}
|
|
10346
|
+
async function closeMcpServerBatches(batches) {
|
|
10347
|
+
let firstError;
|
|
10348
|
+
for (const batch of [...batches].reverse()) {
|
|
10349
|
+
try {
|
|
10350
|
+
await batch.close();
|
|
10351
|
+
} catch (error) {
|
|
10352
|
+
firstError ??= error;
|
|
10353
|
+
}
|
|
10354
|
+
}
|
|
10355
|
+
if (firstError !== void 0) throw firstError;
|
|
10356
|
+
}
|
|
9969
10357
|
async function prepareAgentTools(settings, tools, options = {}) {
|
|
9970
10358
|
const codexConnectorNamespaces = /* @__PURE__ */ new Set();
|
|
10359
|
+
assertMcpServerSelectionWithinBounds(tools);
|
|
9971
10360
|
if (tools.length === 0) {
|
|
9972
10361
|
return { mcpServers: [], close: async () => {
|
|
9973
10362
|
}, codexConnectorNamespaces };
|
|
9974
10363
|
}
|
|
9975
10364
|
const registry = new Map(settings.mcpServers.map((server) => [server.id, server]));
|
|
9976
|
-
const
|
|
9977
|
-
|
|
10365
|
+
const aggregateToolBudget = new McpAggregateToolListBudget();
|
|
10366
|
+
const mcpFetchImpl = options.mcpFetchImpl ?? undiciFetch;
|
|
10367
|
+
const servers = await boundedParallelMap(
|
|
10368
|
+
tools,
|
|
10369
|
+
MCP_MAX_CONCURRENT_SERVER_OPERATIONS,
|
|
10370
|
+
async (tool2, index) => {
|
|
9978
10371
|
const config = registry.get(tool2.id);
|
|
9979
10372
|
if (!config) {
|
|
9980
10373
|
throw new Error(`Unknown MCP server id: ${tool2.id}`);
|
|
9981
10374
|
}
|
|
9982
10375
|
const url = firstPartyMcpServerUrlForRun(settings, config, options.workspaceId) ?? config.url;
|
|
9983
|
-
const
|
|
9984
|
-
const
|
|
10376
|
+
const firstParty = isFirstPartyMcpServer(settings, config);
|
|
10377
|
+
const baseFetch = isCodexAppsMcpServer(config) ? codexAppsSanitizingFetch(mcpFetchImpl, codexConnectorNamespaces) : mcpFetchImpl;
|
|
10378
|
+
const guardedFetch = guardedMcpFetch(
|
|
10379
|
+
firstParty ? { ...settings, integrationsAllowPrivateNetworkTargets: true } : settings,
|
|
10380
|
+
baseFetch,
|
|
10381
|
+
firstParty ? { requireHttpsOutsideLocalTest: false } : {}
|
|
10382
|
+
);
|
|
10383
|
+
const fetchImpl = config.connectionRef ? connectionBrokerFetch(guardedFetch, config, options) : firstParty ? firstPartyAuthFetch(guardedFetch, settings, options) : guardedFetch;
|
|
9985
10384
|
const optional = tool2.optional === true;
|
|
9986
10385
|
const bestEffort = isCodexAppsMcpServer(config) || optional || !!config.connectionRef;
|
|
9987
10386
|
const server = new PrefixedMcpServer(
|
|
@@ -9993,7 +10392,7 @@ async function prepareAgentTools(settings, tools, options = {}) {
|
|
|
9993
10392
|
// MCP SDK's strict Tool schema rejects (fails the turn during tools/list);
|
|
9994
10393
|
// sanitize the response on the wire before validation. The namespace Set
|
|
9995
10394
|
// also captures each tool's original connector namespace (P4 Part B.1).
|
|
9996
|
-
|
|
10395
|
+
fetch: fetchImpl,
|
|
9997
10396
|
...await mcpServerRequestInit(settings, config),
|
|
9998
10397
|
...config.timeoutMs ? {
|
|
9999
10398
|
timeout: config.timeoutMs,
|
|
@@ -10002,30 +10401,35 @@ async function prepareAgentTools(settings, tools, options = {}) {
|
|
|
10002
10401
|
}),
|
|
10003
10402
|
config.id,
|
|
10004
10403
|
config.allowedTools,
|
|
10005
|
-
bestEffort
|
|
10404
|
+
bestEffort,
|
|
10405
|
+
aggregateToolBudget,
|
|
10406
|
+
`${config.id}:${index}`
|
|
10006
10407
|
);
|
|
10007
10408
|
return {
|
|
10008
10409
|
server,
|
|
10009
10410
|
bestEffort,
|
|
10010
10411
|
optional
|
|
10011
10412
|
};
|
|
10012
|
-
}
|
|
10413
|
+
}
|
|
10013
10414
|
);
|
|
10014
10415
|
const requiredServers = servers.filter((entry) => !entry.bestEffort).map((entry) => entry.server);
|
|
10015
10416
|
const bestEffortServers = servers.filter((entry) => entry.bestEffort).map((entry) => entry.server);
|
|
10016
10417
|
const optionalServerNames = new Set(
|
|
10017
10418
|
servers.filter((entry) => entry.optional).map((entry) => entry.server.name)
|
|
10018
10419
|
);
|
|
10019
|
-
const connectedRequired = await
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
}
|
|
10420
|
+
const connectedRequired = await connectMcpServersInBatches(requiredServers, { strict: true });
|
|
10421
|
+
let connectedBestEffort = null;
|
|
10422
|
+
try {
|
|
10423
|
+
connectedBestEffort = bestEffortServers.length ? await connectMcpServersInBatches(bestEffortServers, { strict: false }) : null;
|
|
10424
|
+
} catch (error) {
|
|
10425
|
+
await connectedRequired.close().catch(() => void 0);
|
|
10426
|
+
throw error;
|
|
10427
|
+
}
|
|
10027
10428
|
if (connectedBestEffort) {
|
|
10028
10429
|
for (const failed of connectedBestEffort.failed) {
|
|
10430
|
+
if (failed instanceof PrefixedMcpServer) {
|
|
10431
|
+
failed.releaseAggregateBudget();
|
|
10432
|
+
}
|
|
10029
10433
|
if (!optionalServerNames.has(failed.name)) {
|
|
10030
10434
|
continue;
|
|
10031
10435
|
}
|
|
@@ -10039,10 +10443,20 @@ async function prepareAgentTools(settings, tools, options = {}) {
|
|
|
10039
10443
|
return {
|
|
10040
10444
|
mcpServers: [...connectedRequired.active, ...connectedBestEffort?.active ?? []],
|
|
10041
10445
|
close: async () => {
|
|
10042
|
-
|
|
10446
|
+
let firstError;
|
|
10043
10447
|
if (connectedBestEffort) {
|
|
10044
|
-
|
|
10448
|
+
try {
|
|
10449
|
+
await connectedBestEffort.close();
|
|
10450
|
+
} catch (error) {
|
|
10451
|
+
firstError ??= error;
|
|
10452
|
+
}
|
|
10045
10453
|
}
|
|
10454
|
+
try {
|
|
10455
|
+
await connectedRequired.close();
|
|
10456
|
+
} catch (error) {
|
|
10457
|
+
firstError ??= error;
|
|
10458
|
+
}
|
|
10459
|
+
if (firstError !== void 0) throw firstError;
|
|
10046
10460
|
},
|
|
10047
10461
|
codexConnectorNamespaces
|
|
10048
10462
|
};
|
|
@@ -10054,10 +10468,12 @@ function connectionBrokerFetch(baseFetch, config, options) {
|
|
|
10054
10468
|
}
|
|
10055
10469
|
return async (input, init) => {
|
|
10056
10470
|
const request = await mcpRequestInfo(input, init);
|
|
10471
|
+
const destinationUrl = mcpRequestDestinationUrl(input);
|
|
10057
10472
|
const first = await resolveConnectionForRequest(
|
|
10058
10473
|
options,
|
|
10059
10474
|
config.id,
|
|
10060
10475
|
connectionRef,
|
|
10476
|
+
destinationUrl,
|
|
10061
10477
|
request.toolName,
|
|
10062
10478
|
false
|
|
10063
10479
|
);
|
|
@@ -10069,10 +10485,12 @@ function connectionBrokerFetch(baseFetch, config, options) {
|
|
|
10069
10485
|
withConnectionHeaders(input, init, first.headers)
|
|
10070
10486
|
);
|
|
10071
10487
|
if (response.status === 401) {
|
|
10488
|
+
await cancelMcpResponseBody(response);
|
|
10072
10489
|
const refreshed = await resolveConnectionForRequest(
|
|
10073
10490
|
options,
|
|
10074
10491
|
config.id,
|
|
10075
10492
|
connectionRef,
|
|
10493
|
+
destinationUrl,
|
|
10076
10494
|
request.toolName,
|
|
10077
10495
|
true
|
|
10078
10496
|
);
|
|
@@ -10085,9 +10503,14 @@ function connectionBrokerFetch(baseFetch, config, options) {
|
|
|
10085
10503
|
);
|
|
10086
10504
|
if (retry.status === 403) {
|
|
10087
10505
|
const auth = insufficientScopeAuth(retry.headers, connectionRef, refreshed.connectionId);
|
|
10088
|
-
|
|
10506
|
+
if (auth) {
|
|
10507
|
+
await cancelMcpResponseBody(retry);
|
|
10508
|
+
return await authNeededFetchResponse(options, config.id, request, auth, connectionRef);
|
|
10509
|
+
}
|
|
10510
|
+
return retry;
|
|
10089
10511
|
}
|
|
10090
10512
|
if (retry.status === 401) {
|
|
10513
|
+
await cancelMcpResponseBody(retry);
|
|
10091
10514
|
return await authNeededFetchResponse(
|
|
10092
10515
|
options,
|
|
10093
10516
|
config.id,
|
|
@@ -10109,12 +10532,16 @@ function connectionBrokerFetch(baseFetch, config, options) {
|
|
|
10109
10532
|
}
|
|
10110
10533
|
if (response.status === 403) {
|
|
10111
10534
|
const auth = insufficientScopeAuth(response.headers, connectionRef, first.connectionId);
|
|
10112
|
-
|
|
10535
|
+
if (auth) {
|
|
10536
|
+
await cancelMcpResponseBody(response);
|
|
10537
|
+
return await authNeededFetchResponse(options, config.id, request, auth, connectionRef);
|
|
10538
|
+
}
|
|
10539
|
+
return response;
|
|
10113
10540
|
}
|
|
10114
10541
|
return response;
|
|
10115
10542
|
};
|
|
10116
10543
|
}
|
|
10117
|
-
async function resolveConnectionForRequest(options, serverId, connectionRef, toolName, forceRefresh) {
|
|
10544
|
+
async function resolveConnectionForRequest(options, serverId, connectionRef, destinationUrl, toolName, forceRefresh) {
|
|
10118
10545
|
if (!options.workspaceId || !options.resolveCredential) {
|
|
10119
10546
|
return {
|
|
10120
10547
|
status: "auth_needed",
|
|
@@ -10131,6 +10558,7 @@ async function resolveConnectionForRequest(options, serverId, connectionRef, too
|
|
|
10131
10558
|
workspaceId: options.workspaceId,
|
|
10132
10559
|
serverId,
|
|
10133
10560
|
connectionRef,
|
|
10561
|
+
destinationUrl,
|
|
10134
10562
|
forceRefresh,
|
|
10135
10563
|
...toolName ? { toolName } : {},
|
|
10136
10564
|
...options.subjectId ? { subjectId: options.subjectId } : {}
|
|
@@ -10194,6 +10622,9 @@ async function publishAuthNeeded(options, payload) {
|
|
|
10194
10622
|
} catch {
|
|
10195
10623
|
}
|
|
10196
10624
|
}
|
|
10625
|
+
function mcpRequestDestinationUrl(input) {
|
|
10626
|
+
return new URL(input instanceof Request ? input.url : input.toString()).toString();
|
|
10627
|
+
}
|
|
10197
10628
|
async function mcpRequestInfo(input, init) {
|
|
10198
10629
|
const body = typeof init?.body === "string" ? init.body : input instanceof Request && (init?.method ?? input.method).toUpperCase() === "POST" ? await input.clone().text().catch(() => "") : "";
|
|
10199
10630
|
if (!body) {
|
|
@@ -10326,7 +10757,7 @@ async function signFirstPartyDelegatedBearer(settings, options) {
|
|
|
10326
10757
|
workspaceId: options.workspaceId,
|
|
10327
10758
|
subjectId: options.subjectId ?? "worker:first-party-mcp",
|
|
10328
10759
|
...options.subjectLabel ? { subjectLabel: options.subjectLabel } : {},
|
|
10329
|
-
permissions: options.firstPartyPermissions ??
|
|
10760
|
+
permissions: options.firstPartyPermissions ?? [...DEFAULT_FIRST_PARTY_MCP_PERMISSIONS],
|
|
10330
10761
|
...options.sessionId ? { sessionId: options.sessionId } : {},
|
|
10331
10762
|
...options.turnId ? { turnId: options.turnId } : {},
|
|
10332
10763
|
...options.attemptId ? { attemptId: options.attemptId } : {},
|
|
@@ -10375,21 +10806,6 @@ async function codexAppsMcpRequestInit(settings) {
|
|
|
10375
10806
|
}
|
|
10376
10807
|
return { requestInit: { headers } };
|
|
10377
10808
|
}
|
|
10378
|
-
var firstPartyMcpPermissions = [
|
|
10379
|
-
"workspace:read",
|
|
10380
|
-
"files:read",
|
|
10381
|
-
"documents:search",
|
|
10382
|
-
"scheduled_tasks:manage",
|
|
10383
|
-
"scheduled_tasks:run",
|
|
10384
|
-
"goals:manage",
|
|
10385
|
-
"sessions:read",
|
|
10386
|
-
"sessions:create",
|
|
10387
|
-
"sessions:control",
|
|
10388
|
-
"variable-sets:use",
|
|
10389
|
-
"variable-sets:manage",
|
|
10390
|
-
"rigs:use",
|
|
10391
|
-
"github:use"
|
|
10392
|
-
];
|
|
10393
10809
|
function isCodexAppsMcpServer(config) {
|
|
10394
10810
|
return config.id === CODEX_APPS_MCP_SERVER_ID;
|
|
10395
10811
|
}
|
|
@@ -10457,8 +10873,10 @@ function prefixedMcpToolName(registryId, toolName) {
|
|
|
10457
10873
|
return sharedPrefixedMcpToolName(registryId, toolName);
|
|
10458
10874
|
}
|
|
10459
10875
|
var PrefixedMcpServer = class {
|
|
10460
|
-
constructor(inner, registryId, allowedTools, bestEffort = false) {
|
|
10876
|
+
constructor(inner, registryId, allowedTools, bestEffort = false, aggregateToolBudget, aggregateSourceId = registryId) {
|
|
10461
10877
|
this.inner = inner;
|
|
10878
|
+
this.aggregateToolBudget = aggregateToolBudget;
|
|
10879
|
+
this.aggregateSourceId = aggregateSourceId;
|
|
10462
10880
|
this.name = registryId;
|
|
10463
10881
|
this.prefix = prefixedMcpToolName(registryId, "");
|
|
10464
10882
|
this.cacheToolsList = inner.cacheToolsList;
|
|
@@ -10480,12 +10898,22 @@ var PrefixedMcpServer = class {
|
|
|
10480
10898
|
return this.inner.connect();
|
|
10481
10899
|
}
|
|
10482
10900
|
close() {
|
|
10901
|
+
this.releaseAggregateBudget();
|
|
10483
10902
|
return this.inner.close();
|
|
10484
10903
|
}
|
|
10904
|
+
releaseAggregateBudget() {
|
|
10905
|
+
this.aggregateToolBudget?.remove(this.aggregateSourceId);
|
|
10906
|
+
}
|
|
10485
10907
|
async listTools() {
|
|
10486
|
-
let tools;
|
|
10487
10908
|
try {
|
|
10488
|
-
tools = await this.inner.listTools();
|
|
10909
|
+
const tools = assertMcpToolListWithinBounds(await this.inner.listTools());
|
|
10910
|
+
const exposed = tools.filter((tool2) => this.isAllowed(tool2.name)).map((tool2) => ({
|
|
10911
|
+
...tool2,
|
|
10912
|
+
name: prefixedMcpToolName(this.name, tool2.name)
|
|
10913
|
+
}));
|
|
10914
|
+
const bounded = this.aggregateToolBudget?.replace(this.aggregateSourceId, exposed) ?? assertMcpToolListWithinBounds(exposed);
|
|
10915
|
+
this.listedToolSchemaTokens = estimateSerializedValueTokens(bounded);
|
|
10916
|
+
return bounded;
|
|
10489
10917
|
} catch (error) {
|
|
10490
10918
|
if (!this.bestEffort) {
|
|
10491
10919
|
throw error;
|
|
@@ -10499,14 +10927,9 @@ var PrefixedMcpServer = class {
|
|
|
10499
10927
|
{ serverId: this.name, ...safeMcpErrorFields(error) }
|
|
10500
10928
|
);
|
|
10501
10929
|
}
|
|
10930
|
+
this.releaseAggregateBudget();
|
|
10502
10931
|
return [];
|
|
10503
10932
|
}
|
|
10504
|
-
const exposed = tools.filter((tool2) => this.isAllowed(tool2.name)).map((tool2) => ({
|
|
10505
|
-
...tool2,
|
|
10506
|
-
name: prefixedMcpToolName(this.name, tool2.name)
|
|
10507
|
-
}));
|
|
10508
|
-
this.listedToolSchemaTokens = estimateSerializedValueTokens(exposed);
|
|
10509
|
-
return exposed;
|
|
10510
10933
|
}
|
|
10511
10934
|
/** Latest exact tools/list projection used to build the model request. */
|
|
10512
10935
|
modelToolSchemaTokens() {
|
|
@@ -10518,7 +10941,9 @@ var PrefixedMcpServer = class {
|
|
|
10518
10941
|
throw new Error(`MCP tool ${unprefixed} is not allowed for server ${this.name}`);
|
|
10519
10942
|
}
|
|
10520
10943
|
try {
|
|
10521
|
-
|
|
10944
|
+
const output = await this.inner.callTool(unprefixed, args, meta);
|
|
10945
|
+
assertMcpPayloadWithinBytes(output, MCP_MAX_TOOL_RESULT_BYTES, "MCP tool result");
|
|
10946
|
+
return output;
|
|
10522
10947
|
} catch (error) {
|
|
10523
10948
|
if (isAuthNeededMcpError(error)) {
|
|
10524
10949
|
return {
|
|
@@ -11590,17 +12015,18 @@ function usageFromResponse(response) {
|
|
|
11590
12015
|
),
|
|
11591
12016
|
...numberProp(record, "totalTokens", "totalTokens", "total_tokens"),
|
|
11592
12017
|
...inputTokenDetailsProp(record),
|
|
11593
|
-
...outputTokenDetailsProp(record)
|
|
12018
|
+
...outputTokenDetailsProp(record),
|
|
12019
|
+
...requestUsageEntriesProp(record)
|
|
11594
12020
|
};
|
|
11595
12021
|
return Object.keys(usage).length > 0 ? usage : null;
|
|
11596
12022
|
}
|
|
11597
12023
|
function numberProp(raw, outputKey, ...keys) {
|
|
11598
12024
|
const value = keys.map((key) => raw[key]).find((candidate) => candidate !== void 0);
|
|
11599
|
-
return typeof value === "number"
|
|
12025
|
+
return typeof value === "number" ? { [outputKey]: value } : {};
|
|
11600
12026
|
}
|
|
11601
12027
|
function inputTokenDetailsProp(raw) {
|
|
11602
12028
|
const details = raw.inputTokensDetails ?? raw.input_tokens_details ?? raw.promptTokensDetails ?? raw.prompt_tokens_details;
|
|
11603
|
-
if (
|
|
12029
|
+
if (details === void 0 || details === null) {
|
|
11604
12030
|
return {};
|
|
11605
12031
|
}
|
|
11606
12032
|
return {
|
|
@@ -11610,13 +12036,25 @@ function inputTokenDetailsProp(raw) {
|
|
|
11610
12036
|
function outputTokenDetailsProp(raw) {
|
|
11611
12037
|
const details = raw.outputTokensDetails ?? raw.output_tokens_details;
|
|
11612
12038
|
const normalized = details ?? raw.completionTokensDetails ?? raw.completion_tokens_details;
|
|
11613
|
-
if (
|
|
12039
|
+
if (normalized === void 0 || normalized === null) {
|
|
11614
12040
|
return {};
|
|
11615
12041
|
}
|
|
11616
12042
|
return {
|
|
11617
12043
|
outputTokensDetails: normalized
|
|
11618
12044
|
};
|
|
11619
12045
|
}
|
|
12046
|
+
function requestUsageEntriesProp(raw) {
|
|
12047
|
+
const entries = raw.requestUsageEntries ?? raw.request_usage_entries;
|
|
12048
|
+
if (entries === void 0 || entries === null) {
|
|
12049
|
+
return {};
|
|
12050
|
+
}
|
|
12051
|
+
return {
|
|
12052
|
+
// The normalizer validates every entry and all supported field aliases.
|
|
12053
|
+
// Preserve the SDK objects rather than rebuilding them and accidentally
|
|
12054
|
+
// dropping provider detail fields such as cache_write_tokens.
|
|
12055
|
+
requestUsageEntries: entries
|
|
12056
|
+
};
|
|
12057
|
+
}
|
|
11620
12058
|
function serializeApprovals(interruptions) {
|
|
11621
12059
|
return interruptions.filter((item) => interruptionToolName(item) !== HUMAN_INPUT_TOOL_NAME).map((item) => {
|
|
11622
12060
|
if (typeof item?.toJSON === "function") {
|
|
@@ -12085,13 +12523,95 @@ function runtimeGitBindingDescriptors(resources) {
|
|
|
12085
12523
|
};
|
|
12086
12524
|
});
|
|
12087
12525
|
}
|
|
12526
|
+
function gitCredentialBindingKey(provider, credentialBindingId) {
|
|
12527
|
+
return `${provider}\0${credentialBindingId}`;
|
|
12528
|
+
}
|
|
12529
|
+
function brokeredGitCredentialBindingKeys(bindings) {
|
|
12530
|
+
return new Set(
|
|
12531
|
+
bindings.filter((binding) => binding.transport?.kind === "http_broker").map((binding) => gitCredentialBindingKey(binding.provider, binding.credentialBindingId))
|
|
12532
|
+
);
|
|
12533
|
+
}
|
|
12534
|
+
function runtimeGitHttpBrokerRouteDescriptors(resources, bindings) {
|
|
12535
|
+
const resourceDescriptors = runtimeGitBindingDescriptors(resources);
|
|
12536
|
+
const byBindingAndUri = /* @__PURE__ */ new Map();
|
|
12537
|
+
for (const descriptor of resourceDescriptors) {
|
|
12538
|
+
byBindingAndUri.set(
|
|
12539
|
+
`${gitCredentialBindingKey(descriptor.provider, descriptor.credentialBindingId)}\0${descriptor.uri}`,
|
|
12540
|
+
descriptor
|
|
12541
|
+
);
|
|
12542
|
+
}
|
|
12543
|
+
const routes = [];
|
|
12544
|
+
const claimedRepositoryUris = /* @__PURE__ */ new Set();
|
|
12545
|
+
const claimedBrokerUris = /* @__PURE__ */ new Set();
|
|
12546
|
+
for (const binding of bindings) {
|
|
12547
|
+
if (!binding.transport) continue;
|
|
12548
|
+
if (typeof binding.transport !== "object" || binding.transport.kind !== "http_broker" || !Array.isArray(binding.transport.repositories)) {
|
|
12549
|
+
throw new Error(
|
|
12550
|
+
`Git credential binding ${binding.credentialBindingId} uses an unsupported transport`
|
|
12551
|
+
);
|
|
12552
|
+
}
|
|
12553
|
+
const bindingKey = gitCredentialBindingKey(binding.provider, binding.credentialBindingId);
|
|
12554
|
+
const expected = resourceDescriptors.filter(
|
|
12555
|
+
(descriptor) => gitCredentialBindingKey(descriptor.provider, descriptor.credentialBindingId) === bindingKey
|
|
12556
|
+
);
|
|
12557
|
+
if (expected.length === 0 || binding.transport.repositories.length !== expected.length) {
|
|
12558
|
+
throw new Error(
|
|
12559
|
+
`Git HTTP broker binding ${binding.credentialBindingId} does not cover its exact repository set`
|
|
12560
|
+
);
|
|
12561
|
+
}
|
|
12562
|
+
for (const route of binding.transport.repositories) {
|
|
12563
|
+
if (!route || typeof route !== "object" || typeof route.repositoryUri !== "string" || typeof route.brokerUri !== "string") {
|
|
12564
|
+
throw new Error(
|
|
12565
|
+
`Git HTTP broker binding ${binding.credentialBindingId} contains an invalid repository route`
|
|
12566
|
+
);
|
|
12567
|
+
}
|
|
12568
|
+
const descriptor = byBindingAndUri.get(`${bindingKey}\0${route.repositoryUri}`);
|
|
12569
|
+
if (!descriptor || claimedRepositoryUris.has(route.repositoryUri)) {
|
|
12570
|
+
throw new Error(
|
|
12571
|
+
`Git HTTP broker binding ${binding.credentialBindingId} contains an unexpected repository route`
|
|
12572
|
+
);
|
|
12573
|
+
}
|
|
12574
|
+
let brokerUrl;
|
|
12575
|
+
try {
|
|
12576
|
+
brokerUrl = new URL(route.brokerUri);
|
|
12577
|
+
} catch {
|
|
12578
|
+
throw new Error(
|
|
12579
|
+
`Git HTTP broker binding ${binding.credentialBindingId} contains an invalid broker URI`
|
|
12580
|
+
);
|
|
12581
|
+
}
|
|
12582
|
+
if (brokerUrl.protocol !== "https:" || brokerUrl.username || brokerUrl.password || brokerUrl.search || brokerUrl.hash || brokerUrl.href !== route.brokerUri || claimedBrokerUris.has(brokerUrl.href)) {
|
|
12583
|
+
throw new Error(
|
|
12584
|
+
`Git HTTP broker binding ${binding.credentialBindingId} contains an unsafe broker URI`
|
|
12585
|
+
);
|
|
12586
|
+
}
|
|
12587
|
+
claimedRepositoryUris.add(route.repositoryUri);
|
|
12588
|
+
claimedBrokerUris.add(brokerUrl.href);
|
|
12589
|
+
routes.push({
|
|
12590
|
+
provider: binding.provider,
|
|
12591
|
+
credentialBindingId: binding.credentialBindingId,
|
|
12592
|
+
bindingHash: gitCredentialBindingHash(binding.credentialBindingId),
|
|
12593
|
+
repositoryUri: route.repositoryUri,
|
|
12594
|
+
brokerUri: route.brokerUri,
|
|
12595
|
+
protocol: "https",
|
|
12596
|
+
host: brokerUrl.host.toLowerCase(),
|
|
12597
|
+
path: brokerUrl.pathname.replace(/^\/+|\/+$/g, "")
|
|
12598
|
+
});
|
|
12599
|
+
}
|
|
12600
|
+
}
|
|
12601
|
+
return routes;
|
|
12602
|
+
}
|
|
12088
12603
|
function gitUsernameForProvider(provider) {
|
|
12089
12604
|
if (provider === "github") return "x-access-token";
|
|
12090
12605
|
if (provider === "gitlab") return "oauth2";
|
|
12091
12606
|
return "opengeni";
|
|
12092
12607
|
}
|
|
12093
|
-
function gitCredentialHelperBindingCaseLines(resources) {
|
|
12094
|
-
|
|
12608
|
+
function gitCredentialHelperBindingCaseLines(resources, bindings) {
|
|
12609
|
+
const brokeredBindings = brokeredGitCredentialBindingKeys(bindings);
|
|
12610
|
+
return runtimeGitBindingDescriptors(resources).filter(
|
|
12611
|
+
(descriptor) => !brokeredBindings.has(
|
|
12612
|
+
gitCredentialBindingKey(descriptor.provider, descriptor.credentialBindingId)
|
|
12613
|
+
)
|
|
12614
|
+
).flatMap((descriptor) => {
|
|
12095
12615
|
const paths = /* @__PURE__ */ new Set([
|
|
12096
12616
|
descriptor.path,
|
|
12097
12617
|
descriptor.path.replace(/\.git$/, ""),
|
|
@@ -12102,7 +12622,19 @@ function gitCredentialHelperBindingCaseLines(resources) {
|
|
|
12102
12622
|
);
|
|
12103
12623
|
});
|
|
12104
12624
|
}
|
|
12105
|
-
function
|
|
12625
|
+
function gitCredentialHelperBrokerCaseLines(routes) {
|
|
12626
|
+
return routes.flatMap((route) => {
|
|
12627
|
+
const paths = /* @__PURE__ */ new Set([
|
|
12628
|
+
route.path,
|
|
12629
|
+
route.path.replace(/\.git$/, ""),
|
|
12630
|
+
`${route.path.replace(/\.git$/, "")}.git`
|
|
12631
|
+
]);
|
|
12632
|
+
return [...paths].map(
|
|
12633
|
+
(path) => ` ${shellQuote(`${route.protocol}|${route.host}|${path}`)}) username=opengeni; token_file="$credential_dir/${route.bindingHash}-token" ;;`
|
|
12634
|
+
);
|
|
12635
|
+
});
|
|
12636
|
+
}
|
|
12637
|
+
function gitAskpassHostProviderCaseLines(resources, brokerRoutes) {
|
|
12106
12638
|
const hosts = /* @__PURE__ */ new Map();
|
|
12107
12639
|
for (const descriptor of runtimeGitBindingDescriptors(resources)) {
|
|
12108
12640
|
const entry = hosts.get(descriptor.host) ?? {
|
|
@@ -12112,9 +12644,13 @@ function gitAskpassHostProviderCaseLines(resources) {
|
|
|
12112
12644
|
entry.bindings.add(`${descriptor.provider}\0${descriptor.credentialBindingId}`);
|
|
12113
12645
|
hosts.set(descriptor.host, entry);
|
|
12114
12646
|
}
|
|
12115
|
-
|
|
12116
|
-
|
|
12117
|
-
|
|
12647
|
+
const brokerHosts = [...new Set(brokerRoutes.map((route) => route.host))].sort((a, b) => a.localeCompare(b)).map((hostname) => ` ${shellQuote(hostname)}) printf '\\n'; return 0 ;;`);
|
|
12648
|
+
return [
|
|
12649
|
+
...brokerHosts,
|
|
12650
|
+
...[...hosts.entries()].filter(([, entry]) => entry.bindings.size === 1).sort(([a], [b]) => a.localeCompare(b)).map(
|
|
12651
|
+
([hostname, entry]) => ` ${shellQuote(hostname)}) printf '%s\\n' ${entry.provider}; return 0 ;;`
|
|
12652
|
+
)
|
|
12653
|
+
];
|
|
12118
12654
|
}
|
|
12119
12655
|
function gitCredentialTokenWriterCommandLines(bindings = []) {
|
|
12120
12656
|
const bindingWrites = bindings.flatMap((binding) => {
|
|
@@ -12123,7 +12659,7 @@ function gitCredentialTokenWriterCommandLines(bindings = []) {
|
|
|
12123
12659
|
const count = Math.max(1, binding.providerBindingCount ?? 1);
|
|
12124
12660
|
const provider = binding.provider;
|
|
12125
12661
|
const lines = [`write_git_binding_token ${shellQuote(hash)} "\${${seedEnv}:-}"`];
|
|
12126
|
-
if (count === 1) {
|
|
12662
|
+
if (count === 1 && binding.transport?.kind !== "http_broker") {
|
|
12127
12663
|
lines.push(`write_git_provider_token ${shellQuote(provider)} "\${${seedEnv}:-}"`);
|
|
12128
12664
|
} else {
|
|
12129
12665
|
lines.push(`remove_git_provider_token ${shellQuote(provider)}`);
|
|
@@ -12184,11 +12720,36 @@ function gitCredentialTokenWriterCommandLines(bindings = []) {
|
|
|
12184
12720
|
'umask "$seed_umask"'
|
|
12185
12721
|
];
|
|
12186
12722
|
}
|
|
12723
|
+
function gitHttpBrokerConfigCommandLines(routes) {
|
|
12724
|
+
return [
|
|
12725
|
+
'git_http_broker_config="${OPENGENI_GIT_CREDENTIALS_DIR:-$HOME/.opengeni/git-credentials}/http-broker.gitconfig"',
|
|
12726
|
+
'mkdir -p "$(dirname "$git_http_broker_config")"',
|
|
12727
|
+
'broker_umask="$(umask)"',
|
|
12728
|
+
"umask 077",
|
|
12729
|
+
': > "$git_http_broker_config.tmp.$$"',
|
|
12730
|
+
...routes.map(
|
|
12731
|
+
(route) => `git config --file "$git_http_broker_config.tmp.$$" --add ${shellQuote(`url.${route.brokerUri}.insteadOf`)} ${shellQuote(route.repositoryUri)}`
|
|
12732
|
+
),
|
|
12733
|
+
'mv -f "$git_http_broker_config.tmp.$$" "$git_http_broker_config"',
|
|
12734
|
+
'umask "$broker_umask"',
|
|
12735
|
+
'git config --global --unset-all include.path "$git_http_broker_config" >/dev/null 2>&1 || true',
|
|
12736
|
+
'git config --global --add include.path "$git_http_broker_config"'
|
|
12737
|
+
];
|
|
12738
|
+
}
|
|
12187
12739
|
function gitCredentialHelperCommandLines(resources = [], bindings = []) {
|
|
12188
|
-
const
|
|
12189
|
-
const
|
|
12740
|
+
const brokerRoutes = runtimeGitHttpBrokerRouteDescriptors(resources, bindings);
|
|
12741
|
+
const hostProviderCases = gitAskpassHostProviderCaseLines(resources, brokerRoutes);
|
|
12742
|
+
const bindingCases = [
|
|
12743
|
+
...gitCredentialHelperBindingCaseLines(resources, bindings),
|
|
12744
|
+
...gitCredentialHelperBrokerCaseLines(brokerRoutes)
|
|
12745
|
+
];
|
|
12190
12746
|
const descriptors = runtimeGitBindingDescriptors(resources);
|
|
12191
|
-
const
|
|
12747
|
+
const brokeredBindings = brokeredGitCredentialBindingKeys(bindings);
|
|
12748
|
+
const wrapperDescriptors = bindings.length > 0 ? descriptors.filter(
|
|
12749
|
+
(descriptor) => !brokeredBindings.has(
|
|
12750
|
+
gitCredentialBindingKey(descriptor.provider, descriptor.credentialBindingId)
|
|
12751
|
+
)
|
|
12752
|
+
) : [];
|
|
12192
12753
|
const bindingProviders = /* @__PURE__ */ new Map();
|
|
12193
12754
|
for (const descriptor of runtimeGitBindingDescriptors(resources)) {
|
|
12194
12755
|
const ids = bindingProviders.get(descriptor.provider) ?? /* @__PURE__ */ new Set();
|
|
@@ -12213,6 +12774,23 @@ function gitCredentialHelperCommandLines(resources = [], bindings = []) {
|
|
|
12213
12774
|
] : [];
|
|
12214
12775
|
});
|
|
12215
12776
|
const multiWrapperProviders = bindings.length > 0 ? [...bindingProviders.entries()].filter(([, ids]) => ids.size > 1).map(([provider]) => provider) : [];
|
|
12777
|
+
const brokeredOriginCases = brokerRoutes.flatMap((route) => {
|
|
12778
|
+
const base = route.repositoryUri.replace(/\.git$/, "");
|
|
12779
|
+
return [.../* @__PURE__ */ new Set([route.repositoryUri, base, `${base}.git`])].map(
|
|
12780
|
+
(uri) => ` ${shellQuote(`${route.provider}|${uri}`)}) return 0 ;;`
|
|
12781
|
+
);
|
|
12782
|
+
});
|
|
12783
|
+
const brokeredBindingHashCases = bindings.filter((binding) => binding.transport?.kind === "http_broker").map(
|
|
12784
|
+
(binding) => ` ${shellQuote(`${binding.provider}|${gitCredentialBindingHash(binding.credentialBindingId)}`)}) return 0 ;;`
|
|
12785
|
+
);
|
|
12786
|
+
const providerBindingKinds = /* @__PURE__ */ new Map();
|
|
12787
|
+
for (const binding of bindings) {
|
|
12788
|
+
const counts = providerBindingKinds.get(binding.provider) ?? { direct: 0, brokered: 0 };
|
|
12789
|
+
if (binding.transport?.kind === "http_broker") counts.brokered += 1;
|
|
12790
|
+
else counts.direct += 1;
|
|
12791
|
+
providerBindingKinds.set(binding.provider, counts);
|
|
12792
|
+
}
|
|
12793
|
+
const brokerOnlyProviders = [...providerBindingKinds.entries()].filter(([, counts]) => counts.brokered > 0 && counts.direct === 0).map(([provider]) => provider);
|
|
12216
12794
|
return [
|
|
12217
12795
|
...gitCredentialTokenWriterCommandLines(bindings),
|
|
12218
12796
|
// Provision git/provider-CLI helpers at SETUP (runtime) before any clone
|
|
@@ -12304,6 +12882,7 @@ function gitCredentialHelperCommandLines(resources = [], bindings = []) {
|
|
|
12304
12882
|
"git config --global --add credential.helper ''",
|
|
12305
12883
|
'git config --global --add credential.helper "$git_credential_helper"',
|
|
12306
12884
|
"git config --global credential.useHttpPath true",
|
|
12885
|
+
...gitHttpBrokerConfigCommandLines(brokerRoutes),
|
|
12307
12886
|
'wrapper_dir="${OPENGENI_GIT_CLI_WRAPPER_DIR:-$HOME/.opengeni/bin}"',
|
|
12308
12887
|
'mkdir -p "$wrapper_dir"',
|
|
12309
12888
|
"for opengeni_git_cli_tool in gh glab az; do",
|
|
@@ -12331,12 +12910,24 @@ function gitCredentialHelperCommandLines(resources = [], bindings = []) {
|
|
|
12331
12910
|
" *) return 1 ;;",
|
|
12332
12911
|
" esac",
|
|
12333
12912
|
"}",
|
|
12913
|
+
"binding_hash_is_brokered() {",
|
|
12914
|
+
' case "$provider|$1" in',
|
|
12915
|
+
...brokeredBindingHashCases,
|
|
12916
|
+
" *) return 1 ;;",
|
|
12917
|
+
" esac",
|
|
12918
|
+
"}",
|
|
12334
12919
|
"binding_hash_for_origin() {",
|
|
12335
12920
|
' case "$provider|$1" in',
|
|
12336
12921
|
...originWrapperHashes,
|
|
12337
12922
|
" *) return 1 ;;",
|
|
12338
12923
|
" esac",
|
|
12339
12924
|
"}",
|
|
12925
|
+
"origin_is_brokered() {",
|
|
12926
|
+
' case "$provider|$1" in',
|
|
12927
|
+
...brokeredOriginCases,
|
|
12928
|
+
" *) return 1 ;;",
|
|
12929
|
+
" esac",
|
|
12930
|
+
"}",
|
|
12340
12931
|
"sole_binding_hash() {",
|
|
12341
12932
|
' case "$provider" in',
|
|
12342
12933
|
...soleWrapperHashes,
|
|
@@ -12344,19 +12935,25 @@ function gitCredentialHelperCommandLines(resources = [], bindings = []) {
|
|
|
12344
12935
|
" esac",
|
|
12345
12936
|
"}",
|
|
12346
12937
|
`multi_binding_providers=${shellQuote(multiWrapperProviders.join(" "))}`,
|
|
12938
|
+
`broker_only_providers=${shellQuote(brokerOnlyProviders.join(" "))}`,
|
|
12347
12939
|
'if [ -n "$provider" ]; then',
|
|
12348
12940
|
" binding_hash=",
|
|
12349
12941
|
' if [ -n "${OPENGENI_GIT_BINDING:-}" ]; then',
|
|
12350
12942
|
' binding_hash="$(hash_binding_id "$OPENGENI_GIT_BINDING")"',
|
|
12943
|
+
` binding_hash_is_brokered "$binding_hash" && { printf '%s\\n' "$tool provider API authentication is host-brokered for OPENGENI_GIT_BINDING; use the configured provider MCP tools" >&2; exit 2; }`,
|
|
12351
12944
|
` binding_hash_allowed "$binding_hash" || { printf '%s\\n' "OPENGENI_GIT_BINDING does not select a $provider credential attached to this session" >&2; exit 2; }`,
|
|
12352
12945
|
" elif command -v git >/dev/null 2>&1; then",
|
|
12353
12946
|
' origin="$(git config --get remote.origin.url 2>/dev/null || true)"',
|
|
12947
|
+
` [ -z "$origin" ] || ! origin_is_brokered "$origin" || { printf '%s\\n' "$tool provider API authentication is host-brokered for this repository; use the configured provider MCP tools" >&2; exit 2; }`,
|
|
12354
12948
|
' [ -z "$origin" ] || binding_hash="$(binding_hash_for_origin "$origin" 2>/dev/null || true)"',
|
|
12355
12949
|
" fi",
|
|
12356
12950
|
' [ -n "$binding_hash" ] || binding_hash="$(sole_binding_hash 2>/dev/null || true)"',
|
|
12357
12951
|
' if [ -n "$binding_hash" ]; then',
|
|
12358
12952
|
' token_file="${OPENGENI_GIT_CREDENTIALS_DIR:-$HOME/.opengeni/git-credentials}/$binding_hash-token"',
|
|
12359
12953
|
" else",
|
|
12954
|
+
' case " $broker_only_providers " in',
|
|
12955
|
+
` *" $provider "*) printf '%s\\n' "$tool provider API authentication is host-brokered for this session; use the configured provider MCP tools" >&2; exit 2 ;;`,
|
|
12956
|
+
" esac",
|
|
12360
12957
|
' case " $multi_binding_providers " in',
|
|
12361
12958
|
` *" $provider "*) printf '%s\\n' "Unable to select one of multiple $provider credentials; run inside an attached repository or set OPENGENI_GIT_BINDING" >&2; exit 2 ;;`,
|
|
12362
12959
|
" esac",
|
|
@@ -13194,6 +13791,7 @@ export {
|
|
|
13194
13791
|
GENESIS_TITLE_DIRECTIVE,
|
|
13195
13792
|
HUMAN_INPUT_TOOL_NAME,
|
|
13196
13793
|
MAX_COMPACTION_THRESHOLD_RATIO,
|
|
13794
|
+
MAX_MODEL_USAGE_TOKEN_COUNT,
|
|
13197
13795
|
MIN_COMPACTION_THRESHOLD_RATIO,
|
|
13198
13796
|
MaxTurnsExceededError,
|
|
13199
13797
|
MockAgentResponder,
|
|
@@ -13247,6 +13845,7 @@ export {
|
|
|
13247
13845
|
TerminalServerError,
|
|
13248
13846
|
TerminalServerUnsupportedError,
|
|
13249
13847
|
ToolspaceTokenPathError,
|
|
13848
|
+
TurnSandboxCommandCancelledError,
|
|
13250
13849
|
USER_MESSAGE_TRUNCATION_MARKER,
|
|
13251
13850
|
WorkspaceModelPolicyBlockedError,
|
|
13252
13851
|
agentErrorToControlError,
|
|
@@ -13291,12 +13890,14 @@ export {
|
|
|
13291
13890
|
computerUse,
|
|
13292
13891
|
configureOpenAI,
|
|
13293
13892
|
configureRuntimeMetricsHooks,
|
|
13893
|
+
connectMcpServersInBatches,
|
|
13294
13894
|
contentTypeForCodec,
|
|
13295
13895
|
contextRobustnessFilterForSettings,
|
|
13296
13896
|
coreInstructions,
|
|
13297
13897
|
createProductionAgentRuntime,
|
|
13298
13898
|
createSandboxClient,
|
|
13299
13899
|
createSandboxClientForBackend,
|
|
13900
|
+
createTurnToolCancellationController,
|
|
13300
13901
|
decideCompaction,
|
|
13301
13902
|
decideSelfhostedRetry,
|
|
13302
13903
|
decodeModalSnapshotId,
|
|
@@ -13353,11 +13954,13 @@ export {
|
|
|
13353
13954
|
modelCallUsageTelemetry,
|
|
13354
13955
|
modelResponseUsageFromResponse,
|
|
13355
13956
|
modelResponseUsageFromSdkEvent,
|
|
13957
|
+
modelUsageTokenCountOrNull,
|
|
13356
13958
|
negotiateCapabilities,
|
|
13357
13959
|
negotiateSelfhostedCapabilities,
|
|
13358
13960
|
neutralizeToolSearchItemsInSerializedRunState,
|
|
13359
13961
|
nextDurableOpId,
|
|
13360
13962
|
normalizeComputerCallsFilter,
|
|
13963
|
+
normalizeModelCallUsage,
|
|
13361
13964
|
normalizeRunCredentialsResolution,
|
|
13362
13965
|
normalizeSdkEvent,
|
|
13363
13966
|
normalizeToolOutputForEvent,
|