@dudousxd/nestjs-agent-core 0.39.0 → 0.40.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-agent-core",
3
- "version": "0.39.0",
3
+ "version": "0.40.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/DavideCarvalho/nestjs-agent.git",
@@ -1,121 +0,0 @@
1
- import { StandardSchemaV1 } from '@standard-schema/spec';
2
- import { a as Actor, o as PageContext } from './stream-events-CbVEowYb.cjs';
3
-
4
- /**
5
- * Per-invocation context handed to a tool handler. Host-supplied bits are optional. Identity lives
6
- * on {@link AiToolCtx.actor} — read `ctx.actor.id` / `ctx.actor.tenantRef` (single source of truth;
7
- * no denormalized copies).
8
- */
9
- interface AiToolCtx {
10
- actor: Actor;
11
- threadId: string;
12
- runId: string;
13
- requestId: string;
14
- /**
15
- * The id of the tool call this invocation serves. Absent where a tool is invoked outside a turn
16
- * (the MCP server, a direct `registry.invoke`).
17
- */
18
- toolCallId?: string;
19
- /**
20
- * `<runId>:<toolCallId>` — the same value for every execution of THIS call, and for no other.
21
- *
22
- * A tool's side effect and the checkpoint that records it are two writes. Under the durable
23
- * runner a worker that dies between them leaves a call the journal does not know ran, and the
24
- * runtime's recovery runs it again; an in-step transient retry (a deadlock, a lock-wait timeout)
25
- * re-invokes it too. The library cannot make your write atomic with its journal — so it hands you
26
- * the key that makes the second attempt recognisable: pass it to whatever you call as its
27
- * idempotency key (a payment provider's `Idempotency-Key`, a unique column on the row you insert,
28
- * a workflow's `id`), and a re-execution lands on the first one's result instead of doing it
29
- * twice. Stable across replays and across pods: the run id is the run's own, and the call id
30
- * comes out of the journaled model step.
31
- *
32
- * Absent where a tool is invoked outside a turn (the MCP server, a direct `registry.invoke`).
33
- */
34
- idempotencyKey?: string;
35
- /** The name of the agent running this turn — provenance a tool can scope on (e.g. capability sets). */
36
- agentName?: string;
37
- /** The persona of {@link agentName} the turn runs under, when it runs under one. */
38
- persona?: string;
39
- pageContext?: PageContext;
40
- /** Optional host handle (e.g. an ORM EntityManager) the app threads through options. */
41
- host?: unknown;
42
- /**
43
- * Push a component into the assistant message: streamed live as a `ui` frame and persisted on
44
- * the message, so a reload shows it where the live stream did. Resolves to the component's id.
45
- *
46
- * `id` defaults to `<toolCallId>:ui:<n>` (the n-th push without an `id` in this invocation), so a retried or
47
- * re-executed call REPLACES what it pushed before instead of adding a second copy; pass your own
48
- * `id` to update one component across pushes (streaming rows into a table). `props` must be
49
- * JSON; it is snapshotted when pushed.
50
- *
51
- * Replay-safe under the durable runner: the pushed components ride the tool step's journaled
52
- * result, so a replay neither streams nor persists them again.
53
- *
54
- * Always present. On a surface with no conversation to push into (the MCP server, a direct
55
- * `registry.invoke` without one) it is a no-op that still resolves to an id, so a tool calls
56
- * `ctx.emitUi(…)` unconditionally.
57
- */
58
- emitUi(component: string, props: Record<string, unknown>, options?: {
59
- id?: string;
60
- version?: number;
61
- }): Promise<{
62
- id: string;
63
- }>;
64
- }
65
- /** A tool implementation. `I` is the parsed (Zod-validated) input. */
66
- interface ToolHandler<I = unknown> {
67
- execute(input: I, ctx: AiToolCtx): Promise<unknown>;
68
- /**
69
- * Whether this tool exists in this deployment at all — evaluated per turn, BEFORE the roles
70
- * policy, so a `false` here means the model is never shown the tool rather than being shown one
71
- * it will be refused. Omit → always enabled.
72
- *
73
- * This is the seam for a feature flag or a licensing tier: the handler is an ordinary provider,
74
- * so it can read injected config (`this.config.featureX`) that a decorator, evaluated at import
75
- * time, cannot. Answering "does this capability exist here?"; `roles`/`RolesPolicy` answers the
76
- * separate question "may THIS actor use it?", and both still run.
77
- *
78
- * Prefer this over conditionally registering the provider: registration happens while the
79
- * `@Module` metadata is built, which in most apps is before configuration is loaded.
80
- */
81
- isEnabled?(): boolean | Promise<boolean>;
82
- /**
83
- * Whether THIS actor may use the tool, decided per turn. Omit → the role gate alone decides.
84
- *
85
- * The three existing gates all answer the question somewhere else: `roles` is static data,
86
- * `RolesPolicy` is one app-wide rule for every tool, and an agent's `tools` allow-list is fixed
87
- * when the agent is declared. This one lives on the tool and runs with DI, so it can ask the
88
- * questions only the tool knows to ask — is this user's org on the plan that includes it, does
89
- * this actor own the base being queried, is the per-user override in the DB set today.
90
- *
91
- * Runs AFTER {@link isEnabled} and the `RolesPolicy`, and all of them must pass. Applied both
92
- * when the turn's tool list is built (a denied actor is never shown it) and again on invoke.
93
- */
94
- canUse?(actor: Actor): boolean | Promise<boolean>;
95
- /**
96
- * What the model is told about this tool for THIS turn — a description and/or input schema that
97
- * depend on who is asking (a per-tenant component catalog, a per-plan list of options). Called
98
- * when the turn's tool list is built, after every gate has passed; whatever it returns replaces
99
- * the registered spec's `description` / `inputSchema` in the definition the model sees. Omit, or
100
- * return `undefined`, to use the registered spec as is.
101
- *
102
- * It shapes what the model is SHOWN only: the registry still validates a call against the
103
- * registered `inputSchema`, so a tool whose accepted input varies per turn registers a permissive
104
- * schema and validates in `execute`.
105
- */
106
- describe?(scope: ToolDescribeScope): ToolDescription | undefined | Promise<ToolDescription | undefined>;
107
- }
108
- /** Who a turn's tool list is being built for — what {@link ToolHandler.describe} can vary on. */
109
- interface ToolDescribeScope {
110
- actor: Actor;
111
- /** Absent where the list is built outside a conversation (the MCP server's `tools/list`). */
112
- threadId?: string;
113
- agentName?: string;
114
- }
115
- /** A per-turn override of a tool's model-facing definition ({@link ToolHandler.describe}). */
116
- interface ToolDescription {
117
- description?: string;
118
- inputSchema?: StandardSchemaV1;
119
- }
120
-
121
- export type { AiToolCtx as A, ToolHandler as T, ToolDescribeScope as a, ToolDescription as b };
@@ -1,121 +0,0 @@
1
- import { StandardSchemaV1 } from '@standard-schema/spec';
2
- import { a as Actor, o as PageContext } from './stream-events-CbVEowYb.js';
3
-
4
- /**
5
- * Per-invocation context handed to a tool handler. Host-supplied bits are optional. Identity lives
6
- * on {@link AiToolCtx.actor} — read `ctx.actor.id` / `ctx.actor.tenantRef` (single source of truth;
7
- * no denormalized copies).
8
- */
9
- interface AiToolCtx {
10
- actor: Actor;
11
- threadId: string;
12
- runId: string;
13
- requestId: string;
14
- /**
15
- * The id of the tool call this invocation serves. Absent where a tool is invoked outside a turn
16
- * (the MCP server, a direct `registry.invoke`).
17
- */
18
- toolCallId?: string;
19
- /**
20
- * `<runId>:<toolCallId>` — the same value for every execution of THIS call, and for no other.
21
- *
22
- * A tool's side effect and the checkpoint that records it are two writes. Under the durable
23
- * runner a worker that dies between them leaves a call the journal does not know ran, and the
24
- * runtime's recovery runs it again; an in-step transient retry (a deadlock, a lock-wait timeout)
25
- * re-invokes it too. The library cannot make your write atomic with its journal — so it hands you
26
- * the key that makes the second attempt recognisable: pass it to whatever you call as its
27
- * idempotency key (a payment provider's `Idempotency-Key`, a unique column on the row you insert,
28
- * a workflow's `id`), and a re-execution lands on the first one's result instead of doing it
29
- * twice. Stable across replays and across pods: the run id is the run's own, and the call id
30
- * comes out of the journaled model step.
31
- *
32
- * Absent where a tool is invoked outside a turn (the MCP server, a direct `registry.invoke`).
33
- */
34
- idempotencyKey?: string;
35
- /** The name of the agent running this turn — provenance a tool can scope on (e.g. capability sets). */
36
- agentName?: string;
37
- /** The persona of {@link agentName} the turn runs under, when it runs under one. */
38
- persona?: string;
39
- pageContext?: PageContext;
40
- /** Optional host handle (e.g. an ORM EntityManager) the app threads through options. */
41
- host?: unknown;
42
- /**
43
- * Push a component into the assistant message: streamed live as a `ui` frame and persisted on
44
- * the message, so a reload shows it where the live stream did. Resolves to the component's id.
45
- *
46
- * `id` defaults to `<toolCallId>:ui:<n>` (the n-th push without an `id` in this invocation), so a retried or
47
- * re-executed call REPLACES what it pushed before instead of adding a second copy; pass your own
48
- * `id` to update one component across pushes (streaming rows into a table). `props` must be
49
- * JSON; it is snapshotted when pushed.
50
- *
51
- * Replay-safe under the durable runner: the pushed components ride the tool step's journaled
52
- * result, so a replay neither streams nor persists them again.
53
- *
54
- * Always present. On a surface with no conversation to push into (the MCP server, a direct
55
- * `registry.invoke` without one) it is a no-op that still resolves to an id, so a tool calls
56
- * `ctx.emitUi(…)` unconditionally.
57
- */
58
- emitUi(component: string, props: Record<string, unknown>, options?: {
59
- id?: string;
60
- version?: number;
61
- }): Promise<{
62
- id: string;
63
- }>;
64
- }
65
- /** A tool implementation. `I` is the parsed (Zod-validated) input. */
66
- interface ToolHandler<I = unknown> {
67
- execute(input: I, ctx: AiToolCtx): Promise<unknown>;
68
- /**
69
- * Whether this tool exists in this deployment at all — evaluated per turn, BEFORE the roles
70
- * policy, so a `false` here means the model is never shown the tool rather than being shown one
71
- * it will be refused. Omit → always enabled.
72
- *
73
- * This is the seam for a feature flag or a licensing tier: the handler is an ordinary provider,
74
- * so it can read injected config (`this.config.featureX`) that a decorator, evaluated at import
75
- * time, cannot. Answering "does this capability exist here?"; `roles`/`RolesPolicy` answers the
76
- * separate question "may THIS actor use it?", and both still run.
77
- *
78
- * Prefer this over conditionally registering the provider: registration happens while the
79
- * `@Module` metadata is built, which in most apps is before configuration is loaded.
80
- */
81
- isEnabled?(): boolean | Promise<boolean>;
82
- /**
83
- * Whether THIS actor may use the tool, decided per turn. Omit → the role gate alone decides.
84
- *
85
- * The three existing gates all answer the question somewhere else: `roles` is static data,
86
- * `RolesPolicy` is one app-wide rule for every tool, and an agent's `tools` allow-list is fixed
87
- * when the agent is declared. This one lives on the tool and runs with DI, so it can ask the
88
- * questions only the tool knows to ask — is this user's org on the plan that includes it, does
89
- * this actor own the base being queried, is the per-user override in the DB set today.
90
- *
91
- * Runs AFTER {@link isEnabled} and the `RolesPolicy`, and all of them must pass. Applied both
92
- * when the turn's tool list is built (a denied actor is never shown it) and again on invoke.
93
- */
94
- canUse?(actor: Actor): boolean | Promise<boolean>;
95
- /**
96
- * What the model is told about this tool for THIS turn — a description and/or input schema that
97
- * depend on who is asking (a per-tenant component catalog, a per-plan list of options). Called
98
- * when the turn's tool list is built, after every gate has passed; whatever it returns replaces
99
- * the registered spec's `description` / `inputSchema` in the definition the model sees. Omit, or
100
- * return `undefined`, to use the registered spec as is.
101
- *
102
- * It shapes what the model is SHOWN only: the registry still validates a call against the
103
- * registered `inputSchema`, so a tool whose accepted input varies per turn registers a permissive
104
- * schema and validates in `execute`.
105
- */
106
- describe?(scope: ToolDescribeScope): ToolDescription | undefined | Promise<ToolDescription | undefined>;
107
- }
108
- /** Who a turn's tool list is being built for — what {@link ToolHandler.describe} can vary on. */
109
- interface ToolDescribeScope {
110
- actor: Actor;
111
- /** Absent where the list is built outside a conversation (the MCP server's `tools/list`). */
112
- threadId?: string;
113
- agentName?: string;
114
- }
115
- /** A per-turn override of a tool's model-facing definition ({@link ToolHandler.describe}). */
116
- interface ToolDescription {
117
- description?: string;
118
- inputSchema?: StandardSchemaV1;
119
- }
120
-
121
- export type { AiToolCtx as A, ToolHandler as T, ToolDescribeScope as a, ToolDescription as b };