@rarebit-one/harness-kernel 0.18.0 → 0.19.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/README.md +256 -16
- package/dist/agent.d.ts +29 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +145 -31
- package/dist/agent.js.map +1 -1
- package/dist/connectors/auth.d.ts +32 -0
- package/dist/connectors/auth.d.ts.map +1 -0
- package/dist/connectors/auth.js +85 -0
- package/dist/connectors/auth.js.map +1 -0
- package/dist/connectors/mcpClient.d.ts +14 -4
- package/dist/connectors/mcpClient.d.ts.map +1 -1
- package/dist/connectors/mcpClient.js +32 -11
- package/dist/connectors/mcpClient.js.map +1 -1
- package/dist/engines/acp.d.ts.map +1 -1
- package/dist/engines/acp.js +2 -1
- package/dist/engines/acp.js.map +1 -1
- package/dist/engines/capability.d.ts +1 -1
- package/dist/engines/capability.js +1 -1
- package/dist/engines/claudeCode.d.ts.map +1 -1
- package/dist/engines/claudeCode.js +2 -1
- package/dist/engines/claudeCode.js.map +1 -1
- package/dist/engines/claudeCodeDriver.d.ts.map +1 -1
- package/dist/engines/claudeCodeDriver.js +4 -3
- package/dist/engines/claudeCodeDriver.js.map +1 -1
- package/dist/engines/codex.d.ts +6 -5
- package/dist/engines/codex.d.ts.map +1 -1
- package/dist/engines/codex.js +6 -5
- package/dist/engines/codex.js.map +1 -1
- package/dist/engines/codexDriver.d.ts +1 -1
- package/dist/engines/codexDriver.js +1 -1
- package/dist/engines/connectorMcp.d.ts +13 -0
- package/dist/engines/connectorMcp.d.ts.map +1 -1
- package/dist/engines/connectorMcp.js +23 -0
- package/dist/engines/connectorMcp.js.map +1 -1
- package/dist/engines/gateway.d.ts +5 -2
- package/dist/engines/gateway.d.ts.map +1 -1
- package/dist/engines/gateway.js +7 -2
- package/dist/engines/gateway.js.map +1 -1
- package/dist/engines/native.d.ts.map +1 -1
- package/dist/engines/native.js +10 -3
- package/dist/engines/native.js.map +1 -1
- package/dist/engines/types.d.ts +10 -1
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/events.d.ts +22 -8
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/loop.d.ts +28 -1
- package/dist/loop.d.ts.map +1 -1
- package/dist/loop.js +1 -0
- package/dist/loop.js.map +1 -1
- package/dist/models/chat.d.ts +12 -6
- package/dist/models/chat.d.ts.map +1 -1
- package/dist/models/chat.js +11 -6
- package/dist/models/chat.js.map +1 -1
- package/dist/models/retry.d.ts +259 -0
- package/dist/models/retry.d.ts.map +1 -0
- package/dist/models/retry.js +409 -0
- package/dist/models/retry.js.map +1 -0
- package/dist/models/types.d.ts +7 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/models/types.js.map +1 -1
- package/dist/private.d.ts.map +1 -1
- package/dist/private.js +12 -2
- package/dist/private.js.map +1 -1
- package/dist/processGroup.d.ts +10 -2
- package/dist/processGroup.d.ts.map +1 -1
- package/dist/processGroup.js +29 -2
- package/dist/processGroup.js.map +1 -1
- package/dist/secrets.d.ts +17 -7
- package/dist/secrets.d.ts.map +1 -1
- package/dist/secrets.js +38 -24
- package/dist/secrets.js.map +1 -1
- package/dist/tools/concurrency.d.ts +48 -0
- package/dist/tools/concurrency.d.ts.map +1 -0
- package/dist/tools/concurrency.js +64 -0
- package/dist/tools/concurrency.js.map +1 -0
- package/dist/tools/metadata.d.ts +18 -3
- package/dist/tools/metadata.d.ts.map +1 -1
- package/dist/tools/metadata.js +7 -0
- package/dist/tools/metadata.js.map +1 -1
- package/dist/tools/registry.d.ts +6 -4
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +5 -3
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/terminal.d.ts +8 -6
- package/dist/tools/terminal.d.ts.map +1 -1
- package/dist/tools/terminal.js +8 -6
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/validate.d.ts +49 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +346 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/transcript.d.ts +53 -0
- package/dist/transcript.d.ts.map +1 -0
- package/dist/transcript.js +104 -0
- package/dist/transcript.js.map +1 -0
- package/dist/types.d.ts +44 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/processGroup.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/** How long a stopped harness gets to exit on SIGTERM before SIGKILL. */
|
|
2
2
|
export const DEFAULT_STOP_GRACE_MS = 5_000;
|
|
3
|
+
/**
|
|
4
|
+
* How long to wait, after SIGKILL, for the group to disappear. Death and
|
|
5
|
+
* reaping normally take milliseconds; the bound only matters where nothing
|
|
6
|
+
* reaps orphans (a container whose PID 1 is not an init), so a dead
|
|
7
|
+
* descendant lingers as a zombie and the group never empties.
|
|
8
|
+
*/
|
|
9
|
+
export const KILL_SETTLE_MS = 1_000;
|
|
10
|
+
const SETTLE_POLL_MS = 10;
|
|
3
11
|
/** Signal the whole group; fall back to the leader if the group is gone. */
|
|
4
12
|
function signalGroup(child, sig) {
|
|
5
13
|
try {
|
|
@@ -15,12 +23,24 @@ function signalGroup(child, sig) {
|
|
|
15
23
|
}
|
|
16
24
|
}
|
|
17
25
|
}
|
|
26
|
+
/** True while any process (zombies included) still belongs to group `pgid`. */
|
|
27
|
+
function groupExists(pgid) {
|
|
28
|
+
try {
|
|
29
|
+
process.kill(-pgid, 0);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// ESRCH: the group is empty. EPERM: the id now names someone else's group.
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
18
37
|
/**
|
|
19
38
|
* SIGTERM the group, wait up to `graceMs` for the leader to exit, then SIGKILL
|
|
20
39
|
* whatever remains of the group — unconditionally, so a descendant that
|
|
21
40
|
* ignored SIGTERM (or outlived its parent) cannot keep running after this
|
|
22
|
-
* resolves. SIGKILL
|
|
23
|
-
*
|
|
41
|
+
* resolves. SIGKILL is delivered asynchronously, so this then waits (up to
|
|
42
|
+
* `KILL_SETTLE_MS`) until no process is left in the group: when it resolves,
|
|
43
|
+
* nothing in the group is still executing.
|
|
24
44
|
*/
|
|
25
45
|
export async function terminateProcessGroup(child, graceMs) {
|
|
26
46
|
const exited = () => child.exitCode !== null || child.signalCode !== null;
|
|
@@ -35,5 +55,12 @@ export async function terminateProcessGroup(child, graceMs) {
|
|
|
35
55
|
});
|
|
36
56
|
}
|
|
37
57
|
signalGroup(child, "SIGKILL");
|
|
58
|
+
const pgid = child.pid;
|
|
59
|
+
if (pgid === undefined)
|
|
60
|
+
return;
|
|
61
|
+
const settleBy = Date.now() + KILL_SETTLE_MS;
|
|
62
|
+
while (groupExists(pgid) && Date.now() < settleBy) {
|
|
63
|
+
await new Promise((r) => setTimeout(r, SETTLE_POLL_MS));
|
|
64
|
+
}
|
|
38
65
|
}
|
|
39
66
|
//# sourceMappingURL=processGroup.js.map
|
package/dist/processGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processGroup.js","sourceRoot":"","sources":["../src/processGroup.ts"],"names":[],"mappings":"AAMA,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAA;AAE1C,4EAA4E;AAC5E,SAAS,WAAW,CAAC,KAAmB,EAAE,GAAmB;IAC3D,IAAI,CAAC;QACH,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjB,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"processGroup.js","sourceRoot":"","sources":["../src/processGroup.ts"],"names":[],"mappings":"AAMA,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAA;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA;AAEnC,MAAM,cAAc,GAAG,EAAE,CAAA;AAEzB,4EAA4E;AAC5E,SAAS,WAAW,CAAC,KAAmB,EAAE,GAAmB;IAC3D,IAAI,CAAC;QACH,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjB,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,2EAA2E;QAC3E,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAmB,EAAE,OAAe;IAC9E,MAAM,MAAM,GAAG,GAAY,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,CAAA;IAClF,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IAC7B,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QACd,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC1C,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;gBACtB,YAAY,CAAC,KAAK,CAAC,CAAA;gBACnB,OAAO,EAAE,CAAA;YACX,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAA;IACtB,IAAI,IAAI,KAAK,SAAS;QAAE,OAAM;IAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAA;IAC5C,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAA;IACzD,CAAC;AACH,CAAC"}
|
package/dist/secrets.d.ts
CHANGED
|
@@ -14,13 +14,23 @@ export declare function secretsToEnv(secrets?: Record<string, string>): NodeJS.P
|
|
|
14
14
|
export declare const MIN_MASKED_SECRET_LENGTH = 6;
|
|
15
15
|
/** What a masked secret value is replaced with in model-bound text. */
|
|
16
16
|
export declare const MASKED_SECRET = "[secret]";
|
|
17
|
+
/** Masks resolved secret values in model-bound text; see {@link secretMaskSet}. */
|
|
18
|
+
export interface SecretMaskSet {
|
|
19
|
+
/** Mask `value` from now on (ignored below {@link MIN_MASKED_SECRET_LENGTH}). */
|
|
20
|
+
add: (value: string) => void;
|
|
21
|
+
mask: (text: string) => string;
|
|
22
|
+
}
|
|
17
23
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
+
* Replaces each resolved secret VALUE in text with {@link MASKED_SECRET},
|
|
25
|
+
* longest first so a secret containing another is masked whole. Secrets are
|
|
26
|
+
* handed to executed code as env (see secretsToEnv), so a command such as
|
|
27
|
+
* `env` would otherwise echo them straight into the model's context and on to
|
|
28
|
+
* its provider. It is a backstop, not a classifier: a value the code
|
|
29
|
+
* transformed (encoded, split) is not caught.
|
|
30
|
+
*
|
|
31
|
+
* The set grows during the run: a credential resolved mid-run (a connector's
|
|
32
|
+
* rotated token) is masked from the moment it is added, the same as a secret
|
|
33
|
+
* the run started with.
|
|
24
34
|
*/
|
|
25
|
-
export declare function
|
|
35
|
+
export declare function secretMaskSet(secrets?: Record<string, string>): SecretMaskSet;
|
|
26
36
|
//# sourceMappingURL=secrets.d.ts.map
|
package/dist/secrets.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAAC,UAAU,CAMpF;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC,uEAAuE;AACvE,eAAO,MAAM,aAAa,aAAa,CAAA;AAEvC
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAAC,UAAU,CAMpF;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC,uEAAuE;AACvE,eAAO,MAAM,aAAa,aAAa,CAAA;AAEvC,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,aAAa,CAwBjF"}
|
package/dist/secrets.js
CHANGED
|
@@ -21,31 +21,45 @@ export const MIN_MASKED_SECRET_LENGTH = 6;
|
|
|
21
21
|
/** What a masked secret value is replaced with in model-bound text. */
|
|
22
22
|
export const MASKED_SECRET = "[secret]";
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
24
|
+
* Replaces each resolved secret VALUE in text with {@link MASKED_SECRET},
|
|
25
|
+
* longest first so a secret containing another is masked whole. Secrets are
|
|
26
|
+
* handed to executed code as env (see secretsToEnv), so a command such as
|
|
27
|
+
* `env` would otherwise echo them straight into the model's context and on to
|
|
28
|
+
* its provider. It is a backstop, not a classifier: a value the code
|
|
29
|
+
* transformed (encoded, split) is not caught.
|
|
30
|
+
*
|
|
31
|
+
* The set grows during the run: a credential resolved mid-run (a connector's
|
|
32
|
+
* rotated token) is masked from the moment it is added, the same as a secret
|
|
33
|
+
* the run started with.
|
|
30
34
|
*/
|
|
31
|
-
export function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
export function secretMaskSet(secrets = {}) {
|
|
36
|
+
const known = new Set();
|
|
37
|
+
let values = [];
|
|
38
|
+
const add = (value) => {
|
|
39
|
+
if (typeof value !== "string" || value.length < MIN_MASKED_SECRET_LENGTH)
|
|
40
|
+
return;
|
|
41
|
+
// Each value is also matched in its JSON-escaped form: tools such as
|
|
42
|
+
// run_code JSON-encode their result, so a value holding a quote, backslash
|
|
43
|
+
// or newline (a multi-line private key) reaches the model escaped.
|
|
44
|
+
const forms = [value, JSON.stringify(value).slice(1, -1)].filter((v) => !known.has(v));
|
|
45
|
+
if (forms.length === 0)
|
|
46
|
+
return;
|
|
47
|
+
for (const form of forms)
|
|
48
|
+
known.add(form);
|
|
49
|
+
values = [...known].sort((a, b) => b.length - a.length);
|
|
50
|
+
};
|
|
51
|
+
for (const value of Object.values(secrets))
|
|
52
|
+
add(value);
|
|
53
|
+
return {
|
|
54
|
+
add,
|
|
55
|
+
mask: (text) => {
|
|
56
|
+
let out = text;
|
|
57
|
+
for (const value of values) {
|
|
58
|
+
if (out.includes(value))
|
|
59
|
+
out = out.split(value).join(MASKED_SECRET);
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
},
|
|
49
63
|
};
|
|
50
64
|
}
|
|
51
65
|
//# sourceMappingURL=secrets.js.map
|
package/dist/secrets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkC,EAAE;IAC/D,MAAM,GAAG,GAAsB,EAAE,CAAA;IACjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAClB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAEzC,uEAAuE;AACvE,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkC,EAAE;IAC/D,MAAM,GAAG,GAAsB,EAAE,CAAA;IACjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAClB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAEzC,uEAAuE;AACvE,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAA;AASvC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkC,EAAE;IAChE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;IAC/B,IAAI,MAAM,GAAa,EAAE,CAAA;IACzB,MAAM,GAAG,GAAG,CAAC,KAAa,EAAQ,EAAE;QAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,wBAAwB;YAAE,OAAM;QAChF,qEAAqE;QACrE,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACtF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC9B,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;IACzD,CAAC,CAAA;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAAE,GAAG,CAAC,KAAK,CAAC,CAAA;IACtD,OAAO;QACL,GAAG;QACH,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,GAAG,GAAG,IAAI,CAAA;YACd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACrE,CAAC;YACD,OAAO,GAAG,CAAA;QACZ,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Tool } from "./registry.js";
|
|
2
|
+
/**
|
|
3
|
+
* A run's opt-in to executing one step's tool calls in parallel.
|
|
4
|
+
*
|
|
5
|
+
* Absent, the loop runs every call of a step in series, in the order the model
|
|
6
|
+
* issued them, which is how it has always run. Present, calls the predicate
|
|
7
|
+
* vouches for run in parallel, up to `maxConcurrent` at once.
|
|
8
|
+
*
|
|
9
|
+
* The predicate is the caller's, deliberately. `ToolMetadata.concurrencySafe`
|
|
10
|
+
* is the shared word a tool uses to say it is safe (pass `isConcurrencySafe`
|
|
11
|
+
* to honour it), but deciding to act on that claim is policy, and the loop
|
|
12
|
+
* reads no metadata besides `dispatch`. An application with its own rule (by
|
|
13
|
+
* name, by connector, by a field of its own) passes that instead.
|
|
14
|
+
*
|
|
15
|
+
* The ordering rule keeps the model's order wherever it can matter. A step's
|
|
16
|
+
* calls are split, in order, into segments: each run of consecutive safe calls
|
|
17
|
+
* is one segment and runs in parallel; every other call is a segment of its
|
|
18
|
+
* own. A segment starts only when the one before it has settled. So a call
|
|
19
|
+
* nobody vouched for still sees every earlier call finished and no later call
|
|
20
|
+
* started, exactly as in series; only calls that each declared they do not
|
|
21
|
+
* care are reordered among themselves. Results go back to the model in the
|
|
22
|
+
* order it issued the calls, whatever order they finished in.
|
|
23
|
+
*/
|
|
24
|
+
export interface ToolConcurrency {
|
|
25
|
+
/**
|
|
26
|
+
* The most calls in flight at once. A positive integer; 1 is the same as
|
|
27
|
+
* series, and a cap above a step's number of calls simply runs them all.
|
|
28
|
+
*/
|
|
29
|
+
maxConcurrent: number;
|
|
30
|
+
/** Whether a call to this tool may run beside others of the same step. */
|
|
31
|
+
concurrencySafe: (tool: Tool) => boolean;
|
|
32
|
+
}
|
|
33
|
+
/** Refuse a cap the loop cannot honour, before the run spends anything. */
|
|
34
|
+
export declare function assertToolConcurrency(concurrency: ToolConcurrency | undefined): void;
|
|
35
|
+
/**
|
|
36
|
+
* Run `items` through `run` under the segment rule in {@link ToolConcurrency},
|
|
37
|
+
* returning the results in item order. With no `safe` predicate every item is
|
|
38
|
+
* its own segment, which is plain series.
|
|
39
|
+
*
|
|
40
|
+
* Within a segment, items start in order: the lowest index not yet started is
|
|
41
|
+
* always the next to start, so anything `run` does before its first `await`
|
|
42
|
+
* (emitting a `tool.called`, say) happens in item order too.
|
|
43
|
+
*/
|
|
44
|
+
export declare function runInSegments<T, R>(items: readonly T[], run: (item: T) => Promise<R>, options?: {
|
|
45
|
+
maxConcurrent: number;
|
|
46
|
+
safe: (item: T) => boolean;
|
|
47
|
+
}): Promise<R[]>;
|
|
48
|
+
//# sourceMappingURL=concurrency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/tools/concurrency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB,0EAA0E;IAC1E,eAAe,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAA;CACzC;AAED,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CASpF;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,CAAC,EACtC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC5B,OAAO,CAAC,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAA;CAAE,GAC9D,OAAO,CAAC,CAAC,EAAE,CAAC,CAWd"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** Refuse a cap the loop cannot honour, before the run spends anything. */
|
|
2
|
+
export function assertToolConcurrency(concurrency) {
|
|
3
|
+
if (concurrency === undefined)
|
|
4
|
+
return;
|
|
5
|
+
const max = concurrency.maxConcurrent;
|
|
6
|
+
if (!Number.isInteger(max) || max < 1) {
|
|
7
|
+
throw new Error(`toolConcurrency.maxConcurrent must be a positive integer, got ${String(max)}; ` +
|
|
8
|
+
"omit toolConcurrency to run tool calls in series");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Run `items` through `run` under the segment rule in {@link ToolConcurrency},
|
|
13
|
+
* returning the results in item order. With no `safe` predicate every item is
|
|
14
|
+
* its own segment, which is plain series.
|
|
15
|
+
*
|
|
16
|
+
* Within a segment, items start in order: the lowest index not yet started is
|
|
17
|
+
* always the next to start, so anything `run` does before its first `await`
|
|
18
|
+
* (emitting a `tool.called`, say) happens in item order too.
|
|
19
|
+
*/
|
|
20
|
+
export async function runInSegments(items, run, options) {
|
|
21
|
+
const max = options?.maxConcurrent ?? 1;
|
|
22
|
+
const safe = items.map((item) => options?.safe(item) ?? false);
|
|
23
|
+
const out = [];
|
|
24
|
+
for (let start = 0; start < items.length;) {
|
|
25
|
+
let end = start + 1;
|
|
26
|
+
if (safe[start])
|
|
27
|
+
while (end < items.length && safe[end])
|
|
28
|
+
end += 1;
|
|
29
|
+
out.push(...(await pool(items.slice(start, end), max, run)));
|
|
30
|
+
start = end;
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* At most `max` of `items` in flight at once, started in order; results in order.
|
|
36
|
+
*
|
|
37
|
+
* When one `run` rejects, nothing more is started, and the rejection waits for
|
|
38
|
+
* the items already in flight to settle before it propagates. So, as in
|
|
39
|
+
* series, no item starts after the caller has seen the failure, and nothing an
|
|
40
|
+
* in-flight item does (its closing event, say) lands after the caller has
|
|
41
|
+
* moved on. The first rejection is the one rethrown.
|
|
42
|
+
*/
|
|
43
|
+
async function pool(items, max, run) {
|
|
44
|
+
const out = new Array(items.length);
|
|
45
|
+
let next = 0;
|
|
46
|
+
let failure;
|
|
47
|
+
const worker = async () => {
|
|
48
|
+
while (next < items.length && failure === undefined) {
|
|
49
|
+
const index = next;
|
|
50
|
+
next += 1;
|
|
51
|
+
try {
|
|
52
|
+
out[index] = await run(items[index]);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
failure ??= { error };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
await Promise.all(Array.from({ length: Math.min(max, items.length) }, () => worker()));
|
|
60
|
+
if (failure !== undefined)
|
|
61
|
+
throw failure.error;
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=concurrency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/tools/concurrency.ts"],"names":[],"mappings":"AAkCA,2EAA2E;AAC3E,MAAM,UAAU,qBAAqB,CAAC,WAAwC;IAC5E,IAAI,WAAW,KAAK,SAAS;QAAE,OAAM;IACrC,MAAM,GAAG,GAAG,WAAW,CAAC,aAAa,CAAA;IACrC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,iEAAiE,MAAM,CAAC,GAAG,CAAC,IAAI;YAC9E,kDAAkD,CACrD,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAmB,EACnB,GAA4B,EAC5B,OAA+D;IAE/D,MAAM,GAAG,GAAG,OAAO,EAAE,aAAa,IAAI,CAAC,CAAA;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAA;IAC9D,MAAM,GAAG,GAAQ,EAAE,CAAA;IACnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;QAC1C,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,CAAA;QACnB,IAAI,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC;gBAAE,GAAG,IAAI,CAAC,CAAA;QACjE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;QAC5D,KAAK,GAAG,GAAG,CAAA;IACb,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,IAAI,CAAO,KAAU,EAAE,GAAW,EAAE,GAA4B;IAC7E,MAAM,GAAG,GAAG,IAAI,KAAK,CAAI,KAAK,CAAC,MAAM,CAAC,CAAA;IACtC,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,OAAuC,CAAA;IAC3C,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;QACxB,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,IAAI,CAAA;YAClB,IAAI,IAAI,CAAC,CAAA;YACT,IAAI,CAAC;gBACH,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC,CAAA;YAC3C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,KAAK,EAAE,KAAK,EAAE,CAAA;YACvB,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IACtF,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,OAAO,CAAC,KAAK,CAAA;IAC9C,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
package/dist/tools/metadata.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { Tool } from "./registry.js";
|
|
|
11
11
|
*
|
|
12
12
|
* The metadata here is only ever *descriptive*. The kernel records that a tool
|
|
13
13
|
* says `requiresConfirmation`; it never implements a confirmation flow, because
|
|
14
|
-
* what confirmation means — a modal, a
|
|
14
|
+
* what confirmation means — a modal, a chat approval, a second agent — is the
|
|
15
15
|
* application's decision. Same for undo and retention. Policy lives in the app
|
|
16
16
|
* layer; the vocabulary lives here so every layer agrees on the words.
|
|
17
17
|
*/
|
|
@@ -33,8 +33,9 @@ export type ResultRetention = "ephemeral" | "standard" | "persistent";
|
|
|
33
33
|
* - `terminal` — run it, append its result, then END the loop with the call
|
|
34
34
|
* as the structured answer. A final-answer tool. The other
|
|
35
35
|
* calls of the same assistant turn still run (in order), so
|
|
36
|
-
* the transcript stays whole; the first terminal call
|
|
37
|
-
* succeeds is the answer
|
|
36
|
+
* the transcript stays whole; the first terminal call, in the
|
|
37
|
+
* model's order, that succeeds is the answer, even when calls
|
|
38
|
+
* ran in parallel and a later one finished first.
|
|
38
39
|
* - `external` — the loop does not run it: the call is parked on
|
|
39
40
|
* `LoopResult.pending`, the run ends `suspended`, and the
|
|
40
41
|
* caller resumes the conversation with the call's result (or
|
|
@@ -93,6 +94,15 @@ export interface ToolMetadata {
|
|
|
93
94
|
* kernel only records the claim; deciding to replay is the application's.
|
|
94
95
|
*/
|
|
95
96
|
replay?: "safe" | "unsafe";
|
|
97
|
+
/**
|
|
98
|
+
* The tool may run at the same time as other calls of the same step: it has
|
|
99
|
+
* no effect another call could observe or race (a read, a lookup). Absent
|
|
100
|
+
* means it makes no such claim, and it runs alone. The loop never reads this
|
|
101
|
+
* itself; a run that opts into parallel calls passes a predicate
|
|
102
|
+
* (`toolConcurrency.concurrencySafe`), and `isConcurrencySafe` honours this
|
|
103
|
+
* field.
|
|
104
|
+
*/
|
|
105
|
+
concurrencySafe?: boolean;
|
|
96
106
|
resultRetention?: ResultRetention;
|
|
97
107
|
clientResultVisibility?: ClientResultVisibility;
|
|
98
108
|
}
|
|
@@ -130,6 +140,11 @@ export declare function toolsRequiringConfirmation(tools: Tool[]): Tool[];
|
|
|
130
140
|
* after an interruption. An undeclared tool is excluded: absent means unsafe.
|
|
131
141
|
*/
|
|
132
142
|
export declare function replaySafeTools(tools: Tool[]): Tool[];
|
|
143
|
+
/**
|
|
144
|
+
* Whether a tool declared `concurrencySafe: true`. The predicate to pass as
|
|
145
|
+
* `toolConcurrency.concurrencySafe` when the tools' own claims are the policy.
|
|
146
|
+
*/
|
|
147
|
+
export declare function isConcurrencySafe(tool: Tool): boolean;
|
|
133
148
|
/** Look up the tool that undoes `name`, when one is declared and reversible. */
|
|
134
149
|
export declare function undoToolFor(tools: Tool[], name: string): Tool | undefined;
|
|
135
150
|
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/tools/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,kBAAkB,CAAA;AAElE,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAA;AAErE
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/tools/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,kBAAkB,CAAA;AAElE,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAA;AAErE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;AAE9D;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,YAAY,CAAA;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACpC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;IACzC,+DAA+D;IAC/D,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,gCAAgC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,qCAAqC;IACrC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;IAC1B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;CAChD;AAED,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,GAAE,aAAkB,GAAG,OAAO,CAmBhF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,SAAS,GAAE,aAAkB,GAAG,IAAI,EAAE,CAEhF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,QAAQ,EAAE,CAErD;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,CAErD;AAED,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAEnD;AAED,mEAAmE;AACnE,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAEhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAErD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAErD;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAIzE"}
|
package/dist/tools/metadata.js
CHANGED
|
@@ -54,6 +54,13 @@ export function toolsRequiringConfirmation(tools) {
|
|
|
54
54
|
export function replaySafeTools(tools) {
|
|
55
55
|
return tools.filter((tool) => tool.meta?.replay === "safe");
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Whether a tool declared `concurrencySafe: true`. The predicate to pass as
|
|
59
|
+
* `toolConcurrency.concurrencySafe` when the tools' own claims are the policy.
|
|
60
|
+
*/
|
|
61
|
+
export function isConcurrencySafe(tool) {
|
|
62
|
+
return tool.meta?.concurrencySafe === true;
|
|
63
|
+
}
|
|
57
64
|
/** Look up the tool that undoes `name`, when one is declared and reversible. */
|
|
58
65
|
export function undoToolFor(tools, name) {
|
|
59
66
|
const tool = tools.find((t) => t.spec.name === name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/tools/metadata.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/tools/metadata.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type McpConnection } from "../connectors/mcpClient.js";
|
|
1
|
+
import { type ConnectMcpOptions, type McpConnection } from "../connectors/mcpClient.js";
|
|
2
2
|
import type { ConnectorConfig } from "../types.js";
|
|
3
3
|
import type { ToolSpec } from "../providers/types.js";
|
|
4
4
|
import type { ToolMetadata } from "./metadata.js";
|
|
@@ -79,12 +79,14 @@ export declare const namespacedToolName: ConnectorToolName;
|
|
|
79
79
|
* `<connector>__<tool>` by default so two connectors cannot collide; pass
|
|
80
80
|
* `toolName` to name them differently (a single-connector application may
|
|
81
81
|
* want the server's own names, so its prompts and its tool names match).
|
|
82
|
-
* Returns a `close` to tear down the connections when the run ends.
|
|
82
|
+
* Returns a `close` to tear down the connections when the run ends. `onSecret`
|
|
83
|
+
* is handed to `connect` and hears every connector credential, including each
|
|
84
|
+
* rotated one an `auth.headers` function returns mid-run.
|
|
83
85
|
*/
|
|
84
|
-
export declare function connectorTools(connectors: ConnectorConfig[], connect?: (config: ConnectorConfig) => Promise<McpConnection>, opts?: {
|
|
86
|
+
export declare function connectorTools(connectors: ConnectorConfig[], connect?: (config: ConnectorConfig, opts?: ConnectMcpOptions) => Promise<McpConnection>, opts?: {
|
|
85
87
|
signal?: AbortSignal;
|
|
86
88
|
toolName?: ConnectorToolName;
|
|
87
|
-
}): Promise<{
|
|
89
|
+
} & ConnectMcpOptions): Promise<{
|
|
88
90
|
tools: Tool[];
|
|
89
91
|
close: () => Promise<void>;
|
|
90
92
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,8EAA8E;AAC9E,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,QAAQ,CAAA;IACd,8EAA8E;IAC9E,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3E;;;;;;;;OAQG;IACH,iBAAiB,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAC3F;AAED,sFAAsF;AACtF,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,UAAU,CAAC,CAGrB;AAsCD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,CAAC,EAAE,MAAM,EAAE,EAClB,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,IAAI,EAAE,CAiGR;AAED,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;AAEnF,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,EAAE,iBAAgE,CAAA;AAEjG;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,eAAe,EAAE,EAC7B,OAAO,GAAE,CACP,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE,iBAAiB,KACrB,OAAO,CAAC,aAAa,CAAc,EACxC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAA;CAAE,GAAG,iBAAsB,GACpF,OAAO,CAAC;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAoExD"}
|
package/dist/tools/registry.js
CHANGED
|
@@ -154,10 +154,12 @@ export const namespacedToolName = (connector, tool) => `${connector}__${tool}`;
|
|
|
154
154
|
* `<connector>__<tool>` by default so two connectors cannot collide; pass
|
|
155
155
|
* `toolName` to name them differently (a single-connector application may
|
|
156
156
|
* want the server's own names, so its prompts and its tool names match).
|
|
157
|
-
* Returns a `close` to tear down the connections when the run ends.
|
|
157
|
+
* Returns a `close` to tear down the connections when the run ends. `onSecret`
|
|
158
|
+
* is handed to `connect` and hears every connector credential, including each
|
|
159
|
+
* rotated one an `auth.headers` function returns mid-run.
|
|
158
160
|
*/
|
|
159
161
|
export async function connectorTools(connectors, connect = connectMcp, opts = {}) {
|
|
160
|
-
const { signal } = opts;
|
|
162
|
+
const { signal, onSecret } = opts;
|
|
161
163
|
const nameFor = opts.toolName ?? namespacedToolName;
|
|
162
164
|
const connections = [];
|
|
163
165
|
// Each setup await stops waiting the moment `signal` aborts, so a stalled
|
|
@@ -182,7 +184,7 @@ export async function connectorTools(connectors, connect = connectMcp, opts = {}
|
|
|
182
184
|
for (const config of connectors) {
|
|
183
185
|
if (config.kind !== "mcp")
|
|
184
186
|
continue;
|
|
185
|
-
const connecting = connect(config);
|
|
187
|
+
const connecting = onSecret ? connect(config, { onSecret }) : connect(config);
|
|
186
188
|
let conn;
|
|
187
189
|
try {
|
|
188
190
|
conn = await step(connecting);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAoB,MAAM,qBAAqB,CAAA;AAClF,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/terminal.d.ts
CHANGED
|
@@ -15,12 +15,14 @@ export interface TerminalToolOptions {
|
|
|
15
15
|
*
|
|
16
16
|
* This is how a conversational application gets a typed reply out of the loop
|
|
17
17
|
* instead of parsing prose. The model is told the schema through the tool
|
|
18
|
-
* definition, so the shape is enforced where models enforce shapes best.
|
|
19
|
-
* kernel does not
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
18
|
+
* definition, so the shape is enforced where models enforce shapes best. By
|
|
19
|
+
* default the kernel does not check the arguments against the schema; a run
|
|
20
|
+
* with `validateToolInput: true` does, and refuses a call that does not fit
|
|
21
|
+
* before it can end the run, telling the model what to fix. A rule the schema
|
|
22
|
+
* cannot express (one field required only when another has a given value) is
|
|
23
|
+
* the caller's: supply your own `Tool` with `meta.dispatch: "terminal"` whose
|
|
24
|
+
* executor throws on a bad answer, which sends the error back to the model and
|
|
25
|
+
* lets it try again.
|
|
24
26
|
*
|
|
25
27
|
* The executor here is a no-op that acknowledges the call: a tool result still
|
|
26
28
|
* has to be appended so the transcript carries no dangling tool call and can be
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/tools/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;CACtC;AAED
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/tools/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;CACtC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAU/D"}
|
package/dist/tools/terminal.js
CHANGED
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
*
|
|
5
5
|
* This is how a conversational application gets a typed reply out of the loop
|
|
6
6
|
* instead of parsing prose. The model is told the schema through the tool
|
|
7
|
-
* definition, so the shape is enforced where models enforce shapes best.
|
|
8
|
-
* kernel does not
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
7
|
+
* definition, so the shape is enforced where models enforce shapes best. By
|
|
8
|
+
* default the kernel does not check the arguments against the schema; a run
|
|
9
|
+
* with `validateToolInput: true` does, and refuses a call that does not fit
|
|
10
|
+
* before it can end the run, telling the model what to fix. A rule the schema
|
|
11
|
+
* cannot express (one field required only when another has a given value) is
|
|
12
|
+
* the caller's: supply your own `Tool` with `meta.dispatch: "terminal"` whose
|
|
13
|
+
* executor throws on a bad answer, which sends the error back to the model and
|
|
14
|
+
* lets it try again.
|
|
13
15
|
*
|
|
14
16
|
* The executor here is a no-op that acknowledges the call: a tool result still
|
|
15
17
|
* has to be appended so the transcript carries no dangling tool call and can be
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/tools/terminal.ts"],"names":[],"mappings":"AAaA
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/tools/terminal.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B;IACvD,OAAO;QACL,IAAI,EAAE;YACJ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC;QACD,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE;QAC/C,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;KAC3C,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Tool } from "./registry.js";
|
|
2
|
+
/**
|
|
3
|
+
* One way a tool call's arguments fail the tool's declared `inputSchema`.
|
|
4
|
+
* `path` is a JSON Pointer into the arguments (`/items/0/name`), or `""` for
|
|
5
|
+
* the arguments object itself.
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolInputProblem {
|
|
8
|
+
path: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Check a tool call's arguments against a JSON Schema, returning every problem
|
|
13
|
+
* found (empty when the arguments fit).
|
|
14
|
+
*
|
|
15
|
+
* This is the subset of JSON Schema that tool schemas actually use: `type`
|
|
16
|
+
* (including `integer`, `null` and type arrays), `properties`, `required`,
|
|
17
|
+
* `additionalProperties`, `enum`, `const`, `items` / `prefixItems`, the
|
|
18
|
+
* length, size and range bounds, `pattern`, `allOf` / `anyOf` / `oneOf`,
|
|
19
|
+
* local `$ref`s (`#/$defs/...`, `#/definitions/...`) and OpenAPI's
|
|
20
|
+
* `nullable`. A `$ref`'s sibling keywords apply as in 2019-09 and later, and
|
|
21
|
+
* are ignored when the root `$schema` names draft 03 to 07, where a `$ref`
|
|
22
|
+
* replaced its whole schema object; `const` is ignored before draft 6 and
|
|
23
|
+
* `prefixItems` before 2020-12, the drafts that introduced them. Any other keyword (`format`, `not`,
|
|
24
|
+
* `if`/`then`/`else`, `multipleOf`, `uniqueItems`, the `dependent*` family, a
|
|
25
|
+
* remote or malformed `$ref`, a local `$ref` inside an embedded resource with
|
|
26
|
+
* its own `$id`, a `type` name outside the seven JSON types) is ignored, and
|
|
27
|
+
* `oneOf` is read as `anyOf`. A schema whose check would take more than a
|
|
28
|
+
* fixed amount of work is not judged at all: no problems are returned.
|
|
29
|
+
*
|
|
30
|
+
* Ignoring is the point: the validator may let a bad call through, but it
|
|
31
|
+
* never refuses a call the schema accepts. A refusal costs the model a turn,
|
|
32
|
+
* so a false one is worse than a missed one, and a schema written by someone
|
|
33
|
+
* else (an MCP server's) can use any keyword it likes without the run
|
|
34
|
+
* starting to refuse calls its server would have taken.
|
|
35
|
+
*
|
|
36
|
+
* `pattern` is compiled and run synchronously on the model's input, like any
|
|
37
|
+
* regular expression. A schema author's pattern with catastrophic
|
|
38
|
+
* backtracking (`^(a+)+$`) can stall the event loop, and the run's deadline
|
|
39
|
+
* cannot interrupt it; turn validation on only for tools whose schemas you
|
|
40
|
+
* would run that way.
|
|
41
|
+
*/
|
|
42
|
+
export declare function validateToolInput(schema: unknown, input: unknown): ToolInputProblem[];
|
|
43
|
+
/**
|
|
44
|
+
* The tool result a call gets when its arguments fail the tool's schema, or
|
|
45
|
+
* `undefined` when they fit. The loop answers the call with this instead of
|
|
46
|
+
* running it, and the model corrects the call within its own budgets.
|
|
47
|
+
*/
|
|
48
|
+
export declare function invalidInputRefusal(tool: Tool, input: Record<string, unknown>): string | undefined;
|
|
49
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAUrF;AAKD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,GAAG,SAAS,CAmBpB"}
|