@dudousxd/nestjs-agent-core 0.38.0 → 0.39.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.
@@ -1,4 +1,4 @@
1
- import { M as ModelMessage, a as Actor, d as ToolCallRequest } from './stream-events-CgWqAI-1.js';
1
+ import { M as ModelMessage, a as Actor, d as ToolCallRequest } from './stream-events-CbVEowYb.cjs';
2
2
 
3
3
  /**
4
4
  * The two seams that see a turn's traffic to and from the model: an {@link InputProcessor} rewrites
@@ -23,6 +23,8 @@ interface ProcessorContext {
23
23
  actor: Actor;
24
24
  /** The agent running this turn. Undefined → the default agent. */
25
25
  agentName?: string;
26
+ /** The persona the turn runs under, when it runs under one. */
27
+ persona?: string;
26
28
  /** 0-based model step within the run — the same index the `llm:<step>` checkpoint carries. */
27
29
  step: number;
28
30
  }
@@ -1,4 +1,4 @@
1
- import { M as ModelMessage, a as Actor, d as ToolCallRequest } from './stream-events-CgWqAI-1.cjs';
1
+ import { M as ModelMessage, a as Actor, d as ToolCallRequest } from './stream-events-CbVEowYb.js';
2
2
 
3
3
  /**
4
4
  * The two seams that see a turn's traffic to and from the model: an {@link InputProcessor} rewrites
@@ -23,6 +23,8 @@ interface ProcessorContext {
23
23
  actor: Actor;
24
24
  /** The agent running this turn. Undefined → the default agent. */
25
25
  agentName?: string;
26
+ /** The persona the turn runs under, when it runs under one. */
27
+ persona?: string;
26
28
  /** 0-based model step within the run — the same index the `llm:<step>` checkpoint carries. */
27
29
  step: number;
28
30
  }
@@ -115,6 +115,8 @@ interface CreateThreadInput {
115
115
  * included).
116
116
  */
117
117
  id?: string;
118
+ /** The persona the thread's turns run under when a send names none. See {@link ThreadSummary.persona}. */
119
+ persona?: string;
118
120
  }
119
121
  interface AppendMessageInput {
120
122
  threadId: string;
@@ -122,6 +124,8 @@ interface AppendMessageInput {
122
124
  content: string;
123
125
  /** Which agent produced this message (assistant messages) — provenance. */
124
126
  agentName?: string;
127
+ /** The persona the turn ran under. See {@link StoredMessage.persona}. */
128
+ persona?: string;
125
129
  toolCalls?: ToolCallRequest[];
126
130
  toolResults?: ToolResult[];
127
131
  /** Files the user attached to this message (image/PDF). Persisted verbatim. */
@@ -191,6 +195,8 @@ interface UpdateThreadInput {
191
195
  defaultAgent?: string | null;
192
196
  /** `null` unpins the thread's model (turns run on the provider default). */
193
197
  model?: string | null;
198
+ /** `null` clears the thread's persona (sends fall back to the agent's default persona). */
199
+ persona?: string | null;
194
200
  }
195
201
  interface RecordUsageInput {
196
202
  threadId: string;
@@ -421,6 +427,11 @@ interface AgentStore {
421
427
  * would be pinned for ever with nothing pointing at them. Answering from the surviving message
422
428
  * rows on every call is the only form of this that stays true after a truncation.
423
429
  *
430
+ * A message WAITING IN A THREAD'S QUEUE ({@link import('./chat-queue.js').ChatQueueStore}) counts
431
+ * too: it has been sent, it just has not run yet, and the turn it is waiting to start will read
432
+ * its attachments — a sweep that collected them would fail that turn. That holds for a paused
433
+ * queue as well. Removing the message, or editing its attachments away, frees them again.
434
+ *
424
435
  * Scoped to one actor, like every other read on this surface: media referenced only by ANOTHER
425
436
  * actor's thread is reported unreferenced here, so this can never be turned into a probe for what
426
437
  * exists in someone else's conversation. A host pairs it with its own per-actor inventory, so the
@@ -485,6 +496,8 @@ interface QueuedMessage {
485
496
  content: string;
486
497
  attachments?: MessageAttachment[];
487
498
  agentName?: string;
499
+ /** The persona the send resolved (explicit, the thread's, or the agent's default) — what it starts under. */
500
+ persona?: string;
488
501
  model?: string;
489
502
  pageContext?: PageContext;
490
503
  /**
@@ -501,6 +514,7 @@ interface QueuedMessageView {
501
514
  content: string;
502
515
  attachments?: MessageAttachment[];
503
516
  agentName?: string;
517
+ persona?: string;
504
518
  model?: string;
505
519
  interrupt?: boolean;
506
520
  createdAt: string;
@@ -521,6 +535,7 @@ interface EnqueueMessageInput {
521
535
  content: string;
522
536
  attachments?: MessageAttachment[];
523
537
  agentName?: string;
538
+ persona?: string;
524
539
  model?: string;
525
540
  pageContext?: PageContext;
526
541
  interrupt?: boolean;
@@ -1134,6 +1149,70 @@ interface PromptContext {
1134
1149
  /** The selected agent's name. */
1135
1150
  agentName: string;
1136
1151
  pageContext?: PageContext;
1152
+ /**
1153
+ * The persona this turn runs under, when it runs under one — so an agent's own `@SystemPrompt`
1154
+ * (or a contributor) can vary by persona without the persona carrying a prompt of its own.
1155
+ */
1156
+ persona?: PersonaRef;
1157
+ /**
1158
+ * The agent's own resolved base prompt. Set only while a persona's {@link Persona.systemPrompt} is
1159
+ * being resolved, so a persona builder can wrap the base rather than discard it.
1160
+ */
1161
+ basePrompt?: string;
1162
+ }
1163
+ /**
1164
+ * A named variant of ONE agent: its own prompt and, optionally, a narrower tool allow-list. The
1165
+ * caller picks one per send (`POST <base>/chat { persona }`); everything else — the agent's model,
1166
+ * its access rules, its handoffs, its history — stays the agent's. A variant that needs any of those
1167
+ * to differ is a different `@Agent`, not a persona.
1168
+ */
1169
+ interface Persona {
1170
+ /** Unique within its agent — what a send names and what a message records. */
1171
+ id: string;
1172
+ /** What a picker shows. */
1173
+ label: string;
1174
+ /** One line about what the persona is for, for a picker. */
1175
+ description?: string;
1176
+ /**
1177
+ * The persona's prompt. A flat string STANDS IN FOR the agent's base prompt; a
1178
+ * {@link PromptBuilder} is handed that base as `ctx.basePrompt`, so it can wrap it instead. The
1179
+ * cross-agent contributors still follow either way. Omit → the agent's base prompt, unchanged
1180
+ * (which can itself read `ctx.persona`).
1181
+ */
1182
+ systemPrompt?: string | PromptBuilder;
1183
+ /**
1184
+ * Only these tool names are offered — and only these may be invoked — under this persona. Layered
1185
+ * AFTER the agent's own allow-list, `enabled`, the roles policy and `canUse`: it narrows, never
1186
+ * widens. Omit → whatever the agent offers.
1187
+ */
1188
+ allowedTools?: string[];
1189
+ /**
1190
+ * Agent names this persona answers for: a send, a queued message or a thread that names one of
1191
+ * them runs as THIS agent under THIS persona. For an app that turns separate agents into personas
1192
+ * of one — the threads, messages and in-flight runs that recorded the old agent name keep
1193
+ * resolving, with no data migration.
1194
+ */
1195
+ aliases?: string[];
1196
+ }
1197
+ /** What a prompt builder and a tool see of the turn's persona. */
1198
+ interface PersonaRef {
1199
+ id: string;
1200
+ label: string;
1201
+ }
1202
+ /**
1203
+ * A persona as a turn RESOLVED it, journaled in the `persona:resolve` checkpoint — so every replay
1204
+ * of the run uses this, and not whatever the persona's configuration says by the time it resumes.
1205
+ */
1206
+ interface TurnPersona extends PersonaRef {
1207
+ allowedTools?: string[];
1208
+ /** The persona's prompt, resolved (with the base prompt it wraps). Absent → the base prompt. */
1209
+ prompt?: string;
1210
+ }
1211
+ /** One persona as `GET <base>/agents` lists it — what a persona picker renders. */
1212
+ interface PersonaCatalogEntry {
1213
+ id: string;
1214
+ label: string;
1215
+ description?: string;
1137
1216
  }
1138
1217
  /**
1139
1218
  * An agent's base system prompt. Return a string (optionally async) built from the turn's context —
@@ -1161,6 +1240,13 @@ interface AgentRunInput {
1161
1240
  day?: string;
1162
1241
  /** Which named agent runs this turn. Omitted → the default/single agent. */
1163
1242
  agentName?: string;
1243
+ /**
1244
+ * The persona of {@link agentName} this turn runs under (a {@link Persona.id}). Resolved by the
1245
+ * service from the send, the thread and the agent's default BEFORE the run starts, so it is part
1246
+ * of the run's own input; the loop resolves its definition once, in the `persona:resolve`
1247
+ * checkpoint. Omitted → no persona, and no checkpoint spent on one.
1248
+ */
1249
+ persona?: string;
1164
1250
  /**
1165
1251
  * How many agent→agent delegations deep this run already is (0 for a top-level turn). The runner
1166
1252
  * increments it for each child run; the loop refuses to delegate past its depth ceiling.
@@ -1268,6 +1354,10 @@ interface AgentDefinition {
1268
1354
  * Whether this agent is offered the built-in `ask` tool. Undefined → the module-wide setting.
1269
1355
  */
1270
1356
  ask?: boolean;
1357
+ /** Named variants of this agent — see {@link Persona}. Undefined → none. */
1358
+ personas?: Persona[];
1359
+ /** The persona a send runs under when neither it nor its thread names one. Undefined → none. */
1360
+ defaultPersona?: string;
1271
1361
  }
1272
1362
  /**
1273
1363
  * The read-model the `GET agents` endpoint returns to a client — the safe public subset of an
@@ -1283,6 +1373,10 @@ interface AgentCatalogEntry {
1283
1373
  * so before a chat starts. `GET <base>/models?agent=` reports the same lock as `locked`.
1284
1374
  */
1285
1375
  lockedModel?: string;
1376
+ /** The agent's personas, for a persona picker. Omitted when it declares none. */
1377
+ personas?: PersonaCatalogEntry[];
1378
+ /** The persona a send runs under when it names none. Omitted when the agent has no default. */
1379
+ defaultPersona?: string;
1286
1380
  }
1287
1381
  interface ThreadSummary {
1288
1382
  id: string;
@@ -1309,6 +1403,12 @@ interface ThreadSummary {
1309
1403
  * it; the REST read-model normalizes that to `null`.
1310
1404
  */
1311
1405
  model?: string | null;
1406
+ /**
1407
+ * The persona this thread's turns run under when a send names none — the last one a send on it
1408
+ * named, or `PATCH <base>/threads/:id { persona }`. `null` → the agent's default. Undefined for a
1409
+ * store that does not persist it; the REST read-model normalizes that to `null`.
1410
+ */
1411
+ persona?: string | null;
1312
1412
  }
1313
1413
  interface StoredMessage {
1314
1414
  id: string;
@@ -1316,6 +1416,8 @@ interface StoredMessage {
1316
1416
  content: string;
1317
1417
  /** Which agent produced this message (assistant messages) — provenance for replay / UI / telescope. */
1318
1418
  agentName?: string;
1419
+ /** The persona the turn that wrote this message ran under; absent when it ran under none. */
1420
+ persona?: string;
1319
1421
  toolCalls?: ToolCallRequest[];
1320
1422
  toolResults?: ToolResult[];
1321
1423
  /** Files the user attached to this message (image/PDF). Persisted with the message, replayed as-is. */
@@ -1426,6 +1528,11 @@ interface LlmStepEnvelope {
1426
1528
  bufferOutput?: boolean;
1427
1529
  /** The turn's selected model ({@link AgentRunInput.model}), for the worker's provider call. */
1428
1530
  model?: string;
1531
+ /**
1532
+ * The allow-list of the persona the turn resolved (`persona:resolve`), which the serving worker
1533
+ * intersects with the agent's own. Absent → no persona narrowing, as before personas existed.
1534
+ */
1535
+ personaAllowedTools?: string[];
1429
1536
  }
1430
1537
  /**
1431
1538
  * The serializable subset of `AiToolCtx` — everything except `host` (re-attached handler-side
@@ -1437,6 +1544,8 @@ interface ToolStepCtx {
1437
1544
  runId: string;
1438
1545
  requestId: string;
1439
1546
  agentName?: string;
1547
+ /** The persona the turn runs under ({@link AiToolCtx.persona}). */
1548
+ persona?: string;
1440
1549
  pageContext?: PageContext;
1441
1550
  }
1442
1551
  /** Serializable input for a dispatched tool-execution step. */
@@ -1444,6 +1553,11 @@ interface ToolStepEnvelope {
1444
1553
  toolName: string;
1445
1554
  input: unknown;
1446
1555
  ctx: ToolStepCtx;
1556
+ /**
1557
+ * The only tool names this call may invoke — the turn's persona allow-list (intersected with the
1558
+ * agent's). Checked by `ToolRegistry.invoke` on the worker. Absent → no such check.
1559
+ */
1560
+ allowedTools?: string[];
1447
1561
  /** Applied INSIDE the handler (`withToolTimeout`) — never as a durable step `timeoutMs`. */
1448
1562
  timeoutMs?: number;
1449
1563
  /**
@@ -1952,4 +2066,4 @@ type AgentStreamErrorCode = 'quota_exceeded' | 'output_rejected' | 'structured_o
1952
2066
  /** A model call ended without producing anything. */
1953
2067
  | 'model_no_output' | 'run_failed';
1954
2068
 
1955
- export { type AgentApprovalSettlement as $, type AgentStreamEvent as A, type QueuedMessage as B, type ChatQueueStore as C, type DetachedDelivery as D, type ElicitationRequest as E, type QueuedMessagePatch as F, type QueuePause as G, type HumanReply as H, type AppendMessageInput as I, type ToolResult as J, type MessageFeedback as K, type LlmStepEnvelope as L, type ModelMessage as M, type RecordToolCallInput as N, type ToolCallOutcome as O, type PageContext as P, type QuotaState as Q, type RecordRunStartInput as R, type StoredMessage as S, type ToolSpec as T, type UpdateThreadInput as U, type UpdateToolCallInput as V, type RecordUsageInput as W, ALL_AGENTS as X, ASK_TOOL_DESCRIPTION as Y, ASK_TOOL_NAME as Z, type AgentApprovalRequest as _, type Actor as a, settleDanglingToolCalls as a$, type AgentAttachmentConfig as a0, type AgentCatalogEntry as a1, type AgentClientConfig as a2, type AgentHistoryWindow as a3, type AgentStreamErrorCode as a4, type AskToolInput as a5, type ChatQueueState as a6, DEFAULT_INTAKE_PREAMBLE as a7, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as a8, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as a9, type ToolConfirmation as aA, type ToolPresentationTone as aB, type ToolResultField as aC, type ToolResultView as aD, type ToolStepCtx as aE, type ToolTransientRetryNumbers as aF, type ToolTransientRetryOptions as aG, UNFINISHED_TOOL_CALL as aH, type UsagePurpose as aI, askInputSchema as aJ, askToolDefinition as aK, danglingToolCallIds as aL, decodeStreamEvent as aM, encodeStreamEvent as aN, invokeWithTransientRetry as aO, isChatQueueStore as aP, isTransientToolError as aQ, isTypedQuestion as aR, normalizeElicitationReply as aS, questionOptions as aT, queuedMessageView as aU, readElicitationInput as aV, readElicitationQuestions as aW, releaseThreadRun as aX, renderElicitationAnswers as aY, resolveElicitation as aZ, resolveToolTransientRetryNumbers as a_, ELICITATION_INPUT_TYPES as aa, type ElicitationInput as ab, type ElicitationInputType as ac, type ElicitationOption as ad, type ElicitationOutcome as ae, type ElicitationQuestion as af, type ElicitationReply as ag, type ElicitationResult as ah, type HistoryPolicyContext as ai, type HistorySelection as aj, type HistorySummary as ak, type InvokeWithTransientRetryOptions as al, MAX_ASK_QUESTIONS as am, type MessageFeedbackValue as an, type MessageRole as ao, type PromptContext as ap, type QueuePauseReason as aq, type QueuedMessageView as ar, type QuotaView as as, RUN_ENDED_BEFORE_TOOL_CALL as at, type RecordRunEndInput as au, type ThreadTurnPage as av, type ThreadTurnQuery as aw, type ThreadTurnReader as ax, type ToolCallApprovalStatus as ay, type ToolCatalogEntry as az, type ToolPresentation as b, settleElicitation as b0, validateElicitationAnswer as b1, validateElicitationValue as b2, type ToolDefinition as c, type ToolCallRequest as d, type MessageUsage as e, type AgentUiComponent as f, type AgentRunInput as g, type MessageAttachment as h, type ToolKind as i, type ToolCallStatus as j, type ToolCallApproval as k, type HistoryPolicy as l, type AgentDefinition as m, type AgentStore as n, type AgentDelegation as o, type PromptBuilder as p, type PromptContributor as q, type ToolTransientRetrySetting as r, type AgentIntake as s, type Decision as t, type ToolStepEnvelope as u, type CreateThreadInput as v, type ThreadSummary as w, type ThreadDetail as x, type ToolCallApprovalState as y, type EnqueueMessageInput as z };
2069
+ export { ASK_TOOL_NAME as $, type AgentStreamEvent as A, type ToolCallApprovalState as B, type ChatQueueStore as C, type DetachedDelivery as D, type ElicitationRequest as E, type EnqueueMessageInput as F, type QueuedMessage as G, type HumanReply as H, type QueuedMessagePatch as I, type QueuePause as J, type AppendMessageInput as K, type LlmStepEnvelope as L, type ModelMessage as M, type ToolResult as N, type MessageFeedback as O, type Persona as P, type QuotaState as Q, type RecordRunStartInput as R, type StoredMessage as S, type ToolSpec as T, type UpdateThreadInput as U, type RecordToolCallInput as V, type ToolCallOutcome as W, type UpdateToolCallInput as X, type RecordUsageInput as Y, ALL_AGENTS as Z, ASK_TOOL_DESCRIPTION as _, type Actor as a, releaseThreadRun as a$, type AgentApprovalRequest as a0, type AgentApprovalSettlement as a1, type AgentAttachmentConfig as a2, type AgentCatalogEntry as a3, type AgentClientConfig as a4, type AgentHistoryWindow as a5, type AgentStreamErrorCode as a6, type AskToolInput as a7, type ChatQueueState as a8, DEFAULT_INTAKE_PREAMBLE as a9, type ThreadTurnReader as aA, type ToolCallApprovalStatus as aB, type ToolCatalogEntry as aC, type ToolConfirmation as aD, type ToolPresentationTone as aE, type ToolResultField as aF, type ToolResultView as aG, type ToolStepCtx as aH, type ToolTransientRetryNumbers as aI, type ToolTransientRetryOptions as aJ, type TurnPersona as aK, UNFINISHED_TOOL_CALL as aL, type UsagePurpose as aM, askInputSchema as aN, askToolDefinition as aO, danglingToolCallIds as aP, decodeStreamEvent as aQ, encodeStreamEvent as aR, invokeWithTransientRetry as aS, isChatQueueStore as aT, isTransientToolError as aU, isTypedQuestion as aV, normalizeElicitationReply as aW, questionOptions as aX, queuedMessageView as aY, readElicitationInput as aZ, readElicitationQuestions as a_, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as aa, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as ab, ELICITATION_INPUT_TYPES as ac, type ElicitationInput as ad, type ElicitationInputType as ae, type ElicitationOption as af, type ElicitationOutcome as ag, type ElicitationQuestion as ah, type ElicitationReply as ai, type ElicitationResult as aj, type HistoryPolicyContext as ak, type HistorySelection as al, type HistorySummary as am, type InvokeWithTransientRetryOptions as an, MAX_ASK_QUESTIONS as ao, type MessageFeedbackValue as ap, type MessageRole as aq, type PersonaRef as ar, type PromptContext as as, type QueuePauseReason as at, type QueuedMessageView as au, type QuotaView as av, RUN_ENDED_BEFORE_TOOL_CALL as aw, type RecordRunEndInput as ax, type ThreadTurnPage as ay, type ThreadTurnQuery as az, type ToolPresentation as b, renderElicitationAnswers as b0, resolveElicitation as b1, resolveToolTransientRetryNumbers as b2, settleDanglingToolCalls as b3, settleElicitation as b4, validateElicitationAnswer as b5, validateElicitationValue as b6, type ToolDefinition as c, type ToolCallRequest as d, type MessageUsage as e, type AgentUiComponent as f, type AgentRunInput as g, type MessageAttachment as h, type ToolKind as i, type ToolCallStatus as j, type ToolCallApproval as k, type AgentDefinition as l, type PersonaCatalogEntry as m, type HistoryPolicy as n, type PageContext as o, type AgentStore as p, type AgentDelegation as q, type PromptBuilder as r, type PromptContributor as s, type ToolTransientRetrySetting as t, type AgentIntake as u, type Decision as v, type ToolStepEnvelope as w, type CreateThreadInput as x, type ThreadSummary as y, type ThreadDetail as z };
@@ -115,6 +115,8 @@ interface CreateThreadInput {
115
115
  * included).
116
116
  */
117
117
  id?: string;
118
+ /** The persona the thread's turns run under when a send names none. See {@link ThreadSummary.persona}. */
119
+ persona?: string;
118
120
  }
119
121
  interface AppendMessageInput {
120
122
  threadId: string;
@@ -122,6 +124,8 @@ interface AppendMessageInput {
122
124
  content: string;
123
125
  /** Which agent produced this message (assistant messages) — provenance. */
124
126
  agentName?: string;
127
+ /** The persona the turn ran under. See {@link StoredMessage.persona}. */
128
+ persona?: string;
125
129
  toolCalls?: ToolCallRequest[];
126
130
  toolResults?: ToolResult[];
127
131
  /** Files the user attached to this message (image/PDF). Persisted verbatim. */
@@ -191,6 +195,8 @@ interface UpdateThreadInput {
191
195
  defaultAgent?: string | null;
192
196
  /** `null` unpins the thread's model (turns run on the provider default). */
193
197
  model?: string | null;
198
+ /** `null` clears the thread's persona (sends fall back to the agent's default persona). */
199
+ persona?: string | null;
194
200
  }
195
201
  interface RecordUsageInput {
196
202
  threadId: string;
@@ -421,6 +427,11 @@ interface AgentStore {
421
427
  * would be pinned for ever with nothing pointing at them. Answering from the surviving message
422
428
  * rows on every call is the only form of this that stays true after a truncation.
423
429
  *
430
+ * A message WAITING IN A THREAD'S QUEUE ({@link import('./chat-queue.js').ChatQueueStore}) counts
431
+ * too: it has been sent, it just has not run yet, and the turn it is waiting to start will read
432
+ * its attachments — a sweep that collected them would fail that turn. That holds for a paused
433
+ * queue as well. Removing the message, or editing its attachments away, frees them again.
434
+ *
424
435
  * Scoped to one actor, like every other read on this surface: media referenced only by ANOTHER
425
436
  * actor's thread is reported unreferenced here, so this can never be turned into a probe for what
426
437
  * exists in someone else's conversation. A host pairs it with its own per-actor inventory, so the
@@ -485,6 +496,8 @@ interface QueuedMessage {
485
496
  content: string;
486
497
  attachments?: MessageAttachment[];
487
498
  agentName?: string;
499
+ /** The persona the send resolved (explicit, the thread's, or the agent's default) — what it starts under. */
500
+ persona?: string;
488
501
  model?: string;
489
502
  pageContext?: PageContext;
490
503
  /**
@@ -501,6 +514,7 @@ interface QueuedMessageView {
501
514
  content: string;
502
515
  attachments?: MessageAttachment[];
503
516
  agentName?: string;
517
+ persona?: string;
504
518
  model?: string;
505
519
  interrupt?: boolean;
506
520
  createdAt: string;
@@ -521,6 +535,7 @@ interface EnqueueMessageInput {
521
535
  content: string;
522
536
  attachments?: MessageAttachment[];
523
537
  agentName?: string;
538
+ persona?: string;
524
539
  model?: string;
525
540
  pageContext?: PageContext;
526
541
  interrupt?: boolean;
@@ -1134,6 +1149,70 @@ interface PromptContext {
1134
1149
  /** The selected agent's name. */
1135
1150
  agentName: string;
1136
1151
  pageContext?: PageContext;
1152
+ /**
1153
+ * The persona this turn runs under, when it runs under one — so an agent's own `@SystemPrompt`
1154
+ * (or a contributor) can vary by persona without the persona carrying a prompt of its own.
1155
+ */
1156
+ persona?: PersonaRef;
1157
+ /**
1158
+ * The agent's own resolved base prompt. Set only while a persona's {@link Persona.systemPrompt} is
1159
+ * being resolved, so a persona builder can wrap the base rather than discard it.
1160
+ */
1161
+ basePrompt?: string;
1162
+ }
1163
+ /**
1164
+ * A named variant of ONE agent: its own prompt and, optionally, a narrower tool allow-list. The
1165
+ * caller picks one per send (`POST <base>/chat { persona }`); everything else — the agent's model,
1166
+ * its access rules, its handoffs, its history — stays the agent's. A variant that needs any of those
1167
+ * to differ is a different `@Agent`, not a persona.
1168
+ */
1169
+ interface Persona {
1170
+ /** Unique within its agent — what a send names and what a message records. */
1171
+ id: string;
1172
+ /** What a picker shows. */
1173
+ label: string;
1174
+ /** One line about what the persona is for, for a picker. */
1175
+ description?: string;
1176
+ /**
1177
+ * The persona's prompt. A flat string STANDS IN FOR the agent's base prompt; a
1178
+ * {@link PromptBuilder} is handed that base as `ctx.basePrompt`, so it can wrap it instead. The
1179
+ * cross-agent contributors still follow either way. Omit → the agent's base prompt, unchanged
1180
+ * (which can itself read `ctx.persona`).
1181
+ */
1182
+ systemPrompt?: string | PromptBuilder;
1183
+ /**
1184
+ * Only these tool names are offered — and only these may be invoked — under this persona. Layered
1185
+ * AFTER the agent's own allow-list, `enabled`, the roles policy and `canUse`: it narrows, never
1186
+ * widens. Omit → whatever the agent offers.
1187
+ */
1188
+ allowedTools?: string[];
1189
+ /**
1190
+ * Agent names this persona answers for: a send, a queued message or a thread that names one of
1191
+ * them runs as THIS agent under THIS persona. For an app that turns separate agents into personas
1192
+ * of one — the threads, messages and in-flight runs that recorded the old agent name keep
1193
+ * resolving, with no data migration.
1194
+ */
1195
+ aliases?: string[];
1196
+ }
1197
+ /** What a prompt builder and a tool see of the turn's persona. */
1198
+ interface PersonaRef {
1199
+ id: string;
1200
+ label: string;
1201
+ }
1202
+ /**
1203
+ * A persona as a turn RESOLVED it, journaled in the `persona:resolve` checkpoint — so every replay
1204
+ * of the run uses this, and not whatever the persona's configuration says by the time it resumes.
1205
+ */
1206
+ interface TurnPersona extends PersonaRef {
1207
+ allowedTools?: string[];
1208
+ /** The persona's prompt, resolved (with the base prompt it wraps). Absent → the base prompt. */
1209
+ prompt?: string;
1210
+ }
1211
+ /** One persona as `GET <base>/agents` lists it — what a persona picker renders. */
1212
+ interface PersonaCatalogEntry {
1213
+ id: string;
1214
+ label: string;
1215
+ description?: string;
1137
1216
  }
1138
1217
  /**
1139
1218
  * An agent's base system prompt. Return a string (optionally async) built from the turn's context —
@@ -1161,6 +1240,13 @@ interface AgentRunInput {
1161
1240
  day?: string;
1162
1241
  /** Which named agent runs this turn. Omitted → the default/single agent. */
1163
1242
  agentName?: string;
1243
+ /**
1244
+ * The persona of {@link agentName} this turn runs under (a {@link Persona.id}). Resolved by the
1245
+ * service from the send, the thread and the agent's default BEFORE the run starts, so it is part
1246
+ * of the run's own input; the loop resolves its definition once, in the `persona:resolve`
1247
+ * checkpoint. Omitted → no persona, and no checkpoint spent on one.
1248
+ */
1249
+ persona?: string;
1164
1250
  /**
1165
1251
  * How many agent→agent delegations deep this run already is (0 for a top-level turn). The runner
1166
1252
  * increments it for each child run; the loop refuses to delegate past its depth ceiling.
@@ -1268,6 +1354,10 @@ interface AgentDefinition {
1268
1354
  * Whether this agent is offered the built-in `ask` tool. Undefined → the module-wide setting.
1269
1355
  */
1270
1356
  ask?: boolean;
1357
+ /** Named variants of this agent — see {@link Persona}. Undefined → none. */
1358
+ personas?: Persona[];
1359
+ /** The persona a send runs under when neither it nor its thread names one. Undefined → none. */
1360
+ defaultPersona?: string;
1271
1361
  }
1272
1362
  /**
1273
1363
  * The read-model the `GET agents` endpoint returns to a client — the safe public subset of an
@@ -1283,6 +1373,10 @@ interface AgentCatalogEntry {
1283
1373
  * so before a chat starts. `GET <base>/models?agent=` reports the same lock as `locked`.
1284
1374
  */
1285
1375
  lockedModel?: string;
1376
+ /** The agent's personas, for a persona picker. Omitted when it declares none. */
1377
+ personas?: PersonaCatalogEntry[];
1378
+ /** The persona a send runs under when it names none. Omitted when the agent has no default. */
1379
+ defaultPersona?: string;
1286
1380
  }
1287
1381
  interface ThreadSummary {
1288
1382
  id: string;
@@ -1309,6 +1403,12 @@ interface ThreadSummary {
1309
1403
  * it; the REST read-model normalizes that to `null`.
1310
1404
  */
1311
1405
  model?: string | null;
1406
+ /**
1407
+ * The persona this thread's turns run under when a send names none — the last one a send on it
1408
+ * named, or `PATCH <base>/threads/:id { persona }`. `null` → the agent's default. Undefined for a
1409
+ * store that does not persist it; the REST read-model normalizes that to `null`.
1410
+ */
1411
+ persona?: string | null;
1312
1412
  }
1313
1413
  interface StoredMessage {
1314
1414
  id: string;
@@ -1316,6 +1416,8 @@ interface StoredMessage {
1316
1416
  content: string;
1317
1417
  /** Which agent produced this message (assistant messages) — provenance for replay / UI / telescope. */
1318
1418
  agentName?: string;
1419
+ /** The persona the turn that wrote this message ran under; absent when it ran under none. */
1420
+ persona?: string;
1319
1421
  toolCalls?: ToolCallRequest[];
1320
1422
  toolResults?: ToolResult[];
1321
1423
  /** Files the user attached to this message (image/PDF). Persisted with the message, replayed as-is. */
@@ -1426,6 +1528,11 @@ interface LlmStepEnvelope {
1426
1528
  bufferOutput?: boolean;
1427
1529
  /** The turn's selected model ({@link AgentRunInput.model}), for the worker's provider call. */
1428
1530
  model?: string;
1531
+ /**
1532
+ * The allow-list of the persona the turn resolved (`persona:resolve`), which the serving worker
1533
+ * intersects with the agent's own. Absent → no persona narrowing, as before personas existed.
1534
+ */
1535
+ personaAllowedTools?: string[];
1429
1536
  }
1430
1537
  /**
1431
1538
  * The serializable subset of `AiToolCtx` — everything except `host` (re-attached handler-side
@@ -1437,6 +1544,8 @@ interface ToolStepCtx {
1437
1544
  runId: string;
1438
1545
  requestId: string;
1439
1546
  agentName?: string;
1547
+ /** The persona the turn runs under ({@link AiToolCtx.persona}). */
1548
+ persona?: string;
1440
1549
  pageContext?: PageContext;
1441
1550
  }
1442
1551
  /** Serializable input for a dispatched tool-execution step. */
@@ -1444,6 +1553,11 @@ interface ToolStepEnvelope {
1444
1553
  toolName: string;
1445
1554
  input: unknown;
1446
1555
  ctx: ToolStepCtx;
1556
+ /**
1557
+ * The only tool names this call may invoke — the turn's persona allow-list (intersected with the
1558
+ * agent's). Checked by `ToolRegistry.invoke` on the worker. Absent → no such check.
1559
+ */
1560
+ allowedTools?: string[];
1447
1561
  /** Applied INSIDE the handler (`withToolTimeout`) — never as a durable step `timeoutMs`. */
1448
1562
  timeoutMs?: number;
1449
1563
  /**
@@ -1952,4 +2066,4 @@ type AgentStreamErrorCode = 'quota_exceeded' | 'output_rejected' | 'structured_o
1952
2066
  /** A model call ended without producing anything. */
1953
2067
  | 'model_no_output' | 'run_failed';
1954
2068
 
1955
- export { type AgentApprovalSettlement as $, type AgentStreamEvent as A, type QueuedMessage as B, type ChatQueueStore as C, type DetachedDelivery as D, type ElicitationRequest as E, type QueuedMessagePatch as F, type QueuePause as G, type HumanReply as H, type AppendMessageInput as I, type ToolResult as J, type MessageFeedback as K, type LlmStepEnvelope as L, type ModelMessage as M, type RecordToolCallInput as N, type ToolCallOutcome as O, type PageContext as P, type QuotaState as Q, type RecordRunStartInput as R, type StoredMessage as S, type ToolSpec as T, type UpdateThreadInput as U, type UpdateToolCallInput as V, type RecordUsageInput as W, ALL_AGENTS as X, ASK_TOOL_DESCRIPTION as Y, ASK_TOOL_NAME as Z, type AgentApprovalRequest as _, type Actor as a, settleDanglingToolCalls as a$, type AgentAttachmentConfig as a0, type AgentCatalogEntry as a1, type AgentClientConfig as a2, type AgentHistoryWindow as a3, type AgentStreamErrorCode as a4, type AskToolInput as a5, type ChatQueueState as a6, DEFAULT_INTAKE_PREAMBLE as a7, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as a8, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as a9, type ToolConfirmation as aA, type ToolPresentationTone as aB, type ToolResultField as aC, type ToolResultView as aD, type ToolStepCtx as aE, type ToolTransientRetryNumbers as aF, type ToolTransientRetryOptions as aG, UNFINISHED_TOOL_CALL as aH, type UsagePurpose as aI, askInputSchema as aJ, askToolDefinition as aK, danglingToolCallIds as aL, decodeStreamEvent as aM, encodeStreamEvent as aN, invokeWithTransientRetry as aO, isChatQueueStore as aP, isTransientToolError as aQ, isTypedQuestion as aR, normalizeElicitationReply as aS, questionOptions as aT, queuedMessageView as aU, readElicitationInput as aV, readElicitationQuestions as aW, releaseThreadRun as aX, renderElicitationAnswers as aY, resolveElicitation as aZ, resolveToolTransientRetryNumbers as a_, ELICITATION_INPUT_TYPES as aa, type ElicitationInput as ab, type ElicitationInputType as ac, type ElicitationOption as ad, type ElicitationOutcome as ae, type ElicitationQuestion as af, type ElicitationReply as ag, type ElicitationResult as ah, type HistoryPolicyContext as ai, type HistorySelection as aj, type HistorySummary as ak, type InvokeWithTransientRetryOptions as al, MAX_ASK_QUESTIONS as am, type MessageFeedbackValue as an, type MessageRole as ao, type PromptContext as ap, type QueuePauseReason as aq, type QueuedMessageView as ar, type QuotaView as as, RUN_ENDED_BEFORE_TOOL_CALL as at, type RecordRunEndInput as au, type ThreadTurnPage as av, type ThreadTurnQuery as aw, type ThreadTurnReader as ax, type ToolCallApprovalStatus as ay, type ToolCatalogEntry as az, type ToolPresentation as b, settleElicitation as b0, validateElicitationAnswer as b1, validateElicitationValue as b2, type ToolDefinition as c, type ToolCallRequest as d, type MessageUsage as e, type AgentUiComponent as f, type AgentRunInput as g, type MessageAttachment as h, type ToolKind as i, type ToolCallStatus as j, type ToolCallApproval as k, type HistoryPolicy as l, type AgentDefinition as m, type AgentStore as n, type AgentDelegation as o, type PromptBuilder as p, type PromptContributor as q, type ToolTransientRetrySetting as r, type AgentIntake as s, type Decision as t, type ToolStepEnvelope as u, type CreateThreadInput as v, type ThreadSummary as w, type ThreadDetail as x, type ToolCallApprovalState as y, type EnqueueMessageInput as z };
2069
+ export { ASK_TOOL_NAME as $, type AgentStreamEvent as A, type ToolCallApprovalState as B, type ChatQueueStore as C, type DetachedDelivery as D, type ElicitationRequest as E, type EnqueueMessageInput as F, type QueuedMessage as G, type HumanReply as H, type QueuedMessagePatch as I, type QueuePause as J, type AppendMessageInput as K, type LlmStepEnvelope as L, type ModelMessage as M, type ToolResult as N, type MessageFeedback as O, type Persona as P, type QuotaState as Q, type RecordRunStartInput as R, type StoredMessage as S, type ToolSpec as T, type UpdateThreadInput as U, type RecordToolCallInput as V, type ToolCallOutcome as W, type UpdateToolCallInput as X, type RecordUsageInput as Y, ALL_AGENTS as Z, ASK_TOOL_DESCRIPTION as _, type Actor as a, releaseThreadRun as a$, type AgentApprovalRequest as a0, type AgentApprovalSettlement as a1, type AgentAttachmentConfig as a2, type AgentCatalogEntry as a3, type AgentClientConfig as a4, type AgentHistoryWindow as a5, type AgentStreamErrorCode as a6, type AskToolInput as a7, type ChatQueueState as a8, DEFAULT_INTAKE_PREAMBLE as a9, type ThreadTurnReader as aA, type ToolCallApprovalStatus as aB, type ToolCatalogEntry as aC, type ToolConfirmation as aD, type ToolPresentationTone as aE, type ToolResultField as aF, type ToolResultView as aG, type ToolStepCtx as aH, type ToolTransientRetryNumbers as aI, type ToolTransientRetryOptions as aJ, type TurnPersona as aK, UNFINISHED_TOOL_CALL as aL, type UsagePurpose as aM, askInputSchema as aN, askToolDefinition as aO, danglingToolCallIds as aP, decodeStreamEvent as aQ, encodeStreamEvent as aR, invokeWithTransientRetry as aS, isChatQueueStore as aT, isTransientToolError as aU, isTypedQuestion as aV, normalizeElicitationReply as aW, questionOptions as aX, queuedMessageView as aY, readElicitationInput as aZ, readElicitationQuestions as a_, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as aa, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as ab, ELICITATION_INPUT_TYPES as ac, type ElicitationInput as ad, type ElicitationInputType as ae, type ElicitationOption as af, type ElicitationOutcome as ag, type ElicitationQuestion as ah, type ElicitationReply as ai, type ElicitationResult as aj, type HistoryPolicyContext as ak, type HistorySelection as al, type HistorySummary as am, type InvokeWithTransientRetryOptions as an, MAX_ASK_QUESTIONS as ao, type MessageFeedbackValue as ap, type MessageRole as aq, type PersonaRef as ar, type PromptContext as as, type QueuePauseReason as at, type QueuedMessageView as au, type QuotaView as av, RUN_ENDED_BEFORE_TOOL_CALL as aw, type RecordRunEndInput as ax, type ThreadTurnPage as ay, type ThreadTurnQuery as az, type ToolPresentation as b, renderElicitationAnswers as b0, resolveElicitation as b1, resolveToolTransientRetryNumbers as b2, settleDanglingToolCalls as b3, settleElicitation as b4, validateElicitationAnswer as b5, validateElicitationValue as b6, type ToolDefinition as c, type ToolCallRequest as d, type MessageUsage as e, type AgentUiComponent as f, type AgentRunInput as g, type MessageAttachment as h, type ToolKind as i, type ToolCallStatus as j, type ToolCallApproval as k, type AgentDefinition as l, type PersonaCatalogEntry as m, type HistoryPolicy as n, type PageContext as o, type AgentStore as p, type AgentDelegation as q, type PromptBuilder as r, type PromptContributor as s, type ToolTransientRetrySetting as t, type AgentIntake as u, type Decision as v, type ToolStepEnvelope as w, type CreateThreadInput as x, type ThreadSummary as y, type ThreadDetail as z };
@@ -1,5 +1,5 @@
1
1
  import { StandardSchemaV1 } from '@standard-schema/spec';
2
- import { a as Actor, P as PageContext } from './stream-events-CgWqAI-1.cjs';
2
+ import { a as Actor, o as PageContext } from './stream-events-CbVEowYb.cjs';
3
3
 
4
4
  /**
5
5
  * Per-invocation context handed to a tool handler. Host-supplied bits are optional. Identity lives
@@ -34,6 +34,8 @@ interface AiToolCtx {
34
34
  idempotencyKey?: string;
35
35
  /** The name of the agent running this turn — provenance a tool can scope on (e.g. capability sets). */
36
36
  agentName?: string;
37
+ /** The persona of {@link agentName} the turn runs under, when it runs under one. */
38
+ persona?: string;
37
39
  pageContext?: PageContext;
38
40
  /** Optional host handle (e.g. an ORM EntityManager) the app threads through options. */
39
41
  host?: unknown;
@@ -1,5 +1,5 @@
1
1
  import { StandardSchemaV1 } from '@standard-schema/spec';
2
- import { a as Actor, P as PageContext } from './stream-events-CgWqAI-1.js';
2
+ import { a as Actor, o as PageContext } from './stream-events-CbVEowYb.js';
3
3
 
4
4
  /**
5
5
  * Per-invocation context handed to a tool handler. Host-supplied bits are optional. Identity lives
@@ -34,6 +34,8 @@ interface AiToolCtx {
34
34
  idempotencyKey?: string;
35
35
  /** The name of the agent running this turn — provenance a tool can scope on (e.g. capability sets). */
36
36
  agentName?: string;
37
+ /** The persona of {@link agentName} the turn runs under, when it runs under one. */
38
+ persona?: string;
37
39
  pageContext?: PageContext;
38
40
  /** Optional host handle (e.g. an ORM EntityManager) the app threads through options. */
39
41
  host?: unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-agent-core",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/DavideCarvalho/nestjs-agent.git",