@dudousxd/nestjs-agent 1.5.0 → 1.7.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
@@ -130,6 +130,55 @@ nobody is streaming (including one that has already finished). In-process caller
130
130
  authorized elsewhere use `AgentService.subscribe(runId)`; anything reachable from a request must go
131
131
  through `AgentService.subscribeAs(actor, runId)`.
132
132
 
133
+ ### Resuming a dropped stream
134
+
135
+ Every event frame of `POST /agent/chat` and `GET /agent/chat/:runId/stream` carries an SSE `id:` —
136
+ its 1-based position in the run, the same on every attach. `GET …/stream?after=<n>` (or the
137
+ `Last-Event-ID` header) skips what a reconnecting client already has; the React transport uses it to
138
+ continue a message after a network drop. See docs/stream-protocol.md.
139
+
140
+ ### Message feedback
141
+
142
+ `POST /agent/messages/:id/feedback` `{ value: 'up' | 'down' | null, comment? }` rates a message in
143
+ one of the caller's threads (`null` clears it) and answers `{ feedback }`; `GET /agent/threads/:id`
144
+ returns it on the message. It needs a store with `threadOfMessage` + `setMessageFeedback` (both
145
+ bundled stores and `InMemoryAgentStore` have them) — `501` otherwise.
146
+
147
+ ### Letting callers pick a model
148
+
149
+ ```ts
150
+ AgentModule.forRoot({
151
+ model: aiSdkModel('openai/gpt-4o-mini', { resolveModel: (id) => gateway(id) }),
152
+ models: {
153
+ list: ({ actor }) => ({
154
+ default: 'openai/gpt-4o-mini',
155
+ providers: [
156
+ {
157
+ id: 'openai',
158
+ label: 'OpenAI',
159
+ models: [
160
+ { id: 'openai/gpt-4o-mini', label: 'GPT-4o mini', badges: ['fast'], available: true },
161
+ {
162
+ id: 'openai/o3',
163
+ label: 'o3',
164
+ badges: ['reasoning'],
165
+ available: actor.roles?.includes('PRO') === true,
166
+ unavailableReason: 'Pro plan',
167
+ },
168
+ ],
169
+ },
170
+ ],
171
+ }),
172
+ },
173
+ });
174
+ ```
175
+
176
+ `GET /agent/models?agent=` answers the catalog for the caller (empty without one). A turn runs on
177
+ the send's `model`, else the thread's pinned one (`PATCH /agent/threads/:id { model }`), else the
178
+ provider's default; the id reaches the provider as `ModelTurnArgs.model` for every call of the turn.
179
+ A model the catalog does not list as available for that actor and agent is refused with `400` —
180
+ when pinned and again on each turn. `staticModelCatalog(view)` wraps a fixed list.
181
+
133
182
  ### Who approves an action, and for how long
134
183
 
135
184
  Every `action` tool call waits on the person chatting by default. `approvalPolicy` changes that per
@@ -1,4 +1,4 @@
1
- import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
1
+ import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, ModelCatalog, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
2
2
  import { StandardSchemaV1 } from '@standard-schema/spec';
3
3
  import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
4
4
 
@@ -199,6 +199,12 @@ interface AgentModuleOptions {
199
199
  * `quotaLimitTokens` instead, which binds the built-in ledger-backed store.
200
200
  */
201
201
  quota?: QuotaStore;
202
+ /**
203
+ * Which models a caller may pick — `GET <base>/models`, a send's `model`, a thread's pinned model
204
+ * (`PATCH <base>/threads/:id { model }`). The picked id reaches the {@link ModelProvider} as
205
+ * `ModelTurnArgs.model`. Omit → an empty catalog, and a request naming a model is refused.
206
+ */
207
+ models?: ModelCatalog;
202
208
  /**
203
209
  * Daily per-actor token budget, enforced against the persisted usage ledger by the built-in
204
210
  * `LedgerQuotaStore`. A convenience over wiring a {@link QuotaStore} by hand — set this and quotas
@@ -1,4 +1,4 @@
1
- import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
1
+ import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, ModelCatalog, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
2
2
  import { StandardSchemaV1 } from '@standard-schema/spec';
3
3
  import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
4
4
 
@@ -199,6 +199,12 @@ interface AgentModuleOptions {
199
199
  * `quotaLimitTokens` instead, which binds the built-in ledger-backed store.
200
200
  */
201
201
  quota?: QuotaStore;
202
+ /**
203
+ * Which models a caller may pick — `GET <base>/models`, a send's `model`, a thread's pinned model
204
+ * (`PATCH <base>/threads/:id { model }`). The picked id reaches the {@link ModelProvider} as
205
+ * `ModelTurnArgs.model`. Omit → an empty catalog, and a request naming a model is refused.
206
+ */
207
+ models?: ModelCatalog;
202
208
  /**
203
209
  * Daily per-actor token budget, enforced against the persisted usage ledger by the built-in
204
210
  * `LedgerQuotaStore`. A convenience over wiring a {@link QuotaStore} by hand — set this and quotas