@usabledev/usable-chat 1.210.0 → 1.211.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/cli.js +297 -124
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -95134,6 +95134,12 @@ var init_beta_features = __esm({
|
|
|
95134
95134
|
name: "Research mode",
|
|
95135
95135
|
description: "Run structured, sourced research with specialist workers and an HTML report."
|
|
95136
95136
|
},
|
|
95137
|
+
"auto-model": {
|
|
95138
|
+
key: "auto-model",
|
|
95139
|
+
name: "Auto model",
|
|
95140
|
+
description: "Use Jev to choose a curated model for each text request.",
|
|
95141
|
+
failureMessage: "Could not save Auto model. Try again."
|
|
95142
|
+
},
|
|
95137
95143
|
"configurable-hooks": {
|
|
95138
95144
|
key: "configurable-hooks",
|
|
95139
95145
|
name: "Configurable hooks",
|
|
@@ -95160,7 +95166,8 @@ var init_beta_features = __esm({
|
|
|
95160
95166
|
betaFeatureGrantSchema = external_exports.object({
|
|
95161
95167
|
enabled: external_exports.boolean(),
|
|
95162
95168
|
enabledAt: external_exports.string().datetime(),
|
|
95163
|
-
enabledBy: external_exports.string()
|
|
95169
|
+
enabledBy: external_exports.string(),
|
|
95170
|
+
autoModelChoices: external_exports.object({ simple: external_exports.string(), advanced: external_exports.string() }).optional()
|
|
95164
95171
|
});
|
|
95165
95172
|
userBetaFeaturesSchema = external_exports.record(external_exports.string(), betaFeatureGrantSchema);
|
|
95166
95173
|
}
|
|
@@ -106896,11 +106903,11 @@ var require_randomUUID = __commonJS({
|
|
|
106896
106903
|
var require_dist_cjs31 = __commonJS({
|
|
106897
106904
|
"node_modules/.pnpm/@smithy+uuid@1.1.2/node_modules/@smithy/uuid/dist-cjs/index.js"(exports2) {
|
|
106898
106905
|
"use strict";
|
|
106899
|
-
var
|
|
106906
|
+
var randomUUID16 = require_randomUUID();
|
|
106900
106907
|
var decimalToHex = Array.from({ length: 256 }, (_16, i19) => i19.toString(16).padStart(2, "0"));
|
|
106901
106908
|
var v43 = () => {
|
|
106902
|
-
if (
|
|
106903
|
-
return
|
|
106909
|
+
if (randomUUID16.randomUUID) {
|
|
106910
|
+
return randomUUID16.randomUUID();
|
|
106904
106911
|
}
|
|
106905
106912
|
const rnds = new Uint8Array(16);
|
|
106906
106913
|
crypto.getRandomValues(rnds);
|
|
@@ -144784,8 +144791,8 @@ var require_utils = __commonJS({
|
|
|
144784
144791
|
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
|
|
144785
144792
|
var HOST_DELIM_RE = /[@/?#:]/g;
|
|
144786
144793
|
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
|
|
144787
|
-
function reescapeHostDelimiters(host,
|
|
144788
|
-
const re10 =
|
|
144794
|
+
function reescapeHostDelimiters(host, isIP4) {
|
|
144795
|
+
const re10 = isIP4 ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
|
|
144789
144796
|
re10.lastIndex = 0;
|
|
144790
144797
|
return host.replace(re10, (ch) => HOST_DELIMS[ch]);
|
|
144791
144798
|
}
|
|
@@ -145267,7 +145274,7 @@ var require_fast_uri = __commonJS({
|
|
|
145267
145274
|
fragment: void 0
|
|
145268
145275
|
};
|
|
145269
145276
|
let malformedAuthorityOrPort = false;
|
|
145270
|
-
let
|
|
145277
|
+
let isIP4 = false;
|
|
145271
145278
|
if (options2.reference === "suffix") {
|
|
145272
145279
|
if (options2.scheme) {
|
|
145273
145280
|
uri = options2.scheme + ":" + uri;
|
|
@@ -145297,9 +145304,9 @@ var require_fast_uri = __commonJS({
|
|
|
145297
145304
|
if (ipv4result === false) {
|
|
145298
145305
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
145299
145306
|
parsed.host = ipv6result.host.toLowerCase();
|
|
145300
|
-
|
|
145307
|
+
isIP4 = ipv6result.isIPV6;
|
|
145301
145308
|
} else {
|
|
145302
|
-
|
|
145309
|
+
isIP4 = true;
|
|
145303
145310
|
}
|
|
145304
145311
|
}
|
|
145305
145312
|
if (parsed.scheme === void 0 && parsed.userinfo === void 0 && parsed.host === void 0 && parsed.port === void 0 && parsed.query === void 0 && !parsed.path) {
|
|
@@ -145316,7 +145323,7 @@ var require_fast_uri = __commonJS({
|
|
|
145316
145323
|
}
|
|
145317
145324
|
const schemeHandler = getSchemeHandler(options2.scheme || parsed.scheme);
|
|
145318
145325
|
if (!options2.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
|
|
145319
|
-
if (parsed.host && (options2.domainHost || schemeHandler && schemeHandler.domainHost) &&
|
|
145326
|
+
if (parsed.host && (options2.domainHost || schemeHandler && schemeHandler.domainHost) && isIP4 === false && nonSimpleDomain(parsed.host)) {
|
|
145320
145327
|
try {
|
|
145321
145328
|
parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
|
|
145322
145329
|
} catch (e15) {
|
|
@@ -145330,7 +145337,7 @@ var require_fast_uri = __commonJS({
|
|
|
145330
145337
|
parsed.scheme = unescape(parsed.scheme);
|
|
145331
145338
|
}
|
|
145332
145339
|
if (parsed.host !== void 0) {
|
|
145333
|
-
parsed.host = reescapeHostDelimiters(unescape(parsed.host),
|
|
145340
|
+
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP4);
|
|
145334
145341
|
}
|
|
145335
145342
|
}
|
|
145336
145343
|
if (parsed.path) {
|
|
@@ -162764,6 +162771,12 @@ var init_schema_mcp = __esm({
|
|
|
162764
162771
|
lastError: text2("last_error"),
|
|
162765
162772
|
deletedAt: timestamp("deleted_at", { withTimezone: true }),
|
|
162766
162773
|
sourceEventId: varchar("source_event_id", { length: 255 }),
|
|
162774
|
+
// User approval for credential-bearing profiles (see services/mcp-approval.ts).
|
|
162775
|
+
// Existing rows are grandfathered with approved_via='legacy' and no fingerprint.
|
|
162776
|
+
origin: varchar("origin", { length: 16 }).notNull().default("legacy").$type(),
|
|
162777
|
+
approvedFingerprint: varchar("approved_fingerprint", { length: 80 }),
|
|
162778
|
+
approvedAt: timestamp("approved_at", { withTimezone: true }),
|
|
162779
|
+
approvedVia: varchar("approved_via", { length: 32 }),
|
|
162767
162780
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
162768
162781
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
162769
162782
|
},
|
|
@@ -163435,6 +163448,41 @@ var init_tool = __esm({
|
|
|
163435
163448
|
}
|
|
163436
163449
|
});
|
|
163437
163450
|
|
|
163451
|
+
// src/core/pause/envelope.ts
|
|
163452
|
+
function isMcpApprovalPause(output) {
|
|
163453
|
+
if (!output || typeof output !== "object") return false;
|
|
163454
|
+
const pause = output.__pause;
|
|
163455
|
+
return pause !== void 0 && pause.kind === MCP_APPROVAL_PAUSE_KIND && typeof pause.resumeToken === "string" && typeof pause.mcpApproval?.profileId === "string" && typeof pause.mcpApproval.fingerprint === "string";
|
|
163456
|
+
}
|
|
163457
|
+
function detectPause(toolResult, toolCallId) {
|
|
163458
|
+
if (isAskQuestionPause(toolResult)) {
|
|
163459
|
+
return {
|
|
163460
|
+
resumeToken: toolResult.__pause.resumeToken,
|
|
163461
|
+
questions: toolResult.__pause.questions,
|
|
163462
|
+
context: toolResult.__pause.context,
|
|
163463
|
+
toolCallId
|
|
163464
|
+
};
|
|
163465
|
+
}
|
|
163466
|
+
if (isMcpApprovalPause(toolResult)) {
|
|
163467
|
+
return {
|
|
163468
|
+
kind: MCP_APPROVAL_PAUSE_KIND,
|
|
163469
|
+
resumeToken: toolResult.__pause.resumeToken,
|
|
163470
|
+
mcpApproval: toolResult.__pause.mcpApproval,
|
|
163471
|
+
action: toolResult.__pause.action,
|
|
163472
|
+
toolCallId
|
|
163473
|
+
};
|
|
163474
|
+
}
|
|
163475
|
+
return null;
|
|
163476
|
+
}
|
|
163477
|
+
var MCP_APPROVAL_PAUSE_KIND;
|
|
163478
|
+
var init_envelope = __esm({
|
|
163479
|
+
"src/core/pause/envelope.ts"() {
|
|
163480
|
+
"use strict";
|
|
163481
|
+
init_tool();
|
|
163482
|
+
MCP_APPROVAL_PAUSE_KIND = "mcp-approval";
|
|
163483
|
+
}
|
|
163484
|
+
});
|
|
163485
|
+
|
|
163438
163486
|
// src/core/ai/provider-attempt.ts
|
|
163439
163487
|
function providerAttemptAbortError(attempt) {
|
|
163440
163488
|
const reason = attempt.signal.reason;
|
|
@@ -164100,15 +164148,10 @@ async function adaptClaudeStream(stream, options2) {
|
|
|
164100
164148
|
});
|
|
164101
164149
|
multiplexer.send(cardEvent);
|
|
164102
164150
|
}
|
|
164103
|
-
|
|
164151
|
+
const pause = detectPause(toolResult, id);
|
|
164152
|
+
if (pause) {
|
|
164104
164153
|
pauseDetected = true;
|
|
164105
|
-
if (onPauseDetected)
|
|
164106
|
-
await onPauseDetected({
|
|
164107
|
-
resumeToken: toolResult.__pause.resumeToken,
|
|
164108
|
-
questions: toolResult.__pause.questions,
|
|
164109
|
-
context: toolResult.__pause.context
|
|
164110
|
-
});
|
|
164111
|
-
}
|
|
164154
|
+
if (onPauseDetected) await onPauseDetected(pause);
|
|
164112
164155
|
return { toolResult };
|
|
164113
164156
|
}
|
|
164114
164157
|
if (toolResult?.__parentToolCall === true) {
|
|
@@ -164381,15 +164424,10 @@ async function adaptClaudeStream(stream, options2) {
|
|
|
164381
164424
|
});
|
|
164382
164425
|
multiplexer.send(cardEvent);
|
|
164383
164426
|
}
|
|
164384
|
-
|
|
164427
|
+
const pause = detectPause(toolResult, id);
|
|
164428
|
+
if (pause) {
|
|
164385
164429
|
pauseDetected = true;
|
|
164386
|
-
if (onPauseDetected)
|
|
164387
|
-
await onPauseDetected({
|
|
164388
|
-
resumeToken: toolResult.__pause.resumeToken,
|
|
164389
|
-
questions: toolResult.__pause.questions,
|
|
164390
|
-
context: toolResult.__pause.context
|
|
164391
|
-
});
|
|
164392
|
-
}
|
|
164430
|
+
if (onPauseDetected) await onPauseDetected(pause);
|
|
164393
164431
|
return { toolResult };
|
|
164394
164432
|
}
|
|
164395
164433
|
if (toolResult?.__parentToolCall === true) {
|
|
@@ -164609,7 +164647,7 @@ var init_claude_stream_adapter = __esm({
|
|
|
164609
164647
|
"use strict";
|
|
164610
164648
|
init_logger();
|
|
164611
164649
|
init_store();
|
|
164612
|
-
|
|
164650
|
+
init_envelope();
|
|
164613
164651
|
init_provider_attempt();
|
|
164614
164652
|
}
|
|
164615
164653
|
});
|
|
@@ -164725,15 +164763,10 @@ async function adaptOpenRouterStream(stream, options2) {
|
|
|
164725
164763
|
});
|
|
164726
164764
|
multiplexer.send(cardEvent);
|
|
164727
164765
|
}
|
|
164728
|
-
|
|
164766
|
+
const pause = detectPause(toolResult, id);
|
|
164767
|
+
if (pause) {
|
|
164729
164768
|
pauseDetected = true;
|
|
164730
|
-
if (onPauseDetected)
|
|
164731
|
-
await onPauseDetected({
|
|
164732
|
-
resumeToken: toolResult.__pause.resumeToken,
|
|
164733
|
-
questions: toolResult.__pause.questions,
|
|
164734
|
-
context: toolResult.__pause.context
|
|
164735
|
-
});
|
|
164736
|
-
}
|
|
164769
|
+
if (onPauseDetected) await onPauseDetected(pause);
|
|
164737
164770
|
return;
|
|
164738
164771
|
}
|
|
164739
164772
|
if (toolResult?.__parentToolCall === true) {
|
|
@@ -165310,7 +165343,7 @@ var init_openrouter_stream_adapter = __esm({
|
|
|
165310
165343
|
"use strict";
|
|
165311
165344
|
init_logger();
|
|
165312
165345
|
init_store();
|
|
165313
|
-
|
|
165346
|
+
init_envelope();
|
|
165314
165347
|
init_provider_attempt();
|
|
165315
165348
|
}
|
|
165316
165349
|
});
|
|
@@ -175114,7 +175147,7 @@ var require_gaxios = __commonJS({
|
|
|
175114
175147
|
var retry_js_1 = require_retry();
|
|
175115
175148
|
var stream_1 = __require("stream");
|
|
175116
175149
|
var interceptor_js_1 = require_interceptor();
|
|
175117
|
-
var
|
|
175150
|
+
var randomUUID16 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
175118
175151
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
175119
175152
|
var Gaxios = class {
|
|
175120
175153
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -175387,7 +175420,7 @@ var require_gaxios = __commonJS({
|
|
|
175387
175420
|
*/
|
|
175388
175421
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
175389
175422
|
if (opts.multipart?.length) {
|
|
175390
|
-
const boundary = await
|
|
175423
|
+
const boundary = await randomUUID16();
|
|
175391
175424
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
175392
175425
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
175393
175426
|
} else if (shouldDirectlyPassData) {
|
|
@@ -205823,15 +205856,10 @@ async function callGeminiDirect({
|
|
|
205823
205856
|
try {
|
|
205824
205857
|
if (abortSignal?.aborted) break;
|
|
205825
205858
|
let toolResult = await executeToolByName(toolName, toolArgs, { ...context3, toolCallId });
|
|
205826
|
-
|
|
205859
|
+
const pause = detectPause(toolResult, toolCallId);
|
|
205860
|
+
if (pause) {
|
|
205827
205861
|
pauseDetected = true;
|
|
205828
|
-
if (onPauseDetected)
|
|
205829
|
-
await onPauseDetected({
|
|
205830
|
-
resumeToken: toolResult.__pause.resumeToken,
|
|
205831
|
-
questions: toolResult.__pause.questions,
|
|
205832
|
-
context: toolResult.__pause.context
|
|
205833
|
-
});
|
|
205834
|
-
}
|
|
205862
|
+
if (onPauseDetected) await onPauseDetected(pause);
|
|
205835
205863
|
completedToolCalls.push({ id: toolCallId, name: toolName, arguments: toolArgs });
|
|
205836
205864
|
break;
|
|
205837
205865
|
}
|
|
@@ -205996,15 +206024,10 @@ async function callGeminiDirect({
|
|
|
205996
206024
|
try {
|
|
205997
206025
|
if (abortSignal?.aborted) break;
|
|
205998
206026
|
let toolResult = await executeToolByName(toolName, toolArgs, { ...context3, toolCallId });
|
|
205999
|
-
|
|
206027
|
+
const pause = detectPause(toolResult, toolCallId);
|
|
206028
|
+
if (pause) {
|
|
206000
206029
|
pauseDetected = true;
|
|
206001
|
-
if (onPauseDetected)
|
|
206002
|
-
await onPauseDetected({
|
|
206003
|
-
resumeToken: toolResult.__pause.resumeToken,
|
|
206004
|
-
questions: toolResult.__pause.questions,
|
|
206005
|
-
context: toolResult.__pause.context
|
|
206006
|
-
});
|
|
206007
|
-
}
|
|
206030
|
+
if (onPauseDetected) await onPauseDetected(pause);
|
|
206008
206031
|
completedToolCalls.push({ id: toolCallId, name: toolName, arguments: toolArgs });
|
|
206009
206032
|
break;
|
|
206010
206033
|
}
|
|
@@ -206261,7 +206284,7 @@ var init_gemini_direct_stream_adapter = __esm({
|
|
|
206261
206284
|
init_node2();
|
|
206262
206285
|
init_esm2();
|
|
206263
206286
|
init_store();
|
|
206264
|
-
|
|
206287
|
+
init_envelope();
|
|
206265
206288
|
init_provider_attempt();
|
|
206266
206289
|
}
|
|
206267
206290
|
});
|
|
@@ -207715,6 +207738,7 @@ var init_tool_categories = __esm({
|
|
|
207715
207738
|
"update-project",
|
|
207716
207739
|
"mcp_config_apply",
|
|
207717
207740
|
"mcp_config_request_secret",
|
|
207741
|
+
"mcp_server_request_approval",
|
|
207718
207742
|
"mcp_call_tool",
|
|
207719
207743
|
"mcp_server_create",
|
|
207720
207744
|
"mcp_server_update",
|
|
@@ -220244,6 +220268,7 @@ function buildMcpServerToolsPromptSection({
|
|
|
220244
220268
|
"- Prefer user-wide profile tools: `mcp_server_list`, `mcp_server_create`, `mcp_server_update`, `mcp_server_delete`, and `mcp_server_test`.",
|
|
220245
220269
|
"- Use legacy sandbox config tools `mcp_config_list`, `mcp_config_propose`, `mcp_config_test`, and `mcp_config_apply` only when the user explicitly asks for legacy per-sandbox MCP config.",
|
|
220246
220270
|
"- Never ask the user to reveal secret values. Use `vault_secret_list` to find full secret IDs, or exact Vault secret names when the create/update tool allows them.",
|
|
220271
|
+
"- A server that would receive Vault secrets stays inactive until the user approves it in the app. You cannot approve it: when a tool result says `approvalRequired`, share the `approvalUrl` and wait. Changing its URL, command, or secret bindings requires approval again.",
|
|
220247
220272
|
"- For npx/uvx API-key MCP servers, put command/header flags in `args` and bind secret values through `envSecretRefs`, not `headersSecretRefs`.",
|
|
220248
220273
|
'- Groundcover API-key setup uses `runner: "npx"`, `package: "mcp-remote"`, args including `https://mcp.groundcover.com/api/mcp`, `--header`, `Authorization:${GROUNDCOVER_API_KEY}`, and `envSecretRefs: { "GROUNDCOVER_API_KEY": "<secret-id-or-name>" }`.',
|
|
220249
220274
|
"- After command-based MCP config changes, use `sandbox_list` then `sandbox_restart` if a running execution environment needs a fresh start."
|
|
@@ -220522,6 +220547,43 @@ var init_store2 = __esm({
|
|
|
220522
220547
|
}
|
|
220523
220548
|
});
|
|
220524
220549
|
|
|
220550
|
+
// src/core/pause/mcp-approval.ts
|
|
220551
|
+
var mcp_approval_exports = {};
|
|
220552
|
+
__export2(mcp_approval_exports, {
|
|
220553
|
+
buildMcpApprovalPause: () => buildMcpApprovalPause,
|
|
220554
|
+
buildMcpApprovalPlaceholder: () => buildMcpApprovalPlaceholder,
|
|
220555
|
+
formatMcpApprovalDecision: () => formatMcpApprovalDecision
|
|
220556
|
+
});
|
|
220557
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
220558
|
+
function buildMcpApprovalPause(approval, action5) {
|
|
220559
|
+
return {
|
|
220560
|
+
__pause: {
|
|
220561
|
+
kind: MCP_APPROVAL_PAUSE_KIND,
|
|
220562
|
+
resumeToken: randomUUID5(),
|
|
220563
|
+
mcpApproval: approval,
|
|
220564
|
+
action: action5
|
|
220565
|
+
}
|
|
220566
|
+
};
|
|
220567
|
+
}
|
|
220568
|
+
function buildMcpApprovalPlaceholder(approval) {
|
|
220569
|
+
return `[Awaiting user approval for MCP server "${approval.name}" \u2014 approval card is open]`;
|
|
220570
|
+
}
|
|
220571
|
+
function formatMcpApprovalDecision(params) {
|
|
220572
|
+
const { approval, action: action5, decision } = params;
|
|
220573
|
+
const subject = `MCP server "${approval.name}" (id ${approval.profileId}, ${approval.target})`;
|
|
220574
|
+
const done = action5 === "requested" ? "" : ` It was ${action5}.`;
|
|
220575
|
+
if (decision === "approved") {
|
|
220576
|
+
return `User approved ${subject} to use its Vault secrets.${done} It is now active: test it with mcp_server_test before using its tools.`;
|
|
220577
|
+
}
|
|
220578
|
+
return `User rejected ${subject}; it stays disabled and receives no secrets.${done} Do not retry or re-create it unless the user asks.`;
|
|
220579
|
+
}
|
|
220580
|
+
var init_mcp_approval = __esm({
|
|
220581
|
+
"src/core/pause/mcp-approval.ts"() {
|
|
220582
|
+
"use strict";
|
|
220583
|
+
init_envelope();
|
|
220584
|
+
}
|
|
220585
|
+
});
|
|
220586
|
+
|
|
220525
220587
|
// src/lib/services/user.service.ts
|
|
220526
220588
|
var user_service_exports = {};
|
|
220527
220589
|
__export2(user_service_exports, {
|
|
@@ -223154,32 +223216,15 @@ var init_hook_definition = __esm({
|
|
|
223154
223216
|
}
|
|
223155
223217
|
});
|
|
223156
223218
|
|
|
223157
|
-
// src/lib/
|
|
223158
|
-
import { lookup } from "node:dns/promises";
|
|
223159
|
-
import { request as httpRequest } from "node:http";
|
|
223160
|
-
import { request as httpsRequest } from "node:https";
|
|
223219
|
+
// src/lib/net/guarded-fetch.ts
|
|
223161
223220
|
import { isIP as isIP2 } from "node:net";
|
|
223162
|
-
function boundedJson(value, maxBytes, code = "HOOK_RUNTIME_LIMIT") {
|
|
223163
|
-
const json3 = JSON.stringify(value ?? null);
|
|
223164
|
-
if (Buffer.byteLength(json3, "utf8") > maxBytes) throw new Error(code);
|
|
223165
|
-
return json3;
|
|
223166
|
-
}
|
|
223167
|
-
function usableOrigin() {
|
|
223168
|
-
try {
|
|
223169
|
-
return config2.mcp.url ? new URL(config2.mcp.url).origin : null;
|
|
223170
|
-
} catch {
|
|
223171
|
-
return null;
|
|
223172
|
-
}
|
|
223173
|
-
}
|
|
223174
|
-
function sanitizedUrl(url3) {
|
|
223175
|
-
return `${url3.origin}${url3.pathname}`;
|
|
223176
|
-
}
|
|
223177
223221
|
function normalizeIpLiteral(address) {
|
|
223178
223222
|
return address.toLowerCase().replace(/^\[|\]$/g, "");
|
|
223179
223223
|
}
|
|
223180
223224
|
function embeddedIpv4Address(address) {
|
|
223181
|
-
const
|
|
223182
|
-
if (!
|
|
223225
|
+
const prefix2 = ["::ffff:", "64:ff9b::", "::"].find((candidate) => address.startsWith(candidate));
|
|
223226
|
+
if (!prefix2) return null;
|
|
223227
|
+
const suffix = address.slice(prefix2.length);
|
|
223183
223228
|
if (isIP2(suffix) === 4) return suffix;
|
|
223184
223229
|
const match2 = /^([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(suffix);
|
|
223185
223230
|
if (!match2) return null;
|
|
@@ -223196,7 +223241,40 @@ function isForbiddenAddress(address) {
|
|
|
223196
223241
|
const [a22 = 0, b32 = 0] = normalized.split(".").map(Number);
|
|
223197
223242
|
return a22 === 0 || a22 === 10 || a22 === 127 || a22 === 100 && b32 >= 64 && b32 <= 127 || a22 === 169 && b32 === 254 || a22 === 172 && b32 >= 16 && b32 <= 31 || a22 === 192 && b32 === 0 || a22 === 192 && b32 === 168 || a22 === 198 && (b32 === 18 || b32 === 19) || a22 === 198 && b32 === 51 || a22 === 203 && b32 === 0 || a22 >= 224;
|
|
223198
223243
|
}
|
|
223199
|
-
return normalized.startsWith("fc") || normalized.startsWith("fd") ||
|
|
223244
|
+
return normalized.startsWith("fc") || normalized.startsWith("fd") || /^fe[89a-f]/.test(normalized) || normalized.startsWith("ff") || normalized.startsWith("2001:db8");
|
|
223245
|
+
}
|
|
223246
|
+
var MCP_FETCH_POLICY;
|
|
223247
|
+
var init_guarded_fetch = __esm({
|
|
223248
|
+
"src/lib/net/guarded-fetch.ts"() {
|
|
223249
|
+
"use strict";
|
|
223250
|
+
MCP_FETCH_POLICY = {
|
|
223251
|
+
allowHttp: true,
|
|
223252
|
+
maxResponseBytes: 5 * 1024 * 1024,
|
|
223253
|
+
timeoutMs: 3e4,
|
|
223254
|
+
maxRedirects: 5
|
|
223255
|
+
};
|
|
223256
|
+
}
|
|
223257
|
+
});
|
|
223258
|
+
|
|
223259
|
+
// src/lib/hooks/hook-runtime.ts
|
|
223260
|
+
import { lookup } from "node:dns/promises";
|
|
223261
|
+
import { request as httpRequest } from "node:http";
|
|
223262
|
+
import { request as httpsRequest } from "node:https";
|
|
223263
|
+
import { isIP as isIP3 } from "node:net";
|
|
223264
|
+
function boundedJson(value, maxBytes, code = "HOOK_RUNTIME_LIMIT") {
|
|
223265
|
+
const json3 = JSON.stringify(value ?? null);
|
|
223266
|
+
if (Buffer.byteLength(json3, "utf8") > maxBytes) throw new Error(code);
|
|
223267
|
+
return json3;
|
|
223268
|
+
}
|
|
223269
|
+
function usableOrigin() {
|
|
223270
|
+
try {
|
|
223271
|
+
return config2.mcp.url ? new URL(config2.mcp.url).origin : null;
|
|
223272
|
+
} catch {
|
|
223273
|
+
return null;
|
|
223274
|
+
}
|
|
223275
|
+
}
|
|
223276
|
+
function sanitizedUrl(url3) {
|
|
223277
|
+
return `${url3.origin}${url3.pathname}`;
|
|
223200
223278
|
}
|
|
223201
223279
|
async function validateDestination(url3) {
|
|
223202
223280
|
if (Buffer.byteLength(url3.toString()) > LIMITS.urlBytes || url3.username || url3.password) {
|
|
@@ -223213,8 +223291,8 @@ async function validateDestination(url3) {
|
|
|
223213
223291
|
if (url3.hostname === "localhost" || url3.hostname.endsWith(".local")) {
|
|
223214
223292
|
throw new Error("HOOK_FETCH_DESTINATION_BLOCKED");
|
|
223215
223293
|
}
|
|
223216
|
-
const hostname2 =
|
|
223217
|
-
const addresses =
|
|
223294
|
+
const hostname2 = url3.hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
223295
|
+
const addresses = isIP3(hostname2) ? [{ address: hostname2 }] : await lookup(hostname2, { all: true, verbatim: true });
|
|
223218
223296
|
if (addresses.length === 0 || addresses.some(({ address }) => isForbiddenAddress(address))) {
|
|
223219
223297
|
throw new Error("HOOK_FETCH_DESTINATION_BLOCKED");
|
|
223220
223298
|
}
|
|
@@ -223612,6 +223690,7 @@ var init_hook_runtime = __esm({
|
|
|
223612
223690
|
"use strict";
|
|
223613
223691
|
init_config();
|
|
223614
223692
|
init_dist15();
|
|
223693
|
+
init_guarded_fetch();
|
|
223615
223694
|
LIMITS = {
|
|
223616
223695
|
memoryBytes: 16 * 1024 * 1024,
|
|
223617
223696
|
stackBytes: 256 * 1024,
|
|
@@ -225376,12 +225455,12 @@ var init_hook_runtime_token = __esm({
|
|
|
225376
225455
|
});
|
|
225377
225456
|
|
|
225378
225457
|
// src/lib/hooks/hook-test-confirmation.ts
|
|
225379
|
-
import { randomUUID as
|
|
225458
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
225380
225459
|
async function issueHookTestConfirmation(userId, conversationId, turnId) {
|
|
225381
225460
|
if (!await isRedisAvailable()) return null;
|
|
225382
225461
|
const redis = getRedis();
|
|
225383
225462
|
if (!redis) return null;
|
|
225384
|
-
const token =
|
|
225463
|
+
const token = randomUUID6();
|
|
225385
225464
|
await redis.set(
|
|
225386
225465
|
`hook-test-confirmation:${token}`,
|
|
225387
225466
|
JSON.stringify({ userId, conversationId, turnId }),
|
|
@@ -230847,7 +230926,7 @@ var init_conversation_resource_authorization = __esm({
|
|
|
230847
230926
|
});
|
|
230848
230927
|
|
|
230849
230928
|
// src/lib/services/hook-definition.service.ts
|
|
230850
|
-
import { createHash as createHash10, randomUUID as
|
|
230929
|
+
import { createHash as createHash10, randomUUID as randomUUID7 } from "node:crypto";
|
|
230851
230930
|
function deterministicUuid(namespace, value) {
|
|
230852
230931
|
const bytes = Buffer.from(
|
|
230853
230932
|
createHash10("sha256").update(`${namespace}\0${value}`).digest().subarray(0, 16)
|
|
@@ -230858,8 +230937,8 @@ function deterministicUuid(namespace, value) {
|
|
|
230858
230937
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
230859
230938
|
}
|
|
230860
230939
|
async function createHookDefinition(pathway, userId, input, idempotencyKey) {
|
|
230861
|
-
const hookId = idempotencyKey ? deterministicUuid("usable-chat:hook-definition", `${userId}:${idempotencyKey}`) :
|
|
230862
|
-
const revisionId = idempotencyKey ? deterministicUuid("usable-chat:hook-revision", hookId) :
|
|
230940
|
+
const hookId = idempotencyKey ? deterministicUuid("usable-chat:hook-definition", `${userId}:${idempotencyKey}`) : randomUUID7();
|
|
230941
|
+
const revisionId = idempotencyKey ? deterministicUuid("usable-chat:hook-revision", hookId) : randomUUID7();
|
|
230863
230942
|
const existingHook = await getHookDefinition(userId, hookId);
|
|
230864
230943
|
if (existingHook) return existingHook;
|
|
230865
230944
|
const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -230873,7 +230952,7 @@ async function createHookDefinition(pathway, userId, input, idempotencyKey) {
|
|
|
230873
230952
|
const order = (existing.at(-1)?.order ?? -1) + 1;
|
|
230874
230953
|
await pathway.write("hook-definition.0/hook-definition.created.0", {
|
|
230875
230954
|
data: {
|
|
230876
|
-
id:
|
|
230955
|
+
id: randomUUID7(),
|
|
230877
230956
|
timestamp: timestamp2,
|
|
230878
230957
|
hookId,
|
|
230879
230958
|
revisionId,
|
|
@@ -230922,11 +231001,11 @@ async function reviseHookDefinition(pathway, userId, hookId, baseRevision, input
|
|
|
230922
231001
|
).orderBy(asc(hookDefinitions.order));
|
|
230923
231002
|
order = (rows.at(-1)?.order ?? -1) + 1;
|
|
230924
231003
|
}
|
|
230925
|
-
const revisionId =
|
|
231004
|
+
const revisionId = randomUUID7();
|
|
230926
231005
|
try {
|
|
230927
231006
|
await pathway.write("hook-definition.0/hook-definition.revised.0", {
|
|
230928
231007
|
data: {
|
|
230929
|
-
id:
|
|
231008
|
+
id: randomUUID7(),
|
|
230930
231009
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
230931
231010
|
hookId,
|
|
230932
231011
|
revisionId,
|
|
@@ -230954,7 +231033,7 @@ async function setHookActivation(pathway, userId, hookId, enabled2) {
|
|
|
230954
231033
|
if (!await getHookDefinition(userId, hookId)) return null;
|
|
230955
231034
|
await pathway.write("hook-definition.0/hook-definition.activation-changed.0", {
|
|
230956
231035
|
data: {
|
|
230957
|
-
id:
|
|
231036
|
+
id: randomUUID7(),
|
|
230958
231037
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
230959
231038
|
hookId,
|
|
230960
231039
|
userId,
|
|
@@ -230966,7 +231045,7 @@ async function setHookActivation(pathway, userId, hookId, enabled2) {
|
|
|
230966
231045
|
async function reorderHookDefinitions(pathway, userId, input) {
|
|
230967
231046
|
await pathway.write("hook-definition.0/hook-definition.reordered.0", {
|
|
230968
231047
|
data: {
|
|
230969
|
-
id:
|
|
231048
|
+
id: randomUUID7(),
|
|
230970
231049
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
230971
231050
|
userId,
|
|
230972
231051
|
...input
|
|
@@ -301777,7 +301856,7 @@ var init_httpHeaders = __esm({
|
|
|
301777
301856
|
});
|
|
301778
301857
|
|
|
301779
301858
|
// node_modules/.pnpm/@typespec+ts-http-runtime@0.3.4/node_modules/@typespec/ts-http-runtime/dist/esm/util/uuidUtils.js
|
|
301780
|
-
function
|
|
301859
|
+
function randomUUID8() {
|
|
301781
301860
|
return crypto.randomUUID();
|
|
301782
301861
|
}
|
|
301783
301862
|
var init_uuidUtils = __esm({
|
|
@@ -301831,7 +301910,7 @@ var init_pipelineRequest = __esm({
|
|
|
301831
301910
|
this.abortSignal = options2.abortSignal;
|
|
301832
301911
|
this.onUploadProgress = options2.onUploadProgress;
|
|
301833
301912
|
this.onDownloadProgress = options2.onDownloadProgress;
|
|
301834
|
-
this.requestId = options2.requestId ||
|
|
301913
|
+
this.requestId = options2.requestId || randomUUID8();
|
|
301835
301914
|
this.allowInsecureConnection = options2.allowInsecureConnection ?? false;
|
|
301836
301915
|
this.enableBrowserStreams = options2.enableBrowserStreams ?? false;
|
|
301837
301916
|
this.requestOverrides = options2.requestOverrides;
|
|
@@ -303535,7 +303614,7 @@ var init_concat = __esm({
|
|
|
303535
303614
|
|
|
303536
303615
|
// node_modules/.pnpm/@typespec+ts-http-runtime@0.3.4/node_modules/@typespec/ts-http-runtime/dist/esm/policies/multipartPolicy.js
|
|
303537
303616
|
function generateBoundary() {
|
|
303538
|
-
return `----AzSDKFormBoundary${
|
|
303617
|
+
return `----AzSDKFormBoundary${randomUUID8()}`;
|
|
303539
303618
|
}
|
|
303540
303619
|
function encodeHeaders(headers) {
|
|
303541
303620
|
let result = "";
|
|
@@ -304164,8 +304243,8 @@ var init_typeGuards2 = __esm({
|
|
|
304164
304243
|
function isError2(e15) {
|
|
304165
304244
|
return isError(e15);
|
|
304166
304245
|
}
|
|
304167
|
-
function
|
|
304168
|
-
return
|
|
304246
|
+
function randomUUID9() {
|
|
304247
|
+
return randomUUID8();
|
|
304169
304248
|
}
|
|
304170
304249
|
var isNodeLike2;
|
|
304171
304250
|
var init_esm40 = __esm({
|
|
@@ -333527,7 +333606,7 @@ var init_BlobLeaseClient = __esm({
|
|
|
333527
333606
|
this._containerOrBlobOperation = clientContext.blob;
|
|
333528
333607
|
}
|
|
333529
333608
|
if (!leaseId2) {
|
|
333530
|
-
leaseId2 =
|
|
333609
|
+
leaseId2 = randomUUID9();
|
|
333531
333610
|
}
|
|
333532
333611
|
this._leaseId = leaseId2;
|
|
333533
333612
|
}
|
|
@@ -337934,7 +338013,7 @@ var init_Clients = __esm({
|
|
|
337934
338013
|
throw new RangeError(`The buffer's size is too big or the BlockSize is too small;the number of blocks must be <= ${BLOCK_BLOB_MAX_BLOCKS}`);
|
|
337935
338014
|
}
|
|
337936
338015
|
const blockList = [];
|
|
337937
|
-
const blockIDPrefix =
|
|
338016
|
+
const blockIDPrefix = randomUUID9();
|
|
337938
338017
|
let transferProgress = 0;
|
|
337939
338018
|
const batch = new Batch(options2.concurrency);
|
|
337940
338019
|
for (let i19 = 0; i19 < numBlocks; i19++) {
|
|
@@ -338015,7 +338094,7 @@ var init_Clients = __esm({
|
|
|
338015
338094
|
}
|
|
338016
338095
|
return tracingClient.withSpan("BlockBlobClient-uploadStream", options2, async (updatedOptions) => {
|
|
338017
338096
|
let blockNum = 0;
|
|
338018
|
-
const blockIDPrefix =
|
|
338097
|
+
const blockIDPrefix = randomUUID9();
|
|
338019
338098
|
let transferProgress = 0;
|
|
338020
338099
|
const blockList = [];
|
|
338021
338100
|
const scheduler = new BufferScheduler(
|
|
@@ -339140,7 +339219,7 @@ var init_BlobBatch = __esm({
|
|
|
339140
339219
|
constructor() {
|
|
339141
339220
|
this.operationCount = 0;
|
|
339142
339221
|
this.body = "";
|
|
339143
|
-
const tempGuid =
|
|
339222
|
+
const tempGuid = randomUUID9();
|
|
339144
339223
|
this.boundary = `batch_${tempGuid}`;
|
|
339145
339224
|
this.subRequestPrefix = `--${this.boundary}${HTTP_LINE_ENDING}${HeaderConstants.CONTENT_TYPE}: application/http${HTTP_LINE_ENDING}${HeaderConstants.CONTENT_TRANSFER_ENCODING}: binary`;
|
|
339146
339225
|
this.multipartContentType = `multipart/mixed; boundary=${this.boundary}`;
|
|
@@ -359212,7 +359291,7 @@ __export2(auth_refresh_coordination_exports, {
|
|
|
359212
359291
|
compressAccessTokenRotation: () => compressAccessTokenRotation,
|
|
359213
359292
|
coordinateAccessTokenRefresh: () => coordinateAccessTokenRefresh
|
|
359214
359293
|
});
|
|
359215
|
-
import { createHash as createHash12, randomUUID as
|
|
359294
|
+
import { createHash as createHash12, randomUUID as randomUUID10 } from "node:crypto";
|
|
359216
359295
|
async function coordinateAccessTokenRefresh(token, refresh2) {
|
|
359217
359296
|
const redis = getRedis();
|
|
359218
359297
|
const secret = process.env.NEXTAUTH_SECRET;
|
|
@@ -359264,7 +359343,7 @@ async function coordinateAccessTokenRefresh(token, refresh2) {
|
|
|
359264
359343
|
}
|
|
359265
359344
|
throw new Error("refresh_rotation_chain_limit");
|
|
359266
359345
|
}
|
|
359267
|
-
const owner =
|
|
359346
|
+
const owner = randomUUID10();
|
|
359268
359347
|
if (!await redis.set(key2, owner, "EX", TTL, "NX")) {
|
|
359269
359348
|
for (let attempt = 0; attempt < 20; attempt++) {
|
|
359270
359349
|
await new Promise((resolve9) => setTimeout(resolve9, 250));
|
|
@@ -361655,7 +361734,7 @@ var init_host_jwt = __esm({
|
|
|
361655
361734
|
});
|
|
361656
361735
|
|
|
361657
361736
|
// src/lib/work-runtime/resume-proof.ts
|
|
361658
|
-
import { createHash as createHash14, createHmac as createHmac4, randomUUID as
|
|
361737
|
+
import { createHash as createHash14, createHmac as createHmac4, randomUUID as randomUUID11, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
361659
361738
|
function encoded(value) {
|
|
361660
361739
|
return Buffer.from(value).toString("base64url");
|
|
361661
361740
|
}
|
|
@@ -362500,7 +362579,7 @@ __export2(file_storage_service_exports, {
|
|
|
362500
362579
|
FileStorageService: () => FileStorageService,
|
|
362501
362580
|
fileStorageService: () => fileStorageService
|
|
362502
362581
|
});
|
|
362503
|
-
import { randomUUID as
|
|
362582
|
+
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
362504
362583
|
function estimateBase64Bytes2(base643) {
|
|
362505
362584
|
const content = base643.includes(",") ? base643.split(",")[1] : base643;
|
|
362506
362585
|
const len = content.length;
|
|
@@ -362583,7 +362662,7 @@ var init_file_storage_service = __esm({
|
|
|
362583
362662
|
mimeType: stored2.mimeType ?? params.mimeType
|
|
362584
362663
|
};
|
|
362585
362664
|
}
|
|
362586
|
-
const id =
|
|
362665
|
+
const id = randomUUID12();
|
|
362587
362666
|
const preview = params.previewBytes ?? params.bytes;
|
|
362588
362667
|
const llm = params.llmBytes ?? preview;
|
|
362589
362668
|
const estimatedTokens = Math.ceil(Math.ceil(llm.byteLength * 4 / 3) / 100);
|
|
@@ -362750,7 +362829,7 @@ var init_file_storage_service = __esm({
|
|
|
362750
362829
|
* For documents: keeps extractedContent as text and optional originalContent as base64 bytes.
|
|
362751
362830
|
*/
|
|
362752
362831
|
async storeFile(params) {
|
|
362753
|
-
const fileId =
|
|
362832
|
+
const fileId = randomUUID12();
|
|
362754
362833
|
let extractedContent = params.extractedContent;
|
|
362755
362834
|
let originalContent = params.originalContent ?? null;
|
|
362756
362835
|
if (params.fileType === "image" && params.contentType === "base64") {
|
|
@@ -363039,7 +363118,7 @@ var init_file_storage_service = __esm({
|
|
|
363039
363118
|
paths = await storage.uploadVariants({
|
|
363040
363119
|
fileId,
|
|
363041
363120
|
userId,
|
|
363042
|
-
namespace: `migration-${
|
|
363121
|
+
namespace: `migration-${randomUUID12()}`,
|
|
363043
363122
|
variants: {
|
|
363044
363123
|
original: { bytes: original2, mimeType },
|
|
363045
363124
|
preview: { bytes: preview, mimeType: "image/webp" },
|
|
@@ -363304,7 +363383,7 @@ var init_file_storage_service = __esm({
|
|
|
363304
363383
|
});
|
|
363305
363384
|
|
|
363306
363385
|
// src/core/orchestrator/index.ts
|
|
363307
|
-
import { createHash as createHash17, randomUUID as
|
|
363386
|
+
import { createHash as createHash17, randomUUID as randomUUID13 } from "node:crypto";
|
|
363308
363387
|
function shouldRecoverSilentStop({
|
|
363309
363388
|
text: text5,
|
|
363310
363389
|
lastStepHadToolErrors,
|
|
@@ -363859,21 +363938,24 @@ function createPauseCallback({
|
|
|
363859
363938
|
pauseSignaled
|
|
363860
363939
|
}) {
|
|
363861
363940
|
return async (data2) => {
|
|
363862
|
-
orchestrationLogger.info(
|
|
363863
|
-
|
|
363864
|
-
|
|
363865
|
-
|
|
363941
|
+
orchestrationLogger.info(
|
|
363942
|
+
data2.kind === "mcp-approval" ? "Pause detected \u2014 MCP approval (deferred persist)" : "Pause detected \u2014 askUserQuestion (deferred persist)",
|
|
363943
|
+
{
|
|
363944
|
+
resumeToken: data2.resumeToken,
|
|
363945
|
+
...data2.kind === "mcp-approval" ? { profileId: data2.mcpApproval.profileId } : { questionCount: data2.questions.length }
|
|
363946
|
+
}
|
|
363947
|
+
);
|
|
363866
363948
|
pendingPauseRef.current = { data: data2 };
|
|
363867
363949
|
pauseSignaled.current = true;
|
|
363868
363950
|
};
|
|
363869
363951
|
}
|
|
363870
|
-
function replacePauseToolResultPlaceholder(messages4, toolUseId) {
|
|
363952
|
+
function replacePauseToolResultPlaceholder(messages4, toolUseId, placeholder2 = ASK_QUESTION_PLACEHOLDER) {
|
|
363871
363953
|
for (const msg of messages4) {
|
|
363872
363954
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
363873
363955
|
const parts = msg.content;
|
|
363874
363956
|
for (const part of parts) {
|
|
363875
363957
|
if (part.type === "tool_result" && part.tool_use_id === toolUseId) {
|
|
363876
|
-
part.content =
|
|
363958
|
+
part.content = placeholder2;
|
|
363877
363959
|
return true;
|
|
363878
363960
|
}
|
|
363879
363961
|
}
|
|
@@ -363881,7 +363963,7 @@ function replacePauseToolResultPlaceholder(messages4, toolUseId) {
|
|
|
363881
363963
|
const oaiMsg = msg;
|
|
363882
363964
|
if (oaiMsg.role === "tool" && oaiMsg.tool_call_id === toolUseId) {
|
|
363883
363965
|
;
|
|
363884
|
-
msg.content =
|
|
363966
|
+
msg.content = placeholder2;
|
|
363885
363967
|
return true;
|
|
363886
363968
|
}
|
|
363887
363969
|
}
|
|
@@ -363903,6 +363985,22 @@ async function drainPendingPause({
|
|
|
363903
363985
|
resolveStreamComplete
|
|
363904
363986
|
}) {
|
|
363905
363987
|
const { data: data2 } = pending;
|
|
363988
|
+
if (data2.kind === "mcp-approval") {
|
|
363989
|
+
return drainMcpApprovalPause({
|
|
363990
|
+
data: data2,
|
|
363991
|
+
toolCalls,
|
|
363992
|
+
emitter,
|
|
363993
|
+
multiplexer,
|
|
363994
|
+
context: context3,
|
|
363995
|
+
messageId,
|
|
363996
|
+
correlationId,
|
|
363997
|
+
conversationMessages,
|
|
363998
|
+
persona,
|
|
363999
|
+
config: config3,
|
|
364000
|
+
embedSnapshot,
|
|
364001
|
+
resolveStreamComplete
|
|
364002
|
+
});
|
|
364003
|
+
}
|
|
363906
364004
|
const askToolCall = toolCalls.find((tc) => tc.name === "ask-user-question");
|
|
363907
364005
|
const pausedToolUseId = askToolCall?.id;
|
|
363908
364006
|
if (pausedToolUseId) {
|
|
@@ -363943,7 +364041,7 @@ async function drainPendingPause({
|
|
|
363943
364041
|
if (durable && conversationId && pausedToolUseId) {
|
|
363944
364042
|
await context3.sessionPathway.write("chat-interaction.0/chat-interaction.updated.0", {
|
|
363945
364043
|
data: {
|
|
363946
|
-
id:
|
|
364044
|
+
id: randomUUID13(),
|
|
363947
364045
|
interactionId: data2.resumeToken,
|
|
363948
364046
|
conversationId,
|
|
363949
364047
|
assistantMessageId: messageId,
|
|
@@ -364027,6 +364125,81 @@ async function drainPendingPause({
|
|
|
364027
364125
|
multiplexer.close();
|
|
364028
364126
|
resolveStreamComplete();
|
|
364029
364127
|
}
|
|
364128
|
+
async function drainMcpApprovalPause({
|
|
364129
|
+
data: data2,
|
|
364130
|
+
toolCalls,
|
|
364131
|
+
emitter,
|
|
364132
|
+
multiplexer,
|
|
364133
|
+
context: context3,
|
|
364134
|
+
messageId,
|
|
364135
|
+
correlationId,
|
|
364136
|
+
conversationMessages,
|
|
364137
|
+
persona,
|
|
364138
|
+
config: config3,
|
|
364139
|
+
embedSnapshot,
|
|
364140
|
+
resolveStreamComplete
|
|
364141
|
+
}) {
|
|
364142
|
+
const { buildMcpApprovalPlaceholder: buildMcpApprovalPlaceholder2 } = await Promise.resolve().then(() => (init_mcp_approval(), mcp_approval_exports));
|
|
364143
|
+
const pausedToolUseId = toolCalls.find((tc) => tc.id === data2.toolCallId)?.id ?? [...toolCalls].reverse().find((tc) => tc.name.startsWith("mcp_server_"))?.id;
|
|
364144
|
+
if (pausedToolUseId) {
|
|
364145
|
+
replacePauseToolResultPlaceholder(
|
|
364146
|
+
conversationMessages,
|
|
364147
|
+
pausedToolUseId,
|
|
364148
|
+
buildMcpApprovalPlaceholder2(data2.mcpApproval)
|
|
364149
|
+
);
|
|
364150
|
+
} else {
|
|
364151
|
+
orchestrationLogger.warn("MCP approval pause signaled but its tool_call was not found");
|
|
364152
|
+
}
|
|
364153
|
+
const snapshot2 = ensureToolCallIntegrity([...conversationMessages]);
|
|
364154
|
+
const lastSequence = emitter.getSequence();
|
|
364155
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
364156
|
+
try {
|
|
364157
|
+
const { storePauseState: storePauseState2 } = await Promise.resolve().then(() => (init_store2(), store_exports));
|
|
364158
|
+
await storePauseState2({
|
|
364159
|
+
kind: "mcp-approval",
|
|
364160
|
+
mcpApproval: data2.mcpApproval,
|
|
364161
|
+
mcpAction: data2.action,
|
|
364162
|
+
resumeToken: data2.resumeToken,
|
|
364163
|
+
userId: context3.session?.user?.id || "",
|
|
364164
|
+
conversationId: context3.metadata?.conversationId,
|
|
364165
|
+
messageId,
|
|
364166
|
+
correlationId,
|
|
364167
|
+
lastSequence,
|
|
364168
|
+
conversationMessages: snapshot2,
|
|
364169
|
+
pausedToolUseId,
|
|
364170
|
+
persona,
|
|
364171
|
+
config: config3,
|
|
364172
|
+
questions: [],
|
|
364173
|
+
temporary: context3.metadata?.temporary === true,
|
|
364174
|
+
embedSnapshot,
|
|
364175
|
+
pausedAt: now2.toISOString(),
|
|
364176
|
+
expiresAt: new Date(now2.getTime() + 60 * 60 * 1e3).toISOString()
|
|
364177
|
+
});
|
|
364178
|
+
} catch (error41) {
|
|
364179
|
+
orchestrationLogger.warn("MCP approval pause cache unavailable; approval still works", {
|
|
364180
|
+
resumeToken: data2.resumeToken,
|
|
364181
|
+
error: error41 instanceof Error ? error41.message : String(error41)
|
|
364182
|
+
});
|
|
364183
|
+
}
|
|
364184
|
+
const approvalEvent = emitter.emit(
|
|
364185
|
+
"mcp-approval-request",
|
|
364186
|
+
{
|
|
364187
|
+
interactionId: data2.resumeToken,
|
|
364188
|
+
resumeToken: data2.resumeToken,
|
|
364189
|
+
approval: data2.mcpApproval,
|
|
364190
|
+
action: data2.action
|
|
364191
|
+
}
|
|
364192
|
+
);
|
|
364193
|
+
multiplexer.send(approvalEvent);
|
|
364194
|
+
orchestrationLogger.info("MCP approval requested, closing stream", {
|
|
364195
|
+
resumeToken: data2.resumeToken,
|
|
364196
|
+
profileId: data2.mcpApproval.profileId,
|
|
364197
|
+
pausedToolUseId,
|
|
364198
|
+
lastSequence
|
|
364199
|
+
});
|
|
364200
|
+
multiplexer.close();
|
|
364201
|
+
resolveStreamComplete();
|
|
364202
|
+
}
|
|
364030
364203
|
function safeProviderErrorCategory(value) {
|
|
364031
364204
|
return typeof value === "string" && providerErrorCategories.has(value) ? value : void 0;
|
|
364032
364205
|
}
|
|
@@ -364038,7 +364211,7 @@ function beginNumberedProviderAttempt(budget, route) {
|
|
|
364038
364211
|
const attempt = budget.begin(route);
|
|
364039
364212
|
const number4 = (providerAttemptNumbers.get(budget) ?? 0) + 1;
|
|
364040
364213
|
providerAttemptNumbers.set(budget, number4);
|
|
364041
|
-
return { attempt, id:
|
|
364214
|
+
return { attempt, id: randomUUID13(), number: number4, startedAt: Date.now() };
|
|
364042
364215
|
}
|
|
364043
364216
|
function hasProviderAttemptCapacity(budget) {
|
|
364044
364217
|
return (providerAttemptNumbers.get(budget) ?? 0) < budget.maxAttempts;
|
|
@@ -364137,7 +364310,7 @@ async function callLLM({
|
|
|
364137
364310
|
}
|
|
364138
364311
|
const effectiveZdr2 = openRouterPolicy.effectiveZdr;
|
|
364139
364312
|
const resolveDirectPolicy = (route) => resolveProviderPolicy({ modelId: selectedModelId, route, ...providerPrivacy });
|
|
364140
|
-
const safeCorrelationId = safeProviderIdentifier(context3.correlationId) ?? safeProviderIdentifier(context3.messageId) ??
|
|
364313
|
+
const safeCorrelationId = safeProviderIdentifier(context3.correlationId) ?? safeProviderIdentifier(context3.messageId) ?? randomUUID13();
|
|
364141
364314
|
const safeModel = getModelById(selectedModelId) || getModelEntry(selectedModelId) ? selectedModelId : void 0;
|
|
364142
364315
|
const endpointIdentity = (endpoint) => createHash17("sha256").update(endpoint).digest("hex").slice(0, 16);
|
|
364143
364316
|
const circuitPolicy = (endpoint) => `zdr:${effectiveZdr2 ? "required" : "disabled"}:endpoint:${endpointIdentity(endpoint)}`;
|
|
@@ -366302,7 +366475,7 @@ Folder behavior:
|
|
|
366302
366475
|
}
|
|
366303
366476
|
};
|
|
366304
366477
|
}
|
|
366305
|
-
const planMessage = config3.enableTools ? "\u{1F527} Engaging model with tools..." : "\u{1F4AC} Responding with selected model...";
|
|
366478
|
+
const planMessage = config3.autoModelNotice ?? (config3.enableTools ? "\u{1F527} Engaging model with tools..." : "\u{1F4AC} Responding with selected model...");
|
|
366306
366479
|
const planEvent = emitter.emit("plan", {
|
|
366307
366480
|
plan: planMessage,
|
|
366308
366481
|
steps: config3.maxSteps
|
|
@@ -368468,7 +368641,7 @@ Continue once without hiding or replacing your prior response.`
|
|
|
368468
368641
|
};
|
|
368469
368642
|
}
|
|
368470
368643
|
function createOrchestratorRequest(messages4, context3, config3, persona, apiKey, mcpTools, anthropicApiKey, providerBaseUrl, providerAuthToken, codexAuth) {
|
|
368471
|
-
const messageId = context3.messageId ||
|
|
368644
|
+
const messageId = context3.messageId || randomUUID13();
|
|
368472
368645
|
if (!context3.sessionPathway) {
|
|
368473
368646
|
throw new Error(
|
|
368474
368647
|
"sessionPathway is required but not provided. Ensure createSessionPathwaysForAPI() is called in the API route and sessionPathway is passed to createOrchestratorRequest."
|
|
@@ -370366,7 +370539,7 @@ var init_skills3 = __esm({
|
|
|
370366
370539
|
// src/adapters/cli/subagent.ts
|
|
370367
370540
|
import { spawn as spawn5 } from "node:child_process";
|
|
370368
370541
|
import { basename as basename8 } from "node:path";
|
|
370369
|
-
import { randomUUID as
|
|
370542
|
+
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
370370
370543
|
function currentSubagentDepth() {
|
|
370371
370544
|
const d21 = Number(process.env.USABLE_SUBAGENT_DEPTH ?? 0);
|
|
370372
370545
|
return Number.isFinite(d21) && d21 > 0 ? Math.floor(d21) : 0;
|
|
@@ -370465,7 +370638,7 @@ function publicTask(task) {
|
|
|
370465
370638
|
};
|
|
370466
370639
|
}
|
|
370467
370640
|
function startCliSubagentTask(input) {
|
|
370468
|
-
const taskId = input.taskId ??
|
|
370641
|
+
const taskId = input.taskId ?? randomUUID14();
|
|
370469
370642
|
const abortController = new AbortController();
|
|
370470
370643
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
370471
370644
|
const run2 = input._run ?? runCliSubagent;
|
|
@@ -385940,7 +386113,7 @@ var init_todo_checklist = __esm({
|
|
|
385940
386113
|
// src/cli/warp-agent.ts
|
|
385941
386114
|
import { openSync, writeSync } from "node:fs";
|
|
385942
386115
|
import { basename as basename9 } from "node:path";
|
|
385943
|
-
import { randomUUID as
|
|
386116
|
+
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
385944
386117
|
function isWarpAgentHost() {
|
|
385945
386118
|
return !!process.env.WARP_CLI_AGENT_PROTOCOL_VERSION && process.platform !== "win32";
|
|
385946
386119
|
}
|
|
@@ -385993,7 +386166,7 @@ var init_warp_agent = __esm({
|
|
|
385993
386166
|
"use strict";
|
|
385994
386167
|
WARP_AGENT_SLUG = "usable-chat";
|
|
385995
386168
|
APP_NAME = "usable-chat";
|
|
385996
|
-
sessionId =
|
|
386169
|
+
sessionId = randomUUID15();
|
|
385997
386170
|
}
|
|
385998
386171
|
});
|
|
385999
386172
|
|
|
@@ -391935,7 +392108,7 @@ init_tui_select();
|
|
|
391935
392108
|
init_model_registry();
|
|
391936
392109
|
|
|
391937
392110
|
// package.json
|
|
391938
|
-
var version2 = "1.
|
|
392111
|
+
var version2 = "1.211.0";
|
|
391939
392112
|
|
|
391940
392113
|
// src/adapters/cli/model-catalog.ts
|
|
391941
392114
|
init_codex_auth();
|