@runtypelabs/sdk 4.1.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +130 -86
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.mjs +130 -86
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1274,6 +1274,39 @@ function createExternalTool(config) {
|
|
|
1274
1274
|
};
|
|
1275
1275
|
}
|
|
1276
1276
|
|
|
1277
|
+
// src/local-tool-pause.ts
|
|
1278
|
+
var PENDING_NAMELESS_KEY = "";
|
|
1279
|
+
function collectLocalToolAwait(pausedTools, event) {
|
|
1280
|
+
if (event.type !== "flow_await" && event.type !== "step_await") return;
|
|
1281
|
+
const name = typeof event.toolName === "string" && event.toolName ? event.toolName : "";
|
|
1282
|
+
const executionId = typeof event.executionId === "string" && event.executionId ? event.executionId : void 0;
|
|
1283
|
+
if (name) {
|
|
1284
|
+
const pending = pausedTools.get(PENDING_NAMELESS_KEY);
|
|
1285
|
+
if (pending) pausedTools.delete(PENDING_NAMELESS_KEY);
|
|
1286
|
+
const prev2 = pausedTools.get(name) ?? pending;
|
|
1287
|
+
pausedTools.set(name, {
|
|
1288
|
+
toolName: name,
|
|
1289
|
+
executionId: executionId ?? prev2?.executionId ?? "",
|
|
1290
|
+
parameters: event.parameters ?? prev2?.parameters
|
|
1291
|
+
});
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
const namedKeys = [...pausedTools.keys()].filter((key) => key !== PENDING_NAMELESS_KEY);
|
|
1295
|
+
const targetKey = namedKeys.length > 0 ? namedKeys[namedKeys.length - 1] : PENDING_NAMELESS_KEY;
|
|
1296
|
+
const prev = pausedTools.get(targetKey);
|
|
1297
|
+
pausedTools.set(targetKey, {
|
|
1298
|
+
toolName: targetKey,
|
|
1299
|
+
executionId: executionId ?? prev?.executionId ?? "",
|
|
1300
|
+
parameters: event.parameters ?? prev?.parameters
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
function resolveBatchExecutionId(pausedTools) {
|
|
1304
|
+
for (const tool of pausedTools) {
|
|
1305
|
+
if (tool.executionId) return tool.executionId;
|
|
1306
|
+
}
|
|
1307
|
+
return "";
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1277
1310
|
// src/flows-namespace.ts
|
|
1278
1311
|
function isRecord(value) {
|
|
1279
1312
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -1821,7 +1854,7 @@ var RuntypeFlowBuilder = class {
|
|
|
1821
1854
|
};
|
|
1822
1855
|
const processStep = async (response) => {
|
|
1823
1856
|
if (isStreaming) {
|
|
1824
|
-
|
|
1857
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
1825
1858
|
const wrappedCallbacks = {
|
|
1826
1859
|
...callbacks,
|
|
1827
1860
|
onFlowStart: (event) => callbacks?.onFlowStart?.(event),
|
|
@@ -1834,23 +1867,7 @@ var RuntypeFlowBuilder = class {
|
|
|
1834
1867
|
const { streamEvents: streamEvents2, stepDeltaText: stepDeltaText2, stepDisplayName: stepDisplayName2, flowErrorMessage: flowErrorMessage2 } = await Promise.resolve().then(() => (init_stream_utils(), stream_utils_exports));
|
|
1835
1868
|
try {
|
|
1836
1869
|
for await (const event of streamEvents2(response)) {
|
|
1837
|
-
|
|
1838
|
-
if (awaitEvent.type === "flow_await") {
|
|
1839
|
-
const prev = pausedState;
|
|
1840
|
-
pausedState = {
|
|
1841
|
-
toolName: awaitEvent.toolName || prev?.toolName || "",
|
|
1842
|
-
parameters: awaitEvent.parameters ?? prev?.parameters,
|
|
1843
|
-
executionId: awaitEvent.executionId || prev?.executionId || ""
|
|
1844
|
-
};
|
|
1845
|
-
}
|
|
1846
|
-
if (awaitEvent.type === "step_await") {
|
|
1847
|
-
const prev = pausedState;
|
|
1848
|
-
pausedState = {
|
|
1849
|
-
toolName: awaitEvent.toolName || prev?.toolName || "",
|
|
1850
|
-
parameters: awaitEvent.parameters ?? prev?.parameters,
|
|
1851
|
-
executionId: awaitEvent.executionId || prev?.executionId || ""
|
|
1852
|
-
};
|
|
1853
|
-
}
|
|
1870
|
+
collectLocalToolAwait(pausedTools, event);
|
|
1854
1871
|
switch (event.type) {
|
|
1855
1872
|
case "flow_start":
|
|
1856
1873
|
wrappedCallbacks.onFlowStart?.(event);
|
|
@@ -1878,19 +1895,34 @@ var RuntypeFlowBuilder = class {
|
|
|
1878
1895
|
wrappedCallbacks.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
1879
1896
|
throw e;
|
|
1880
1897
|
}
|
|
1881
|
-
if (
|
|
1898
|
+
if (pausedTools.size > 0) {
|
|
1882
1899
|
return {
|
|
1883
1900
|
done: false,
|
|
1884
|
-
result: { status: "paused",
|
|
1901
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
1885
1902
|
};
|
|
1886
1903
|
}
|
|
1887
1904
|
return { done: true, result: accumulatedSummary };
|
|
1888
1905
|
} else {
|
|
1889
1906
|
const data = await response.json();
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1907
|
+
if (data.status === "paused") {
|
|
1908
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
1909
|
+
if (Array.isArray(data.events)) {
|
|
1910
|
+
for (const event of data.events) {
|
|
1911
|
+
collectLocalToolAwait(pausedTools, event);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
if (pausedTools.size === 0 && typeof data.pausedReason === "object" && data.pausedReason !== null && data.pausedReason.type === "local_action") {
|
|
1915
|
+
collectLocalToolAwait(pausedTools, {
|
|
1916
|
+
...data.pausedReason,
|
|
1917
|
+
type: "flow_await"
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
return {
|
|
1921
|
+
done: false,
|
|
1922
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
return { done: true, result: data };
|
|
1894
1926
|
}
|
|
1895
1927
|
};
|
|
1896
1928
|
let currentResponse;
|
|
@@ -1916,16 +1948,28 @@ var RuntypeFlowBuilder = class {
|
|
|
1916
1948
|
);
|
|
1917
1949
|
}
|
|
1918
1950
|
const pausedResult = result;
|
|
1919
|
-
if (pausedResult.status === "paused" && pausedResult.
|
|
1920
|
-
const
|
|
1921
|
-
if (!localTools[toolName]) {
|
|
1922
|
-
throw new Error(`Local tool "${toolName}" required but not provided in localTools map`);
|
|
1923
|
-
}
|
|
1951
|
+
if (pausedResult.status === "paused" && pausedResult.pausedTools?.length) {
|
|
1952
|
+
const executionId = resolveBatchExecutionId(pausedResult.pausedTools);
|
|
1924
1953
|
try {
|
|
1925
|
-
const
|
|
1954
|
+
const outputs = await Promise.all(
|
|
1955
|
+
pausedResult.pausedTools.map(async ({ toolName, parameters }) => {
|
|
1956
|
+
if (!localTools[toolName]) {
|
|
1957
|
+
throw new Error(
|
|
1958
|
+
`Local tool "${toolName}" required but not provided in localTools map`
|
|
1959
|
+
);
|
|
1960
|
+
}
|
|
1961
|
+
try {
|
|
1962
|
+
return [toolName, await localTools[toolName](parameters)];
|
|
1963
|
+
} catch (error) {
|
|
1964
|
+
throw new Error(
|
|
1965
|
+
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
1966
|
+
);
|
|
1967
|
+
}
|
|
1968
|
+
})
|
|
1969
|
+
);
|
|
1926
1970
|
const resumeData = {
|
|
1927
1971
|
executionId,
|
|
1928
|
-
toolOutputs:
|
|
1972
|
+
toolOutputs: Object.fromEntries(outputs),
|
|
1929
1973
|
streamResponse: isStreaming
|
|
1930
1974
|
};
|
|
1931
1975
|
if (isStreaming) {
|
|
@@ -1940,9 +1984,7 @@ var RuntypeFlowBuilder = class {
|
|
|
1940
1984
|
});
|
|
1941
1985
|
}
|
|
1942
1986
|
} catch (error) {
|
|
1943
|
-
throw new Error(
|
|
1944
|
-
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
1945
|
-
);
|
|
1987
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
1946
1988
|
}
|
|
1947
1989
|
} else {
|
|
1948
1990
|
break;
|
|
@@ -8515,11 +8557,7 @@ function hasToolEntryShape(value) {
|
|
|
8515
8557
|
return typeof value.execute === "function" && typeof value.description === "string" && typeof value.parametersSchema === "object" && value.parametersSchema !== null;
|
|
8516
8558
|
}
|
|
8517
8559
|
function isPausedLocalActionResult(value) {
|
|
8518
|
-
|
|
8519
|
-
return false;
|
|
8520
|
-
}
|
|
8521
|
-
const { pausedReason } = value;
|
|
8522
|
-
return pausedReason === void 0 || isObjectRecord(pausedReason) && pausedReason.type === "local_action" && typeof pausedReason.toolName === "string" && typeof pausedReason.executionId === "string";
|
|
8560
|
+
return isObjectRecord(value) && value.status === "paused" && Array.isArray(value.pausedTools) && value.pausedTools.length > 0;
|
|
8523
8561
|
}
|
|
8524
8562
|
var RuntypeClient2 = class {
|
|
8525
8563
|
constructor(config = {}) {
|
|
@@ -8621,7 +8659,7 @@ var RuntypeClient2 = class {
|
|
|
8621
8659
|
};
|
|
8622
8660
|
const processStep = async (response) => {
|
|
8623
8661
|
if (isStreaming) {
|
|
8624
|
-
|
|
8662
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
8625
8663
|
const wrappedCallbacks = {
|
|
8626
8664
|
...callbacks,
|
|
8627
8665
|
onFlowStart: (event) => callbacks?.onFlowStart?.(event),
|
|
@@ -8638,26 +8676,7 @@ var RuntypeClient2 = class {
|
|
|
8638
8676
|
};
|
|
8639
8677
|
try {
|
|
8640
8678
|
for await (const event of streamEvents2(response)) {
|
|
8641
|
-
|
|
8642
|
-
const pausedEvent = event;
|
|
8643
|
-
const prev = pausedState;
|
|
8644
|
-
const next = {
|
|
8645
|
-
toolName: pausedEvent.toolName ?? prev?.toolName ?? "",
|
|
8646
|
-
executionId: pausedEvent.executionId ?? prev?.executionId ?? "",
|
|
8647
|
-
parameters: prev?.parameters
|
|
8648
|
-
};
|
|
8649
|
-
pausedState = next;
|
|
8650
|
-
}
|
|
8651
|
-
if (event.type === "step_await") {
|
|
8652
|
-
const pausedEvent = event;
|
|
8653
|
-
const prev = pausedState;
|
|
8654
|
-
const next = {
|
|
8655
|
-
toolName: typeof pausedEvent.toolName === "string" ? pausedEvent.toolName : prev?.toolName ?? "",
|
|
8656
|
-
parameters: pausedEvent.parameters,
|
|
8657
|
-
executionId: typeof pausedEvent.executionId === "string" ? pausedEvent.executionId : prev?.executionId ?? ""
|
|
8658
|
-
};
|
|
8659
|
-
pausedState = next;
|
|
8660
|
-
}
|
|
8679
|
+
collectLocalToolAwait(pausedTools, event);
|
|
8661
8680
|
switch (event.type) {
|
|
8662
8681
|
case "flow_start":
|
|
8663
8682
|
wrappedCallbacks.onFlowStart?.(event);
|
|
@@ -8685,19 +8704,34 @@ var RuntypeClient2 = class {
|
|
|
8685
8704
|
wrappedCallbacks.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
8686
8705
|
throw e;
|
|
8687
8706
|
}
|
|
8688
|
-
if (
|
|
8707
|
+
if (pausedTools.size > 0) {
|
|
8689
8708
|
return {
|
|
8690
8709
|
done: false,
|
|
8691
|
-
result: { status: "paused",
|
|
8710
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
8692
8711
|
};
|
|
8693
8712
|
}
|
|
8694
8713
|
return { done: true, result: summary };
|
|
8695
8714
|
} else {
|
|
8696
8715
|
const data = await response.json();
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8716
|
+
if (data.status === "paused") {
|
|
8717
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
8718
|
+
if (Array.isArray(data.events)) {
|
|
8719
|
+
for (const event of data.events) {
|
|
8720
|
+
collectLocalToolAwait(pausedTools, event);
|
|
8721
|
+
}
|
|
8722
|
+
}
|
|
8723
|
+
if (pausedTools.size === 0 && isObjectRecord(data.pausedReason) && data.pausedReason.type === "local_action") {
|
|
8724
|
+
collectLocalToolAwait(pausedTools, {
|
|
8725
|
+
...data.pausedReason,
|
|
8726
|
+
type: "flow_await"
|
|
8727
|
+
});
|
|
8728
|
+
}
|
|
8729
|
+
return {
|
|
8730
|
+
done: false,
|
|
8731
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
8732
|
+
};
|
|
8733
|
+
}
|
|
8734
|
+
return { done: true, result: data };
|
|
8701
8735
|
}
|
|
8702
8736
|
};
|
|
8703
8737
|
let currentResponse;
|
|
@@ -8717,26 +8751,38 @@ var RuntypeClient2 = class {
|
|
|
8717
8751
|
new Response(JSON.stringify(result), { headers: { "content-type": "application/json" } })
|
|
8718
8752
|
);
|
|
8719
8753
|
}
|
|
8720
|
-
if (isPausedLocalActionResult(result)
|
|
8721
|
-
const
|
|
8722
|
-
const BARE_NAME_NAMESPACES = ["webmcp:"];
|
|
8723
|
-
const lookupCandidates = [toolName];
|
|
8724
|
-
for (const ns of BARE_NAME_NAMESPACES) {
|
|
8725
|
-
if (toolName.startsWith(ns)) {
|
|
8726
|
-
lookupCandidates.push(toolName.slice(ns.length));
|
|
8727
|
-
}
|
|
8728
|
-
}
|
|
8729
|
-
const matchedKey = lookupCandidates.find((key) => localTools[key]);
|
|
8730
|
-
const toolEntry = matchedKey ? localTools[matchedKey] : void 0;
|
|
8731
|
-
if (!toolEntry) {
|
|
8732
|
-
throw new Error(`Local tool "${toolName}" required but not provided in localTools map`);
|
|
8733
|
-
}
|
|
8734
|
-
const handler = hasToolEntryShape(toolEntry) ? toolEntry.execute : toolEntry;
|
|
8754
|
+
if (isPausedLocalActionResult(result)) {
|
|
8755
|
+
const executionId = resolveBatchExecutionId(result.pausedTools);
|
|
8735
8756
|
try {
|
|
8736
|
-
const
|
|
8757
|
+
const outputs = await Promise.all(
|
|
8758
|
+
result.pausedTools.map(async ({ toolName, parameters }) => {
|
|
8759
|
+
const BARE_NAME_NAMESPACES = ["webmcp:"];
|
|
8760
|
+
const lookupCandidates = [toolName];
|
|
8761
|
+
for (const ns of BARE_NAME_NAMESPACES) {
|
|
8762
|
+
if (toolName.startsWith(ns)) {
|
|
8763
|
+
lookupCandidates.push(toolName.slice(ns.length));
|
|
8764
|
+
}
|
|
8765
|
+
}
|
|
8766
|
+
const matchedKey = lookupCandidates.find((key) => localTools[key]);
|
|
8767
|
+
const toolEntry = matchedKey ? localTools[matchedKey] : void 0;
|
|
8768
|
+
if (!toolEntry) {
|
|
8769
|
+
throw new Error(
|
|
8770
|
+
`Local tool "${toolName}" required but not provided in localTools map`
|
|
8771
|
+
);
|
|
8772
|
+
}
|
|
8773
|
+
const handler = hasToolEntryShape(toolEntry) ? toolEntry.execute : toolEntry;
|
|
8774
|
+
try {
|
|
8775
|
+
return [toolName, await handler(parameters)];
|
|
8776
|
+
} catch (error) {
|
|
8777
|
+
throw new Error(
|
|
8778
|
+
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
8779
|
+
);
|
|
8780
|
+
}
|
|
8781
|
+
})
|
|
8782
|
+
);
|
|
8737
8783
|
const resumeData = {
|
|
8738
8784
|
executionId,
|
|
8739
|
-
toolOutputs:
|
|
8785
|
+
toolOutputs: Object.fromEntries(outputs),
|
|
8740
8786
|
streamResponse: isStreaming
|
|
8741
8787
|
};
|
|
8742
8788
|
if (isStreaming) {
|
|
@@ -8748,9 +8794,7 @@ var RuntypeClient2 = class {
|
|
|
8748
8794
|
});
|
|
8749
8795
|
}
|
|
8750
8796
|
} catch (error) {
|
|
8751
|
-
throw new Error(
|
|
8752
|
-
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
8753
|
-
);
|
|
8797
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
8754
8798
|
}
|
|
8755
8799
|
} else {
|
|
8756
8800
|
break;
|
package/dist/index.d.cts
CHANGED
|
@@ -6745,7 +6745,7 @@ interface paths {
|
|
|
6745
6745
|
}[];
|
|
6746
6746
|
/** @description Whether to stream the response via SSE */
|
|
6747
6747
|
streamResponse?: boolean;
|
|
6748
|
-
/** @description
|
|
6748
|
+
/** @description Local tool outputs for the paused execution. Key each output by the per-call `toolCallId` from the `flow_await` / `agent_await` event (preferred, and required to disambiguate parallel calls to the same tool), or by tool name (legacy; collapses same-tool parallel calls onto one slot). */
|
|
6749
6749
|
toolOutputs?: {
|
|
6750
6750
|
[key: string]: unknown;
|
|
6751
6751
|
};
|
|
@@ -31471,6 +31471,7 @@ interface components {
|
|
|
31471
31471
|
[key: string]: unknown;
|
|
31472
31472
|
};
|
|
31473
31473
|
seq: number;
|
|
31474
|
+
toolCallId?: string;
|
|
31474
31475
|
toolId: string;
|
|
31475
31476
|
toolName: string;
|
|
31476
31477
|
/** @enum {string} */
|
|
@@ -31814,6 +31815,7 @@ interface components {
|
|
|
31814
31815
|
[key: string]: unknown;
|
|
31815
31816
|
};
|
|
31816
31817
|
seq: number;
|
|
31818
|
+
toolCallId?: string;
|
|
31817
31819
|
toolId: string;
|
|
31818
31820
|
toolName: string;
|
|
31819
31821
|
/** @enum {string} */
|
|
@@ -31993,6 +31995,7 @@ interface components {
|
|
|
31993
31995
|
[key: string]: unknown;
|
|
31994
31996
|
};
|
|
31995
31997
|
seq?: number;
|
|
31998
|
+
toolCallId?: string;
|
|
31996
31999
|
toolId?: string;
|
|
31997
32000
|
toolName?: string;
|
|
31998
32001
|
/** @enum {string} */
|
|
@@ -32384,6 +32387,7 @@ interface components {
|
|
|
32384
32387
|
[key: string]: unknown;
|
|
32385
32388
|
};
|
|
32386
32389
|
seq?: number;
|
|
32390
|
+
toolCallId?: string;
|
|
32387
32391
|
toolId?: string;
|
|
32388
32392
|
toolName?: string;
|
|
32389
32393
|
/** @enum {string} */
|
|
@@ -34100,6 +34104,18 @@ interface DispatchRequest {
|
|
|
34100
34104
|
* `clientTools[]` is per-dispatch, `resolveTools` is per-iteration.
|
|
34101
34105
|
*/
|
|
34102
34106
|
clientTools?: ClientToolDefinition[];
|
|
34107
|
+
/**
|
|
34108
|
+
* Optional policy governing how `clientTools[]` are admitted on this
|
|
34109
|
+
* (API-key) dispatch. On the API-key path the caller is trusted, so
|
|
34110
|
+
* `origin: 'webmcp'` tools are admitted by default — their presence in
|
|
34111
|
+
* `clientTools[]` is the opt-in. `allowlist` is an optional self-restriction
|
|
34112
|
+
* (glob patterns: exact, or single trailing `*`) narrowing which webmcp
|
|
34113
|
+
* tools are accepted; omit it to admit all. `origin: 'sdk'` tools are never
|
|
34114
|
+
* gated. Mirrors the shared `ClientToolsPolicy`.
|
|
34115
|
+
*/
|
|
34116
|
+
clientToolsPolicy?: {
|
|
34117
|
+
allowlist?: string[];
|
|
34118
|
+
};
|
|
34103
34119
|
secrets?: Record<string, string>;
|
|
34104
34120
|
inputs?: Record<string, unknown>;
|
|
34105
34121
|
options?: {
|
|
@@ -34208,6 +34224,12 @@ interface DeploySandboxRequest {
|
|
|
34208
34224
|
sandboxId?: string;
|
|
34209
34225
|
startCommand?: string;
|
|
34210
34226
|
files?: Record<string, string>;
|
|
34227
|
+
/** Custom labels applied at sandbox creation (Daytona), for provenance/cleanup. */
|
|
34228
|
+
labels?: Record<string, string>;
|
|
34229
|
+
/** Auto-stop interval in minutes (Daytona). Defaults to 120 when omitted. */
|
|
34230
|
+
autoStopInterval?: number;
|
|
34231
|
+
/** Auto-delete interval in minutes (Daytona); 0 deletes immediately on stop. Disabled when omitted. */
|
|
34232
|
+
autoDeleteInterval?: number;
|
|
34211
34233
|
}
|
|
34212
34234
|
interface DeploySandboxResponse {
|
|
34213
34235
|
sandboxId: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -6745,7 +6745,7 @@ interface paths {
|
|
|
6745
6745
|
}[];
|
|
6746
6746
|
/** @description Whether to stream the response via SSE */
|
|
6747
6747
|
streamResponse?: boolean;
|
|
6748
|
-
/** @description
|
|
6748
|
+
/** @description Local tool outputs for the paused execution. Key each output by the per-call `toolCallId` from the `flow_await` / `agent_await` event (preferred, and required to disambiguate parallel calls to the same tool), or by tool name (legacy; collapses same-tool parallel calls onto one slot). */
|
|
6749
6749
|
toolOutputs?: {
|
|
6750
6750
|
[key: string]: unknown;
|
|
6751
6751
|
};
|
|
@@ -31471,6 +31471,7 @@ interface components {
|
|
|
31471
31471
|
[key: string]: unknown;
|
|
31472
31472
|
};
|
|
31473
31473
|
seq: number;
|
|
31474
|
+
toolCallId?: string;
|
|
31474
31475
|
toolId: string;
|
|
31475
31476
|
toolName: string;
|
|
31476
31477
|
/** @enum {string} */
|
|
@@ -31814,6 +31815,7 @@ interface components {
|
|
|
31814
31815
|
[key: string]: unknown;
|
|
31815
31816
|
};
|
|
31816
31817
|
seq: number;
|
|
31818
|
+
toolCallId?: string;
|
|
31817
31819
|
toolId: string;
|
|
31818
31820
|
toolName: string;
|
|
31819
31821
|
/** @enum {string} */
|
|
@@ -31993,6 +31995,7 @@ interface components {
|
|
|
31993
31995
|
[key: string]: unknown;
|
|
31994
31996
|
};
|
|
31995
31997
|
seq?: number;
|
|
31998
|
+
toolCallId?: string;
|
|
31996
31999
|
toolId?: string;
|
|
31997
32000
|
toolName?: string;
|
|
31998
32001
|
/** @enum {string} */
|
|
@@ -32384,6 +32387,7 @@ interface components {
|
|
|
32384
32387
|
[key: string]: unknown;
|
|
32385
32388
|
};
|
|
32386
32389
|
seq?: number;
|
|
32390
|
+
toolCallId?: string;
|
|
32387
32391
|
toolId?: string;
|
|
32388
32392
|
toolName?: string;
|
|
32389
32393
|
/** @enum {string} */
|
|
@@ -34100,6 +34104,18 @@ interface DispatchRequest {
|
|
|
34100
34104
|
* `clientTools[]` is per-dispatch, `resolveTools` is per-iteration.
|
|
34101
34105
|
*/
|
|
34102
34106
|
clientTools?: ClientToolDefinition[];
|
|
34107
|
+
/**
|
|
34108
|
+
* Optional policy governing how `clientTools[]` are admitted on this
|
|
34109
|
+
* (API-key) dispatch. On the API-key path the caller is trusted, so
|
|
34110
|
+
* `origin: 'webmcp'` tools are admitted by default — their presence in
|
|
34111
|
+
* `clientTools[]` is the opt-in. `allowlist` is an optional self-restriction
|
|
34112
|
+
* (glob patterns: exact, or single trailing `*`) narrowing which webmcp
|
|
34113
|
+
* tools are accepted; omit it to admit all. `origin: 'sdk'` tools are never
|
|
34114
|
+
* gated. Mirrors the shared `ClientToolsPolicy`.
|
|
34115
|
+
*/
|
|
34116
|
+
clientToolsPolicy?: {
|
|
34117
|
+
allowlist?: string[];
|
|
34118
|
+
};
|
|
34103
34119
|
secrets?: Record<string, string>;
|
|
34104
34120
|
inputs?: Record<string, unknown>;
|
|
34105
34121
|
options?: {
|
|
@@ -34208,6 +34224,12 @@ interface DeploySandboxRequest {
|
|
|
34208
34224
|
sandboxId?: string;
|
|
34209
34225
|
startCommand?: string;
|
|
34210
34226
|
files?: Record<string, string>;
|
|
34227
|
+
/** Custom labels applied at sandbox creation (Daytona), for provenance/cleanup. */
|
|
34228
|
+
labels?: Record<string, string>;
|
|
34229
|
+
/** Auto-stop interval in minutes (Daytona). Defaults to 120 when omitted. */
|
|
34230
|
+
autoStopInterval?: number;
|
|
34231
|
+
/** Auto-delete interval in minutes (Daytona); 0 deletes immediately on stop. Disabled when omitted. */
|
|
34232
|
+
autoDeleteInterval?: number;
|
|
34211
34233
|
}
|
|
34212
34234
|
interface DeploySandboxResponse {
|
|
34213
34235
|
sandboxId: string;
|
package/dist/index.mjs
CHANGED
|
@@ -1191,6 +1191,39 @@ function createExternalTool(config) {
|
|
|
1191
1191
|
};
|
|
1192
1192
|
}
|
|
1193
1193
|
|
|
1194
|
+
// src/local-tool-pause.ts
|
|
1195
|
+
var PENDING_NAMELESS_KEY = "";
|
|
1196
|
+
function collectLocalToolAwait(pausedTools, event) {
|
|
1197
|
+
if (event.type !== "flow_await" && event.type !== "step_await") return;
|
|
1198
|
+
const name = typeof event.toolName === "string" && event.toolName ? event.toolName : "";
|
|
1199
|
+
const executionId = typeof event.executionId === "string" && event.executionId ? event.executionId : void 0;
|
|
1200
|
+
if (name) {
|
|
1201
|
+
const pending = pausedTools.get(PENDING_NAMELESS_KEY);
|
|
1202
|
+
if (pending) pausedTools.delete(PENDING_NAMELESS_KEY);
|
|
1203
|
+
const prev2 = pausedTools.get(name) ?? pending;
|
|
1204
|
+
pausedTools.set(name, {
|
|
1205
|
+
toolName: name,
|
|
1206
|
+
executionId: executionId ?? prev2?.executionId ?? "",
|
|
1207
|
+
parameters: event.parameters ?? prev2?.parameters
|
|
1208
|
+
});
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
const namedKeys = [...pausedTools.keys()].filter((key) => key !== PENDING_NAMELESS_KEY);
|
|
1212
|
+
const targetKey = namedKeys.length > 0 ? namedKeys[namedKeys.length - 1] : PENDING_NAMELESS_KEY;
|
|
1213
|
+
const prev = pausedTools.get(targetKey);
|
|
1214
|
+
pausedTools.set(targetKey, {
|
|
1215
|
+
toolName: targetKey,
|
|
1216
|
+
executionId: executionId ?? prev?.executionId ?? "",
|
|
1217
|
+
parameters: event.parameters ?? prev?.parameters
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
function resolveBatchExecutionId(pausedTools) {
|
|
1221
|
+
for (const tool of pausedTools) {
|
|
1222
|
+
if (tool.executionId) return tool.executionId;
|
|
1223
|
+
}
|
|
1224
|
+
return "";
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1194
1227
|
// src/flows-namespace.ts
|
|
1195
1228
|
function isRecord(value) {
|
|
1196
1229
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -1738,7 +1771,7 @@ var RuntypeFlowBuilder = class {
|
|
|
1738
1771
|
};
|
|
1739
1772
|
const processStep = async (response) => {
|
|
1740
1773
|
if (isStreaming) {
|
|
1741
|
-
|
|
1774
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
1742
1775
|
const wrappedCallbacks = {
|
|
1743
1776
|
...callbacks,
|
|
1744
1777
|
onFlowStart: (event) => callbacks?.onFlowStart?.(event),
|
|
@@ -1751,23 +1784,7 @@ var RuntypeFlowBuilder = class {
|
|
|
1751
1784
|
const { streamEvents: streamEvents2, stepDeltaText: stepDeltaText2, stepDisplayName: stepDisplayName2, flowErrorMessage: flowErrorMessage2 } = await Promise.resolve().then(() => (init_stream_utils(), stream_utils_exports));
|
|
1752
1785
|
try {
|
|
1753
1786
|
for await (const event of streamEvents2(response)) {
|
|
1754
|
-
|
|
1755
|
-
if (awaitEvent.type === "flow_await") {
|
|
1756
|
-
const prev = pausedState;
|
|
1757
|
-
pausedState = {
|
|
1758
|
-
toolName: awaitEvent.toolName || prev?.toolName || "",
|
|
1759
|
-
parameters: awaitEvent.parameters ?? prev?.parameters,
|
|
1760
|
-
executionId: awaitEvent.executionId || prev?.executionId || ""
|
|
1761
|
-
};
|
|
1762
|
-
}
|
|
1763
|
-
if (awaitEvent.type === "step_await") {
|
|
1764
|
-
const prev = pausedState;
|
|
1765
|
-
pausedState = {
|
|
1766
|
-
toolName: awaitEvent.toolName || prev?.toolName || "",
|
|
1767
|
-
parameters: awaitEvent.parameters ?? prev?.parameters,
|
|
1768
|
-
executionId: awaitEvent.executionId || prev?.executionId || ""
|
|
1769
|
-
};
|
|
1770
|
-
}
|
|
1787
|
+
collectLocalToolAwait(pausedTools, event);
|
|
1771
1788
|
switch (event.type) {
|
|
1772
1789
|
case "flow_start":
|
|
1773
1790
|
wrappedCallbacks.onFlowStart?.(event);
|
|
@@ -1795,19 +1812,34 @@ var RuntypeFlowBuilder = class {
|
|
|
1795
1812
|
wrappedCallbacks.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
1796
1813
|
throw e;
|
|
1797
1814
|
}
|
|
1798
|
-
if (
|
|
1815
|
+
if (pausedTools.size > 0) {
|
|
1799
1816
|
return {
|
|
1800
1817
|
done: false,
|
|
1801
|
-
result: { status: "paused",
|
|
1818
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
1802
1819
|
};
|
|
1803
1820
|
}
|
|
1804
1821
|
return { done: true, result: accumulatedSummary };
|
|
1805
1822
|
} else {
|
|
1806
1823
|
const data = await response.json();
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1824
|
+
if (data.status === "paused") {
|
|
1825
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
1826
|
+
if (Array.isArray(data.events)) {
|
|
1827
|
+
for (const event of data.events) {
|
|
1828
|
+
collectLocalToolAwait(pausedTools, event);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
if (pausedTools.size === 0 && typeof data.pausedReason === "object" && data.pausedReason !== null && data.pausedReason.type === "local_action") {
|
|
1832
|
+
collectLocalToolAwait(pausedTools, {
|
|
1833
|
+
...data.pausedReason,
|
|
1834
|
+
type: "flow_await"
|
|
1835
|
+
});
|
|
1836
|
+
}
|
|
1837
|
+
return {
|
|
1838
|
+
done: false,
|
|
1839
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
1840
|
+
};
|
|
1841
|
+
}
|
|
1842
|
+
return { done: true, result: data };
|
|
1811
1843
|
}
|
|
1812
1844
|
};
|
|
1813
1845
|
let currentResponse;
|
|
@@ -1833,16 +1865,28 @@ var RuntypeFlowBuilder = class {
|
|
|
1833
1865
|
);
|
|
1834
1866
|
}
|
|
1835
1867
|
const pausedResult = result;
|
|
1836
|
-
if (pausedResult.status === "paused" && pausedResult.
|
|
1837
|
-
const
|
|
1838
|
-
if (!localTools[toolName]) {
|
|
1839
|
-
throw new Error(`Local tool "${toolName}" required but not provided in localTools map`);
|
|
1840
|
-
}
|
|
1868
|
+
if (pausedResult.status === "paused" && pausedResult.pausedTools?.length) {
|
|
1869
|
+
const executionId = resolveBatchExecutionId(pausedResult.pausedTools);
|
|
1841
1870
|
try {
|
|
1842
|
-
const
|
|
1871
|
+
const outputs = await Promise.all(
|
|
1872
|
+
pausedResult.pausedTools.map(async ({ toolName, parameters }) => {
|
|
1873
|
+
if (!localTools[toolName]) {
|
|
1874
|
+
throw new Error(
|
|
1875
|
+
`Local tool "${toolName}" required but not provided in localTools map`
|
|
1876
|
+
);
|
|
1877
|
+
}
|
|
1878
|
+
try {
|
|
1879
|
+
return [toolName, await localTools[toolName](parameters)];
|
|
1880
|
+
} catch (error) {
|
|
1881
|
+
throw new Error(
|
|
1882
|
+
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
1883
|
+
);
|
|
1884
|
+
}
|
|
1885
|
+
})
|
|
1886
|
+
);
|
|
1843
1887
|
const resumeData = {
|
|
1844
1888
|
executionId,
|
|
1845
|
-
toolOutputs:
|
|
1889
|
+
toolOutputs: Object.fromEntries(outputs),
|
|
1846
1890
|
streamResponse: isStreaming
|
|
1847
1891
|
};
|
|
1848
1892
|
if (isStreaming) {
|
|
@@ -1857,9 +1901,7 @@ var RuntypeFlowBuilder = class {
|
|
|
1857
1901
|
});
|
|
1858
1902
|
}
|
|
1859
1903
|
} catch (error) {
|
|
1860
|
-
throw new Error(
|
|
1861
|
-
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
1862
|
-
);
|
|
1904
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
1863
1905
|
}
|
|
1864
1906
|
} else {
|
|
1865
1907
|
break;
|
|
@@ -8432,11 +8474,7 @@ function hasToolEntryShape(value) {
|
|
|
8432
8474
|
return typeof value.execute === "function" && typeof value.description === "string" && typeof value.parametersSchema === "object" && value.parametersSchema !== null;
|
|
8433
8475
|
}
|
|
8434
8476
|
function isPausedLocalActionResult(value) {
|
|
8435
|
-
|
|
8436
|
-
return false;
|
|
8437
|
-
}
|
|
8438
|
-
const { pausedReason } = value;
|
|
8439
|
-
return pausedReason === void 0 || isObjectRecord(pausedReason) && pausedReason.type === "local_action" && typeof pausedReason.toolName === "string" && typeof pausedReason.executionId === "string";
|
|
8477
|
+
return isObjectRecord(value) && value.status === "paused" && Array.isArray(value.pausedTools) && value.pausedTools.length > 0;
|
|
8440
8478
|
}
|
|
8441
8479
|
var RuntypeClient2 = class {
|
|
8442
8480
|
constructor(config = {}) {
|
|
@@ -8538,7 +8576,7 @@ var RuntypeClient2 = class {
|
|
|
8538
8576
|
};
|
|
8539
8577
|
const processStep = async (response) => {
|
|
8540
8578
|
if (isStreaming) {
|
|
8541
|
-
|
|
8579
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
8542
8580
|
const wrappedCallbacks = {
|
|
8543
8581
|
...callbacks,
|
|
8544
8582
|
onFlowStart: (event) => callbacks?.onFlowStart?.(event),
|
|
@@ -8555,26 +8593,7 @@ var RuntypeClient2 = class {
|
|
|
8555
8593
|
};
|
|
8556
8594
|
try {
|
|
8557
8595
|
for await (const event of streamEvents2(response)) {
|
|
8558
|
-
|
|
8559
|
-
const pausedEvent = event;
|
|
8560
|
-
const prev = pausedState;
|
|
8561
|
-
const next = {
|
|
8562
|
-
toolName: pausedEvent.toolName ?? prev?.toolName ?? "",
|
|
8563
|
-
executionId: pausedEvent.executionId ?? prev?.executionId ?? "",
|
|
8564
|
-
parameters: prev?.parameters
|
|
8565
|
-
};
|
|
8566
|
-
pausedState = next;
|
|
8567
|
-
}
|
|
8568
|
-
if (event.type === "step_await") {
|
|
8569
|
-
const pausedEvent = event;
|
|
8570
|
-
const prev = pausedState;
|
|
8571
|
-
const next = {
|
|
8572
|
-
toolName: typeof pausedEvent.toolName === "string" ? pausedEvent.toolName : prev?.toolName ?? "",
|
|
8573
|
-
parameters: pausedEvent.parameters,
|
|
8574
|
-
executionId: typeof pausedEvent.executionId === "string" ? pausedEvent.executionId : prev?.executionId ?? ""
|
|
8575
|
-
};
|
|
8576
|
-
pausedState = next;
|
|
8577
|
-
}
|
|
8596
|
+
collectLocalToolAwait(pausedTools, event);
|
|
8578
8597
|
switch (event.type) {
|
|
8579
8598
|
case "flow_start":
|
|
8580
8599
|
wrappedCallbacks.onFlowStart?.(event);
|
|
@@ -8602,19 +8621,34 @@ var RuntypeClient2 = class {
|
|
|
8602
8621
|
wrappedCallbacks.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
8603
8622
|
throw e;
|
|
8604
8623
|
}
|
|
8605
|
-
if (
|
|
8624
|
+
if (pausedTools.size > 0) {
|
|
8606
8625
|
return {
|
|
8607
8626
|
done: false,
|
|
8608
|
-
result: { status: "paused",
|
|
8627
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
8609
8628
|
};
|
|
8610
8629
|
}
|
|
8611
8630
|
return { done: true, result: summary };
|
|
8612
8631
|
} else {
|
|
8613
8632
|
const data = await response.json();
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8633
|
+
if (data.status === "paused") {
|
|
8634
|
+
const pausedTools = /* @__PURE__ */ new Map();
|
|
8635
|
+
if (Array.isArray(data.events)) {
|
|
8636
|
+
for (const event of data.events) {
|
|
8637
|
+
collectLocalToolAwait(pausedTools, event);
|
|
8638
|
+
}
|
|
8639
|
+
}
|
|
8640
|
+
if (pausedTools.size === 0 && isObjectRecord(data.pausedReason) && data.pausedReason.type === "local_action") {
|
|
8641
|
+
collectLocalToolAwait(pausedTools, {
|
|
8642
|
+
...data.pausedReason,
|
|
8643
|
+
type: "flow_await"
|
|
8644
|
+
});
|
|
8645
|
+
}
|
|
8646
|
+
return {
|
|
8647
|
+
done: false,
|
|
8648
|
+
result: { status: "paused", pausedTools: [...pausedTools.values()] }
|
|
8649
|
+
};
|
|
8650
|
+
}
|
|
8651
|
+
return { done: true, result: data };
|
|
8618
8652
|
}
|
|
8619
8653
|
};
|
|
8620
8654
|
let currentResponse;
|
|
@@ -8634,26 +8668,38 @@ var RuntypeClient2 = class {
|
|
|
8634
8668
|
new Response(JSON.stringify(result), { headers: { "content-type": "application/json" } })
|
|
8635
8669
|
);
|
|
8636
8670
|
}
|
|
8637
|
-
if (isPausedLocalActionResult(result)
|
|
8638
|
-
const
|
|
8639
|
-
const BARE_NAME_NAMESPACES = ["webmcp:"];
|
|
8640
|
-
const lookupCandidates = [toolName];
|
|
8641
|
-
for (const ns of BARE_NAME_NAMESPACES) {
|
|
8642
|
-
if (toolName.startsWith(ns)) {
|
|
8643
|
-
lookupCandidates.push(toolName.slice(ns.length));
|
|
8644
|
-
}
|
|
8645
|
-
}
|
|
8646
|
-
const matchedKey = lookupCandidates.find((key) => localTools[key]);
|
|
8647
|
-
const toolEntry = matchedKey ? localTools[matchedKey] : void 0;
|
|
8648
|
-
if (!toolEntry) {
|
|
8649
|
-
throw new Error(`Local tool "${toolName}" required but not provided in localTools map`);
|
|
8650
|
-
}
|
|
8651
|
-
const handler = hasToolEntryShape(toolEntry) ? toolEntry.execute : toolEntry;
|
|
8671
|
+
if (isPausedLocalActionResult(result)) {
|
|
8672
|
+
const executionId = resolveBatchExecutionId(result.pausedTools);
|
|
8652
8673
|
try {
|
|
8653
|
-
const
|
|
8674
|
+
const outputs = await Promise.all(
|
|
8675
|
+
result.pausedTools.map(async ({ toolName, parameters }) => {
|
|
8676
|
+
const BARE_NAME_NAMESPACES = ["webmcp:"];
|
|
8677
|
+
const lookupCandidates = [toolName];
|
|
8678
|
+
for (const ns of BARE_NAME_NAMESPACES) {
|
|
8679
|
+
if (toolName.startsWith(ns)) {
|
|
8680
|
+
lookupCandidates.push(toolName.slice(ns.length));
|
|
8681
|
+
}
|
|
8682
|
+
}
|
|
8683
|
+
const matchedKey = lookupCandidates.find((key) => localTools[key]);
|
|
8684
|
+
const toolEntry = matchedKey ? localTools[matchedKey] : void 0;
|
|
8685
|
+
if (!toolEntry) {
|
|
8686
|
+
throw new Error(
|
|
8687
|
+
`Local tool "${toolName}" required but not provided in localTools map`
|
|
8688
|
+
);
|
|
8689
|
+
}
|
|
8690
|
+
const handler = hasToolEntryShape(toolEntry) ? toolEntry.execute : toolEntry;
|
|
8691
|
+
try {
|
|
8692
|
+
return [toolName, await handler(parameters)];
|
|
8693
|
+
} catch (error) {
|
|
8694
|
+
throw new Error(
|
|
8695
|
+
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
8696
|
+
);
|
|
8697
|
+
}
|
|
8698
|
+
})
|
|
8699
|
+
);
|
|
8654
8700
|
const resumeData = {
|
|
8655
8701
|
executionId,
|
|
8656
|
-
toolOutputs:
|
|
8702
|
+
toolOutputs: Object.fromEntries(outputs),
|
|
8657
8703
|
streamResponse: isStreaming
|
|
8658
8704
|
};
|
|
8659
8705
|
if (isStreaming) {
|
|
@@ -8665,9 +8711,7 @@ var RuntypeClient2 = class {
|
|
|
8665
8711
|
});
|
|
8666
8712
|
}
|
|
8667
8713
|
} catch (error) {
|
|
8668
|
-
throw new Error(
|
|
8669
|
-
`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`
|
|
8670
|
-
);
|
|
8714
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
8671
8715
|
}
|
|
8672
8716
|
} else {
|
|
8673
8717
|
break;
|
package/package.json
CHANGED