@orkestrel/agent 0.0.27 → 0.0.29
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/src/core/index.cjs +31 -15
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +30 -7
- package/dist/src/core/index.d.ts +30 -7
- package/dist/src/core/index.js +31 -15
- package/dist/src/core/index.js.map +1 -1
- package/package.json +15 -15
|
@@ -446,7 +446,12 @@ export declare type AgentEventMap = {
|
|
|
446
446
|
readonly tool: readonly [call: ToolCall, result: ToolResult];
|
|
447
447
|
/** Reports a turn's {@link TokenUsage} — emitted after a usage-bearing provider call. */
|
|
448
448
|
readonly usage: readonly [usage: TokenUsage];
|
|
449
|
-
/**
|
|
449
|
+
/**
|
|
450
|
+
* Reports a call denied by scope or authority, before dispatch.
|
|
451
|
+
* A turn advertising no tools drops each call with `no tool is advertised in the active scope`.
|
|
452
|
+
* Otherwise a call excluded by the tool allow-list carries `<tool name> is not in the active scope` and
|
|
453
|
+
* produces a denial tool result and message. Authority evaluates only admitted calls.
|
|
454
|
+
*/
|
|
450
455
|
readonly deny: readonly [call: ToolCall, reason: string | undefined];
|
|
451
456
|
/** Reports the run settled successfully (a natural finish or a cancel's partial) — the {@link AgentResult}. */
|
|
452
457
|
readonly finish: readonly [result: AgentResult];
|
|
@@ -761,7 +766,7 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
|
|
|
761
766
|
* - `workspaces` — an optional pre-built {@link WorkspaceManagerInterface} forwarded to the
|
|
762
767
|
* agent's context; a fresh empty one is created when omitted (mirrors {@link AgentContextOptions.workspaces}).
|
|
763
768
|
* - `scope` — an optional initial active {@link ScopeInterface} forwarded to the agent's context
|
|
764
|
-
* (the
|
|
769
|
+
* (the context and tool-dispatch filter); `undefined` ⇒ every registered tool is admitted.
|
|
765
770
|
* - `on` — the reserved {@link EmitterHooks} key: initial listeners for the agent's
|
|
766
771
|
* {@link AgentEventMap}, wired at construction (for example `{ finish: (r) => log(r) }`).
|
|
767
772
|
*/
|
|
@@ -776,7 +781,16 @@ export declare interface AgentOptions {
|
|
|
776
781
|
readonly instructions?: InstructionManagerInterface;
|
|
777
782
|
/** Reuses a pre-built workspace registry forwarded to the agent's context; a fresh empty one is created when omitted. */
|
|
778
783
|
readonly workspaces?: WorkspaceManagerInterface;
|
|
779
|
-
/**
|
|
784
|
+
/**
|
|
785
|
+
* Sets the initial active scope; `undefined` admits every registered tool.
|
|
786
|
+
* Each turn snapshots the scope's tool allow-list before advertising and checks calls
|
|
787
|
+
* against that list before applying authority. An absent list also admits unknown names
|
|
788
|
+
* to authority and the registry, which returns its tool-not-found failure.
|
|
789
|
+
* A reply to a turn advertising no tools ends the run as its answer, records an assistant
|
|
790
|
+
* message without calls, and emits a `deny` event for every dropped call without marking it partial.
|
|
791
|
+
* Other scoped-out calls produce denial tool results and messages, and the loop continues.
|
|
792
|
+
* Changing the context scope through the `apply` method takes effect on the next turn.
|
|
793
|
+
*/
|
|
780
794
|
readonly scope?: ScopeInterface;
|
|
781
795
|
/** Caps the tool-iteration turns before the loop stops; defaults to `DEFAULT_AGENT_LIMIT`. */
|
|
782
796
|
readonly limit?: number;
|
|
@@ -789,11 +803,11 @@ export declare interface AgentOptions {
|
|
|
789
803
|
/** Carries an external cancel; its abort commits a partial result. */
|
|
790
804
|
readonly signal?: AbortSignal;
|
|
791
805
|
/**
|
|
792
|
-
* Holds an optional policy gate consulted
|
|
806
|
+
* Holds an optional policy gate consulted after scope admits a tool call — a denied call is
|
|
793
807
|
* fed back to the model as a denial {@link ToolResult} (a `tool` chunk + a tool
|
|
794
808
|
* message) rather than executed (no tool run, no budget cost), so the model sees the
|
|
795
|
-
* denial and can react; an allowed call dispatches normally. Omitted ⇒ every call
|
|
796
|
-
* dispatches
|
|
809
|
+
* denial and can react; an allowed call dispatches normally. Omitted ⇒ every admitted call
|
|
810
|
+
* dispatches through the registry.
|
|
797
811
|
*/
|
|
798
812
|
readonly authority?: AuthorityInterface;
|
|
799
813
|
/**
|
|
@@ -1138,6 +1152,11 @@ export declare interface AgentResult {
|
|
|
1138
1152
|
readonly thinking?: string;
|
|
1139
1153
|
/** Holds the summed {@link TokenUsage} across the turn's provider calls (present when any reported it). */
|
|
1140
1154
|
readonly usage?: TokenUsage;
|
|
1155
|
+
/**
|
|
1156
|
+
* Reports cancellation or a turn limit reached with unresolved tool intent.
|
|
1157
|
+
* A reply to a turn advertising no tools is a complete answer (`false`), even if it
|
|
1158
|
+
* contains calls: those calls are dropped and observed through the `deny` event.
|
|
1159
|
+
*/
|
|
1141
1160
|
readonly partial: boolean;
|
|
1142
1161
|
}
|
|
1143
1162
|
|
|
@@ -5193,7 +5212,11 @@ export declare class Scope implements ScopeInterface {
|
|
|
5193
5212
|
export declare interface ScopeFilter {
|
|
5194
5213
|
/** Lists the allowed instruction `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
|
|
5195
5214
|
readonly instructions?: readonly string[];
|
|
5196
|
-
/**
|
|
5215
|
+
/**
|
|
5216
|
+
* Lists the allowed tool `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
|
|
5217
|
+
* The loop advertises and dispatches only admitted tools, checking scope before authority.
|
|
5218
|
+
* If no definition is advertised, the reply ends the run without dispatching its calls.
|
|
5219
|
+
*/
|
|
5197
5220
|
readonly tools?: readonly string[];
|
|
5198
5221
|
/**
|
|
5199
5222
|
* Lists the allowed active-workspace file `path`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed) —
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -446,7 +446,12 @@ export declare type AgentEventMap = {
|
|
|
446
446
|
readonly tool: readonly [call: ToolCall, result: ToolResult];
|
|
447
447
|
/** Reports a turn's {@link TokenUsage} — emitted after a usage-bearing provider call. */
|
|
448
448
|
readonly usage: readonly [usage: TokenUsage];
|
|
449
|
-
/**
|
|
449
|
+
/**
|
|
450
|
+
* Reports a call denied by scope or authority, before dispatch.
|
|
451
|
+
* A turn advertising no tools drops each call with `no tool is advertised in the active scope`.
|
|
452
|
+
* Otherwise a call excluded by the tool allow-list carries `<tool name> is not in the active scope` and
|
|
453
|
+
* produces a denial tool result and message. Authority evaluates only admitted calls.
|
|
454
|
+
*/
|
|
450
455
|
readonly deny: readonly [call: ToolCall, reason: string | undefined];
|
|
451
456
|
/** Reports the run settled successfully (a natural finish or a cancel's partial) — the {@link AgentResult}. */
|
|
452
457
|
readonly finish: readonly [result: AgentResult];
|
|
@@ -761,7 +766,7 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
|
|
|
761
766
|
* - `workspaces` — an optional pre-built {@link WorkspaceManagerInterface} forwarded to the
|
|
762
767
|
* agent's context; a fresh empty one is created when omitted (mirrors {@link AgentContextOptions.workspaces}).
|
|
763
768
|
* - `scope` — an optional initial active {@link ScopeInterface} forwarded to the agent's context
|
|
764
|
-
* (the
|
|
769
|
+
* (the context and tool-dispatch filter); `undefined` ⇒ every registered tool is admitted.
|
|
765
770
|
* - `on` — the reserved {@link EmitterHooks} key: initial listeners for the agent's
|
|
766
771
|
* {@link AgentEventMap}, wired at construction (for example `{ finish: (r) => log(r) }`).
|
|
767
772
|
*/
|
|
@@ -776,7 +781,16 @@ export declare interface AgentOptions {
|
|
|
776
781
|
readonly instructions?: InstructionManagerInterface;
|
|
777
782
|
/** Reuses a pre-built workspace registry forwarded to the agent's context; a fresh empty one is created when omitted. */
|
|
778
783
|
readonly workspaces?: WorkspaceManagerInterface;
|
|
779
|
-
/**
|
|
784
|
+
/**
|
|
785
|
+
* Sets the initial active scope; `undefined` admits every registered tool.
|
|
786
|
+
* Each turn snapshots the scope's tool allow-list before advertising and checks calls
|
|
787
|
+
* against that list before applying authority. An absent list also admits unknown names
|
|
788
|
+
* to authority and the registry, which returns its tool-not-found failure.
|
|
789
|
+
* A reply to a turn advertising no tools ends the run as its answer, records an assistant
|
|
790
|
+
* message without calls, and emits a `deny` event for every dropped call without marking it partial.
|
|
791
|
+
* Other scoped-out calls produce denial tool results and messages, and the loop continues.
|
|
792
|
+
* Changing the context scope through the `apply` method takes effect on the next turn.
|
|
793
|
+
*/
|
|
780
794
|
readonly scope?: ScopeInterface;
|
|
781
795
|
/** Caps the tool-iteration turns before the loop stops; defaults to `DEFAULT_AGENT_LIMIT`. */
|
|
782
796
|
readonly limit?: number;
|
|
@@ -789,11 +803,11 @@ export declare interface AgentOptions {
|
|
|
789
803
|
/** Carries an external cancel; its abort commits a partial result. */
|
|
790
804
|
readonly signal?: AbortSignal;
|
|
791
805
|
/**
|
|
792
|
-
* Holds an optional policy gate consulted
|
|
806
|
+
* Holds an optional policy gate consulted after scope admits a tool call — a denied call is
|
|
793
807
|
* fed back to the model as a denial {@link ToolResult} (a `tool` chunk + a tool
|
|
794
808
|
* message) rather than executed (no tool run, no budget cost), so the model sees the
|
|
795
|
-
* denial and can react; an allowed call dispatches normally. Omitted ⇒ every call
|
|
796
|
-
* dispatches
|
|
809
|
+
* denial and can react; an allowed call dispatches normally. Omitted ⇒ every admitted call
|
|
810
|
+
* dispatches through the registry.
|
|
797
811
|
*/
|
|
798
812
|
readonly authority?: AuthorityInterface;
|
|
799
813
|
/**
|
|
@@ -1138,6 +1152,11 @@ export declare interface AgentResult {
|
|
|
1138
1152
|
readonly thinking?: string;
|
|
1139
1153
|
/** Holds the summed {@link TokenUsage} across the turn's provider calls (present when any reported it). */
|
|
1140
1154
|
readonly usage?: TokenUsage;
|
|
1155
|
+
/**
|
|
1156
|
+
* Reports cancellation or a turn limit reached with unresolved tool intent.
|
|
1157
|
+
* A reply to a turn advertising no tools is a complete answer (`false`), even if it
|
|
1158
|
+
* contains calls: those calls are dropped and observed through the `deny` event.
|
|
1159
|
+
*/
|
|
1141
1160
|
readonly partial: boolean;
|
|
1142
1161
|
}
|
|
1143
1162
|
|
|
@@ -5193,7 +5212,11 @@ export declare class Scope implements ScopeInterface {
|
|
|
5193
5212
|
export declare interface ScopeFilter {
|
|
5194
5213
|
/** Lists the allowed instruction `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
|
|
5195
5214
|
readonly instructions?: readonly string[];
|
|
5196
|
-
/**
|
|
5215
|
+
/**
|
|
5216
|
+
* Lists the allowed tool `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
|
|
5217
|
+
* The loop advertises and dispatches only admitted tools, checking scope before authority.
|
|
5218
|
+
* If no definition is advertised, the reply ends the run without dispatching its calls.
|
|
5219
|
+
*/
|
|
5197
5220
|
readonly tools?: readonly string[];
|
|
5198
5221
|
/**
|
|
5199
5222
|
* Lists the allowed active-workspace file `path`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed) —
|
package/dist/src/core/index.js
CHANGED
|
@@ -2447,7 +2447,8 @@ var Agent = class {
|
|
|
2447
2447
|
broke = true;
|
|
2448
2448
|
break;
|
|
2449
2449
|
}
|
|
2450
|
-
const
|
|
2450
|
+
const names = this.#context.scope?.tools?.slice();
|
|
2451
|
+
const advertised = filterAllowList(names, tools.definitions(), (definition) => definition.name);
|
|
2451
2452
|
const definitions = advertised.length > 0 ? advertised : void 0;
|
|
2452
2453
|
let charged = 0;
|
|
2453
2454
|
let turnContent = "";
|
|
@@ -2501,8 +2502,10 @@ var Agent = class {
|
|
|
2501
2502
|
usage: resultUsage
|
|
2502
2503
|
};
|
|
2503
2504
|
}
|
|
2504
|
-
if (
|
|
2505
|
-
|
|
2505
|
+
if (definitions === void 0) for (const call of result.tools ?? []) this.#emitter.emit("deny", call, "no tool is advertised in the active scope");
|
|
2506
|
+
else if (result.tools !== void 0 && result.tools.length > 0) {
|
|
2507
|
+
const admitted = filterAllowList(names, result.tools, (call) => call.name);
|
|
2508
|
+
const authorization = this.#authorize(result.tools, admitted);
|
|
2506
2509
|
if (abort.signal.aborted) {
|
|
2507
2510
|
partial = true;
|
|
2508
2511
|
broke = true;
|
|
@@ -2574,24 +2577,33 @@ var Agent = class {
|
|
|
2574
2577
|
messages.splice(0, messages.length, ...this.#context.build(this.#provider.format));
|
|
2575
2578
|
return false;
|
|
2576
2579
|
}
|
|
2577
|
-
#authorize(calls) {
|
|
2578
|
-
if (this.#authority === void 0) return void 0;
|
|
2580
|
+
#authorize(calls, admitted) {
|
|
2579
2581
|
const authority = this.#authority;
|
|
2580
|
-
const allowed =
|
|
2582
|
+
const allowed = /* @__PURE__ */ new Map();
|
|
2581
2583
|
const denials = /* @__PURE__ */ new Map();
|
|
2582
|
-
for (const call of calls) {
|
|
2584
|
+
for (const [index, call] of calls.entries()) {
|
|
2585
|
+
if (!admitted.includes(call)) {
|
|
2586
|
+
const reason = `${call.name} is not in the active scope`;
|
|
2587
|
+
denials.set(index, denyCall(call, reason));
|
|
2588
|
+
this.#emitter.emit("deny", call, reason);
|
|
2589
|
+
continue;
|
|
2590
|
+
}
|
|
2591
|
+
if (authority === void 0) {
|
|
2592
|
+
allowed.set(index, call);
|
|
2593
|
+
continue;
|
|
2594
|
+
}
|
|
2583
2595
|
let decision;
|
|
2584
2596
|
try {
|
|
2585
2597
|
decision = authority.evaluate({ call });
|
|
2586
2598
|
} catch (error) {
|
|
2587
2599
|
const reason = errorToMessage(error);
|
|
2588
|
-
denials.set(
|
|
2600
|
+
denials.set(index, denyCall(call, reason));
|
|
2589
2601
|
this.#emitter.emit("deny", call, reason);
|
|
2590
2602
|
continue;
|
|
2591
2603
|
}
|
|
2592
|
-
if (decision.allowed) allowed.
|
|
2604
|
+
if (decision.allowed) allowed.set(index, call);
|
|
2593
2605
|
else {
|
|
2594
|
-
denials.set(
|
|
2606
|
+
denials.set(index, denyCall(call, decision.reason));
|
|
2595
2607
|
this.#emitter.emit("deny", call, decision.reason);
|
|
2596
2608
|
}
|
|
2597
2609
|
}
|
|
@@ -2601,12 +2613,16 @@ var Agent = class {
|
|
|
2601
2613
|
};
|
|
2602
2614
|
}
|
|
2603
2615
|
async #dispatch(tools, calls, signal, authorization) {
|
|
2604
|
-
if (authorization === void 0) return tools.execute(calls, { signal });
|
|
2605
2616
|
const { allowed, denials } = authorization;
|
|
2606
|
-
const executed = allowed.
|
|
2607
|
-
const
|
|
2608
|
-
|
|
2609
|
-
|
|
2617
|
+
const executed = allowed.size > 0 ? await tools.execute([...allowed.values()], { signal }) : [];
|
|
2618
|
+
const results = new Map(denials);
|
|
2619
|
+
let offset = 0;
|
|
2620
|
+
for (const index of allowed.keys()) {
|
|
2621
|
+
const result = executed[offset];
|
|
2622
|
+
if (result !== void 0) results.set(index, result);
|
|
2623
|
+
offset += 1;
|
|
2624
|
+
}
|
|
2625
|
+
return calls.map((call, index) => results.get(index) ?? denyCall(call, void 0));
|
|
2610
2626
|
}
|
|
2611
2627
|
async *#provide(messages, signal, definitions, think, schema, onDelta) {
|
|
2612
2628
|
const options = {};
|