@dudousxd/nestjs-agent-core 0.11.0 → 0.12.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 +73 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -3
- package/dist/index.d.ts +93 -3
- package/dist/index.js +68 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -98,6 +98,16 @@ interface ToolSpec {
|
|
|
98
98
|
targetAgent?: string;
|
|
99
99
|
/** Roles allowed to invoke. Undefined → defaults applied by RolesPolicy (e.g. ADMIN-only). */
|
|
100
100
|
roles?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* Whether the tool exists in this deployment. `false` (or a predicate returning `false`) drops it
|
|
103
|
+
* before the role filter, so it is never offered to the model and cannot be invoked. Undefined →
|
|
104
|
+
* enabled.
|
|
105
|
+
*
|
|
106
|
+
* A predicate is re-evaluated every turn, so a flag flipped at runtime takes effect on the next
|
|
107
|
+
* message with nothing re-registered. For availability that depends on injected services, put
|
|
108
|
+
* `isEnabled()` on the handler instead — a spec is data, a handler is a provider.
|
|
109
|
+
*/
|
|
110
|
+
enabled?: boolean | (() => boolean | Promise<boolean>);
|
|
101
111
|
/**
|
|
102
112
|
* An authorization ability name (e.g. 'cache.purge'). Consumed by an ability-aware RolesPolicy
|
|
103
113
|
* such as the `@dudousxd/nestjs-agent-authz` Gate adapter. Apps that don't use authz ignore it
|
|
@@ -465,6 +475,33 @@ interface AiToolCtx {
|
|
|
465
475
|
/** A tool implementation. `I` is the parsed (Zod-validated) input. */
|
|
466
476
|
interface ToolHandler<I = unknown> {
|
|
467
477
|
execute(input: I, ctx: AiToolCtx): Promise<unknown>;
|
|
478
|
+
/**
|
|
479
|
+
* Whether this tool exists in this deployment at all — evaluated per turn, BEFORE the roles
|
|
480
|
+
* policy, so a `false` here means the model is never shown the tool rather than being shown one
|
|
481
|
+
* it will be refused. Omit → always enabled.
|
|
482
|
+
*
|
|
483
|
+
* This is the seam for a feature flag or a licensing tier: the handler is an ordinary provider,
|
|
484
|
+
* so it can read injected config (`this.config.featureX`) that a decorator, evaluated at import
|
|
485
|
+
* time, cannot. Answering "does this capability exist here?"; `roles`/`RolesPolicy` answers the
|
|
486
|
+
* separate question "may THIS actor use it?", and both still run.
|
|
487
|
+
*
|
|
488
|
+
* Prefer this over conditionally registering the provider: registration happens while the
|
|
489
|
+
* `@Module` metadata is built, which in most apps is before configuration is loaded.
|
|
490
|
+
*/
|
|
491
|
+
isEnabled?(): boolean | Promise<boolean>;
|
|
492
|
+
/**
|
|
493
|
+
* Whether THIS actor may use the tool, decided per turn. Omit → the role gate alone decides.
|
|
494
|
+
*
|
|
495
|
+
* The three existing gates all answer the question somewhere else: `roles` is static data,
|
|
496
|
+
* `RolesPolicy` is one app-wide rule for every tool, and an agent's `tools` allow-list is fixed
|
|
497
|
+
* when the agent is declared. This one lives on the tool and runs with DI, so it can ask the
|
|
498
|
+
* questions only the tool knows to ask — is this user's org on the plan that includes it, does
|
|
499
|
+
* this actor own the base being queried, is the per-user override in the DB set today.
|
|
500
|
+
*
|
|
501
|
+
* Runs AFTER {@link isEnabled} and the `RolesPolicy`, and all of them must pass. Applied both
|
|
502
|
+
* when the turn's tool list is built (a denied actor is never shown it) and again on invoke.
|
|
503
|
+
*/
|
|
504
|
+
canUse?(actor: Actor): boolean | Promise<boolean>;
|
|
468
505
|
}
|
|
469
506
|
|
|
470
507
|
/**
|
|
@@ -1404,6 +1441,36 @@ declare function dayBoundsUtc(range: GovernanceRange): {
|
|
|
1404
1441
|
end: Date;
|
|
1405
1442
|
};
|
|
1406
1443
|
|
|
1444
|
+
/**
|
|
1445
|
+
* Is this tool part of this deployment right now? `ToolSpec.enabled` and the handler's
|
|
1446
|
+
* `isEnabled()` are ANDed — either one saying no is enough — and both default to yes.
|
|
1447
|
+
*
|
|
1448
|
+
* Resolved per turn rather than at registration, so the answer can come from configuration that
|
|
1449
|
+
* did not exist when the module was built.
|
|
1450
|
+
*/
|
|
1451
|
+
declare function isToolEnabled(spec: ToolSpec, handler?: ToolHandler): Promise<boolean>;
|
|
1452
|
+
/**
|
|
1453
|
+
* Zeroth filter layer: drop tools this deployment has turned off, before anyone asks who may call
|
|
1454
|
+
* them. A disabled tool is absent, not forbidden — the difference matters, because "forbidden"
|
|
1455
|
+
* tells the model (and the user reading a refusal) that the capability exists.
|
|
1456
|
+
*/
|
|
1457
|
+
declare function filterToolsByEnabled<T extends {
|
|
1458
|
+
spec: ToolSpec;
|
|
1459
|
+
handler?: ToolHandler;
|
|
1460
|
+
}>(entries: T[]): Promise<T[]>;
|
|
1461
|
+
/**
|
|
1462
|
+
* May this actor use this tool, per the tool's OWN gate? Tools without a `canUse` say yes and are
|
|
1463
|
+
* governed by the `RolesPolicy` alone.
|
|
1464
|
+
*/
|
|
1465
|
+
declare function canActorUseTool(actor: Actor, handler?: ToolHandler): Promise<boolean>;
|
|
1466
|
+
/**
|
|
1467
|
+
* Third filter layer: drop tools whose own `canUse` refuses this actor. Runs after the app-wide
|
|
1468
|
+
* `RolesPolicy`, and is additive to it — a tool can narrow who reaches it, never widen.
|
|
1469
|
+
*/
|
|
1470
|
+
declare function filterToolsByCanUse<T extends {
|
|
1471
|
+
spec: ToolSpec;
|
|
1472
|
+
handler?: ToolHandler;
|
|
1473
|
+
}>(entries: T[], actor: Actor): Promise<T[]>;
|
|
1407
1474
|
/** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */
|
|
1408
1475
|
declare function filterToolsByRole(tools: ToolSpec[], actor: Actor, policy: RolesPolicy): Promise<ToolSpec[]>;
|
|
1409
1476
|
/** Second filter layer: if the agent pins an allow-list, keep only those tool names. */
|
|
@@ -1423,6 +1490,19 @@ declare class ToolForbiddenError extends Error {
|
|
|
1423
1490
|
readonly toolName: string;
|
|
1424
1491
|
constructor(toolName: string);
|
|
1425
1492
|
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Thrown when a registered tool is invoked while this deployment has it turned off (`enabled` /
|
|
1495
|
+
* `isEnabled()`). Distinct from {@link ToolForbiddenError}, which is about the actor, and from
|
|
1496
|
+
* {@link ToolNotFoundError}, which is about a name nobody registered — an operator reading a log
|
|
1497
|
+
* needs to tell "you flipped the flag" apart from "that tool does not exist in this build".
|
|
1498
|
+
*
|
|
1499
|
+
* Reachable in normal operation, not just from a forged call: a HITL `action` approved before the
|
|
1500
|
+
* flag was turned off runs its tool afterwards.
|
|
1501
|
+
*/
|
|
1502
|
+
declare class ToolDisabledError extends Error {
|
|
1503
|
+
readonly toolName: string;
|
|
1504
|
+
constructor(toolName: string);
|
|
1505
|
+
}
|
|
1426
1506
|
/** Thrown when a tool is invoked that was never registered. */
|
|
1427
1507
|
declare class ToolNotFoundError extends Error {
|
|
1428
1508
|
readonly toolName: string;
|
|
@@ -1447,9 +1527,19 @@ declare class ToolRegistry {
|
|
|
1447
1527
|
has(name: string): boolean;
|
|
1448
1528
|
spec(name: string): ToolSpec | undefined;
|
|
1449
1529
|
allSpecs(): ToolSpec[];
|
|
1450
|
-
/**
|
|
1530
|
+
/**
|
|
1531
|
+
* The tools to offer the model for this actor+agent, after the four filter layers: what this
|
|
1532
|
+
* deployment has enabled, what this actor's role allows, what each tool's own `canUse` allows
|
|
1533
|
+
* this actor, and finally what this agent pinned.
|
|
1534
|
+
*
|
|
1535
|
+
* Every layer only ever removes tools, so no arrangement of them can widen what a turn reaches.
|
|
1536
|
+
*/
|
|
1451
1537
|
definitionsFor(actor: Actor, policy: RolesPolicy, allowedTools?: string[]): Promise<ToolDefinition[]>;
|
|
1452
|
-
/**
|
|
1538
|
+
/**
|
|
1539
|
+
* Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —
|
|
1540
|
+
* a call can reach here from a replayed durable step or an approval granted before the flag
|
|
1541
|
+
* moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.
|
|
1542
|
+
*/
|
|
1453
1543
|
invoke(name: string, input: unknown, ctx: AiToolCtx, policy: RolesPolicy): Promise<unknown>;
|
|
1454
1544
|
}
|
|
1455
1545
|
/** Default gate: one of the actor's roles must be in spec.roles (defaulting to ADMIN-only). */
|
|
@@ -1745,4 +1835,4 @@ type AgentDiagnosticKey = `agent:${AgentDiagnosticEvent}`;
|
|
|
1745
1835
|
*/
|
|
1746
1836
|
declare function agentDiagnosticKey(event: AgentDiagnosticEvent): AgentDiagnosticKey;
|
|
1747
1837
|
|
|
1748
|
-
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type ApprovalWhere, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type DetailThreadRef, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceRunDetail, type GovernanceThreadDetail, type GovernanceThreadDetailQuery, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunToolCallRow, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, THREAD_DETAIL_CONTENT_CHARS, type ThreadActivityRow, type ThreadDetail, type ThreadMessageRow, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadUsageRollup, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByRole, invokeWithTransientRetry, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, rollupThreadUsage, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, truncateDetailContent, withToolTimeout };
|
|
1838
|
+
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type ApprovalWhere, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type DetailThreadRef, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceRunDetail, type GovernanceThreadDetail, type GovernanceThreadDetailQuery, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunToolCallRow, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, THREAD_DETAIL_CONTENT_CHARS, type ThreadActivityRow, type ThreadDetail, type ThreadMessageRow, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadUsageRollup, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolDisabledError, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, canActorUseTool, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByCanUse, filterToolsByEnabled, filterToolsByRole, invokeWithTransientRetry, isToolEnabled, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, rollupThreadUsage, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, truncateDetailContent, withToolTimeout };
|
package/dist/index.d.ts
CHANGED
|
@@ -98,6 +98,16 @@ interface ToolSpec {
|
|
|
98
98
|
targetAgent?: string;
|
|
99
99
|
/** Roles allowed to invoke. Undefined → defaults applied by RolesPolicy (e.g. ADMIN-only). */
|
|
100
100
|
roles?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* Whether the tool exists in this deployment. `false` (or a predicate returning `false`) drops it
|
|
103
|
+
* before the role filter, so it is never offered to the model and cannot be invoked. Undefined →
|
|
104
|
+
* enabled.
|
|
105
|
+
*
|
|
106
|
+
* A predicate is re-evaluated every turn, so a flag flipped at runtime takes effect on the next
|
|
107
|
+
* message with nothing re-registered. For availability that depends on injected services, put
|
|
108
|
+
* `isEnabled()` on the handler instead — a spec is data, a handler is a provider.
|
|
109
|
+
*/
|
|
110
|
+
enabled?: boolean | (() => boolean | Promise<boolean>);
|
|
101
111
|
/**
|
|
102
112
|
* An authorization ability name (e.g. 'cache.purge'). Consumed by an ability-aware RolesPolicy
|
|
103
113
|
* such as the `@dudousxd/nestjs-agent-authz` Gate adapter. Apps that don't use authz ignore it
|
|
@@ -465,6 +475,33 @@ interface AiToolCtx {
|
|
|
465
475
|
/** A tool implementation. `I` is the parsed (Zod-validated) input. */
|
|
466
476
|
interface ToolHandler<I = unknown> {
|
|
467
477
|
execute(input: I, ctx: AiToolCtx): Promise<unknown>;
|
|
478
|
+
/**
|
|
479
|
+
* Whether this tool exists in this deployment at all — evaluated per turn, BEFORE the roles
|
|
480
|
+
* policy, so a `false` here means the model is never shown the tool rather than being shown one
|
|
481
|
+
* it will be refused. Omit → always enabled.
|
|
482
|
+
*
|
|
483
|
+
* This is the seam for a feature flag or a licensing tier: the handler is an ordinary provider,
|
|
484
|
+
* so it can read injected config (`this.config.featureX`) that a decorator, evaluated at import
|
|
485
|
+
* time, cannot. Answering "does this capability exist here?"; `roles`/`RolesPolicy` answers the
|
|
486
|
+
* separate question "may THIS actor use it?", and both still run.
|
|
487
|
+
*
|
|
488
|
+
* Prefer this over conditionally registering the provider: registration happens while the
|
|
489
|
+
* `@Module` metadata is built, which in most apps is before configuration is loaded.
|
|
490
|
+
*/
|
|
491
|
+
isEnabled?(): boolean | Promise<boolean>;
|
|
492
|
+
/**
|
|
493
|
+
* Whether THIS actor may use the tool, decided per turn. Omit → the role gate alone decides.
|
|
494
|
+
*
|
|
495
|
+
* The three existing gates all answer the question somewhere else: `roles` is static data,
|
|
496
|
+
* `RolesPolicy` is one app-wide rule for every tool, and an agent's `tools` allow-list is fixed
|
|
497
|
+
* when the agent is declared. This one lives on the tool and runs with DI, so it can ask the
|
|
498
|
+
* questions only the tool knows to ask — is this user's org on the plan that includes it, does
|
|
499
|
+
* this actor own the base being queried, is the per-user override in the DB set today.
|
|
500
|
+
*
|
|
501
|
+
* Runs AFTER {@link isEnabled} and the `RolesPolicy`, and all of them must pass. Applied both
|
|
502
|
+
* when the turn's tool list is built (a denied actor is never shown it) and again on invoke.
|
|
503
|
+
*/
|
|
504
|
+
canUse?(actor: Actor): boolean | Promise<boolean>;
|
|
468
505
|
}
|
|
469
506
|
|
|
470
507
|
/**
|
|
@@ -1404,6 +1441,36 @@ declare function dayBoundsUtc(range: GovernanceRange): {
|
|
|
1404
1441
|
end: Date;
|
|
1405
1442
|
};
|
|
1406
1443
|
|
|
1444
|
+
/**
|
|
1445
|
+
* Is this tool part of this deployment right now? `ToolSpec.enabled` and the handler's
|
|
1446
|
+
* `isEnabled()` are ANDed — either one saying no is enough — and both default to yes.
|
|
1447
|
+
*
|
|
1448
|
+
* Resolved per turn rather than at registration, so the answer can come from configuration that
|
|
1449
|
+
* did not exist when the module was built.
|
|
1450
|
+
*/
|
|
1451
|
+
declare function isToolEnabled(spec: ToolSpec, handler?: ToolHandler): Promise<boolean>;
|
|
1452
|
+
/**
|
|
1453
|
+
* Zeroth filter layer: drop tools this deployment has turned off, before anyone asks who may call
|
|
1454
|
+
* them. A disabled tool is absent, not forbidden — the difference matters, because "forbidden"
|
|
1455
|
+
* tells the model (and the user reading a refusal) that the capability exists.
|
|
1456
|
+
*/
|
|
1457
|
+
declare function filterToolsByEnabled<T extends {
|
|
1458
|
+
spec: ToolSpec;
|
|
1459
|
+
handler?: ToolHandler;
|
|
1460
|
+
}>(entries: T[]): Promise<T[]>;
|
|
1461
|
+
/**
|
|
1462
|
+
* May this actor use this tool, per the tool's OWN gate? Tools without a `canUse` say yes and are
|
|
1463
|
+
* governed by the `RolesPolicy` alone.
|
|
1464
|
+
*/
|
|
1465
|
+
declare function canActorUseTool(actor: Actor, handler?: ToolHandler): Promise<boolean>;
|
|
1466
|
+
/**
|
|
1467
|
+
* Third filter layer: drop tools whose own `canUse` refuses this actor. Runs after the app-wide
|
|
1468
|
+
* `RolesPolicy`, and is additive to it — a tool can narrow who reaches it, never widen.
|
|
1469
|
+
*/
|
|
1470
|
+
declare function filterToolsByCanUse<T extends {
|
|
1471
|
+
spec: ToolSpec;
|
|
1472
|
+
handler?: ToolHandler;
|
|
1473
|
+
}>(entries: T[], actor: Actor): Promise<T[]>;
|
|
1407
1474
|
/** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */
|
|
1408
1475
|
declare function filterToolsByRole(tools: ToolSpec[], actor: Actor, policy: RolesPolicy): Promise<ToolSpec[]>;
|
|
1409
1476
|
/** Second filter layer: if the agent pins an allow-list, keep only those tool names. */
|
|
@@ -1423,6 +1490,19 @@ declare class ToolForbiddenError extends Error {
|
|
|
1423
1490
|
readonly toolName: string;
|
|
1424
1491
|
constructor(toolName: string);
|
|
1425
1492
|
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Thrown when a registered tool is invoked while this deployment has it turned off (`enabled` /
|
|
1495
|
+
* `isEnabled()`). Distinct from {@link ToolForbiddenError}, which is about the actor, and from
|
|
1496
|
+
* {@link ToolNotFoundError}, which is about a name nobody registered — an operator reading a log
|
|
1497
|
+
* needs to tell "you flipped the flag" apart from "that tool does not exist in this build".
|
|
1498
|
+
*
|
|
1499
|
+
* Reachable in normal operation, not just from a forged call: a HITL `action` approved before the
|
|
1500
|
+
* flag was turned off runs its tool afterwards.
|
|
1501
|
+
*/
|
|
1502
|
+
declare class ToolDisabledError extends Error {
|
|
1503
|
+
readonly toolName: string;
|
|
1504
|
+
constructor(toolName: string);
|
|
1505
|
+
}
|
|
1426
1506
|
/** Thrown when a tool is invoked that was never registered. */
|
|
1427
1507
|
declare class ToolNotFoundError extends Error {
|
|
1428
1508
|
readonly toolName: string;
|
|
@@ -1447,9 +1527,19 @@ declare class ToolRegistry {
|
|
|
1447
1527
|
has(name: string): boolean;
|
|
1448
1528
|
spec(name: string): ToolSpec | undefined;
|
|
1449
1529
|
allSpecs(): ToolSpec[];
|
|
1450
|
-
/**
|
|
1530
|
+
/**
|
|
1531
|
+
* The tools to offer the model for this actor+agent, after the four filter layers: what this
|
|
1532
|
+
* deployment has enabled, what this actor's role allows, what each tool's own `canUse` allows
|
|
1533
|
+
* this actor, and finally what this agent pinned.
|
|
1534
|
+
*
|
|
1535
|
+
* Every layer only ever removes tools, so no arrangement of them can widen what a turn reaches.
|
|
1536
|
+
*/
|
|
1451
1537
|
definitionsFor(actor: Actor, policy: RolesPolicy, allowedTools?: string[]): Promise<ToolDefinition[]>;
|
|
1452
|
-
/**
|
|
1538
|
+
/**
|
|
1539
|
+
* Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —
|
|
1540
|
+
* a call can reach here from a replayed durable step or an approval granted before the flag
|
|
1541
|
+
* moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.
|
|
1542
|
+
*/
|
|
1453
1543
|
invoke(name: string, input: unknown, ctx: AiToolCtx, policy: RolesPolicy): Promise<unknown>;
|
|
1454
1544
|
}
|
|
1455
1545
|
/** Default gate: one of the actor's roles must be in spec.roles (defaulting to ADMIN-only). */
|
|
@@ -1745,4 +1835,4 @@ type AgentDiagnosticKey = `agent:${AgentDiagnosticEvent}`;
|
|
|
1745
1835
|
*/
|
|
1746
1836
|
declare function agentDiagnosticKey(event: AgentDiagnosticEvent): AgentDiagnosticKey;
|
|
1747
1837
|
|
|
1748
|
-
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type ApprovalWhere, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type DetailThreadRef, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceRunDetail, type GovernanceThreadDetail, type GovernanceThreadDetailQuery, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunToolCallRow, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, THREAD_DETAIL_CONTENT_CHARS, type ThreadActivityRow, type ThreadDetail, type ThreadMessageRow, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadUsageRollup, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByRole, invokeWithTransientRetry, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, rollupThreadUsage, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, truncateDetailContent, withToolTimeout };
|
|
1838
|
+
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type ApprovalWhere, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type DetailThreadRef, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceRunDetail, type GovernanceThreadDetail, type GovernanceThreadDetailQuery, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunToolCallRow, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, THREAD_DETAIL_CONTENT_CHARS, type ThreadActivityRow, type ThreadDetail, type ThreadMessageRow, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadUsageRollup, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolDisabledError, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, canActorUseTool, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByCanUse, filterToolsByEnabled, filterToolsByRole, invokeWithTransientRetry, isToolEnabled, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, rollupThreadUsage, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, truncateDetailContent, withToolTimeout };
|
package/dist/index.js
CHANGED
|
@@ -223,6 +223,34 @@ function dayBoundsUtc(range) {
|
|
|
223
223
|
__name(dayBoundsUtc, "dayBoundsUtc");
|
|
224
224
|
|
|
225
225
|
// src/tool-filters.ts
|
|
226
|
+
async function isToolEnabled(spec, handler) {
|
|
227
|
+
const declared = typeof spec.enabled === "function" ? await spec.enabled() : spec.enabled ?? true;
|
|
228
|
+
if (!declared) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
return handler?.isEnabled === void 0 ? true : await handler.isEnabled();
|
|
232
|
+
}
|
|
233
|
+
__name(isToolEnabled, "isToolEnabled");
|
|
234
|
+
async function filterToolsByEnabled(entries) {
|
|
235
|
+
const checked = await Promise.all(entries.map(async (entry) => ({
|
|
236
|
+
entry,
|
|
237
|
+
enabled: await isToolEnabled(entry.spec, entry.handler)
|
|
238
|
+
})));
|
|
239
|
+
return checked.filter((row) => row.enabled).map((row) => row.entry);
|
|
240
|
+
}
|
|
241
|
+
__name(filterToolsByEnabled, "filterToolsByEnabled");
|
|
242
|
+
async function canActorUseTool(actor, handler) {
|
|
243
|
+
return handler?.canUse === void 0 ? true : await handler.canUse(actor);
|
|
244
|
+
}
|
|
245
|
+
__name(canActorUseTool, "canActorUseTool");
|
|
246
|
+
async function filterToolsByCanUse(entries, actor) {
|
|
247
|
+
const checked = await Promise.all(entries.map(async (entry) => ({
|
|
248
|
+
entry,
|
|
249
|
+
allowed: await canActorUseTool(actor, entry.handler)
|
|
250
|
+
})));
|
|
251
|
+
return checked.filter((row) => row.allowed).map((row) => row.entry);
|
|
252
|
+
}
|
|
253
|
+
__name(filterToolsByCanUse, "filterToolsByCanUse");
|
|
226
254
|
async function filterToolsByRole(tools, actor, policy) {
|
|
227
255
|
const checked = await Promise.all(tools.map(async (tool) => ({
|
|
228
256
|
tool,
|
|
@@ -273,6 +301,16 @@ var ToolForbiddenError = class extends Error {
|
|
|
273
301
|
this.name = "ToolForbiddenError";
|
|
274
302
|
}
|
|
275
303
|
};
|
|
304
|
+
var ToolDisabledError = class extends Error {
|
|
305
|
+
static {
|
|
306
|
+
__name(this, "ToolDisabledError");
|
|
307
|
+
}
|
|
308
|
+
toolName;
|
|
309
|
+
constructor(toolName) {
|
|
310
|
+
super(`Tool "${toolName}" is disabled in this deployment`), this.toolName = toolName;
|
|
311
|
+
this.name = "ToolDisabledError";
|
|
312
|
+
}
|
|
313
|
+
};
|
|
276
314
|
var ToolNotFoundError = class extends Error {
|
|
277
315
|
static {
|
|
278
316
|
__name(this, "ToolNotFoundError");
|
|
@@ -316,10 +354,21 @@ var ToolRegistry = class {
|
|
|
316
354
|
...this.entries.values()
|
|
317
355
|
].map((entry) => entry.spec);
|
|
318
356
|
}
|
|
319
|
-
/**
|
|
357
|
+
/**
|
|
358
|
+
* The tools to offer the model for this actor+agent, after the four filter layers: what this
|
|
359
|
+
* deployment has enabled, what this actor's role allows, what each tool's own `canUse` allows
|
|
360
|
+
* this actor, and finally what this agent pinned.
|
|
361
|
+
*
|
|
362
|
+
* Every layer only ever removes tools, so no arrangement of them can widen what a turn reaches.
|
|
363
|
+
*/
|
|
320
364
|
async definitionsFor(actor, policy, allowedTools) {
|
|
321
|
-
const
|
|
322
|
-
|
|
365
|
+
const live = await filterToolsByEnabled([
|
|
366
|
+
...this.entries.values()
|
|
367
|
+
]);
|
|
368
|
+
const allowedByRole = new Set((await filterToolsByRole(live.map((entry) => entry.spec), actor, policy)).map((spec) => spec.name));
|
|
369
|
+
const roleScoped = live.filter((entry) => allowedByRole.has(entry.spec.name));
|
|
370
|
+
const actorScoped = await filterToolsByCanUse(roleScoped, actor);
|
|
371
|
+
const allowScoped = filterToolsByAllowList(actorScoped.map((entry) => entry.spec), allowedTools);
|
|
323
372
|
return allowScoped.map((spec) => ({
|
|
324
373
|
name: spec.name,
|
|
325
374
|
kind: spec.kind,
|
|
@@ -327,15 +376,25 @@ var ToolRegistry = class {
|
|
|
327
376
|
inputSchema: spec.inputSchema
|
|
328
377
|
}));
|
|
329
378
|
}
|
|
330
|
-
/**
|
|
379
|
+
/**
|
|
380
|
+
* Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —
|
|
381
|
+
* a call can reach here from a replayed durable step or an approval granted before the flag
|
|
382
|
+
* moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.
|
|
383
|
+
*/
|
|
331
384
|
async invoke(name, input, ctx, policy) {
|
|
332
385
|
const entry = this.entries.get(name);
|
|
333
386
|
if (entry === void 0) {
|
|
334
387
|
throw new ToolNotFoundError(name);
|
|
335
388
|
}
|
|
389
|
+
if (!await isToolEnabled(entry.spec, entry.handler)) {
|
|
390
|
+
throw new ToolDisabledError(name);
|
|
391
|
+
}
|
|
336
392
|
if (!await policy.can(ctx.actor, entry.spec)) {
|
|
337
393
|
throw new ToolForbiddenError(name);
|
|
338
394
|
}
|
|
395
|
+
if (!await canActorUseTool(ctx.actor, entry.handler)) {
|
|
396
|
+
throw new ToolForbiddenError(name);
|
|
397
|
+
}
|
|
339
398
|
const validation = await entry.spec.inputSchema["~standard"].validate(input);
|
|
340
399
|
if (validation.issues !== void 0) {
|
|
341
400
|
throw new ToolInputInvalidError(name, validation.issues);
|
|
@@ -1213,6 +1272,7 @@ export {
|
|
|
1213
1272
|
DefaultRolesPolicy,
|
|
1214
1273
|
QuotaExceededError,
|
|
1215
1274
|
THREAD_DETAIL_CONTENT_CHARS,
|
|
1275
|
+
ToolDisabledError,
|
|
1216
1276
|
ToolForbiddenError,
|
|
1217
1277
|
ToolInputInvalidError,
|
|
1218
1278
|
ToolNotFoundError,
|
|
@@ -1222,12 +1282,16 @@ export {
|
|
|
1222
1282
|
bucketByModel,
|
|
1223
1283
|
bucketByThread,
|
|
1224
1284
|
bucketUsageTrend,
|
|
1285
|
+
canActorUseTool,
|
|
1225
1286
|
dayBoundsUtc,
|
|
1226
1287
|
encodeStreamEvent,
|
|
1227
1288
|
estimateCost,
|
|
1228
1289
|
filterToolsByAllowList,
|
|
1290
|
+
filterToolsByCanUse,
|
|
1291
|
+
filterToolsByEnabled,
|
|
1229
1292
|
filterToolsByRole,
|
|
1230
1293
|
invokeWithTransientRetry,
|
|
1294
|
+
isToolEnabled,
|
|
1231
1295
|
isTransientToolError,
|
|
1232
1296
|
publishAgentDelegated,
|
|
1233
1297
|
publishAgentMessage,
|