@dudousxd/nestjs-agent-core 0.18.0 → 0.19.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/README.md CHANGED
@@ -37,6 +37,7 @@ import type { ModelProvider, AgentStore, ToolSpec, RolesPolicy } from '@dudousxd
37
37
  - `settleAll(tasks)` / `SettledTask<T>` — the implementation behind the optional `AgentLoopHooks.parallel`, which is how a turn's `read` tool calls run concurrently. It invokes every task synchronously, in list order, before awaiting any of them (so a runner that takes checkpoint positions on the call keeps them in call order), and resolves only once all of them have settled (so a runner that unwinds a turn by throwing never abandons a sibling mid-dispatch). A runner that assigns positions anywhere else simply omits the hook and the loop stays sequential.
38
38
  - `AgentStreamEvent` / `encodeStreamEvent` / `decodeStreamEvent` — the live-stream vocabulary (text, reasoning, tool calls with optional `parentId` nesting, `elicitation`, `approval-requested` with `approver`/`expiresAt`, server-pushed `ui` components, `title`, `cancelled`). It is also the contract a runner that is not this loop writes to get the React client for free: see [docs/stream-protocol.md](../../docs/stream-protocol.md). `AgentUiComponent` and `AgentApprovalRequest` are the payload types.
39
39
  - `observeTurnFrames` / `withTurnFrames` — what a model turn streamed that its result does not carry: the model's thinking (`reasoning` text, and `reasoningMs` summed over each burst of consecutive reasoning frames) and pushed `ui` components (first-seen order, last props per id). The loop and the dispatched `llm` step wrap the provider's sink with it inside the model checkpoint, so every provider that streams the vocabulary gets reasoning persisted (`StoredMessage.reasoning` / `reasoningMs` / `ui`) and a replay reads the journaled numbers back. A provider may set `ModelTurnResult.reasoning` / `reasoningMs` / `ui` itself; its values win. The step's `reasoningMs` also rides the `step-finish` frame.
40
+ - `ToolPresentation` / `ToolResultView` / `ToolCatalogEntry` — how a person-facing surface talks about a tool without naming it (`ToolSpec.presentation`, set by `@AiTool({ presentation })`; never shown to the model). `ToolRegistry.visibleSpecs(actor, policy, allowList)` returns the whole specs behind the same gates `definitionsFor` applies, which is what `GET /agent/tools` serves.
40
41
  - `runAgentLoop(deps, input, hooks)` — the loop; the NestJS package drives it from both runners
41
42
 
42
43
  ## Guardrails — `@dudousxd/nestjs-agent-core/guardrails`
@@ -1,4 +1,4 @@
1
- import { A as Actor, I as InputProcessor, O as OutputProcessor, T as ToolHandler } from '../tool-CHIw-aTx.cjs';
1
+ import { A as Actor, I as InputProcessor, O as OutputProcessor, T as ToolHandler } from '../tool-Q2rmGeaG.cjs';
2
2
  import '@standard-schema/spec';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { A as Actor, I as InputProcessor, O as OutputProcessor, T as ToolHandler } from '../tool-CHIw-aTx.js';
1
+ import { A as Actor, I as InputProcessor, O as OutputProcessor, T as ToolHandler } from '../tool-Q2rmGeaG.js';
2
2
  import '@standard-schema/spec';
3
3
 
4
4
  /**
package/dist/index.cjs CHANGED
@@ -2050,6 +2050,19 @@ var ToolRegistry = class {
2050
2050
  * tool the allow-list has already excluded is a call whose answer nothing reads.
2051
2051
  */
2052
2052
  async definitionsFor(actor, policy, allowedTools) {
2053
+ return (await this.visibleSpecs(actor, policy, allowedTools)).map((spec) => ({
2054
+ name: spec.name,
2055
+ kind: spec.kind,
2056
+ description: spec.description,
2057
+ inputSchema: spec.inputSchema
2058
+ }));
2059
+ }
2060
+ /**
2061
+ * The specs {@link definitionsFor} offers the model, whole — the same four gates (allow-list,
2062
+ * enabled, role, `canUse`) in the same order. For a surface that lists what an actor can reach
2063
+ * (`GET <base>/tools`), which must never disagree with what the model is actually shown.
2064
+ */
2065
+ async visibleSpecs(actor, policy, allowedTools) {
2053
2066
  const pinnedNames = new Set(filterToolsByAllowList(this.allSpecs(), allowedTools).map((spec) => spec.name));
2054
2067
  const pinned = [
2055
2068
  ...this.entries.values()
@@ -2058,12 +2071,7 @@ var ToolRegistry = class {
2058
2071
  const allowedByRole = new Set((await filterToolsByRole(live.map((entry) => entry.spec), actor, policy)).map((spec) => spec.name));
2059
2072
  const roleScoped = live.filter((entry) => allowedByRole.has(entry.spec.name));
2060
2073
  const actorScoped = await filterToolsByCanUse(roleScoped, actor);
2061
- return actorScoped.map(({ spec }) => ({
2062
- name: spec.name,
2063
- kind: spec.kind,
2064
- description: spec.description,
2065
- inputSchema: spec.inputSchema
2066
- }));
2074
+ return actorScoped.map(({ spec }) => spec);
2067
2075
  }
2068
2076
  /**
2069
2077
  * Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —