@dudousxd/nestjs-agent 0.1.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.js ADDED
@@ -0,0 +1,1427 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/agent.module.ts
5
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER5, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_DURABLE_RUNNER, AGENT_MODEL as AGENT_MODEL2, AGENT_OPTIONS as AGENT_OPTIONS3, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_REGISTRY as AGENT_REGISTRY3, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK2, AGENT_STORE as AGENT_STORE4, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry3, DefaultRolesPolicy, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
6
+ import { Global, Module } from "@nestjs/common";
7
+ import { DiscoveryModule, RouterModule } from "@nestjs/core";
8
+
9
+ // src/agent-deps.factory.ts
10
+ import { AGENT_MODEL, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK, AGENT_STORE, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2 } from "@dudousxd/nestjs-agent-core";
11
+ import { AGENT_OPTIONS } from "@dudousxd/nestjs-agent-core";
12
+ import { Inject, Injectable } from "@nestjs/common";
13
+ function _ts_decorate(decorators, target, key, desc) {
14
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
15
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
16
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
17
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
18
+ }
19
+ __name(_ts_decorate, "_ts_decorate");
20
+ function _ts_metadata(k, v) {
21
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
+ }
23
+ __name(_ts_metadata, "_ts_metadata");
24
+ function _ts_param(paramIndex, decorator) {
25
+ return function(target, key) {
26
+ decorator(target, key, paramIndex);
27
+ };
28
+ }
29
+ __name(_ts_param, "_ts_param");
30
+ function delegateToolName(target) {
31
+ return `ask_${target.replace(/[^a-zA-Z0-9]+/g, "_")}`;
32
+ }
33
+ __name(delegateToolName, "delegateToolName");
34
+ var AgentDepsFactory2 = class {
35
+ static {
36
+ __name(this, "AgentDepsFactory");
37
+ }
38
+ options;
39
+ model;
40
+ store;
41
+ sink;
42
+ rolesPolicy;
43
+ registry;
44
+ agents;
45
+ quota;
46
+ constructor(options, model, store, sink, rolesPolicy, registry, agents, quota) {
47
+ this.options = options;
48
+ this.model = model;
49
+ this.store = store;
50
+ this.sink = sink;
51
+ this.rolesPolicy = rolesPolicy;
52
+ this.registry = registry;
53
+ this.agents = agents;
54
+ this.quota = quota;
55
+ }
56
+ defaultAgentName() {
57
+ return this.options.defaultAgent?.name ?? "default";
58
+ }
59
+ effectiveTools(definition) {
60
+ if (definition === void 0) {
61
+ return void 0;
62
+ }
63
+ const delegated = (definition.delegatesTo ?? []).map(delegateToolName);
64
+ if (definition.tools === void 0 && delegated.length === 0) {
65
+ return void 0;
66
+ }
67
+ return [
68
+ ...definition.tools ?? [],
69
+ ...delegated
70
+ ];
71
+ }
72
+ forAgent(agentName) {
73
+ const name = agentName ?? this.defaultAgentName();
74
+ const definition = this.agents.get(name);
75
+ const personas = /* @__PURE__ */ new Map();
76
+ for (const persona of definition?.personas ?? []) {
77
+ personas.set(persona.id, persona);
78
+ }
79
+ const toolAllowList = this.effectiveTools(definition);
80
+ const followUpsCount = this.followUpsCount();
81
+ const retrieval = this.options.retrieval;
82
+ return {
83
+ model: this.model,
84
+ store: this.store,
85
+ sink: this.sink,
86
+ rolesPolicy: this.rolesPolicy,
87
+ registry: this.registry,
88
+ systemPrompt: definition?.systemPrompt ?? "You are a helpful assistant.",
89
+ maxSteps: definition?.maxSteps ?? 8,
90
+ personas,
91
+ defaultPersona: definition?.defaultPersona ?? "default",
92
+ ...definition?.modelId !== void 0 ? {
93
+ modelId: definition.modelId
94
+ } : {},
95
+ ...this.quota !== void 0 ? {
96
+ quota: this.quota
97
+ } : {},
98
+ ...toolAllowList !== void 0 ? {
99
+ toolAllowList
100
+ } : {},
101
+ ...this.options.toolTimeoutMs !== void 0 ? {
102
+ toolTimeoutMs: this.options.toolTimeoutMs
103
+ } : {},
104
+ ...followUpsCount !== void 0 ? {
105
+ followUpsCount
106
+ } : {},
107
+ ...retrieval?.mode === "inject" ? {
108
+ retriever: retrieval.retriever,
109
+ ...retrieval.topK !== void 0 ? {
110
+ retrievalTopK: retrieval.topK
111
+ } : {}
112
+ } : {}
113
+ };
114
+ }
115
+ /** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */
116
+ followUpsCount() {
117
+ const followUps = this.options.followUps;
118
+ if (followUps === true) {
119
+ return 3;
120
+ }
121
+ if (typeof followUps === "object") {
122
+ return followUps.count;
123
+ }
124
+ return void 0;
125
+ }
126
+ };
127
+ AgentDepsFactory2 = _ts_decorate([
128
+ Injectable(),
129
+ _ts_param(0, Inject(AGENT_OPTIONS)),
130
+ _ts_param(1, Inject(AGENT_MODEL)),
131
+ _ts_param(2, Inject(AGENT_STORE)),
132
+ _ts_param(3, Inject(AGENT_SINK)),
133
+ _ts_param(4, Inject(AGENT_ROLES_POLICY)),
134
+ _ts_param(5, Inject(AGENT_TOOL_REGISTRY)),
135
+ _ts_param(6, Inject(AGENT_REGISTRY)),
136
+ _ts_param(7, Inject(AGENT_QUOTA_STORE)),
137
+ _ts_metadata("design:type", Function),
138
+ _ts_metadata("design:paramtypes", [
139
+ typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
140
+ typeof ModelProvider === "undefined" ? Object : ModelProvider,
141
+ typeof AgentStore === "undefined" ? Object : AgentStore,
142
+ typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
143
+ typeof RolesPolicy === "undefined" ? Object : RolesPolicy,
144
+ typeof ToolRegistry2 === "undefined" ? Object : ToolRegistry2,
145
+ typeof AgentRegistry2 === "undefined" ? Object : AgentRegistry2,
146
+ Object
147
+ ])
148
+ ], AgentDepsFactory2);
149
+
150
+ // src/agent.service.ts
151
+ import { AGENT_DEPS_FACTORY, AGENT_RUNNER, AGENT_STORE as AGENT_STORE2 } from "@dudousxd/nestjs-agent-core";
152
+ import { BadRequestException, ForbiddenException, Inject as Inject2, Injectable as Injectable2, NotFoundException } from "@nestjs/common";
153
+
154
+ // src/agent-deps.ts
155
+ function utcDay(date = /* @__PURE__ */ new Date()) {
156
+ return date.toISOString().slice(0, 10);
157
+ }
158
+ __name(utcDay, "utcDay");
159
+ function childSinkWriter(writer) {
160
+ return {
161
+ write: /* @__PURE__ */ __name((chunk) => writer.write(chunk), "write"),
162
+ end: /* @__PURE__ */ __name(async () => {
163
+ }, "end"),
164
+ fail: /* @__PURE__ */ __name(async () => {
165
+ }, "fail")
166
+ };
167
+ }
168
+ __name(childSinkWriter, "childSinkWriter");
169
+
170
+ // src/agent.service.ts
171
+ function _ts_decorate2(decorators, target, key, desc) {
172
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
173
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
174
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
175
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
176
+ }
177
+ __name(_ts_decorate2, "_ts_decorate");
178
+ function _ts_metadata2(k, v) {
179
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
180
+ }
181
+ __name(_ts_metadata2, "_ts_metadata");
182
+ function _ts_param2(paramIndex, decorator) {
183
+ return function(target, key) {
184
+ decorator(target, key, paramIndex);
185
+ };
186
+ }
187
+ __name(_ts_param2, "_ts_param");
188
+ var AgentService = class {
189
+ static {
190
+ __name(this, "AgentService");
191
+ }
192
+ runner;
193
+ store;
194
+ deps;
195
+ constructor(runner, store, deps) {
196
+ this.runner = runner;
197
+ this.store = store;
198
+ this.deps = deps;
199
+ }
200
+ async chat(params) {
201
+ const agentName = params.agentName ?? this.deps.defaultAgentName();
202
+ let threadId = params.threadId;
203
+ if (threadId === void 0) {
204
+ if (params.regenerate === true) {
205
+ throw new BadRequestException("regenerate requires an existing threadId");
206
+ }
207
+ const created = await this.store.createThread({
208
+ actor: params.actor,
209
+ persona: params.personaId ?? this.deps.forAgent(agentName).defaultPersona
210
+ });
211
+ threadId = created.id;
212
+ } else if (params.regenerate === true) {
213
+ await this.assertOwnsThread(params.actor, threadId);
214
+ }
215
+ const persona = this.resolvePersona(agentName, params.personaId);
216
+ const input = {
217
+ threadId,
218
+ actor: params.actor,
219
+ userText: params.message,
220
+ day: utcDay(),
221
+ agentName,
222
+ ...params.regenerate === true ? {
223
+ regenerate: true
224
+ } : {},
225
+ ...persona !== void 0 ? {
226
+ persona
227
+ } : {},
228
+ ...params.pageContext !== void 0 ? {
229
+ pageContext: params.pageContext
230
+ } : {}
231
+ };
232
+ const { runId } = await this.runner.start(input);
233
+ await this.store.setActiveStream(threadId, runId);
234
+ return {
235
+ runId,
236
+ threadId
237
+ };
238
+ }
239
+ subscribe(runId) {
240
+ return this.deps.forAgent().sink.subscribe(runId);
241
+ }
242
+ async approve(actor, toolCallId) {
243
+ const runId = await this.runForOwnedToolCall(actor, toolCallId);
244
+ return this.runner.signal(runId, toolCallId, {
245
+ approved: true
246
+ });
247
+ }
248
+ async reject(actor, toolCallId, reason) {
249
+ const runId = await this.runForOwnedToolCall(actor, toolCallId);
250
+ return this.runner.signal(runId, toolCallId, {
251
+ approved: false,
252
+ ...reason !== void 0 ? {
253
+ reason
254
+ } : {}
255
+ });
256
+ }
257
+ async cancel(actor, runId) {
258
+ await this.assertOwnsActiveStream(actor, runId);
259
+ return this.runner.cancel(runId);
260
+ }
261
+ resolvePersona(agentName, id) {
262
+ const deps = this.deps.forAgent(agentName);
263
+ return deps.personas.get(id ?? deps.defaultPersona);
264
+ }
265
+ personaCatalog(agentName) {
266
+ return [
267
+ ...this.deps.forAgent(agentName).personas.values()
268
+ ].map((persona) => ({
269
+ id: persona.id,
270
+ label: persona.label
271
+ }));
272
+ }
273
+ listThreads(actorRef) {
274
+ return this.store.listThreads(actorRef);
275
+ }
276
+ async getThread(actor, threadId) {
277
+ await this.assertOwnsThread(actor, threadId);
278
+ return this.store.getThread(threadId);
279
+ }
280
+ async deleteThread(actor, threadId) {
281
+ await this.assertOwnsThread(actor, threadId);
282
+ return this.store.softDeleteThread(threadId);
283
+ }
284
+ async forkThread(actor, threadId, fromMessageId) {
285
+ await this.assertOwnsThread(actor, threadId);
286
+ return this.store.forkThread(threadId, fromMessageId);
287
+ }
288
+ async quotaToday(actorRef) {
289
+ return this.store.quotaToday(actorRef, utcDay());
290
+ }
291
+ /**
292
+ * Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing
293
+ * thread is a 404; someone else's thread is a 403 — one actor never touches another's thread.
294
+ */
295
+ async assertOwnsThread(actor, threadId) {
296
+ const owner = await this.store.ownerOfThread(threadId);
297
+ if (owner === null) {
298
+ throw new NotFoundException(`thread ${threadId} not found`);
299
+ }
300
+ if (owner !== actor.id) {
301
+ throw new ForbiddenException("thread belongs to another actor");
302
+ }
303
+ }
304
+ /**
305
+ * Authorization + routing seam for HITL approve/reject: assert the caller owns the tool call's
306
+ * thread, then resolve the run currently awaiting that call (its thread's active stream). That run
307
+ * is the sub-agent's own child run when the pending call belongs to a delegated agent — the client
308
+ * never knows or supplies a runId; it is derived here from the tool call alone.
309
+ */
310
+ async runForOwnedToolCall(actor, toolCallId) {
311
+ const owner = await this.store.ownerOfToolCall(toolCallId);
312
+ if (owner === null) {
313
+ throw new NotFoundException(`tool call ${toolCallId} not found`);
314
+ }
315
+ if (owner !== actor.id) {
316
+ throw new ForbiddenException("tool call belongs to another actor");
317
+ }
318
+ const runId = await this.store.runForToolCall(toolCallId);
319
+ if (runId === null) {
320
+ throw new NotFoundException(`tool call ${toolCallId} has no active run to signal`);
321
+ }
322
+ return runId;
323
+ }
324
+ /** Authorization seam for `cancel`: the caller must own the thread currently streaming this run. */
325
+ async assertOwnsActiveStream(actor, runId) {
326
+ const owner = await this.store.ownerOfActiveStream(runId);
327
+ if (owner === null) {
328
+ throw new NotFoundException(`no active run ${runId}`);
329
+ }
330
+ if (owner !== actor.id) {
331
+ throw new ForbiddenException("run belongs to another actor");
332
+ }
333
+ }
334
+ };
335
+ AgentService = _ts_decorate2([
336
+ Injectable2(),
337
+ _ts_param2(0, Inject2(AGENT_RUNNER)),
338
+ _ts_param2(1, Inject2(AGENT_STORE2)),
339
+ _ts_param2(2, Inject2(AGENT_DEPS_FACTORY)),
340
+ _ts_metadata2("design:type", Function),
341
+ _ts_metadata2("design:paramtypes", [
342
+ typeof AgentRunner === "undefined" ? Object : AgentRunner,
343
+ typeof AgentStore === "undefined" ? Object : AgentStore,
344
+ typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
345
+ ])
346
+ ], AgentService);
347
+
348
+ // src/controller/chat.controller.ts
349
+ import { AGENT_ACTOR_RESOLVER, AgentStreamError } from "@dudousxd/nestjs-agent-core";
350
+ import { Body, Controller, Get, Inject as Inject3, Param, Post, Req, Res } from "@nestjs/common";
351
+ function _ts_decorate3(decorators, target, key, desc) {
352
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
353
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
354
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
355
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
356
+ }
357
+ __name(_ts_decorate3, "_ts_decorate");
358
+ function _ts_metadata3(k, v) {
359
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
360
+ }
361
+ __name(_ts_metadata3, "_ts_metadata");
362
+ function _ts_param3(paramIndex, decorator) {
363
+ return function(target, key) {
364
+ decorator(target, key, paramIndex);
365
+ };
366
+ }
367
+ __name(_ts_param3, "_ts_param");
368
+ var ChatController = class {
369
+ static {
370
+ __name(this, "ChatController");
371
+ }
372
+ agent;
373
+ actorResolver;
374
+ constructor(agent, actorResolver) {
375
+ this.agent = agent;
376
+ this.actorResolver = actorResolver;
377
+ }
378
+ async chat(req, res, body) {
379
+ const actor = await this.actorResolver.resolve(req);
380
+ const { runId, threadId } = await this.agent.chat({
381
+ actor,
382
+ message: body.message,
383
+ ...body.threadId !== void 0 ? {
384
+ threadId: body.threadId
385
+ } : {},
386
+ ...body.agent !== void 0 ? {
387
+ agentName: body.agent
388
+ } : {},
389
+ ...body.persona !== void 0 ? {
390
+ personaId: body.persona
391
+ } : {},
392
+ ...body.pageContext !== void 0 ? {
393
+ pageContext: body.pageContext
394
+ } : {},
395
+ ...body.regenerate === true ? {
396
+ regenerate: true
397
+ } : {}
398
+ });
399
+ await this.pipe(res, runId, threadId);
400
+ }
401
+ async stream(runId, res) {
402
+ await this.pipe(res, runId);
403
+ }
404
+ async cancel(req, runId) {
405
+ const actor = await this.actorResolver.resolve(req);
406
+ await this.agent.cancel(actor, runId);
407
+ return {
408
+ aborted: true
409
+ };
410
+ }
411
+ async pipe(res, runId, threadId) {
412
+ res.setHeader("Content-Type", "text/event-stream");
413
+ res.setHeader("Cache-Control", "no-cache");
414
+ res.setHeader("Connection", "keep-alive");
415
+ res.setHeader("X-Agent-Run-Id", runId);
416
+ if (threadId !== void 0) {
417
+ res.setHeader("X-Agent-Thread-Id", threadId);
418
+ }
419
+ res.write(`event: meta
420
+ data: ${JSON.stringify({
421
+ runId,
422
+ threadId
423
+ })}
424
+
425
+ `);
426
+ const decoder = new TextDecoder();
427
+ try {
428
+ for await (const chunk of this.agent.subscribe(runId)) {
429
+ res.write(`data: ${JSON.stringify({
430
+ delta: decoder.decode(chunk)
431
+ })}
432
+
433
+ `);
434
+ }
435
+ res.write("event: done\ndata: {}\n\n");
436
+ } catch (error) {
437
+ const payload = error instanceof AgentStreamError ? {
438
+ code: error.code,
439
+ message: error.message
440
+ } : {
441
+ code: "run_failed",
442
+ message: error instanceof Error ? error.message : "stream error"
443
+ };
444
+ res.write(`event: error
445
+ data: ${JSON.stringify(payload)}
446
+
447
+ `);
448
+ }
449
+ res.end();
450
+ }
451
+ };
452
+ _ts_decorate3([
453
+ Post("chat"),
454
+ _ts_param3(0, Req()),
455
+ _ts_param3(1, Res()),
456
+ _ts_param3(2, Body()),
457
+ _ts_metadata3("design:type", Function),
458
+ _ts_metadata3("design:paramtypes", [
459
+ typeof Request === "undefined" ? Object : Request,
460
+ typeof Response === "undefined" ? Object : Response,
461
+ typeof ChatBody === "undefined" ? Object : ChatBody
462
+ ]),
463
+ _ts_metadata3("design:returntype", Promise)
464
+ ], ChatController.prototype, "chat", null);
465
+ _ts_decorate3([
466
+ Get("chat/:runId/stream"),
467
+ _ts_param3(0, Param("runId")),
468
+ _ts_param3(1, Res()),
469
+ _ts_metadata3("design:type", Function),
470
+ _ts_metadata3("design:paramtypes", [
471
+ String,
472
+ typeof Response === "undefined" ? Object : Response
473
+ ]),
474
+ _ts_metadata3("design:returntype", Promise)
475
+ ], ChatController.prototype, "stream", null);
476
+ _ts_decorate3([
477
+ Post("chat/:runId/cancel"),
478
+ _ts_param3(0, Req()),
479
+ _ts_param3(1, Param("runId")),
480
+ _ts_metadata3("design:type", Function),
481
+ _ts_metadata3("design:paramtypes", [
482
+ typeof Request === "undefined" ? Object : Request,
483
+ String
484
+ ]),
485
+ _ts_metadata3("design:returntype", Promise)
486
+ ], ChatController.prototype, "cancel", null);
487
+ ChatController = _ts_decorate3([
488
+ Controller(),
489
+ _ts_param3(1, Inject3(AGENT_ACTOR_RESOLVER)),
490
+ _ts_metadata3("design:type", Function),
491
+ _ts_metadata3("design:paramtypes", [
492
+ typeof AgentService === "undefined" ? Object : AgentService,
493
+ typeof ActorResolver === "undefined" ? Object : ActorResolver
494
+ ])
495
+ ], ChatController);
496
+
497
+ // src/controller/quota.controller.ts
498
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER2 } from "@dudousxd/nestjs-agent-core";
499
+ import { Controller as Controller2, Get as Get2, Inject as Inject4, Req as Req2 } from "@nestjs/common";
500
+ function _ts_decorate4(decorators, target, key, desc) {
501
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
502
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
503
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
504
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
505
+ }
506
+ __name(_ts_decorate4, "_ts_decorate");
507
+ function _ts_metadata4(k, v) {
508
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
509
+ }
510
+ __name(_ts_metadata4, "_ts_metadata");
511
+ function _ts_param4(paramIndex, decorator) {
512
+ return function(target, key) {
513
+ decorator(target, key, paramIndex);
514
+ };
515
+ }
516
+ __name(_ts_param4, "_ts_param");
517
+ var QuotaController = class {
518
+ static {
519
+ __name(this, "QuotaController");
520
+ }
521
+ agent;
522
+ actorResolver;
523
+ constructor(agent, actorResolver) {
524
+ this.agent = agent;
525
+ this.actorResolver = actorResolver;
526
+ }
527
+ async today(req) {
528
+ const actor = await this.actorResolver.resolve(req);
529
+ return this.agent.quotaToday(actor.id);
530
+ }
531
+ };
532
+ _ts_decorate4([
533
+ Get2("today"),
534
+ _ts_param4(0, Req2()),
535
+ _ts_metadata4("design:type", Function),
536
+ _ts_metadata4("design:paramtypes", [
537
+ typeof Request === "undefined" ? Object : Request
538
+ ]),
539
+ _ts_metadata4("design:returntype", Promise)
540
+ ], QuotaController.prototype, "today", null);
541
+ QuotaController = _ts_decorate4([
542
+ Controller2("quota"),
543
+ _ts_param4(1, Inject4(AGENT_ACTOR_RESOLVER2)),
544
+ _ts_metadata4("design:type", Function),
545
+ _ts_metadata4("design:paramtypes", [
546
+ typeof AgentService === "undefined" ? Object : AgentService,
547
+ typeof ActorResolver === "undefined" ? Object : ActorResolver
548
+ ])
549
+ ], QuotaController);
550
+
551
+ // src/controller/threads.controller.ts
552
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER3 } from "@dudousxd/nestjs-agent-core";
553
+ import { Controller as Controller3, Delete, Get as Get3, Inject as Inject5, Param as Param2, Post as Post2, Req as Req3 } from "@nestjs/common";
554
+ function _ts_decorate5(decorators, target, key, desc) {
555
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
556
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
557
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
558
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
559
+ }
560
+ __name(_ts_decorate5, "_ts_decorate");
561
+ function _ts_metadata5(k, v) {
562
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
563
+ }
564
+ __name(_ts_metadata5, "_ts_metadata");
565
+ function _ts_param5(paramIndex, decorator) {
566
+ return function(target, key) {
567
+ decorator(target, key, paramIndex);
568
+ };
569
+ }
570
+ __name(_ts_param5, "_ts_param");
571
+ var ThreadsController = class {
572
+ static {
573
+ __name(this, "ThreadsController");
574
+ }
575
+ agent;
576
+ actorResolver;
577
+ constructor(agent, actorResolver) {
578
+ this.agent = agent;
579
+ this.actorResolver = actorResolver;
580
+ }
581
+ async list(req) {
582
+ const actor = await this.actorResolver.resolve(req);
583
+ return this.agent.listThreads(actor.id);
584
+ }
585
+ personas() {
586
+ return this.agent.personaCatalog();
587
+ }
588
+ async detail(req, id) {
589
+ const actor = await this.actorResolver.resolve(req);
590
+ return this.agent.getThread(actor, id);
591
+ }
592
+ async remove(req, id) {
593
+ const actor = await this.actorResolver.resolve(req);
594
+ await this.agent.deleteThread(actor, id);
595
+ return {
596
+ ok: true
597
+ };
598
+ }
599
+ async fork(req, id, messageId) {
600
+ const actor = await this.actorResolver.resolve(req);
601
+ return this.agent.forkThread(actor, id, messageId);
602
+ }
603
+ };
604
+ _ts_decorate5([
605
+ Get3(),
606
+ _ts_param5(0, Req3()),
607
+ _ts_metadata5("design:type", Function),
608
+ _ts_metadata5("design:paramtypes", [
609
+ typeof Request === "undefined" ? Object : Request
610
+ ]),
611
+ _ts_metadata5("design:returntype", Promise)
612
+ ], ThreadsController.prototype, "list", null);
613
+ _ts_decorate5([
614
+ Get3("personas/catalog"),
615
+ _ts_metadata5("design:type", Function),
616
+ _ts_metadata5("design:paramtypes", []),
617
+ _ts_metadata5("design:returntype", void 0)
618
+ ], ThreadsController.prototype, "personas", null);
619
+ _ts_decorate5([
620
+ Get3(":id"),
621
+ _ts_param5(0, Req3()),
622
+ _ts_param5(1, Param2("id")),
623
+ _ts_metadata5("design:type", Function),
624
+ _ts_metadata5("design:paramtypes", [
625
+ typeof Request === "undefined" ? Object : Request,
626
+ String
627
+ ]),
628
+ _ts_metadata5("design:returntype", Promise)
629
+ ], ThreadsController.prototype, "detail", null);
630
+ _ts_decorate5([
631
+ Delete(":id"),
632
+ _ts_param5(0, Req3()),
633
+ _ts_param5(1, Param2("id")),
634
+ _ts_metadata5("design:type", Function),
635
+ _ts_metadata5("design:paramtypes", [
636
+ typeof Request === "undefined" ? Object : Request,
637
+ String
638
+ ]),
639
+ _ts_metadata5("design:returntype", Promise)
640
+ ], ThreadsController.prototype, "remove", null);
641
+ _ts_decorate5([
642
+ Post2(":id/fork-from/:messageId"),
643
+ _ts_param5(0, Req3()),
644
+ _ts_param5(1, Param2("id")),
645
+ _ts_param5(2, Param2("messageId")),
646
+ _ts_metadata5("design:type", Function),
647
+ _ts_metadata5("design:paramtypes", [
648
+ typeof Request === "undefined" ? Object : Request,
649
+ String,
650
+ String
651
+ ]),
652
+ _ts_metadata5("design:returntype", Promise)
653
+ ], ThreadsController.prototype, "fork", null);
654
+ ThreadsController = _ts_decorate5([
655
+ Controller3("threads"),
656
+ _ts_param5(1, Inject5(AGENT_ACTOR_RESOLVER3)),
657
+ _ts_metadata5("design:type", Function),
658
+ _ts_metadata5("design:paramtypes", [
659
+ typeof AgentService === "undefined" ? Object : AgentService,
660
+ typeof ActorResolver === "undefined" ? Object : ActorResolver
661
+ ])
662
+ ], ThreadsController);
663
+
664
+ // src/controller/tool-call.controller.ts
665
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER4 } from "@dudousxd/nestjs-agent-core";
666
+ import { Body as Body2, Controller as Controller4, Inject as Inject6, Post as Post3, Req as Req4 } from "@nestjs/common";
667
+ function _ts_decorate6(decorators, target, key, desc) {
668
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
669
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
670
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
671
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
672
+ }
673
+ __name(_ts_decorate6, "_ts_decorate");
674
+ function _ts_metadata6(k, v) {
675
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
676
+ }
677
+ __name(_ts_metadata6, "_ts_metadata");
678
+ function _ts_param6(paramIndex, decorator) {
679
+ return function(target, key) {
680
+ decorator(target, key, paramIndex);
681
+ };
682
+ }
683
+ __name(_ts_param6, "_ts_param");
684
+ var ToolCallController = class {
685
+ static {
686
+ __name(this, "ToolCallController");
687
+ }
688
+ agent;
689
+ actorResolver;
690
+ constructor(agent, actorResolver) {
691
+ this.agent = agent;
692
+ this.actorResolver = actorResolver;
693
+ }
694
+ async approve(req, body) {
695
+ const actor = await this.actorResolver.resolve(req);
696
+ await this.agent.approve(actor, body.toolCallId);
697
+ return {
698
+ ok: true
699
+ };
700
+ }
701
+ async reject(req, body) {
702
+ const actor = await this.actorResolver.resolve(req);
703
+ await this.agent.reject(actor, body.toolCallId, body.reason);
704
+ return {
705
+ ok: true
706
+ };
707
+ }
708
+ };
709
+ _ts_decorate6([
710
+ Post3("approve"),
711
+ _ts_param6(0, Req4()),
712
+ _ts_param6(1, Body2()),
713
+ _ts_metadata6("design:type", Function),
714
+ _ts_metadata6("design:paramtypes", [
715
+ typeof Request === "undefined" ? Object : Request,
716
+ typeof ApproveBody === "undefined" ? Object : ApproveBody
717
+ ]),
718
+ _ts_metadata6("design:returntype", Promise)
719
+ ], ToolCallController.prototype, "approve", null);
720
+ _ts_decorate6([
721
+ Post3("reject"),
722
+ _ts_param6(0, Req4()),
723
+ _ts_param6(1, Body2()),
724
+ _ts_metadata6("design:type", Function),
725
+ _ts_metadata6("design:paramtypes", [
726
+ typeof Request === "undefined" ? Object : Request,
727
+ typeof RejectBody === "undefined" ? Object : RejectBody
728
+ ]),
729
+ _ts_metadata6("design:returntype", Promise)
730
+ ], ToolCallController.prototype, "reject", null);
731
+ ToolCallController = _ts_decorate6([
732
+ Controller4("tool-call"),
733
+ _ts_param6(1, Inject6(AGENT_ACTOR_RESOLVER4)),
734
+ _ts_metadata6("design:type", Function),
735
+ _ts_metadata6("design:paramtypes", [
736
+ typeof AgentService === "undefined" ? Object : AgentService,
737
+ typeof ActorResolver === "undefined" ? Object : ActorResolver
738
+ ])
739
+ ], ToolCallController);
740
+
741
+ // src/discovery/ai-tool-discovery.service.ts
742
+ import { AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_REGISTRY as AGENT_REGISTRY2, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2 } from "@dudousxd/nestjs-agent-core";
743
+ import { Inject as Inject7, Injectable as Injectable3, Logger } from "@nestjs/common";
744
+ import { DiscoveryService } from "@nestjs/core";
745
+ import { z } from "zod";
746
+
747
+ // src/decorator/ai-tool.decorator.ts
748
+ import "reflect-metadata";
749
+ var AI_TOOL_METADATA = Symbol("nestjs-agent:ai-tool");
750
+ function AiTool(options) {
751
+ return (target) => {
752
+ Reflect.defineMetadata(AI_TOOL_METADATA, options, target);
753
+ };
754
+ }
755
+ __name(AiTool, "AiTool");
756
+ function readAiToolMetadata(target) {
757
+ return Reflect.getMetadata(AI_TOOL_METADATA, target.constructor);
758
+ }
759
+ __name(readAiToolMetadata, "readAiToolMetadata");
760
+
761
+ // src/functional-tool.ts
762
+ var AGENT_TOOL_BRAND = Symbol.for("@dudousxd/nestjs-agent:functional-tool");
763
+ function brand(tool) {
764
+ return {
765
+ [AGENT_TOOL_BRAND]: true,
766
+ spec: tool.spec,
767
+ handler: tool.handler
768
+ };
769
+ }
770
+ __name(brand, "brand");
771
+ function isBrandedFunctionalTool(value) {
772
+ return AGENT_TOOL_BRAND in value && "spec" in value && "handler" in value;
773
+ }
774
+ __name(isBrandedFunctionalTool, "isBrandedFunctionalTool");
775
+ function provideAgentTool(factoryOrTool, inject) {
776
+ const provide = Symbol("nestjs-agent:functional-tool-instance");
777
+ if (typeof factoryOrTool === "function") {
778
+ return {
779
+ provide,
780
+ useFactory: /* @__PURE__ */ __name((...deps) => brand(factoryOrTool(...deps)), "useFactory"),
781
+ inject: inject ?? []
782
+ };
783
+ }
784
+ return {
785
+ provide,
786
+ useValue: brand(factoryOrTool)
787
+ };
788
+ }
789
+ __name(provideAgentTool, "provideAgentTool");
790
+
791
+ // src/discovery/ai-tool-discovery.service.ts
792
+ function _ts_decorate7(decorators, target, key, desc) {
793
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
794
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
795
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
796
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
797
+ }
798
+ __name(_ts_decorate7, "_ts_decorate");
799
+ function _ts_metadata7(k, v) {
800
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
801
+ }
802
+ __name(_ts_metadata7, "_ts_metadata");
803
+ function _ts_param7(paramIndex, decorator) {
804
+ return function(target, key) {
805
+ decorator(target, key, paramIndex);
806
+ };
807
+ }
808
+ __name(_ts_param7, "_ts_param");
809
+ var AiToolDiscoveryService = class _AiToolDiscoveryService {
810
+ static {
811
+ __name(this, "AiToolDiscoveryService");
812
+ }
813
+ discovery;
814
+ registry;
815
+ agents;
816
+ options;
817
+ logger = new Logger(_AiToolDiscoveryService.name);
818
+ constructor(discovery, registry, agents, options) {
819
+ this.discovery = discovery;
820
+ this.registry = registry;
821
+ this.agents = agents;
822
+ this.options = options;
823
+ }
824
+ onApplicationBootstrap() {
825
+ let count = 0;
826
+ let functional = 0;
827
+ for (const wrapper of this.discovery.getProviders()) {
828
+ const instance = wrapper.instance;
829
+ if (instance === null || instance === void 0 || typeof instance !== "object") {
830
+ continue;
831
+ }
832
+ if (isBrandedFunctionalTool(instance)) {
833
+ if (this.registerFunctionalTool(instance)) {
834
+ functional += 1;
835
+ }
836
+ continue;
837
+ }
838
+ const meta = readAiToolMetadata(instance);
839
+ if (meta === void 0) {
840
+ continue;
841
+ }
842
+ const handler = instance;
843
+ if (typeof handler.execute !== "function") {
844
+ this.logger.warn(`@AiTool "${meta.name}" has no execute() method \u2014 skipped`);
845
+ continue;
846
+ }
847
+ this.registry.register({
848
+ name: meta.name,
849
+ kind: meta.kind,
850
+ description: meta.description,
851
+ inputSchema: meta.input,
852
+ // Leave roles unset when the tool didn't declare any — the RolesPolicy owns the default
853
+ // (its `defaultRoles`). Baking it in here too would leak it into custom policies.
854
+ ...meta.roles !== void 0 ? {
855
+ roles: meta.roles
856
+ } : {},
857
+ ...meta.ability !== void 0 ? {
858
+ ability: meta.ability
859
+ } : {}
860
+ }, {
861
+ execute: /* @__PURE__ */ __name((input, ctx) => instance.execute(input, ctx), "execute")
862
+ });
863
+ count += 1;
864
+ }
865
+ for (const tool of this.options.tools ?? []) {
866
+ if (this.registerFunctionalTool(tool)) {
867
+ functional += 1;
868
+ }
869
+ }
870
+ let delegates = 0;
871
+ for (const definition of this.agents.list()) {
872
+ for (const target of definition.delegatesTo ?? []) {
873
+ const targetDefinition = this.agents.get(target);
874
+ if (targetDefinition === void 0) {
875
+ throw new Error(`Agent "${definition.name}" delegatesTo "${target}", which is not a registered agent. Register it via AgentModule.forFeature([...]) or fix the name.`);
876
+ }
877
+ const name = delegateToolName(target);
878
+ if (this.registry.has(name)) {
879
+ continue;
880
+ }
881
+ const targetBlurb = typeof targetDefinition.systemPrompt === "string" ? ` It is: ${targetDefinition.systemPrompt}` : "";
882
+ this.registry.register(
883
+ {
884
+ name,
885
+ kind: "agent",
886
+ targetAgent: target,
887
+ description: `Delegate a task to the "${target}" agent and get its answer.${targetBlurb}`,
888
+ inputSchema: z.object({
889
+ task: z.string()
890
+ })
891
+ },
892
+ // Loop-handled (kind 'agent'); the handler is never called.
893
+ {
894
+ execute: /* @__PURE__ */ __name(async () => ({}), "execute")
895
+ }
896
+ );
897
+ delegates += 1;
898
+ }
899
+ }
900
+ this.logger.log(`registered ${count} AI tool(s), ${functional} functional tool(s) and ${delegates} delegate tool(s)`);
901
+ }
902
+ /**
903
+ * Registers a functional tool's `{ spec, handler }`, skipping it if a tool of the same name is
904
+ * already registered. Returns whether it was newly registered.
905
+ */
906
+ registerFunctionalTool(tool) {
907
+ if (this.registry.has(tool.spec.name)) {
908
+ this.logger.warn(`functional tool "${tool.spec.name}" duplicates a registered name \u2014 skipped`);
909
+ return false;
910
+ }
911
+ this.registry.register(tool.spec, tool.handler);
912
+ return true;
913
+ }
914
+ };
915
+ AiToolDiscoveryService = _ts_decorate7([
916
+ Injectable3(),
917
+ _ts_param7(1, Inject7(AGENT_TOOL_REGISTRY2)),
918
+ _ts_param7(2, Inject7(AGENT_REGISTRY2)),
919
+ _ts_param7(3, Inject7(AGENT_OPTIONS2)),
920
+ _ts_metadata7("design:type", Function),
921
+ _ts_metadata7("design:paramtypes", [
922
+ typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
923
+ typeof ToolRegistry === "undefined" ? Object : ToolRegistry,
924
+ typeof AgentRegistry === "undefined" ? Object : AgentRegistry,
925
+ typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions
926
+ ])
927
+ ], AiToolDiscoveryService);
928
+
929
+ // src/in-process-sink.ts
930
+ import { AgentStreamError as AgentStreamError2 } from "@dudousxd/nestjs-agent-core";
931
+ var InProcessTokenStreamSink = class {
932
+ static {
933
+ __name(this, "InProcessTokenStreamSink");
934
+ }
935
+ runs = /* @__PURE__ */ new Map();
936
+ buffer(runId) {
937
+ let buf = this.runs.get(runId);
938
+ if (buf === void 0) {
939
+ buf = {
940
+ chunks: [],
941
+ ended: false,
942
+ notify: /* @__PURE__ */ new Set()
943
+ };
944
+ this.runs.set(runId, buf);
945
+ }
946
+ return buf;
947
+ }
948
+ wake(buf) {
949
+ for (const resolve of buf.notify) {
950
+ resolve();
951
+ }
952
+ buf.notify.clear();
953
+ }
954
+ open(runId) {
955
+ const buf = this.buffer(runId);
956
+ return {
957
+ write: /* @__PURE__ */ __name((chunk) => {
958
+ buf.chunks.push(chunk);
959
+ this.wake(buf);
960
+ }, "write"),
961
+ end: /* @__PURE__ */ __name(() => {
962
+ buf.ended = true;
963
+ this.wake(buf);
964
+ }, "end"),
965
+ fail: /* @__PURE__ */ __name((error) => {
966
+ buf.failure = error;
967
+ buf.ended = true;
968
+ this.wake(buf);
969
+ }, "fail")
970
+ };
971
+ }
972
+ async *subscribe(runId) {
973
+ const buf = this.buffer(runId);
974
+ let index = 0;
975
+ while (true) {
976
+ while (index < buf.chunks.length) {
977
+ const chunk = buf.chunks[index];
978
+ index += 1;
979
+ if (chunk !== void 0) {
980
+ yield chunk;
981
+ }
982
+ }
983
+ if (buf.ended) {
984
+ if (buf.failure !== void 0) {
985
+ throw new AgentStreamError2(buf.failure);
986
+ }
987
+ return;
988
+ }
989
+ await new Promise((resolve) => buf.notify.add(resolve));
990
+ }
991
+ }
992
+ close(runId) {
993
+ this.runs.delete(runId);
994
+ }
995
+ };
996
+
997
+ // src/ledger-quota-store.ts
998
+ var LedgerQuotaStore = class {
999
+ static {
1000
+ __name(this, "LedgerQuotaStore");
1001
+ }
1002
+ store;
1003
+ limitTokens;
1004
+ constructor(store, limitTokens) {
1005
+ this.store = store;
1006
+ this.limitTokens = limitTokens;
1007
+ }
1008
+ async check(actorRef, day) {
1009
+ const { usedTokens } = await this.store.quotaToday(actorRef, day);
1010
+ return {
1011
+ usedTokens,
1012
+ limitTokens: this.limitTokens,
1013
+ withinLimit: usedTokens < this.limitTokens
1014
+ };
1015
+ }
1016
+ async bump() {
1017
+ }
1018
+ };
1019
+
1020
+ // src/runner/inline-agent-runner.ts
1021
+ import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_STORE as AGENT_STORE3, QuotaExceededError, publishAgentRunFailed, runAgentLoop } from "@dudousxd/nestjs-agent-core";
1022
+ import { Inject as Inject8, Injectable as Injectable4, Logger as Logger2 } from "@nestjs/common";
1023
+ function _ts_decorate8(decorators, target, key, desc) {
1024
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1025
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1026
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1027
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1028
+ }
1029
+ __name(_ts_decorate8, "_ts_decorate");
1030
+ function _ts_metadata8(k, v) {
1031
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1032
+ }
1033
+ __name(_ts_metadata8, "_ts_metadata");
1034
+ function _ts_param8(paramIndex, decorator) {
1035
+ return function(target, key) {
1036
+ decorator(target, key, paramIndex);
1037
+ };
1038
+ }
1039
+ __name(_ts_param8, "_ts_param");
1040
+ var InlineAgentRunner = class _InlineAgentRunner {
1041
+ static {
1042
+ __name(this, "InlineAgentRunner");
1043
+ }
1044
+ factory;
1045
+ store;
1046
+ logger = new Logger2(_InlineAgentRunner.name);
1047
+ pending = /* @__PURE__ */ new Map();
1048
+ constructor(factory, store) {
1049
+ this.factory = factory;
1050
+ this.store = store;
1051
+ }
1052
+ async start(input) {
1053
+ const runId = crypto.randomUUID();
1054
+ const day = input.day ?? utcDay();
1055
+ const deps = this.factory.forAgent(input.agentName);
1056
+ const hooks = this.topLevelHooks(runId, deps, input.actor, day);
1057
+ void runAgentLoop({
1058
+ ...deps,
1059
+ day
1060
+ }, input, hooks).catch(async (error) => {
1061
+ const message = error instanceof Error ? error.message : String(error);
1062
+ const code = error instanceof QuotaExceededError ? "quota_exceeded" : "run_failed";
1063
+ this.logger.error(`agent run ${runId} failed (${code}): ${message}`);
1064
+ publishAgentRunFailed({
1065
+ runId,
1066
+ code,
1067
+ message
1068
+ });
1069
+ const writer = await deps.sink.open(runId);
1070
+ await writer.fail({
1071
+ code,
1072
+ message
1073
+ });
1074
+ });
1075
+ return {
1076
+ runId
1077
+ };
1078
+ }
1079
+ async signal(runId, toolCallId, decision) {
1080
+ const key = `${runId}:${toolCallId}`;
1081
+ const resolve = this.pending.get(key);
1082
+ if (resolve !== void 0) {
1083
+ this.pending.delete(key);
1084
+ resolve(decision);
1085
+ }
1086
+ }
1087
+ async cancel(runId) {
1088
+ const deps = this.factory.forAgent();
1089
+ const writer = await deps.sink.open(runId);
1090
+ await writer.end();
1091
+ }
1092
+ topLevelHooks(runId, deps, actor, day) {
1093
+ return {
1094
+ runId,
1095
+ openSink: /* @__PURE__ */ __name(() => deps.sink.open(runId), "openSink"),
1096
+ awaitApproval: /* @__PURE__ */ __name((call) => new Promise((resolve) => {
1097
+ this.pending.set(`${runId}:${call.id}`, resolve);
1098
+ }), "awaitApproval"),
1099
+ step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
1100
+ runAgent: /* @__PURE__ */ __name((agentName, task) => this.runNested(agentName, task, actor, day, 1, runId), "runAgent")
1101
+ };
1102
+ }
1103
+ /**
1104
+ * Delegate to another agent as a nested in-process run. The sub-agent streams into `sinkRunId`
1105
+ * (the top-level run the human is watching) so its output and any pending action tool are visible,
1106
+ * and its own approvals resolve through the shared pending map keyed by its own runId.
1107
+ */
1108
+ async runNested(agentName, task, actor, day, depth, sinkRunId) {
1109
+ const subThread = await this.store.createThread({
1110
+ actor,
1111
+ persona: "default",
1112
+ transient: true
1113
+ });
1114
+ const runId = crypto.randomUUID();
1115
+ await this.store.setActiveStream(subThread.id, runId);
1116
+ const deps = this.factory.forAgent(agentName);
1117
+ const hooks = {
1118
+ runId,
1119
+ // Forward into the top-level stream; the top-level run owns end/fail on that shared sink.
1120
+ openSink: /* @__PURE__ */ __name(async () => childSinkWriter(await deps.sink.open(sinkRunId)), "openSink"),
1121
+ awaitApproval: /* @__PURE__ */ __name((call) => new Promise((resolve) => {
1122
+ this.pending.set(`${runId}:${call.id}`, resolve);
1123
+ }), "awaitApproval"),
1124
+ step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
1125
+ runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested(childName, childTask, actor, day, depth + 1, sinkRunId), "runAgent")
1126
+ };
1127
+ return runAgentLoop({
1128
+ ...deps,
1129
+ day
1130
+ }, {
1131
+ threadId: subThread.id,
1132
+ actor,
1133
+ userText: task,
1134
+ agentName,
1135
+ day,
1136
+ delegationDepth: depth,
1137
+ sinkRunId
1138
+ }, hooks);
1139
+ }
1140
+ };
1141
+ InlineAgentRunner = _ts_decorate8([
1142
+ Injectable4(),
1143
+ _ts_param8(0, Inject8(AGENT_DEPS_FACTORY2)),
1144
+ _ts_param8(1, Inject8(AGENT_STORE3)),
1145
+ _ts_metadata8("design:type", Function),
1146
+ _ts_metadata8("design:paramtypes", [
1147
+ typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
1148
+ typeof AgentStore === "undefined" ? Object : AgentStore
1149
+ ])
1150
+ ], InlineAgentRunner);
1151
+
1152
+ // src/agent.module.ts
1153
+ function _ts_decorate9(decorators, target, key, desc) {
1154
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1155
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1156
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1157
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1158
+ }
1159
+ __name(_ts_decorate9, "_ts_decorate");
1160
+ var FEATURE_INIT = Symbol("nestjs-agent:feature-init");
1161
+ var DEFAULT_PATH = "agent";
1162
+ function defaultDefinition(options) {
1163
+ return {
1164
+ name: "default",
1165
+ ...options.defaultAgent
1166
+ };
1167
+ }
1168
+ __name(defaultDefinition, "defaultDefinition");
1169
+ function sharedProviders(durable, includeStore) {
1170
+ const providers = [
1171
+ {
1172
+ provide: AGENT_TOOL_REGISTRY3,
1173
+ useFactory: /* @__PURE__ */ __name(() => new ToolRegistry3(), "useFactory")
1174
+ },
1175
+ {
1176
+ provide: AGENT_REGISTRY3,
1177
+ useFactory: /* @__PURE__ */ __name((options) => {
1178
+ const registry = new AgentRegistry3();
1179
+ registry.register(defaultDefinition(options));
1180
+ return registry;
1181
+ }, "useFactory"),
1182
+ inject: [
1183
+ AGENT_OPTIONS3
1184
+ ]
1185
+ },
1186
+ {
1187
+ provide: AGENT_SINK2,
1188
+ useFactory: /* @__PURE__ */ __name((options) => options.sink ?? new InProcessTokenStreamSink(), "useFactory"),
1189
+ inject: [
1190
+ AGENT_OPTIONS3
1191
+ ]
1192
+ },
1193
+ {
1194
+ provide: AGENT_ROLES_POLICY2,
1195
+ useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new DefaultRolesPolicy(options.defaultRoles), "useFactory"),
1196
+ inject: [
1197
+ AGENT_OPTIONS3
1198
+ ]
1199
+ },
1200
+ {
1201
+ provide: AGENT_ACTOR_RESOLVER5,
1202
+ useFactory: /* @__PURE__ */ __name((options) => options.actorResolver, "useFactory"),
1203
+ inject: [
1204
+ AGENT_OPTIONS3
1205
+ ]
1206
+ },
1207
+ {
1208
+ provide: AGENT_MODEL2,
1209
+ useFactory: /* @__PURE__ */ __name((o) => o.model, "useFactory"),
1210
+ inject: [
1211
+ AGENT_OPTIONS3
1212
+ ]
1213
+ },
1214
+ {
1215
+ // An explicit `quota` wins; otherwise `quotaLimitTokens` binds the built-in ledger-backed
1216
+ // store; otherwise quotas are off (undefined). The ledger store reads the same usage rows
1217
+ // the loop already writes, so enforcement needs no extra shared state across replicas.
1218
+ provide: AGENT_QUOTA_STORE2,
1219
+ useFactory: /* @__PURE__ */ __name((o, store) => o.quota ?? (o.quotaLimitTokens !== void 0 ? new LedgerQuotaStore(store, o.quotaLimitTokens) : void 0), "useFactory"),
1220
+ inject: [
1221
+ AGENT_OPTIONS3,
1222
+ AGENT_STORE4
1223
+ ]
1224
+ },
1225
+ AgentDepsFactory2,
1226
+ {
1227
+ provide: AGENT_DEPS_FACTORY3,
1228
+ useExisting: AgentDepsFactory2
1229
+ },
1230
+ AiToolDiscoveryService,
1231
+ InlineAgentRunner,
1232
+ AgentService
1233
+ ];
1234
+ if (includeStore) {
1235
+ providers.push({
1236
+ provide: AGENT_STORE4,
1237
+ useFactory: /* @__PURE__ */ __name((o) => o.store, "useFactory"),
1238
+ inject: [
1239
+ AGENT_OPTIONS3
1240
+ ]
1241
+ });
1242
+ }
1243
+ if (durable) {
1244
+ providers.push({
1245
+ provide: AGENT_RUNNER2,
1246
+ useFactory: /* @__PURE__ */ __name((durableRunner) => {
1247
+ if (durableRunner === void 0) {
1248
+ throw new Error("AgentModule.forRoot({ durable: true }) requires importing AgentDurableModule from '@dudousxd/nestjs-agent/durable' (alongside a configured DurableModule). It was not found.");
1249
+ }
1250
+ return durableRunner;
1251
+ }, "useFactory"),
1252
+ inject: [
1253
+ {
1254
+ token: AGENT_DURABLE_RUNNER,
1255
+ optional: true
1256
+ }
1257
+ ]
1258
+ });
1259
+ } else {
1260
+ providers.push({
1261
+ provide: AGENT_RUNNER2,
1262
+ useExisting: InlineAgentRunner
1263
+ });
1264
+ }
1265
+ return providers;
1266
+ }
1267
+ __name(sharedProviders, "sharedProviders");
1268
+ function exportsFor(includeStore) {
1269
+ return [
1270
+ AGENT_OPTIONS3,
1271
+ AGENT_TOOL_REGISTRY3,
1272
+ AGENT_REGISTRY3,
1273
+ AGENT_SINK2,
1274
+ AGENT_ROLES_POLICY2,
1275
+ AGENT_ACTOR_RESOLVER5,
1276
+ AGENT_MODEL2,
1277
+ ...includeStore ? [
1278
+ AGENT_STORE4
1279
+ ] : [],
1280
+ AGENT_QUOTA_STORE2,
1281
+ AGENT_DEPS_FACTORY3,
1282
+ AgentDepsFactory2,
1283
+ AgentService,
1284
+ InlineAgentRunner
1285
+ ];
1286
+ }
1287
+ __name(exportsFor, "exportsFor");
1288
+ var CONTROLLERS = [
1289
+ ChatController,
1290
+ ThreadsController,
1291
+ ToolCallController,
1292
+ QuotaController
1293
+ ];
1294
+ function routerFor(path) {
1295
+ return RouterModule.register([
1296
+ {
1297
+ path,
1298
+ module: AgentModule
1299
+ }
1300
+ ]);
1301
+ }
1302
+ __name(routerFor, "routerFor");
1303
+ var AgentModule = class _AgentModule {
1304
+ static {
1305
+ __name(this, "AgentModule");
1306
+ }
1307
+ static forRoot(options) {
1308
+ const path = options.path ?? DEFAULT_PATH;
1309
+ const includeStore = options.store !== void 0;
1310
+ return {
1311
+ module: _AgentModule,
1312
+ global: true,
1313
+ imports: [
1314
+ DiscoveryModule,
1315
+ routerFor(path)
1316
+ ],
1317
+ controllers: CONTROLLERS,
1318
+ providers: [
1319
+ {
1320
+ provide: AGENT_OPTIONS3,
1321
+ useValue: options
1322
+ },
1323
+ ...sharedProviders(options.durable ?? false, includeStore)
1324
+ ],
1325
+ exports: exportsFor(includeStore)
1326
+ };
1327
+ }
1328
+ static forRootAsync(options) {
1329
+ const path = options.path ?? DEFAULT_PATH;
1330
+ return {
1331
+ module: _AgentModule,
1332
+ global: true,
1333
+ imports: [
1334
+ DiscoveryModule,
1335
+ routerFor(path),
1336
+ ...options.imports ?? []
1337
+ ],
1338
+ controllers: CONTROLLERS,
1339
+ providers: [
1340
+ {
1341
+ provide: AGENT_OPTIONS3,
1342
+ useFactory: options.useFactory,
1343
+ inject: options.inject ?? []
1344
+ },
1345
+ // The async factory resolves too late to inspect `store`, so we always bind AGENT_STORE here
1346
+ // (its factory reads the resolved options). Omit-and-import-a-store-module is a `forRoot` path.
1347
+ ...sharedProviders(options.durable ?? false, true)
1348
+ ],
1349
+ exports: exportsFor(true)
1350
+ };
1351
+ }
1352
+ /** Register additional named agents (an orchestrator + its sub-agents). */
1353
+ static forFeature(definitions) {
1354
+ return {
1355
+ module: _AgentModule,
1356
+ providers: [
1357
+ {
1358
+ provide: FEATURE_INIT,
1359
+ useFactory: /* @__PURE__ */ __name((registry) => {
1360
+ for (const definition of definitions) {
1361
+ registry.register(definition);
1362
+ }
1363
+ return true;
1364
+ }, "useFactory"),
1365
+ inject: [
1366
+ AGENT_REGISTRY3
1367
+ ]
1368
+ }
1369
+ ]
1370
+ };
1371
+ }
1372
+ };
1373
+ AgentModule = _ts_decorate9([
1374
+ Global(),
1375
+ Module({})
1376
+ ], AgentModule);
1377
+
1378
+ // src/resolver/header-actor-resolver.ts
1379
+ function readHeader(req, name) {
1380
+ if (typeof req !== "object" || req === null || !("headers" in req)) return void 0;
1381
+ const { headers } = req;
1382
+ if (typeof headers !== "object" || headers === null || !(name in headers)) return void 0;
1383
+ const value = Reflect.get(headers, name);
1384
+ return typeof value === "string" ? value : void 0;
1385
+ }
1386
+ __name(readHeader, "readHeader");
1387
+ var HeaderActorResolver = class {
1388
+ static {
1389
+ __name(this, "HeaderActorResolver");
1390
+ }
1391
+ resolve(req) {
1392
+ const id = readHeader(req, "x-actor-id");
1393
+ if (id === void 0 || id.length === 0) {
1394
+ throw new Error("HeaderActorResolver: missing x-actor-id header. No default actor is fabricated. Send x-actor-id from a trusted gateway, or configure AgentModule.forRoot({ actorResolver }) with a resolver that reads your authenticated principal.");
1395
+ }
1396
+ const roles = (readHeader(req, "x-actor-role") ?? "").split(",").map((role) => role.trim()).filter((role) => role.length > 0);
1397
+ const tenantRef = readHeader(req, "x-tenant-ref");
1398
+ return {
1399
+ id,
1400
+ roles,
1401
+ ...tenantRef !== void 0 ? {
1402
+ tenantRef
1403
+ } : {}
1404
+ };
1405
+ }
1406
+ };
1407
+
1408
+ // src/index.ts
1409
+ export * from "@dudousxd/nestjs-agent-core";
1410
+ export {
1411
+ AGENT_TOOL_BRAND,
1412
+ AI_TOOL_METADATA,
1413
+ AgentDepsFactory2 as AgentDepsFactory,
1414
+ AgentModule,
1415
+ AgentService,
1416
+ AiTool,
1417
+ AiToolDiscoveryService,
1418
+ HeaderActorResolver,
1419
+ InProcessTokenStreamSink,
1420
+ InlineAgentRunner,
1421
+ LedgerQuotaStore,
1422
+ delegateToolName,
1423
+ provideAgentTool,
1424
+ readAiToolMetadata,
1425
+ utcDay
1426
+ };
1427
+ //# sourceMappingURL=index.js.map