@opengeni/runtime 2.5.2 → 2.5.3-canary.1
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/{agent-Q2VNH5FV.js → agent-RJQLKFIW.js} +2 -2
- package/dist/{chunk-LGLJ5PVD.js → chunk-46BFUGFL.js} +2622 -1368
- package/dist/chunk-46BFUGFL.js.map +1 -0
- package/dist/{chunk-CD22I76N.js → chunk-FHGLYLBL.js} +2 -2
- package/dist/{chunk-25B3EQRW.js → chunk-UNICCRW5.js} +4 -4
- package/dist/{chunk-GJC7H2FC.js → chunk-VUEWS4GI.js} +494 -95
- package/dist/chunk-VUEWS4GI.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +22 -4
- package/dist/{localSources-Z5IJIIRV.js → localSources-PVFCAPN2.js} +3 -3
- package/dist/mcp-operation-dispatch.d.ts +45 -0
- package/dist/mcp-operation-observation.d.ts +137 -0
- package/dist/operational-instructions.d.ts +1 -1
- package/dist/sandbox/archive-spool.d.ts +14 -0
- package/dist/sandbox/host-archive-spool.d.ts +19 -0
- package/dist/sandbox/index.d.ts +5 -1
- package/dist/sandbox/index.js +7 -3
- package/dist/sandbox/routing/backend-resolver.d.ts +1 -0
- package/dist/sandbox/selfhosted/file-transfer.d.ts +20 -0
- package/dist/sandbox/selfhosted/session.d.ts +7 -0
- package/dist/sandbox/workspace-archive.d.ts +7 -0
- package/dist/workspace-skills.d.ts +4 -0
- package/dist/workspace-tool-gateway.js +4 -4
- package/package.json +11 -11
- package/src/bundled_default_skills/document-parsing/SKILL.md +36 -0
- package/src/bundled_site_skills/opengeni-sites/SKILL.md +1 -1
- package/src/index.ts +231 -45
- package/src/lazy-tool-transport.ts +2 -0
- package/src/mcp-operation-dispatch.ts +144 -0
- package/src/mcp-operation-observation.ts +148 -0
- package/src/operational-instructions.ts +1 -1
- package/src/runtime-skills.ts +7 -2
- package/src/sandbox/archive-spool.ts +16 -0
- package/src/sandbox/host-archive-spool.ts +1040 -0
- package/src/sandbox/index.ts +292 -203
- package/src/sandbox/routing/backend-resolver.ts +2 -0
- package/src/sandbox/selfhosted/control-rpc.ts +22 -0
- package/src/sandbox/selfhosted/fault-rendering.ts +9 -0
- package/src/sandbox/selfhosted/file-transfer.ts +160 -0
- package/src/sandbox/selfhosted/op-testing.ts +3 -0
- package/src/sandbox/selfhosted/session.ts +194 -5
- package/src/sandbox/workspace-archive.ts +54 -1
- package/src/workspace-skills.ts +171 -31
- package/dist/chunk-GJC7H2FC.js.map +0 -1
- package/dist/chunk-LGLJ5PVD.js.map +0 -1
- /package/dist/{agent-Q2VNH5FV.js.map → agent-RJQLKFIW.js.map} +0 -0
- /package/dist/{chunk-CD22I76N.js.map → chunk-FHGLYLBL.js.map} +0 -0
- /package/dist/{chunk-25B3EQRW.js.map → chunk-UNICCRW5.js.map} +0 -0
- /package/dist/{localSources-Z5IJIIRV.js.map → localSources-PVFCAPN2.js.map} +0 -0
|
@@ -23,14 +23,17 @@ import {
|
|
|
23
23
|
withRunCredentialsClient,
|
|
24
24
|
withRunCredentialsSession,
|
|
25
25
|
wrapCapabilityToolsForTurnCancellation
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-46BFUGFL.js";
|
|
27
27
|
import {
|
|
28
28
|
MemorySession,
|
|
29
29
|
connectMcpServers
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-FHGLYLBL.js";
|
|
31
31
|
import {
|
|
32
32
|
SKILL_MAX_FILES,
|
|
33
|
+
SKILL_READ_MAX_OUTPUT_BYTES,
|
|
34
|
+
SKILL_READ_MAX_PATHS,
|
|
33
35
|
SkillFileError,
|
|
36
|
+
assertSkillRelativePath,
|
|
34
37
|
buildPortableSkillArtifact,
|
|
35
38
|
listSkillPaths,
|
|
36
39
|
readSkillFiles,
|
|
@@ -108,7 +111,7 @@ import {
|
|
|
108
111
|
tool,
|
|
109
112
|
withGenerationSpan,
|
|
110
113
|
withResponseSpan
|
|
111
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-UNICCRW5.js";
|
|
112
115
|
|
|
113
116
|
// src/command-read-refresh.ts
|
|
114
117
|
async function executeCommandReadWithRefresh(input) {
|
|
@@ -203,6 +206,168 @@ function commandSnapshot(result) {
|
|
|
203
206
|
}
|
|
204
207
|
}
|
|
205
208
|
|
|
209
|
+
// src/mcp-operation-dispatch.ts
|
|
210
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
211
|
+
var dispatchContext = new AsyncLocalStorage();
|
|
212
|
+
function hasActiveRecoverableMcpOperation() {
|
|
213
|
+
return dispatchContext.getStore() !== void 0;
|
|
214
|
+
}
|
|
215
|
+
var McpOperationOutcomeUnknownError = class extends Error {
|
|
216
|
+
constructor(operationId, cause) {
|
|
217
|
+
super(
|
|
218
|
+
`MCP operation ${operationId} has an unknown outcome. Read the existing operation result; do not repeat the mutation.`,
|
|
219
|
+
{ cause }
|
|
220
|
+
);
|
|
221
|
+
this.operationId = operationId;
|
|
222
|
+
this.name = "McpOperationOutcomeUnknownError";
|
|
223
|
+
}
|
|
224
|
+
code = "mcp_operation_outcome_unknown";
|
|
225
|
+
};
|
|
226
|
+
async function runRecoverableMcpOperation(operation, persistence, execute) {
|
|
227
|
+
const context = {
|
|
228
|
+
operation: { ...operation },
|
|
229
|
+
persistence,
|
|
230
|
+
captureStarted: false,
|
|
231
|
+
captured: false,
|
|
232
|
+
closed: false
|
|
233
|
+
};
|
|
234
|
+
return await dispatchContext.run(context, async () => {
|
|
235
|
+
let result;
|
|
236
|
+
try {
|
|
237
|
+
try {
|
|
238
|
+
result = await execute();
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (!context.captured) throw error;
|
|
241
|
+
try {
|
|
242
|
+
await persistence.settleOriginal({
|
|
243
|
+
operationId: operation.operationId,
|
|
244
|
+
outcome: "outcome_unknown"
|
|
245
|
+
});
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
throw new McpOperationOutcomeUnknownError(operation.operationId, error);
|
|
249
|
+
}
|
|
250
|
+
if (!context.captured) {
|
|
251
|
+
throw new Error("Recoverable MCP execution did not cross its durable capture boundary");
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
await persistence.settleOriginal({
|
|
255
|
+
operationId: operation.operationId,
|
|
256
|
+
outcome: "completed",
|
|
257
|
+
result
|
|
258
|
+
});
|
|
259
|
+
} catch (error) {
|
|
260
|
+
throw new McpOperationOutcomeUnknownError(operation.operationId, error);
|
|
261
|
+
}
|
|
262
|
+
return result;
|
|
263
|
+
} finally {
|
|
264
|
+
context.closed = true;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
async function captureMcpOperationDispatch(input) {
|
|
269
|
+
const context = dispatchContext.getStore();
|
|
270
|
+
if (!context) return;
|
|
271
|
+
const operation = context.operation;
|
|
272
|
+
if (input.operationId !== operation.operationId || input.serverId !== operation.serverId || input.toolName !== operation.originalTool || input.destinationDigest !== operation.destinationDigest || !/^[a-f0-9]{64}$/u.test(input.authorityDigest))
|
|
273
|
+
throw new Error("Recoverable MCP dispatch identity does not match its trusted binding");
|
|
274
|
+
if (context.closed || context.captureStarted) {
|
|
275
|
+
throw new Error("MCP operation dispatch is already claimed or closed");
|
|
276
|
+
}
|
|
277
|
+
context.captureStarted = true;
|
|
278
|
+
const result = await context.persistence.capture({
|
|
279
|
+
...operation,
|
|
280
|
+
authorityDigest: input.authorityDigest
|
|
281
|
+
});
|
|
282
|
+
if (result !== "created")
|
|
283
|
+
throw new Error("MCP operation was already dispatched; read its existing result");
|
|
284
|
+
if (context.closed) throw new Error("MCP operation dispatch closed during capture");
|
|
285
|
+
context.captured = true;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// src/mcp-operation-observation.ts
|
|
289
|
+
import { AttemptToolResult } from "@opengeni/contracts";
|
|
290
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
291
|
+
var observationAuthority = new AsyncLocalStorage2();
|
|
292
|
+
async function runMcpOperationObservationWithAuthority(binding, execute) {
|
|
293
|
+
const scope = { binding: { ...binding }, closed: false };
|
|
294
|
+
return await observationAuthority.run(scope, async () => {
|
|
295
|
+
try {
|
|
296
|
+
return await execute();
|
|
297
|
+
} finally {
|
|
298
|
+
scope.closed = true;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
function assertMcpOperationObservationAuthority(actual) {
|
|
303
|
+
const scope = observationAuthority.getStore();
|
|
304
|
+
if (!scope) return;
|
|
305
|
+
const expected = scope.binding;
|
|
306
|
+
if (scope.closed || actual.serverId !== expected.serverId || actual.toolName !== expected.observerTool || actual.destinationDigest !== expected.destinationDigest || actual.authorityDigest !== expected.authorityDigest) {
|
|
307
|
+
throw new Error("MCP operation observation authority changed before provider use");
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
var fingerprint = external_exports.object({
|
|
311
|
+
version: external_exports.literal(1),
|
|
312
|
+
algorithm: external_exports.literal("sha256"),
|
|
313
|
+
value: external_exports.string().regex(/^[a-f0-9]{64}$/u)
|
|
314
|
+
}).strict();
|
|
315
|
+
var identity = {
|
|
316
|
+
version: external_exports.literal(1),
|
|
317
|
+
operationRef: external_exports.string().uuid(),
|
|
318
|
+
fingerprint
|
|
319
|
+
};
|
|
320
|
+
var receiptSchema = external_exports.discriminatedUnion("status", [
|
|
321
|
+
external_exports.object({ ...identity, status: external_exports.literal("unknown") }).strict(),
|
|
322
|
+
external_exports.object({
|
|
323
|
+
...identity,
|
|
324
|
+
status: external_exports.literal("pending"),
|
|
325
|
+
evidenceRevision: external_exports.string().min(1)
|
|
326
|
+
}).strict(),
|
|
327
|
+
external_exports.object({
|
|
328
|
+
...identity,
|
|
329
|
+
status: external_exports.literal("completed"),
|
|
330
|
+
receiptRevision: external_exports.string().min(1).refine((value) => Buffer.byteLength(value, "utf8") <= 1024, {
|
|
331
|
+
message: "MCP receipt revision must fit the ledger's 1024-byte identity field"
|
|
332
|
+
}),
|
|
333
|
+
result: AttemptToolResult
|
|
334
|
+
}).strict(),
|
|
335
|
+
external_exports.object({ ...identity, status: external_exports.literal("conflict") }).strict()
|
|
336
|
+
]);
|
|
337
|
+
var bindingSchema = external_exports.object({
|
|
338
|
+
operationId: external_exports.string().uuid(),
|
|
339
|
+
serverId: external_exports.string().min(1),
|
|
340
|
+
originalTool: external_exports.string().min(1),
|
|
341
|
+
observerTool: external_exports.string().min(1),
|
|
342
|
+
argumentDigest: fingerprint.shape.value
|
|
343
|
+
}).strict().refine((value) => value.originalTool !== value.observerTool, {
|
|
344
|
+
message: "The observer must not be the original mutation tool"
|
|
345
|
+
});
|
|
346
|
+
async function observeMcpOperation(input) {
|
|
347
|
+
const binding = bindingSchema.parse(input.binding);
|
|
348
|
+
if (!await input.authorize("before_request")) {
|
|
349
|
+
throw new Error("MCP operation observation is not authorized");
|
|
350
|
+
}
|
|
351
|
+
const response = await input.callObserver(binding.observerTool, {
|
|
352
|
+
version: 1,
|
|
353
|
+
operationRef: binding.operationId,
|
|
354
|
+
originalTool: binding.originalTool,
|
|
355
|
+
fingerprint: { version: 1, algorithm: "sha256", value: binding.argumentDigest }
|
|
356
|
+
});
|
|
357
|
+
if (!await input.authorize("before_delivery")) {
|
|
358
|
+
throw new Error("MCP operation observation is not authorized for delivery");
|
|
359
|
+
}
|
|
360
|
+
const envelope = AttemptToolResult.parse(response);
|
|
361
|
+
if (envelope.isError) {
|
|
362
|
+
throw new Error("MCP operation observer returned an error, not a receipt");
|
|
363
|
+
}
|
|
364
|
+
const receipt = receiptSchema.parse(envelope.structuredContent);
|
|
365
|
+
if (receipt.operationRef !== binding.operationId || receipt.fingerprint.value !== binding.argumentDigest) {
|
|
366
|
+
throw new Error("MCP operation observation receipt identity does not match");
|
|
367
|
+
}
|
|
368
|
+
return receipt;
|
|
369
|
+
}
|
|
370
|
+
|
|
206
371
|
// src/skill-catalog.ts
|
|
207
372
|
var SKILL_CATALOG_MAX_BYTES = 32 * 1024;
|
|
208
373
|
var SKILL_CATALOG_MAX_ENTRIES = 128;
|
|
@@ -259,6 +424,7 @@ import {
|
|
|
259
424
|
AGENT_INSTRUCTIONS_CORE_PLACEHOLDER,
|
|
260
425
|
collectSandboxEnvironment,
|
|
261
426
|
configuredProviders as configuredProviders2,
|
|
427
|
+
McpOperationRecoverySchema,
|
|
262
428
|
firstPartyMcpInternalBaseUrl,
|
|
263
429
|
firstPartyMcpInternalWorkspaceUrl as firstPartyMcpInternalWorkspaceUrl2,
|
|
264
430
|
resolveFirstPartyDelegationSecret as resolveFirstPartyDelegationSecret2,
|
|
@@ -299,7 +465,7 @@ import {
|
|
|
299
465
|
GenerateVideoToolInput,
|
|
300
466
|
GetVideoGenerationCapabilitiesToolInput,
|
|
301
467
|
RequestHumanInputToolInput as RequestHumanInputToolInput2,
|
|
302
|
-
AttemptToolResult as
|
|
468
|
+
AttemptToolResult as AttemptToolResult3
|
|
303
469
|
} from "@opengeni/contracts";
|
|
304
470
|
import { renderSessionGoalContext as renderSessionGoalContext2 } from "@opengeni/contracts";
|
|
305
471
|
|
|
@@ -2842,13 +3008,13 @@ function convertToOutputItem(items) {
|
|
|
2842
3008
|
};
|
|
2843
3009
|
return output;
|
|
2844
3010
|
} else if (item.type === "program") {
|
|
2845
|
-
const { id, call_id, code, fingerprint, type: _type, ...providerData } = item;
|
|
3011
|
+
const { id, call_id, code, fingerprint: fingerprint2, type: _type, ...providerData } = item;
|
|
2846
3012
|
const output = {
|
|
2847
3013
|
type: "program",
|
|
2848
3014
|
id,
|
|
2849
3015
|
callId: call_id,
|
|
2850
3016
|
code,
|
|
2851
|
-
fingerprint,
|
|
3017
|
+
fingerprint: fingerprint2,
|
|
2852
3018
|
providerData
|
|
2853
3019
|
};
|
|
2854
3020
|
return output;
|
|
@@ -3763,14 +3929,14 @@ var OpenAIResponsesWSModel = class extends OpenAIResponsesModel {
|
|
|
3763
3929
|
return baseURL.toString();
|
|
3764
3930
|
}
|
|
3765
3931
|
async #ensureWebSocketConnection(wsURL, headers, signal, requestTimeoutDeadline) {
|
|
3766
|
-
const
|
|
3767
|
-
if (this.#wsConnection && this.#wsConnectionIdentity && this.#wsConnectionIdentity ===
|
|
3932
|
+
const identity2 = this.#getConnectionIdentity(wsURL, headers);
|
|
3933
|
+
if (this.#wsConnection && this.#wsConnectionIdentity && this.#wsConnectionIdentity === identity2 && this.#wsConnection.isReusable()) {
|
|
3768
3934
|
return { connection: this.#wsConnection, reused: true };
|
|
3769
3935
|
}
|
|
3770
3936
|
await this.#dropWebSocketConnection();
|
|
3771
3937
|
const connectTimeout = this.#resolveWebSocketRequestTimeout(requestTimeoutDeadline, (configuredTimeoutMs) => `Responses websocket connection timed out before opening after ${configuredTimeoutMs}ms.`);
|
|
3772
3938
|
this.#wsConnection = await ResponsesWebSocketConnection.connect(wsURL, headers, signal, connectTimeout.timeoutMs, connectTimeout.errorMessage, this.#websocketOptions);
|
|
3773
|
-
this.#wsConnectionIdentity =
|
|
3939
|
+
this.#wsConnectionIdentity = identity2;
|
|
3774
3940
|
return { connection: this.#wsConnection, reused: false };
|
|
3775
3941
|
}
|
|
3776
3942
|
async #reconnectWebSocketConnection(wsURL, headers, signal, requestTimeoutDeadline) {
|
|
@@ -7022,8 +7188,8 @@ function searchToolPool(availableTools, rawArguments) {
|
|
|
7022
7188
|
}
|
|
7023
7189
|
|
|
7024
7190
|
// src/model-request-capture.ts
|
|
7025
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
7026
|
-
var modelRequestCapture = new
|
|
7191
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
|
|
7192
|
+
var modelRequestCapture = new AsyncLocalStorage3();
|
|
7027
7193
|
var captureIndices = /* @__PURE__ */ new WeakMap();
|
|
7028
7194
|
function nextModelContextCaptureIndex(agent) {
|
|
7029
7195
|
const index = (captureIndices.get(agent) ?? 0) + 1;
|
|
@@ -7160,6 +7326,8 @@ var ALWAYS_VISIBLE_BASE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
7160
7326
|
"apply_patch",
|
|
7161
7327
|
// The server-backed reader needs neither sandbox setup nor tool search.
|
|
7162
7328
|
"skill_read",
|
|
7329
|
+
// Repository descriptors route to the live sandbox reader.
|
|
7330
|
+
"repository_skill_read",
|
|
7163
7331
|
"request_human_input",
|
|
7164
7332
|
"list_models"
|
|
7165
7333
|
]);
|
|
@@ -7787,7 +7955,7 @@ var LazyToolModelProvider = class {
|
|
|
7787
7955
|
|
|
7788
7956
|
// src/mcp-result-custom-data.ts
|
|
7789
7957
|
import {
|
|
7790
|
-
AttemptToolResult
|
|
7958
|
+
AttemptToolResult as AttemptToolResult2
|
|
7791
7959
|
} from "@opengeni/contracts";
|
|
7792
7960
|
import { randomUUID } from "crypto";
|
|
7793
7961
|
var OPENGENI_MCP_RESULT_CUSTOM_DATA_KEY = "__opengeniMcpResultV1";
|
|
@@ -7858,7 +8026,7 @@ function normalizeSdkToolOutputCustomData(value) {
|
|
|
7858
8026
|
return JSON.parse(JSON.stringify(value));
|
|
7859
8027
|
}
|
|
7860
8028
|
function normalizeMcpResult(value) {
|
|
7861
|
-
return normalizeProtocolJsonValue(
|
|
8029
|
+
return normalizeProtocolJsonValue(AttemptToolResult2.parse(value), "$.mcpResult");
|
|
7862
8030
|
}
|
|
7863
8031
|
var McpResultCustomDataBridge = class {
|
|
7864
8032
|
constructor(input) {
|
|
@@ -8048,7 +8216,7 @@ function compactMcpResultCustomDataRunState(serialized) {
|
|
|
8048
8216
|
function mcpResultFromCustomData(customData) {
|
|
8049
8217
|
if (!customData || typeof customData !== "object" || Array.isArray(customData)) return null;
|
|
8050
8218
|
const marker = customData[OPENGENI_MCP_RESULT_CUSTOM_DATA_KEY];
|
|
8051
|
-
const parsed =
|
|
8219
|
+
const parsed = AttemptToolResult2.safeParse(marker);
|
|
8052
8220
|
return parsed.success ? parsed.data : null;
|
|
8053
8221
|
}
|
|
8054
8222
|
|
|
@@ -8263,7 +8431,7 @@ import {
|
|
|
8263
8431
|
CODEX_ORIGINATOR,
|
|
8264
8432
|
codexAppsSanitizingFetch
|
|
8265
8433
|
} from "@opengeni/codex";
|
|
8266
|
-
import { AsyncLocalStorage as
|
|
8434
|
+
import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
|
|
8267
8435
|
import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
|
|
8268
8436
|
import { dirname as dirname2, isAbsolute, join as join2, posix as posixPath2 } from "path";
|
|
8269
8437
|
|
|
@@ -8856,7 +9024,7 @@ Skills are reusable instructions supplied dynamically for the current session. W
|
|
|
8856
9024
|
|
|
8857
9025
|
Use \`session_events\` for conversation history: its default returns user and completed assistant messages, not execution noise. Cursors only paginate. Request \`results\` for final outcomes, \`tools\` for tool receipts, or \`debug\` for explicit diagnostics; request large tool bodies only when needed. Use the returned continuation cursor rather than rereading whole pages. Audit reads do not acknowledge command completion.
|
|
8858
9026
|
|
|
8859
|
-
For a yielded command, use \`command_read\` to read available output and status, or \`command_wait\` to wait briefly using the same command interface. Keep the command ID and output cursor. A terminal read suppresses any still-pending completion notification; a running read does not. Earlier tool results and delivered messages never change. Use \`command_input\` only to send input where supported, not to poll output. An unsupported input capability does not imply output is unavailable. Give foreground commands a realistic requested wait;
|
|
9027
|
+
For a yielded command, use \`command_read\` to read available output and status, or \`command_wait\` to wait briefly using the same command interface. Keep the command ID and output cursor. A terminal read suppresses any still-pending completion notification; a running read does not. Earlier tool results and delivered messages never change. Use \`command_input\` only to send input where supported, not to poll output. An unsupported input capability does not imply output is unavailable. Give foreground commands a realistic requested wait; default to 10 seconds (yield_time_ms: 10000). An internal polling slice is not a reason to return a background handle.
|
|
8860
9028
|
|
|
8861
9029
|
If the user asks to create, inspect, continue, pause, resume, steer, rename, or otherwise manage a session, use the corresponding session tool. Pause affects the selected workstream and its descendants: pausing an ancestor also stops you, so you cannot then Resume yourself. Coordinate disjoint edits through messages instead of ancestor Pause.
|
|
8862
9030
|
|
|
@@ -10975,9 +11143,9 @@ function* jsonStringFragments(value) {
|
|
|
10975
11143
|
}
|
|
10976
11144
|
|
|
10977
11145
|
// src/model-preparation-diagnostics.ts
|
|
10978
|
-
import { AsyncLocalStorage as
|
|
10979
|
-
var modelPreparationObserver = new
|
|
10980
|
-
var modelTransportStartedObserver = new
|
|
11146
|
+
import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
|
|
11147
|
+
var modelPreparationObserver = new AsyncLocalStorage4();
|
|
11148
|
+
var modelTransportStartedObserver = new AsyncLocalStorage4();
|
|
10981
11149
|
var ModelPreparationTraceProcessor = class {
|
|
10982
11150
|
async onTraceStart(_trace) {
|
|
10983
11151
|
}
|
|
@@ -11711,6 +11879,7 @@ function configureOpenAI(settings) {
|
|
|
11711
11879
|
|
|
11712
11880
|
// src/workspace-skills.ts
|
|
11713
11881
|
import { createHash as createHash4 } from "crypto";
|
|
11882
|
+
import { parseSkillFrontmatter } from "@opengeni/contracts";
|
|
11714
11883
|
import { SandboxFilesystemNotFoundError } from "modal";
|
|
11715
11884
|
var SKILL_FILE = "SKILL.md";
|
|
11716
11885
|
var MAX_DISCOVERED_SKILLS = 256;
|
|
@@ -11729,21 +11898,84 @@ var WorkspaceSkillsCapability = class extends Capability {
|
|
|
11729
11898
|
}
|
|
11730
11899
|
type = "workspace-skills";
|
|
11731
11900
|
discovery;
|
|
11732
|
-
|
|
11901
|
+
bind(session) {
|
|
11902
|
+
if (this._session !== session) delete this.discovery;
|
|
11903
|
+
return super.bind(session);
|
|
11904
|
+
}
|
|
11905
|
+
discover() {
|
|
11733
11906
|
const session = requireWorkspaceSkillSession(this._session);
|
|
11734
|
-
this.discovery ??= discoverWorkspaceSkills(
|
|
11907
|
+
return this.discovery ??= discoverWorkspaceSkills(
|
|
11735
11908
|
session,
|
|
11736
11909
|
this.searchPaths,
|
|
11737
11910
|
this.reservedNames,
|
|
11738
11911
|
this._runAs,
|
|
11739
11912
|
this.shadowedNames
|
|
11740
11913
|
);
|
|
11741
|
-
|
|
11914
|
+
}
|
|
11915
|
+
tools() {
|
|
11916
|
+
return [
|
|
11917
|
+
tool({
|
|
11918
|
+
name: "repository_skill_read",
|
|
11919
|
+
description: "Read current repository Skill files from the bound workspace. Use the exact repository: identifier from the Repository skills index. Omit paths for SKILL.md; explicit relative paths read only those files. Set listFiles:true without paths for a bounded file inventory. This reads live files through the sandbox, including Connected Machines.",
|
|
11920
|
+
parameters: external_exports.object({
|
|
11921
|
+
skill: external_exports.string().min(1),
|
|
11922
|
+
paths: external_exports.array(external_exports.string().min(1).max(1024)).min(1).max(SKILL_READ_MAX_PATHS).optional(),
|
|
11923
|
+
listFiles: external_exports.boolean().optional()
|
|
11924
|
+
}),
|
|
11925
|
+
execute: async (request) => {
|
|
11926
|
+
if (request.listFiles && request.paths !== void 0)
|
|
11927
|
+
throw new SkillFileError(
|
|
11928
|
+
"invalid_request",
|
|
11929
|
+
"listFiles:true cannot be combined with paths."
|
|
11930
|
+
);
|
|
11931
|
+
const skill = (await this.discover()).find(
|
|
11932
|
+
(entry) => repositorySkillId(entry) === request.skill
|
|
11933
|
+
);
|
|
11934
|
+
if (!skill)
|
|
11935
|
+
throw new SkillFileError(
|
|
11936
|
+
"missing_file",
|
|
11937
|
+
"Repository Skill is not in this index. Use its exact repository: identifier."
|
|
11938
|
+
);
|
|
11939
|
+
const session = requireWorkspaceSkillSession(this._session);
|
|
11940
|
+
const root = skill.path.slice(0, -SKILL_FILE.length - 1);
|
|
11941
|
+
const result = request.listFiles ? listSkillPaths(
|
|
11942
|
+
await repositorySkillInventory(session, root, this._runAs),
|
|
11943
|
+
MAX_SKILL_ENTRIES
|
|
11944
|
+
) : readSkillFiles(
|
|
11945
|
+
await repositorySkillFiles(
|
|
11946
|
+
session,
|
|
11947
|
+
root,
|
|
11948
|
+
request.paths ?? [SKILL_FILE],
|
|
11949
|
+
this._runAs
|
|
11950
|
+
),
|
|
11951
|
+
request.paths
|
|
11952
|
+
);
|
|
11953
|
+
const output = JSON.stringify({
|
|
11954
|
+
skillId: request.skill,
|
|
11955
|
+
source: "repository",
|
|
11956
|
+
root,
|
|
11957
|
+
...result
|
|
11958
|
+
});
|
|
11959
|
+
if (new TextEncoder().encode(output).byteLength > SKILL_READ_MAX_OUTPUT_BYTES) {
|
|
11960
|
+
throw new SkillFileError(
|
|
11961
|
+
"output_too_large",
|
|
11962
|
+
"Repository Skill response exceeds the read output limit. Request fewer paths."
|
|
11963
|
+
);
|
|
11964
|
+
}
|
|
11965
|
+
return output;
|
|
11966
|
+
}
|
|
11967
|
+
})
|
|
11968
|
+
];
|
|
11969
|
+
}
|
|
11970
|
+
async instructions() {
|
|
11971
|
+
const skills = await this.discover();
|
|
11742
11972
|
if (skills.length === 0) return null;
|
|
11743
|
-
const available = skills.map(
|
|
11973
|
+
const available = skills.map(
|
|
11974
|
+
(skill) => `- ${JSON.stringify({ id: repositorySkillId(skill), name: skill.name, description: skill.description, reader: "repository_skill_read", path: skill.path })}`
|
|
11975
|
+
).join("\n");
|
|
11744
11976
|
return `## Repository skills
|
|
11745
11977
|
|
|
11746
|
-
Repository skills are instructions already present in the live workspace.
|
|
11978
|
+
Repository skills are instructions already present in the live workspace. Read them with repository_skill_read using the exact repository: id below. The reader returns current live files; ordinary filesystem tools execute referenced scripts and read binary assets. Configured Skills use their separate skill_read index.
|
|
11747
11979
|
|
|
11748
11980
|
### Available repository skills
|
|
11749
11981
|
${available}
|
|
@@ -11808,6 +12040,14 @@ async function discoverWorkspaceSkillsUnmeasured(session, searchPaths, reservedN
|
|
|
11808
12040
|
const skillMarkdownPath = joinWorkspacePath(entry.path, SKILL_FILE);
|
|
11809
12041
|
let markdown;
|
|
11810
12042
|
try {
|
|
12043
|
+
const skillEntries = await session.listDir({
|
|
12044
|
+
path: entry.path,
|
|
12045
|
+
...runAs ? { runAs } : {}
|
|
12046
|
+
});
|
|
12047
|
+
if (!skillEntries.some(
|
|
12048
|
+
(candidate2) => candidate2.name === SKILL_FILE && candidate2.type === "file"
|
|
12049
|
+
))
|
|
12050
|
+
continue;
|
|
11811
12051
|
const content = await session.readFile({
|
|
11812
12052
|
path: skillMarkdownPath,
|
|
11813
12053
|
...runAs ? { runAs } : {}
|
|
@@ -11825,7 +12065,7 @@ async function discoverWorkspaceSkillsUnmeasured(session, searchPaths, reservedN
|
|
|
11825
12065
|
const key = name.toLowerCase();
|
|
11826
12066
|
if (shadowedNames.has(key)) continue;
|
|
11827
12067
|
const description = frontmatter.description?.trim() || "No description provided.";
|
|
11828
|
-
if (description.length > 2048
|
|
12068
|
+
if (description.length > 2048) {
|
|
11829
12069
|
throw new Error(`Repository skill "${name}" has an invalid description`);
|
|
11830
12070
|
}
|
|
11831
12071
|
if (reservedNames.has(key)) {
|
|
@@ -11896,26 +12136,59 @@ async function fingerprintWorkspaceDirectory(session, root, runAs) {
|
|
|
11896
12136
|
await visit(root, "");
|
|
11897
12137
|
return hash.digest("hex");
|
|
11898
12138
|
}
|
|
11899
|
-
function
|
|
11900
|
-
|
|
11901
|
-
|
|
11902
|
-
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
|
|
11916
|
-
|
|
12139
|
+
function repositorySkillId(skill) {
|
|
12140
|
+
return `repository:${skill.path}`;
|
|
12141
|
+
}
|
|
12142
|
+
async function repositorySkillFiles(session, root, paths, runAs) {
|
|
12143
|
+
readSkillFiles(
|
|
12144
|
+
paths.map((path) => ({ path, content: "" })),
|
|
12145
|
+
paths
|
|
12146
|
+
);
|
|
12147
|
+
const files = [];
|
|
12148
|
+
for (const path of paths) {
|
|
12149
|
+
let directory = root;
|
|
12150
|
+
const segments = path.split("/");
|
|
12151
|
+
for (const [index, name] of segments.entries()) {
|
|
12152
|
+
const entries = await session.listDir({ path: directory, ...runAs ? { runAs } : {} });
|
|
12153
|
+
const entry = entries.find((candidate) => candidate.name === name);
|
|
12154
|
+
const expected = index === segments.length - 1 ? "file" : "dir";
|
|
12155
|
+
if (entry?.type !== expected)
|
|
12156
|
+
throw new SkillFileError("missing_file", `Repository Skill file is unavailable: ${path}`);
|
|
12157
|
+
directory = joinWorkspacePath(directory, name);
|
|
12158
|
+
}
|
|
12159
|
+
const content = await session.readFile({ path: directory, ...runAs ? { runAs } : {} });
|
|
12160
|
+
files.push({
|
|
12161
|
+
path,
|
|
12162
|
+
content: typeof content === "string" ? content : new TextDecoder("utf-8", { fatal: true }).decode(content)
|
|
12163
|
+
});
|
|
12164
|
+
readSkillFiles(
|
|
12165
|
+
files,
|
|
12166
|
+
files.map((file2) => file2.path)
|
|
12167
|
+
);
|
|
12168
|
+
}
|
|
12169
|
+
return files;
|
|
12170
|
+
}
|
|
12171
|
+
async function repositorySkillInventory(session, root, runAs) {
|
|
12172
|
+
const files = [];
|
|
12173
|
+
let count = 0;
|
|
12174
|
+
async function visit(relative) {
|
|
12175
|
+
const entries = await session.listDir({
|
|
12176
|
+
path: relative ? joinWorkspacePath(root, relative) : root,
|
|
12177
|
+
...runAs ? { runAs } : {}
|
|
12178
|
+
});
|
|
12179
|
+
for (const entry of entries) {
|
|
12180
|
+
if (++count > MAX_SKILL_ENTRIES)
|
|
12181
|
+
throw new SkillFileError("output_too_large", "Repository Skill inventory is too large.");
|
|
12182
|
+
assertSkillRelativePath(entry.name);
|
|
12183
|
+
if (entry.name.includes("/"))
|
|
12184
|
+
throw new SkillFileError("invalid_path", "Invalid repository directory entry.");
|
|
12185
|
+
const path = relative ? `${relative}/${entry.name}` : entry.name;
|
|
12186
|
+
if (entry.type === "dir") await visit(path);
|
|
12187
|
+
else if (entry.type === "file") files.push({ path, content: "" });
|
|
12188
|
+
}
|
|
11917
12189
|
}
|
|
11918
|
-
|
|
12190
|
+
await visit("");
|
|
12191
|
+
return files;
|
|
11919
12192
|
}
|
|
11920
12193
|
function joinWorkspacePath(parent, child) {
|
|
11921
12194
|
return `${parent.replace(/\/+$/, "")}/${child}`;
|
|
@@ -11933,7 +12206,7 @@ import { existsSync, readdirSync } from "fs";
|
|
|
11933
12206
|
// ../sdk/package.json
|
|
11934
12207
|
var package_default = {
|
|
11935
12208
|
name: "@opengeni/sdk",
|
|
11936
|
-
version: "5.0.
|
|
12209
|
+
version: "5.0.5-canary.1",
|
|
11937
12210
|
description: "Framework-agnostic TypeScript SDK for the OpenGeni API: typed client, session lifecycle, SSE event streaming with reconnect + replay-by-sequence, and proxy re-streaming helpers.",
|
|
11938
12211
|
license: "Apache-2.0",
|
|
11939
12212
|
repository: {
|
|
@@ -12073,7 +12346,7 @@ var package_default = {
|
|
|
12073
12346
|
// ../react/package.json
|
|
12074
12347
|
var package_default2 = {
|
|
12075
12348
|
name: "@opengeni/react",
|
|
12076
|
-
version: "5.0.
|
|
12349
|
+
version: "5.0.5-canary.1",
|
|
12077
12350
|
description: "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views \u2014 token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
|
|
12078
12351
|
license: "Apache-2.0",
|
|
12079
12352
|
repository: {
|
|
@@ -12217,6 +12490,7 @@ var package_default2 = {
|
|
|
12217
12490
|
"react-resizable-panels": "^4.11.2",
|
|
12218
12491
|
"remark-gfm": "^4.0.1",
|
|
12219
12492
|
"tailwind-merge": "^3.5.0",
|
|
12493
|
+
"thinking-orbs": "^0.3.1",
|
|
12220
12494
|
virtua: "^0.49.2"
|
|
12221
12495
|
},
|
|
12222
12496
|
devDependencies: {
|
|
@@ -12325,7 +12599,7 @@ var package_default2 = {
|
|
|
12325
12599
|
// ../codemode/package.json
|
|
12326
12600
|
var package_default3 = {
|
|
12327
12601
|
name: "@opengeni/codemode",
|
|
12328
|
-
version: "0.5.
|
|
12602
|
+
version: "0.5.6-canary.1",
|
|
12329
12603
|
description: "Attempt-frozen programmatic tool catalog and execution authority for OpenGeni.",
|
|
12330
12604
|
license: "Apache-2.0",
|
|
12331
12605
|
repository: {
|
|
@@ -12374,7 +12648,7 @@ var package_default3 = {
|
|
|
12374
12648
|
// ../ogtool/package.json
|
|
12375
12649
|
var package_default4 = {
|
|
12376
12650
|
name: "@opengeni/ogtool",
|
|
12377
|
-
version: "0.3.
|
|
12651
|
+
version: "0.3.38-canary.1",
|
|
12378
12652
|
description: "Codemode CLI and typed client entrypoint for an OpenGeni execution attempt.",
|
|
12379
12653
|
license: "Apache-2.0",
|
|
12380
12654
|
repository: {
|
|
@@ -12453,7 +12727,7 @@ var emptyNativeToolSkillSet = Object.freeze({
|
|
|
12453
12727
|
videoGeneration: false
|
|
12454
12728
|
});
|
|
12455
12729
|
function loadNativeToolSkillArtifacts(nativeTools) {
|
|
12456
|
-
const directories = [];
|
|
12730
|
+
const directories = ["bundled_default_skills"];
|
|
12457
12731
|
if (nativeTools.projects) directories.push("bundled_project_skills");
|
|
12458
12732
|
if (nativeTools.editableArtifacts) directories.push("bundled_artifact_skills");
|
|
12459
12733
|
if (nativeTools.sites) directories.push("bundled_site_skills");
|
|
@@ -12670,7 +12944,12 @@ function selectionForActivation({
|
|
|
12670
12944
|
}
|
|
12671
12945
|
}
|
|
12672
12946
|
function nativeToolSkillSources(nativeTools) {
|
|
12673
|
-
const sources = [
|
|
12947
|
+
const sources = [
|
|
12948
|
+
{
|
|
12949
|
+
names: skillDirNames(packagedSkillDirectory("bundled_default_skills")),
|
|
12950
|
+
reason: "included by default"
|
|
12951
|
+
}
|
|
12952
|
+
];
|
|
12674
12953
|
if (nativeTools.editableArtifacts) {
|
|
12675
12954
|
sources.push({
|
|
12676
12955
|
names: skillDirNames(packagedSkillDirectory("bundled_artifact_skills")),
|
|
@@ -16788,7 +17067,8 @@ var ConnectorActionExecutionError = class extends Error {
|
|
|
16788
17067
|
this.connectorActionOutcome = outcome;
|
|
16789
17068
|
}
|
|
16790
17069
|
};
|
|
16791
|
-
var modelToolInvocation = new
|
|
17070
|
+
var modelToolInvocation = new AsyncLocalStorage5();
|
|
17071
|
+
var modelMcpCallIdentity = new AsyncLocalStorage5();
|
|
16792
17072
|
var agentInputWaitYields = /* @__PURE__ */ new WeakMap();
|
|
16793
17073
|
function rigInstructions(rig) {
|
|
16794
17074
|
return [
|
|
@@ -17231,6 +17511,7 @@ function buildOpenGeniAgent(settings, resources, options = {}) {
|
|
|
17231
17511
|
agent2,
|
|
17232
17512
|
options.approvedToolCallId
|
|
17233
17513
|
);
|
|
17514
|
+
installModelMcpCallIdentity(agent2);
|
|
17234
17515
|
return agent2;
|
|
17235
17516
|
}
|
|
17236
17517
|
if (options.activeSandboxBackend === "selfhosted" && !options.sandboxWorkspaceRoot) {
|
|
@@ -17332,6 +17613,7 @@ function buildOpenGeniAgent(settings, resources, options = {}) {
|
|
|
17332
17613
|
agent,
|
|
17333
17614
|
options.approvedToolCallId
|
|
17334
17615
|
);
|
|
17616
|
+
installModelMcpCallIdentity(agent);
|
|
17335
17617
|
return agent;
|
|
17336
17618
|
}
|
|
17337
17619
|
function maybeInstallLazyToolTransport(agent, settings, options) {
|
|
@@ -17368,6 +17650,35 @@ function sessionMcpApprovalConnectionId(serverId, url) {
|
|
|
17368
17650
|
const targetHash = createHash5("sha256").update(url, "utf8").digest("hex");
|
|
17369
17651
|
return `session-mcp:${serverId}:${targetHash}`;
|
|
17370
17652
|
}
|
|
17653
|
+
function installModelMcpCallIdentity(agent) {
|
|
17654
|
+
const listMcpTools = agent.getMcpTools.bind(agent);
|
|
17655
|
+
agent.getMcpTools = async (resolutionContext) => (await listMcpTools(resolutionContext)).map((tool2) => {
|
|
17656
|
+
if (tool2.type !== "function") return tool2;
|
|
17657
|
+
const invoke = tool2.invoke.bind(tool2);
|
|
17658
|
+
return {
|
|
17659
|
+
...tool2,
|
|
17660
|
+
invoke: async (runContext, input, details) => {
|
|
17661
|
+
const callId3 = details?.toolCall?.callId;
|
|
17662
|
+
return await modelMcpCallIdentity.run(
|
|
17663
|
+
typeof callId3 === "string" && callId3.length > 0 ? { modelName: tool2.name, callId: callId3 } : null,
|
|
17664
|
+
async () => await invoke(runContext, input, details)
|
|
17665
|
+
);
|
|
17666
|
+
}
|
|
17667
|
+
};
|
|
17668
|
+
});
|
|
17669
|
+
const clone = agent.clone?.bind(agent);
|
|
17670
|
+
if (clone) {
|
|
17671
|
+
agent.clone = (config) => {
|
|
17672
|
+
const cloned = clone(config);
|
|
17673
|
+
installModelMcpCallIdentity(cloned);
|
|
17674
|
+
return cloned;
|
|
17675
|
+
};
|
|
17676
|
+
}
|
|
17677
|
+
}
|
|
17678
|
+
function modelMcpSourceCallId(modelName) {
|
|
17679
|
+
const identity2 = modelMcpCallIdentity.getStore();
|
|
17680
|
+
return identity2?.modelName === modelName ? identity2.callId : void 0;
|
|
17681
|
+
}
|
|
17371
17682
|
function installMcpApprovalPolicy(agent, policies, connectorActionPolicy, approvedToolCallId) {
|
|
17372
17683
|
const approvalRequiredCallIds = /* @__PURE__ */ new Set();
|
|
17373
17684
|
const preparations = /* @__PURE__ */ new Map();
|
|
@@ -17958,24 +18269,30 @@ async function prepareAgentTools(settings, tools, options = {}) {
|
|
|
17958
18269
|
}
|
|
17959
18270
|
const optional2 = tool2.optional === true;
|
|
17960
18271
|
return {
|
|
17961
|
-
server:
|
|
17962
|
-
|
|
17963
|
-
|
|
17964
|
-
|
|
17965
|
-
|
|
17966
|
-
|
|
17967
|
-
|
|
17968
|
-
|
|
17969
|
-
|
|
17970
|
-
|
|
17971
|
-
|
|
17972
|
-
|
|
17973
|
-
|
|
17974
|
-
|
|
18272
|
+
server: configureMcpOperationRecovery(
|
|
18273
|
+
new PrefixedMcpServer(
|
|
18274
|
+
local.server,
|
|
18275
|
+
config.id,
|
|
18276
|
+
config.allowedTools,
|
|
18277
|
+
optional2 || Boolean(config.connectionRef),
|
|
18278
|
+
aggregateToolBudget,
|
|
18279
|
+
`${config.id}:${index}`,
|
|
18280
|
+
false,
|
|
18281
|
+
buildConnectorAttachmentAuthority(
|
|
18282
|
+
config,
|
|
18283
|
+
options,
|
|
18284
|
+
resolvedMcpToolConnectionIds,
|
|
18285
|
+
config.url,
|
|
18286
|
+
local.resolvedConnectionId
|
|
18287
|
+
),
|
|
18288
|
+
tool2.eager !== true,
|
|
18289
|
+
local.preflightCall,
|
|
18290
|
+
local.approvalAuthority
|
|
17975
18291
|
),
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
|
|
18292
|
+
config,
|
|
18293
|
+
options,
|
|
18294
|
+
config.url,
|
|
18295
|
+
false
|
|
17979
18296
|
),
|
|
17980
18297
|
bestEffort: optional2 || Boolean(config.connectionRef),
|
|
17981
18298
|
optional: optional2,
|
|
@@ -18048,20 +18365,26 @@ async function prepareAgentTools(settings, tools, options = {}) {
|
|
|
18048
18365
|
clientSessionTimeoutSeconds: Math.ceil(config.timeoutMs / 1e3)
|
|
18049
18366
|
} : {}
|
|
18050
18367
|
});
|
|
18051
|
-
const server =
|
|
18052
|
-
|
|
18053
|
-
|
|
18054
|
-
|
|
18055
|
-
|
|
18056
|
-
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
|
|
18063
|
-
|
|
18064
|
-
|
|
18368
|
+
const server = configureMcpOperationRecovery(
|
|
18369
|
+
new PrefixedMcpServer(
|
|
18370
|
+
innerServer,
|
|
18371
|
+
config.id,
|
|
18372
|
+
config.allowedTools,
|
|
18373
|
+
bestEffort,
|
|
18374
|
+
aggregateToolBudget,
|
|
18375
|
+
`${config.id}:${index}`,
|
|
18376
|
+
firstParty && !bestEffort,
|
|
18377
|
+
buildConnectorAttachmentAuthority(config, options, resolvedMcpToolConnectionIds, url),
|
|
18378
|
+
tool2.eager !== true,
|
|
18379
|
+
void 0,
|
|
18380
|
+
void 0,
|
|
18381
|
+
firstParty && config.id === "opengeni" && !config.connectionRef && !bridge ? inputWaitYield : void 0,
|
|
18382
|
+
firstParty && config.id === "opengeni" && !config.connectionRef && !bridge ? options.refreshOwnedCommand : void 0
|
|
18383
|
+
),
|
|
18384
|
+
config,
|
|
18385
|
+
options,
|
|
18386
|
+
url,
|
|
18387
|
+
Boolean(config.connectionRef) && !bridge && !isCodexAppsMcpServer(config)
|
|
18065
18388
|
);
|
|
18066
18389
|
return {
|
|
18067
18390
|
server,
|
|
@@ -18570,17 +18893,39 @@ async function prepareToolGatewayDefinitionsFromServers(servers, registry) {
|
|
|
18570
18893
|
...context.signal ? { signal: context.signal } : {}
|
|
18571
18894
|
})
|
|
18572
18895
|
} : {},
|
|
18573
|
-
execute: async (args, context) =>
|
|
18574
|
-
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18896
|
+
execute: async (args, context) => {
|
|
18897
|
+
const execute = async () => await server.executeCatalogTool(
|
|
18898
|
+
toolName,
|
|
18899
|
+
args,
|
|
18900
|
+
{
|
|
18901
|
+
...context.transportMeta ?? {},
|
|
18902
|
+
opengeniOperationId: context.operationId
|
|
18903
|
+
},
|
|
18904
|
+
{
|
|
18905
|
+
...context.signal ? { signal: context.signal } : {}
|
|
18906
|
+
}
|
|
18907
|
+
);
|
|
18908
|
+
const recovery = configuredMcpOperationRecovery(server, toolName);
|
|
18909
|
+
if (!recovery) return await execute();
|
|
18910
|
+
if (!recovery.supported || !["model", "codemode"].includes(context.caller.kind)) {
|
|
18911
|
+
throw new Error(
|
|
18912
|
+
"MCP operation recovery requires an exact attempt and remote brokered execution"
|
|
18913
|
+
);
|
|
18582
18914
|
}
|
|
18583
|
-
|
|
18915
|
+
return await runRecoverableMcpOperation(
|
|
18916
|
+
{
|
|
18917
|
+
operationId: context.operationId,
|
|
18918
|
+
...context.sourceCallId === void 0 ? {} : { sourceCallId: context.sourceCallId },
|
|
18919
|
+
serverId: server.registryId,
|
|
18920
|
+
originalTool: toolName,
|
|
18921
|
+
observerTool: recovery.policy[toolName].observerTool,
|
|
18922
|
+
destinationDigest: recovery.destinationDigest,
|
|
18923
|
+
argumentDigest: digestCanonicalJson(args)
|
|
18924
|
+
},
|
|
18925
|
+
recovery.persistence,
|
|
18926
|
+
execute
|
|
18927
|
+
);
|
|
18928
|
+
}
|
|
18584
18929
|
};
|
|
18585
18930
|
});
|
|
18586
18931
|
}
|
|
@@ -18594,6 +18939,22 @@ function attemptToolCodemodePath(serverId, toolName) {
|
|
|
18594
18939
|
}
|
|
18595
18940
|
return [serverId, toolName];
|
|
18596
18941
|
}
|
|
18942
|
+
var mcpOperationRecoveryByServer = /* @__PURE__ */ new WeakMap();
|
|
18943
|
+
function configureMcpOperationRecovery(server, config, options, destinationUrl, brokered) {
|
|
18944
|
+
if (config.operationRecovery && options.mcpOperationPersistence) {
|
|
18945
|
+
mcpOperationRecoveryByServer.set(server, {
|
|
18946
|
+
policy: McpOperationRecoverySchema.parse(config.operationRecovery),
|
|
18947
|
+
persistence: options.mcpOperationPersistence,
|
|
18948
|
+
destinationDigest: digestCanonicalJson(new URL(destinationUrl).toString()),
|
|
18949
|
+
supported: brokered && attemptToolScope(options) !== null
|
|
18950
|
+
});
|
|
18951
|
+
}
|
|
18952
|
+
return server;
|
|
18953
|
+
}
|
|
18954
|
+
function configuredMcpOperationRecovery(server, toolName) {
|
|
18955
|
+
const recovery = mcpOperationRecoveryByServer.get(server);
|
|
18956
|
+
return recovery && Object.hasOwn(recovery.policy, toolName) ? recovery : void 0;
|
|
18957
|
+
}
|
|
18597
18958
|
function attemptToolSource(serverId) {
|
|
18598
18959
|
if (serverId === "opengeni" || serverId === "files" || serverId === "docs") {
|
|
18599
18960
|
return serverId;
|
|
@@ -18650,6 +19011,24 @@ function connectionBrokerFetch(baseFetch, config, options, resolvedMcpConnection
|
|
|
18650
19011
|
suppressSetupAuthNeeded
|
|
18651
19012
|
);
|
|
18652
19013
|
}
|
|
19014
|
+
if (request.method === "tools/call") {
|
|
19015
|
+
assertMcpOperationObservationAuthority({
|
|
19016
|
+
serverId: config.id,
|
|
19017
|
+
...request.toolName === void 0 ? {} : { toolName: request.toolName },
|
|
19018
|
+
destinationDigest: digestCanonicalJson(destinationUrl),
|
|
19019
|
+
...first.operationAuthorityDigest === void 0 ? {} : { authorityDigest: first.operationAuthorityDigest }
|
|
19020
|
+
});
|
|
19021
|
+
if (hasActiveRecoverableMcpOperation() && (request.batch || request.id === void 0 || request.id === null || !request.operationId || !request.toolName)) {
|
|
19022
|
+
throw new Error("Recoverable MCP request is missing its exact dispatch identity");
|
|
19023
|
+
}
|
|
19024
|
+
await captureMcpOperationDispatch({
|
|
19025
|
+
operationId: request.operationId ?? "",
|
|
19026
|
+
serverId: config.id,
|
|
19027
|
+
toolName: request.toolName ?? "",
|
|
19028
|
+
destinationDigest: digestCanonicalJson(destinationUrl),
|
|
19029
|
+
authorityDigest: first.operationAuthorityDigest ?? ""
|
|
19030
|
+
});
|
|
19031
|
+
}
|
|
18653
19032
|
const response = await baseFetch(
|
|
18654
19033
|
fetchInputForAttempt(input),
|
|
18655
19034
|
withConnectionHeaders(input, init, first.headers)
|
|
@@ -19635,10 +20014,12 @@ var AttemptDefinitionMcpServer = class {
|
|
|
19635
20014
|
async callToolResult(toolName, args, meta, options) {
|
|
19636
20015
|
if (this.closed) throw new Error("local model tool server is closed");
|
|
19637
20016
|
const environment = await this.requiredAttemptToolEnvironment();
|
|
20017
|
+
const sourceCallId = modelMcpSourceCallId(toolName);
|
|
19638
20018
|
return await this.resultCustomDataBridge.captureResult(
|
|
19639
20019
|
args,
|
|
19640
20020
|
async (cleanArgs) => environment.callModel({
|
|
19641
20021
|
modelName: toolName,
|
|
20022
|
+
...sourceCallId === void 0 ? {} : { sourceCallId },
|
|
19642
20023
|
arguments: cleanArgs ?? {},
|
|
19643
20024
|
subjectId: this.subjectId,
|
|
19644
20025
|
...meta === void 0 ? {} : { transportMeta: meta },
|
|
@@ -19888,8 +20269,10 @@ var PrefixedMcpServer = class _PrefixedMcpServer {
|
|
|
19888
20269
|
}
|
|
19889
20270
|
return await this.resultCustomDataBridge.captureResult(args, async (cleanArgs) => {
|
|
19890
20271
|
if (this.attemptToolEnvironment) {
|
|
20272
|
+
const sourceCallId = modelMcpSourceCallId(toolName);
|
|
19891
20273
|
return await this.attemptToolEnvironment.callModel({
|
|
19892
20274
|
modelName: toolName,
|
|
20275
|
+
...sourceCallId === void 0 ? {} : { sourceCallId },
|
|
19893
20276
|
arguments: cleanArgs ?? {},
|
|
19894
20277
|
subjectId: this.attemptToolSubjectId,
|
|
19895
20278
|
...meta === void 0 ? {} : { transportMeta: meta },
|
|
@@ -19909,6 +20292,9 @@ var PrefixedMcpServer = class _PrefixedMcpServer {
|
|
|
19909
20292
|
if (!this.isAllowed(unprefixed)) {
|
|
19910
20293
|
throw new Error(`MCP tool ${unprefixed} is not allowed for server ${this.registryId}`);
|
|
19911
20294
|
}
|
|
20295
|
+
if (configuredMcpOperationRecovery(this, unprefixed) && !hasActiveRecoverableMcpOperation()) {
|
|
20296
|
+
throw new Error("MCP operation recovery requires its trusted attempt execution context");
|
|
20297
|
+
}
|
|
19912
20298
|
const recordsPhysicalCall = !(this.inner instanceof _PrefixedMcpServer);
|
|
19913
20299
|
const startedAt = recordsPhysicalCall ? performance.now() : 0;
|
|
19914
20300
|
let metricRecorded = false;
|
|
@@ -19929,7 +20315,7 @@ var PrefixedMcpServer = class _PrefixedMcpServer {
|
|
|
19929
20315
|
args: args ?? {},
|
|
19930
20316
|
...options?.signal ? { signal: options.signal } : {},
|
|
19931
20317
|
refresh: this.refreshOwnedCommand,
|
|
19932
|
-
call: async (callArgs) =>
|
|
20318
|
+
call: async (callArgs) => AttemptToolResult3.parse(unwrapSdkMcpResultProjection(await physicalCall(callArgs)))
|
|
19933
20319
|
}) : await physicalCall(args ?? {});
|
|
19934
20320
|
const rawOutput = unwrapSdkMcpResultProjection(projectedOutput);
|
|
19935
20321
|
const connectionId = operationId ? this.connectorAttachmentAuthority?.connectionIdForOperation(operationId) : void 0;
|
|
@@ -19954,7 +20340,7 @@ var PrefixedMcpServer = class _PrefixedMcpServer {
|
|
|
19954
20340
|
});
|
|
19955
20341
|
}
|
|
19956
20342
|
});
|
|
19957
|
-
const result =
|
|
20343
|
+
const result = AttemptToolResult3.parse(output);
|
|
19958
20344
|
boundedMcpToolResult(result);
|
|
19959
20345
|
recordOutcome(result.isError === true ? "provider_declared_error" : "success");
|
|
19960
20346
|
if (unprefixed === "wait_for_input" && result.isError !== true) {
|
|
@@ -19962,6 +20348,12 @@ var PrefixedMcpServer = class _PrefixedMcpServer {
|
|
|
19962
20348
|
}
|
|
19963
20349
|
return result;
|
|
19964
20350
|
} catch (error) {
|
|
20351
|
+
if (hasActiveRecoverableMcpOperation()) {
|
|
20352
|
+
recordOutcome(
|
|
20353
|
+
isToolOutcomeUncertainMcpError(error) ? "outcome_uncertain" : isAuthNeededMcpError(error) ? "auth_needed" : mcpThrownToolCallOutcome(error, options?.signal)
|
|
20354
|
+
);
|
|
20355
|
+
throw error;
|
|
20356
|
+
}
|
|
19965
20357
|
if (isToolOutcomeUncertainMcpError(error)) {
|
|
19966
20358
|
recordOutcome("outcome_uncertain");
|
|
19967
20359
|
return boundedMcpToolResult({
|
|
@@ -22845,6 +23237,13 @@ function sortJson(value) {
|
|
|
22845
23237
|
}
|
|
22846
23238
|
|
|
22847
23239
|
export {
|
|
23240
|
+
hasActiveRecoverableMcpOperation,
|
|
23241
|
+
McpOperationOutcomeUnknownError,
|
|
23242
|
+
runRecoverableMcpOperation,
|
|
23243
|
+
captureMcpOperationDispatch,
|
|
23244
|
+
runMcpOperationObservationWithAuthority,
|
|
23245
|
+
assertMcpOperationObservationAuthority,
|
|
23246
|
+
observeMcpOperation,
|
|
22848
23247
|
formatSkillCatalog,
|
|
22849
23248
|
OpenAIResponsesModel,
|
|
22850
23249
|
OpenAIChatCompletionsModel,
|
|
@@ -23094,4 +23493,4 @@ export {
|
|
|
23094
23493
|
runAzureCliLoginHook,
|
|
23095
23494
|
renderSessionGoalContext2 as renderSessionGoalContext
|
|
23096
23495
|
};
|
|
23097
|
-
//# sourceMappingURL=chunk-
|
|
23496
|
+
//# sourceMappingURL=chunk-VUEWS4GI.js.map
|