@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.
- package/README.md +2 -2
- package/dist/ag-ui/index.d.cts +1 -1
- package/dist/ag-ui/index.d.ts +1 -1
- package/dist/genui/index.d.cts +2 -2
- package/dist/genui/index.d.ts +2 -2
- package/dist/guardrails/index.d.cts +3 -3
- package/dist/guardrails/index.d.ts +3 -3
- package/dist/index.cjs +198 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -10
- package/dist/index.d.ts +55 -10
- package/dist/index.js +194 -20
- package/dist/index.js.map +1 -1
- package/dist/{processors-D5110pit.d.ts → processors-6p9nrqEi.d.cts} +3 -1
- package/dist/{processors-C0snQzZJ.d.cts → processors-Bp5XmF6V.d.ts} +3 -1
- package/dist/{stream-events-CgWqAI-1.d.cts → stream-events-CbVEowYb.d.cts} +115 -1
- package/dist/{stream-events-CgWqAI-1.d.ts → stream-events-CbVEowYb.d.ts} +115 -1
- package/dist/{tool-DuJ-_qXM.d.cts → tool-DZYLEKnl.d.cts} +3 -1
- package/dist/{tool-DklsS3JX.d.ts → tool-_iq4xRyk.d.ts} +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ import type { ModelProvider, AgentStore, ToolSpec, RolesPolicy } from '@dudousxd
|
|
|
23
23
|
- `ToolHandler.describe?({ actor, threadId?, agentName? })` — **a per-turn description.** Called when the turn's tool list is built, after every gate; what it returns replaces the spec's `description` / `inputSchema` in what the model sees (`registry.definitionsFor(actor, policy, allowList, { threadId, agentName })`). The registry still validates calls against the registered schema, so a tool whose input varies per turn registers a permissive one and validates in `execute`.
|
|
24
24
|
- `@dudousxd/nestjs-agent-core/genui` (+ `/genui/builtins`) — **the generative-UI catalog**, an isomorphic entry (no server-only import; a spec holds that line) a browser imports too: `defineComponent` / `defineCatalog` (Standard Schema or JSON Schema props), validation, `catalogToModelText`, `componentToText` fallbacks, tree helpers, and `genuiTools(catalog, { mode, terminal, showTool, resolveCatalog, … })` — the tools that push components, with an optional per-request catalog resolver consulted on every call and every turn's description. NestJS apps use `AgentGenuiModule` (`@dudousxd/nestjs-agent/genui`) instead of calling `genuiTools` themselves.
|
|
25
25
|
- `AgentDefinition` — a named agent (`systemPrompt` string | `PromptBuilder`, `tools`, `delegatesTo`, `personas`, …) for multi-agent setups. `delegatesTo` holds `AgentDelegation` entries: a bare target name for the delegation that waits, `{ agent, detached: true }` for one that does not.
|
|
26
|
-
- `detachedStarted` / `detachedDelivered` / `settleUnsettledDelegation` / `AgentLoopHooks.startAgent` / `AgentRunInput.deliverTo` — **delegation that does not block the chat.** An `agent`-kind call whose spec says `detached` is STARTED rather than awaited (`hooks.startAgent`, which the durable runner maps to `ctx.startChild
|
|
26
|
+
- `detachedStarted` / `detachedDelivered` / `settleUnsettledDelegation` / `AgentLoopHooks.startAgent` / `AgentRunInput.deliverTo` — **delegation that does not block the chat.** An `agent`-kind call whose spec says `detached` is STARTED rather than awaited (`hooks.startAgent`, which the durable runner maps to a run of its own — started from a journaled `detach:<toolCallId>` step, NOT a `ctx.startChild`, so a Stop on the delegating turn does not cascade to it — and the inline one to a loop nobody awaits), and the turn ends with a `DetachedDelegationReceipt` as the call's result instead of an answer. The started run carries a `deliverTo` address — the delegating thread and the call that started it — and posts its answer there as a message of its own, stamped with its own `runId` and `agentName`, so a client renders "the research agent finished" rather than the assistant's next reply. Whether a call detaches is settled INSIDE `persist:toolcall` alongside its kind and target, never from a live registry lookup, so a replay reads the branch back rather than re-deciding it; the loop writes the same checkpoint names either way, and only the runner's own positions (`patch:agent:detached-unlinked` + `detach:` — or `spawn:` on a run journaled by `@dudousxd/nestjs-agent` 1.19.2 or earlier — versus the awaited child's `signal:child:`) differ. A detached run outlives a Stop on the turn that started it; it is stopped by its own `runId`, and the card follows it to `delivered`, `failed` or `cancelled`. A detached run streams into its OWN sink and its `action` tools park on its OWN run, so its approval reaches the pending-approvals surface instead of an inline card in whatever turn happens to be open. `settleUnsettledDelegation` is the runner's half: a run that crashed or was stopped posts a message saying so (once — a thread already holding a message from that run is left alone, so the body and the runner may both call it), because "started" is the one state a reader can neither wait on nor act on. `AgentRunInput.parentRunId` / `RecordRunStartInput.parentRunId` record the edge, so a delegation is not a run row with nothing pointing at it.
|
|
27
27
|
- `RolesPolicy.can(actor, tool): boolean | Promise<boolean>` — the tool authorization seam
|
|
28
28
|
- `HistoryPolicy` — the ceiling on how much of a thread rides into a turn. `select(messages, ctx)` must be pure; the loop runs it INSIDE `load:thread`, so the ceiling bounds the journal as well as the prompt — the checkpoint holds the selected messages rather than the whole `ThreadDetail`, and a run recorded before that keeps the old payload via `ctx.patched('agent:selected-history')`. The optional `summarize(dropped, ctx)` may call a model and runs in its own `history:summarize` checkpoint (which is also the only case where the dropped messages are journaled at all). `windowHistory`, `summarizeWithModel` and `estimateMessageTokens` are the built-ins. A policy MAY also declare `maxMessages` — the most messages `select` can ever keep — which the loop passes to `ThreadTurnReader` below as the store's read bound. Declaring it is a promise that `select` keeps at most that many, and that they are the NEWEST ones; a ceiling expressed only in tokens declares nothing, since one message can be four tokens or forty thousand and no row count follows from a budget.
|
|
29
29
|
- `ThreadTurnReader.loadThreadForTurn({ threadId, messageLimit })` — **the read a turn actually needs.** `getThread` materializes a thread's whole transcript (every message row, every attachment, every tool output it ever recorded) to build a prompt bounded to its last few messages: on a 50-turn thread whose turns each ran a 50 KB tool that is ~2.6 MB per load, over 99% of it tool output. This read is bounded by the database (`order by created_at desc, id desc limit ?`, reversed for the prompt) and projected to the columns a model turn reads — `usage`, `follow_ups` and `run_id` stay in the table. The loop probes for it STRUCTURALLY, the same way `AgentService` probes `defaultAgentForThread`: a store that does not implement it keeps working through the full read, with no config change and no warning. `messageLimit` comes from `HistoryPolicy.maxMessages`, and is omitted — meaning read everything — for a policy that summarizes (`summarize` is handed what `select` DROPPED, and a read bounded to what it keeps drops nothing) or whose ceiling is only a token budget. Which branch ran is invisible to the journal by construction: both produce the same three answers, so the payload `load:thread` records is identical either way and a deployment's choice of store can never decide a run's checkpoints. `hasAssistantMessage` is answered over the WHOLE thread, never the page — it decides a `thread-start` intake, and a window holding only the user's last questions belongs to a conversation that has still been answered.
|
|
@@ -34,7 +34,7 @@ import type { ModelProvider, AgentStore, ToolSpec, RolesPolicy } from '@dudousxd
|
|
|
34
34
|
- `Skill` / `SkillProvider` / `ScopeResolver` / `offerSkills` — authored procedures the model pulls in when a task calls for one, instead of every instruction living in the system prompt. A skill is not an agent: an `@Agent` is WHO answers, a skill is HOW one task is done, and any agent may load one. Scoping is by an opaque TOKEN (`actor:u1`, `tenant:berlin`, `global`, or a host's own `depot:north`), and which tokens apply is a host-supplied `ScopeResolver` returning them most-specific-first — so precedence falls out of the order and a new axis is a resolver change, not a schema change. `defaultScopeResolver` covers the tokens derivable from `Actor` alone (actor / tenant / global); `actorScope`, `tenantScope` and `GLOBAL_SCOPE` mint them. This package owns NO skill table: the host owns the rows behind `SkillProvider` (`list(scopes, ctx)` for the catalog, `load(name, scope, ctx)` for one body), so a consumer can relate its own `Sector` entity against the token values in its own read model without writing migrations into a schema the boot-time heal also edits. `staticSkillProvider` and `compositeSkillProvider` are the built-ins. `resolveSkillCatalog` is the pure precedence pass: most specific wins, and the loser's scope is recorded on `shadows` rather than discarded, so the model can say "your setting differs from the org default" instead of choosing silently. What enters the SYSTEM prompt is the catalog only — one line per skill, bounded by `maxSkills` (`DEFAULT_MAX_SKILLS`) — while a BODY arrives as a `skill` tool result on the transcript, where the `HistoryPolicy` ceiling already governs it. The loop spends ONE checkpoint on all of it (`skills:catalog`) holding the whole offer, and serves each load inside the ordinary `tool:<callId>` checkpoint, so both the scopes that applied and the body that entered the prompt are facts the journal holds rather than answers a replaying process's provider would give afresh. `loadSkill` refuses any name the turn's own catalog does not carry, which makes the journaled catalog the authorization boundary as well as the menu. `skillWriteVerdict` is the write rule: your own scope is yours, a wider one needs an elevated HUMAN author, and nothing but a human may ever write above its own scope — an agent that could write a `tenant:` skill is an agent whose prompt anyone in the tenant can edit by talking to it.
|
|
35
35
|
- `MemoryRecord` / `MemoryProvider` / `offerMemories` / `writeMemory` — what the assistant concluded about a person or an organisation, carried across turns and threads. Scoped by the SAME opaque tokens and the same `ScopeResolver` skills use, so a deployment has one answer to "which scopes does this actor have". A memory is a keyed fact: `{ key, text, scope, origin, updatedAt }`, and the key is what makes a conflict mechanically detectable — two memories sharing a key at different scopes are one question answered twice, and `resolveMemoryDigest` lets the narrower win. Where it does, the entry's `overrides` carries the beaten **text** and its **author**, not merely its scope (a skill's `shadows`): the model is following one procedure either way, but a memory is a VALUE, and an agent that knew only that a wider one existed could tell the user nothing except which it picked. **Not retrieval:** a passage is a document someone authored and can fix at its source, a memory is the agent's own inference about someone who never saw it written — hence `MemoryOrigin` on every record, a block that tells the model these are its own fallible notes, and `forget` being REQUIRED on the provider while `write` is optional. Every provider method and every multi-argument export here takes ONE named object (`ListMemoriesInput`, `StoreMemoryInput`, `ResolveMemoryDigestInput`, …): `key`, `text` and `scope` are all strings, and transposed positional arguments would compile clean and write a fact whose key is its value. `memoryWriteVerdict` carries the same four rules as `skillWriteVerdict`; rule three (nothing but a human may write above its own scope, whatever elevation a host grants) is enforced by SHAPE as well as by check, since `rememberToolDefinition()` takes no scope parameter. `memoryForgetVerdict` is narrower still and takes no `elevated` flag: deleting what the assistant believes about YOU needs nobody's permission. What enters the system prompt is one line per memory bounded by `maxMemories` (`DEFAULT_MAX_MEMORIES`), each capped at `maxFactChars` (`DEFAULT_MAX_FACT_CHARS`) when it is WRITTEN — so the block's ceiling is the product of two numbers an operator set, and there is no body/catalog split because a fact that cannot be stated in a line is a document. **The prompt budget is bounded; the store is not.** Once the applicable set outgrows the block, WHICH memories it carries is a decision, and making it by scope starves the widest scopes first — one person's twentieth note would end every chance their organisation's facts had, leaving only a non-zero `omitted` behind. So a provider MAY implement `search({ scopes, query, limit, ctx })` and the block is filled by relevance to the turn instead; omit it and every turn is served by `list`, selecting narrowest-then-newest as before. Scope remains a hard FILTER that gates before ranking (a record returned outside `scopes` is dropped, so a host's filter bug costs throughput rather than privacy), and `search` must return every record sharing a returned key or precedence inverts. `MemoryRecord.pinned` is the categorical always-on marker — present whatever the turn is about, spending the same budget, never set by the agent (`StoreMemoryInput` has no such field, and the `remember` tool has no such parameter), with `MemoryDigest.pinnedOmitted` naming the one omission that is a misconfiguration rather than a budget. `buildMemoryBlock` frames entries by `origin.author`: what the agent CONCLUDED is hedged ("your own notes … prefer what the user says now"), what a person STATED is not, because telling a model to prefer the user over an organisation's published policy hands any user an override of it by assertion. A `partial` block says so, so the model does not read an absence as evidence. The loop spends ONE checkpoint (`memory:digest`) holding the whole digest — the search included, since a ranking is the most re-derivable decision here — which is both what the block is rendered from and what a later `remember` call is authorized against; the write itself happens inside the ordinary `tool:<callId>` checkpoint, which is what makes it idempotent under replay. The query is the user's own turn text and nothing else: the only thing available before the first model call, already a journaled input to the run, and it fails at a turn with no topic — which is what `pinned` is for.
|
|
36
36
|
- `AgentStore.setMessageToolResults(messageId, results)` — a message's tool CALLS are known when it is appended and their outputs are not, so the loop settles them afterwards with one write of the turn's complete result list (its synthetic `retrieve` / `structured_output` calls included). Both halves live on the message because that is where a thread reader pairs them; a call whose output only ever reaches the `agent_tool_call` table renders as a tool still running. Required, not optional — a store that silently declines it breaks a client with nothing logged.
|
|
37
|
-
- `AttachmentStagingStore.list(input)` / `AgentStore.referencedMediaIds(actorRef, mediaIds)` — the two halves of attachment housekeeping, split the way ownership is. `stage()` writes bytes before any message exists, so an upload the user never sent leaves media nothing points at; the HOST can enumerate that media (it stored it) but cannot see a transcript, and this library sees every transcript but never holds bytes. `list` returns `StagedAttachment` metadata (`mediaId`, `name`, `contentType`, `sizeBytes`, `createdAt` — no `url`, since `resolve` mints those per turn precisely so they can be short-lived); `referencedMediaIds` answers which of a set of ids a message that still exists carries, scoped to one actor. The answer is DERIVED from the surviving message rows on every call, never latched: `truncateFrom` deletes messages — regenerating a turn does exactly that — so a reference disappears, and a flag set at send time would pin the bytes for ever. Both are optional; a caller that cannot get an answer must collect nothing rather than read silence as "unreferenced". `AgentService.collectableAttachments` composes them, and deletes nothing.
|
|
37
|
+
- `AttachmentStagingStore.list(input)` / `AgentStore.referencedMediaIds(actorRef, mediaIds)` — the two halves of attachment housekeeping, split the way ownership is. `stage()` writes bytes before any message exists, so an upload the user never sent leaves media nothing points at; the HOST can enumerate that media (it stored it) but cannot see a transcript, and this library sees every transcript but never holds bytes. `list` returns `StagedAttachment` metadata (`mediaId`, `name`, `contentType`, `sizeBytes`, `createdAt` — no `url`, since `resolve` mints those per turn precisely so they can be short-lived); `referencedMediaIds` answers which of a set of ids a message that still exists — or one still waiting in a thread's queue — carries, scoped to one actor. The answer is DERIVED from the surviving message rows on every call, never latched: `truncateFrom` deletes messages — regenerating a turn does exactly that — so a reference disappears, and a flag set at send time would pin the bytes for ever. Both are optional; a caller that cannot get an answer must collect nothing rather than read silence as "unreferenced". `AgentService.collectableAttachments` composes them, and deletes nothing.
|
|
38
38
|
- `agentFailureCode(error)` — the stream error code for a failed run (`cancelled`, `quota_exceeded`, `output_rejected`, `structured_output_invalid`, `replay_diverged` for the durable runtime refusing a checkpoint position, `model_no_output` for a model call that produced nothing, else `run_failed`), so a control doing its job never reads as the model breaking. `streamFailure(error)` is the `{ code, message }` a runner closes the stream with: for a crash the message is `RUN_FAILED_MESSAGE` in production and the raw text elsewhere (`exposeStreamErrorDetails` decides it outright) — the error itself belongs in the log and on the run row.
|
|
39
39
|
- `settleDanglingToolCalls(messages, outcomes?)` / `danglingToolCallIds(messages)` — give every tool call in a history a result. A turn that dies mid-step leaves an assistant message asking for tools and answered by nothing, which a provider refuses, so every later turn on the thread fails too. The loop settles them inside `load:thread` (no new position; a replay reads the recorded payload) from the calls' own rows where the store implements the optional `AgentStore.toolCallOutcomes` — a tool that DID run hands the model its real output, so it is not run again — and otherwise with `UNFINISHED_TOOL_CALL`. `AgentStore.failUnsettledToolCalls(runId, error)` (optional) is what a failing run calls so no approval card waits on it; `settleDeadRun(store, { runId, threadId?, failure? })` is the same for a caller with no journal left to write to.
|
|
40
40
|
- `AiToolCtx.idempotencyKey` (`<runId>:<toolCallId>`) / `AiToolCtx.toolCallId` — the same for every execution of one call, so a tool re-run after a worker died between its side effect and its checkpoint (or by a transient retry) can be made to land on the first attempt. `toolCallContext(ctx, toolCallId)` builds it for a runner's own dispatched step.
|
package/dist/ag-ui/index.d.cts
CHANGED
package/dist/ag-ui/index.d.ts
CHANGED
package/dist/genui/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as Catalog, J as JsonSchema, G as GenuiValidation, b as GenuiIssue } from '../catalog-CrzetM3_.cjs';
|
|
2
2
|
export { A as AjvLike, c as COMPONENT_NAME, d as CatalogOptions, C as ComponentDefinition, e as JsonSchemaValidator, P as PropsSchema, f as ajvValidator, g as builtinJsonSchemaValidator, h as defineCatalog, i as defineComponent, j as formatIssues, k as isStandardSchema, t as toJsonSchema, l as toSnakeCase, m as toolNameFor, v as validateProps, n as validatePropsSync } from '../catalog-CrzetM3_.cjs';
|
|
3
3
|
import { StandardSchemaV1, StandardJSONSchemaV1 } from '@standard-schema/spec';
|
|
4
|
-
import { T as ToolHandler } from '../tool-
|
|
5
|
-
import { a as Actor, T as ToolSpec, b as ToolPresentation } from '../stream-events-
|
|
4
|
+
import { T as ToolHandler } from '../tool-DZYLEKnl.cjs';
|
|
5
|
+
import { a as Actor, T as ToolSpec, b as ToolPresentation } from '../stream-events-CbVEowYb.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* One node of a composed UI: a catalog component, its props, and — for components declared with
|
package/dist/genui/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as Catalog, J as JsonSchema, G as GenuiValidation, b as GenuiIssue } from '../catalog-CrzetM3_.js';
|
|
2
2
|
export { A as AjvLike, c as COMPONENT_NAME, d as CatalogOptions, C as ComponentDefinition, e as JsonSchemaValidator, P as PropsSchema, f as ajvValidator, g as builtinJsonSchemaValidator, h as defineCatalog, i as defineComponent, j as formatIssues, k as isStandardSchema, t as toJsonSchema, l as toSnakeCase, m as toolNameFor, v as validateProps, n as validatePropsSync } from '../catalog-CrzetM3_.js';
|
|
3
3
|
import { StandardSchemaV1, StandardJSONSchemaV1 } from '@standard-schema/spec';
|
|
4
|
-
import { T as ToolHandler } from '../tool-
|
|
5
|
-
import { a as Actor, T as ToolSpec, b as ToolPresentation } from '../stream-events-
|
|
4
|
+
import { T as ToolHandler } from '../tool-_iq4xRyk.js';
|
|
5
|
+
import { a as Actor, T as ToolSpec, b as ToolPresentation } from '../stream-events-CbVEowYb.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* One node of a composed UI: a catalog component, its props, and — for components declared with
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { I as InputProcessor, O as OutputProcessor } from '../processors-
|
|
2
|
-
import { T as ToolHandler } from '../tool-
|
|
3
|
-
import { a as Actor } from '../stream-events-
|
|
1
|
+
import { I as InputProcessor, O as OutputProcessor } from '../processors-6p9nrqEi.cjs';
|
|
2
|
+
import { T as ToolHandler } from '../tool-DZYLEKnl.cjs';
|
|
3
|
+
import { a as Actor } from '../stream-events-CbVEowYb.cjs';
|
|
4
4
|
import '@standard-schema/spec';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { I as InputProcessor, O as OutputProcessor } from '../processors-
|
|
2
|
-
import { T as ToolHandler } from '../tool-
|
|
3
|
-
import { a as Actor } from '../stream-events-
|
|
1
|
+
import { I as InputProcessor, O as OutputProcessor } from '../processors-Bp5XmF6V.js';
|
|
2
|
+
import { T as ToolHandler } from '../tool-_iq4xRyk.js';
|
|
3
|
+
import { a as Actor } from '../stream-events-CbVEowYb.js';
|
|
4
4
|
import '@standard-schema/spec';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -140,9 +140,11 @@ __export(src_exports, {
|
|
|
140
140
|
filterToolsByEnabled: () => filterToolsByEnabled,
|
|
141
141
|
filterToolsByRole: () => filterToolsByRole,
|
|
142
142
|
findCatalogModel: () => findCatalogModel,
|
|
143
|
+
findPersona: () => findPersona,
|
|
143
144
|
gateFollowUps: () => gateFollowUps,
|
|
144
145
|
gateTail: () => gateTail,
|
|
145
146
|
hashConfirmToken: () => hashConfirmToken,
|
|
147
|
+
intersectAllowLists: () => intersectAllowLists,
|
|
146
148
|
invokeWithTransientRetry: () => invokeWithTransientRetry,
|
|
147
149
|
isChatQueueStore: () => isChatQueueStore,
|
|
148
150
|
isControlFlowSignal: () => isControlFlowSignal,
|
|
@@ -160,6 +162,7 @@ __export(src_exports, {
|
|
|
160
162
|
observeTurnFrames: () => observeTurnFrames,
|
|
161
163
|
offerMemories: () => offerMemories,
|
|
162
164
|
offerSkills: () => offerSkills,
|
|
165
|
+
personaCatalogEntry: () => personaCatalogEntry,
|
|
163
166
|
publishAgentDelegated: () => publishAgentDelegated,
|
|
164
167
|
publishAgentMemoryResolved: () => publishAgentMemoryResolved,
|
|
165
168
|
publishAgentMemoryWritten: () => publishAgentMemoryWritten,
|
|
@@ -189,6 +192,7 @@ __export(src_exports, {
|
|
|
189
192
|
resolveGateLookback: () => resolveGateLookback,
|
|
190
193
|
resolveMemoryDigest: () => resolveMemoryDigest,
|
|
191
194
|
resolveOutputGateMode: () => resolveOutputGateMode,
|
|
195
|
+
resolvePersonaAlias: () => resolvePersonaAlias,
|
|
192
196
|
resolveSkillCatalog: () => resolveSkillCatalog,
|
|
193
197
|
resolveToolTransientRetryNumbers: () => resolveToolTransientRetryNumbers,
|
|
194
198
|
rollupThreadUsage: () => rollupThreadUsage,
|
|
@@ -565,6 +569,9 @@ function queuedMessageView(message) {
|
|
|
565
569
|
...message.agentName !== void 0 ? {
|
|
566
570
|
agentName: message.agentName
|
|
567
571
|
} : {},
|
|
572
|
+
...message.persona !== void 0 ? {
|
|
573
|
+
persona: message.persona
|
|
574
|
+
} : {},
|
|
568
575
|
...message.model !== void 0 ? {
|
|
569
576
|
model: message.model
|
|
570
577
|
} : {},
|
|
@@ -957,6 +964,54 @@ function filterToolsByAllowList(tools, allowedTools) {
|
|
|
957
964
|
}
|
|
958
965
|
__name(filterToolsByAllowList, "filterToolsByAllowList");
|
|
959
966
|
|
|
967
|
+
// src/personas.ts
|
|
968
|
+
function intersectAllowLists(first, second) {
|
|
969
|
+
if (first === void 0) {
|
|
970
|
+
return second === void 0 ? void 0 : [
|
|
971
|
+
...second
|
|
972
|
+
];
|
|
973
|
+
}
|
|
974
|
+
if (second === void 0) {
|
|
975
|
+
return [
|
|
976
|
+
...first
|
|
977
|
+
];
|
|
978
|
+
}
|
|
979
|
+
const allowed = new Set(second);
|
|
980
|
+
return first.filter((name) => allowed.has(name));
|
|
981
|
+
}
|
|
982
|
+
__name(intersectAllowLists, "intersectAllowLists");
|
|
983
|
+
function findPersona(definition, id) {
|
|
984
|
+
if (id === void 0) {
|
|
985
|
+
return void 0;
|
|
986
|
+
}
|
|
987
|
+
return definition?.personas?.find((persona) => persona.id === id);
|
|
988
|
+
}
|
|
989
|
+
__name(findPersona, "findPersona");
|
|
990
|
+
function personaCatalogEntry(persona) {
|
|
991
|
+
return {
|
|
992
|
+
id: persona.id,
|
|
993
|
+
label: persona.label,
|
|
994
|
+
...persona.description !== void 0 ? {
|
|
995
|
+
description: persona.description
|
|
996
|
+
} : {}
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
__name(personaCatalogEntry, "personaCatalogEntry");
|
|
1000
|
+
function resolvePersonaAlias(definitions, name) {
|
|
1001
|
+
for (const definition of definitions) {
|
|
1002
|
+
for (const persona of definition.personas ?? []) {
|
|
1003
|
+
if (persona.aliases?.includes(name) === true) {
|
|
1004
|
+
return {
|
|
1005
|
+
agent: definition.name,
|
|
1006
|
+
persona: persona.id
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
return void 0;
|
|
1012
|
+
}
|
|
1013
|
+
__name(resolvePersonaAlias, "resolvePersonaAlias");
|
|
1014
|
+
|
|
960
1015
|
// src/history.ts
|
|
961
1016
|
function estimateMessageTokens(message) {
|
|
962
1017
|
const extras = (message.toolCalls !== void 0 ? JSON.stringify(message.toolCalls).length : 0) + (message.toolResults !== void 0 ? JSON.stringify(message.toolResults).length : 0);
|
|
@@ -2745,7 +2800,8 @@ function detachedUnsettled(args) {
|
|
|
2745
2800
|
__name(detachedUnsettled, "detachedUnsettled");
|
|
2746
2801
|
async function settleUnsettledDelegation(args) {
|
|
2747
2802
|
const { store, delivery, agent, runId, status } = args;
|
|
2748
|
-
|
|
2803
|
+
const thread = await store.getThread(delivery.threadId);
|
|
2804
|
+
if (thread === null || thread.messages.some((message) => message.runId === runId)) {
|
|
2749
2805
|
return;
|
|
2750
2806
|
}
|
|
2751
2807
|
await store.appendMessage({
|
|
@@ -2895,7 +2951,7 @@ var ToolRegistry = class {
|
|
|
2895
2951
|
* a call can reach here from a replayed durable step or an approval granted before the flag
|
|
2896
2952
|
* moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.
|
|
2897
2953
|
*/
|
|
2898
|
-
async invoke(name, input, ctx, policy) {
|
|
2954
|
+
async invoke(name, input, ctx, policy, options = {}) {
|
|
2899
2955
|
const entry = this.entries.get(name);
|
|
2900
2956
|
if (entry === void 0) {
|
|
2901
2957
|
throw new ToolNotFoundError(name);
|
|
@@ -2909,6 +2965,9 @@ var ToolRegistry = class {
|
|
|
2909
2965
|
if (!await canActorUseTool(ctx.actor, entry.handler)) {
|
|
2910
2966
|
throw new ToolForbiddenError(name);
|
|
2911
2967
|
}
|
|
2968
|
+
if (options.allowedTools !== void 0 && !options.allowedTools.includes(name)) {
|
|
2969
|
+
throw new ToolForbiddenError(name);
|
|
2970
|
+
}
|
|
2912
2971
|
const validation = await entry.spec.inputSchema["~standard"].validate(input);
|
|
2913
2972
|
if (validation.issues !== void 0) {
|
|
2914
2973
|
throw new ToolInputInvalidError(name, validation.issues);
|
|
@@ -3260,16 +3319,10 @@ async function resolvePrompt(prompt, ctx) {
|
|
|
3260
3319
|
return typeof prompt === "function" ? prompt(ctx) : prompt;
|
|
3261
3320
|
}
|
|
3262
3321
|
__name(resolvePrompt, "resolvePrompt");
|
|
3263
|
-
async function resolveSystemPrompt(deps, input) {
|
|
3264
|
-
const ctx =
|
|
3265
|
-
actor: input.actor,
|
|
3266
|
-
agentName: input.agentName ?? "default",
|
|
3267
|
-
...input.pageContext !== void 0 ? {
|
|
3268
|
-
pageContext: input.pageContext
|
|
3269
|
-
} : {}
|
|
3270
|
-
};
|
|
3322
|
+
async function resolveSystemPrompt(deps, input, persona) {
|
|
3323
|
+
const ctx = promptContext(input, persona);
|
|
3271
3324
|
const sections = [
|
|
3272
|
-
await resolvePrompt(deps.systemPrompt, ctx)
|
|
3325
|
+
persona?.prompt ?? await resolvePrompt(deps.systemPrompt, ctx)
|
|
3273
3326
|
];
|
|
3274
3327
|
for (const contribute of deps.promptContributors ?? []) {
|
|
3275
3328
|
const section = await contribute(ctx);
|
|
@@ -3280,6 +3333,67 @@ async function resolveSystemPrompt(deps, input) {
|
|
|
3280
3333
|
return sections.join("\n\n");
|
|
3281
3334
|
}
|
|
3282
3335
|
__name(resolveSystemPrompt, "resolveSystemPrompt");
|
|
3336
|
+
function withoutPersona(input) {
|
|
3337
|
+
const { persona: _dropped, ...rest } = input;
|
|
3338
|
+
return rest;
|
|
3339
|
+
}
|
|
3340
|
+
__name(withoutPersona, "withoutPersona");
|
|
3341
|
+
function promptContext(input, persona) {
|
|
3342
|
+
return {
|
|
3343
|
+
actor: input.actor,
|
|
3344
|
+
agentName: input.agentName ?? "default",
|
|
3345
|
+
...input.pageContext !== void 0 ? {
|
|
3346
|
+
pageContext: input.pageContext
|
|
3347
|
+
} : {},
|
|
3348
|
+
...persona !== void 0 ? {
|
|
3349
|
+
persona: {
|
|
3350
|
+
id: persona.id,
|
|
3351
|
+
label: persona.label
|
|
3352
|
+
}
|
|
3353
|
+
} : {}
|
|
3354
|
+
};
|
|
3355
|
+
}
|
|
3356
|
+
__name(promptContext, "promptContext");
|
|
3357
|
+
async function resolveTurnPersona(deps, input) {
|
|
3358
|
+
const persona = findPersona(deps, input.persona);
|
|
3359
|
+
if (persona === void 0) {
|
|
3360
|
+
return null;
|
|
3361
|
+
}
|
|
3362
|
+
const ref = {
|
|
3363
|
+
id: persona.id,
|
|
3364
|
+
label: persona.label
|
|
3365
|
+
};
|
|
3366
|
+
let prompt;
|
|
3367
|
+
if (persona.systemPrompt !== void 0) {
|
|
3368
|
+
const ctx = promptContext(input, ref);
|
|
3369
|
+
const basePrompt = typeof persona.systemPrompt === "function" ? await resolvePrompt(deps.systemPrompt, ctx) : void 0;
|
|
3370
|
+
prompt = await resolvePrompt(persona.systemPrompt, {
|
|
3371
|
+
...ctx,
|
|
3372
|
+
...basePrompt !== void 0 ? {
|
|
3373
|
+
basePrompt
|
|
3374
|
+
} : {}
|
|
3375
|
+
});
|
|
3376
|
+
}
|
|
3377
|
+
return {
|
|
3378
|
+
...ref,
|
|
3379
|
+
...persona.allowedTools !== void 0 ? {
|
|
3380
|
+
allowedTools: [
|
|
3381
|
+
...persona.allowedTools
|
|
3382
|
+
]
|
|
3383
|
+
} : {},
|
|
3384
|
+
...prompt !== void 0 ? {
|
|
3385
|
+
prompt
|
|
3386
|
+
} : {}
|
|
3387
|
+
};
|
|
3388
|
+
}
|
|
3389
|
+
__name(resolveTurnPersona, "resolveTurnPersona");
|
|
3390
|
+
function personaRefusal(persona, toolName) {
|
|
3391
|
+
if (persona?.allowedTools === void 0 || persona.allowedTools.includes(toolName)) {
|
|
3392
|
+
return null;
|
|
3393
|
+
}
|
|
3394
|
+
return `(tool "${toolName}" is not available to the "${persona.id}" persona)`;
|
|
3395
|
+
}
|
|
3396
|
+
__name(personaRefusal, "personaRefusal");
|
|
3283
3397
|
function extractTask(input) {
|
|
3284
3398
|
if (typeof input === "object" && input !== null && "task" in input) {
|
|
3285
3399
|
const task = input.task;
|
|
@@ -3521,6 +3635,9 @@ function processorContext(input, step) {
|
|
|
3521
3635
|
step,
|
|
3522
3636
|
...input.agentName !== void 0 ? {
|
|
3523
3637
|
agentName: input.agentName
|
|
3638
|
+
} : {},
|
|
3639
|
+
...input.persona !== void 0 ? {
|
|
3640
|
+
persona: input.persona
|
|
3524
3641
|
} : {}
|
|
3525
3642
|
};
|
|
3526
3643
|
}
|
|
@@ -3684,6 +3801,9 @@ function toolContext(deps, input, hooks) {
|
|
|
3684
3801
|
...input.agentName !== void 0 ? {
|
|
3685
3802
|
agentName: input.agentName
|
|
3686
3803
|
} : {},
|
|
3804
|
+
...input.persona !== void 0 ? {
|
|
3805
|
+
persona: input.persona
|
|
3806
|
+
} : {},
|
|
3687
3807
|
...input.pageContext !== void 0 ? {
|
|
3688
3808
|
pageContext: input.pageContext
|
|
3689
3809
|
} : {},
|
|
@@ -3731,6 +3851,9 @@ async function runIntake(intake, deps, input, hooks, writer, threadHasAssistant)
|
|
|
3731
3851
|
],
|
|
3732
3852
|
...input.agentName !== void 0 ? {
|
|
3733
3853
|
agentName: input.agentName
|
|
3854
|
+
} : {},
|
|
3855
|
+
...input.persona !== void 0 ? {
|
|
3856
|
+
persona: input.persona
|
|
3734
3857
|
} : {}
|
|
3735
3858
|
});
|
|
3736
3859
|
await deps.store.recordToolCall({
|
|
@@ -4076,6 +4199,7 @@ async function invokeClaimedTool(turn, claimed) {
|
|
|
4076
4199
|
if (claimed.toolType === "memory") {
|
|
4077
4200
|
return await rememberIntoTurn(turn, claimed, startedAt);
|
|
4078
4201
|
}
|
|
4202
|
+
const invokeAllowList = turn.persona?.allowedTools === void 0 ? void 0 : intersectAllowLists(deps.toolAllowList, turn.persona.allowedTools);
|
|
4079
4203
|
let raw;
|
|
4080
4204
|
if (hooks.dispatchTool) {
|
|
4081
4205
|
const stepCtx = {
|
|
@@ -4086,6 +4210,9 @@ async function invokeClaimedTool(turn, claimed) {
|
|
|
4086
4210
|
...input.agentName !== void 0 ? {
|
|
4087
4211
|
agentName: input.agentName
|
|
4088
4212
|
} : {},
|
|
4213
|
+
...input.persona !== void 0 ? {
|
|
4214
|
+
persona: input.persona
|
|
4215
|
+
} : {},
|
|
4089
4216
|
...input.pageContext !== void 0 ? {
|
|
4090
4217
|
pageContext: input.pageContext
|
|
4091
4218
|
} : {}
|
|
@@ -4094,6 +4221,9 @@ async function invokeClaimedTool(turn, claimed) {
|
|
|
4094
4221
|
toolName: call.name,
|
|
4095
4222
|
input: call.input,
|
|
4096
4223
|
ctx: stepCtx,
|
|
4224
|
+
...invokeAllowList !== void 0 ? {
|
|
4225
|
+
allowedTools: invokeAllowList
|
|
4226
|
+
} : {},
|
|
4097
4227
|
...deps.toolTimeoutMs !== void 0 ? {
|
|
4098
4228
|
timeoutMs: deps.toolTimeoutMs
|
|
4099
4229
|
} : {},
|
|
@@ -4116,7 +4246,9 @@ async function invokeClaimedTool(turn, claimed) {
|
|
|
4116
4246
|
return deps.registry.invoke(call.name, call.input, {
|
|
4117
4247
|
...toolCallContext(ctx, call.id),
|
|
4118
4248
|
emitUi: ui2.emit
|
|
4119
|
-
}, deps.rolesPolicy
|
|
4249
|
+
}, deps.rolesPolicy, invokeAllowList !== void 0 ? {
|
|
4250
|
+
allowedTools: invokeAllowList
|
|
4251
|
+
} : {});
|
|
4120
4252
|
}, deps.toolTransientRetry ?? {}, {
|
|
4121
4253
|
...hooks.isControlFlowError !== void 0 ? {
|
|
4122
4254
|
isControlFlowError: hooks.isControlFlowError
|
|
@@ -4247,7 +4379,7 @@ async function delegateToolCall(turn, claimed) {
|
|
|
4247
4379
|
const { deps, input, hooks } = turn;
|
|
4248
4380
|
const { call, targetAgent = call.name } = claimed;
|
|
4249
4381
|
const task = extractTask(call.input);
|
|
4250
|
-
const refusal = delegationRefusal({
|
|
4382
|
+
const refusal = personaRefusal(turn.persona, call.name) ?? delegationRefusal({
|
|
4251
4383
|
deps,
|
|
4252
4384
|
input,
|
|
4253
4385
|
targetAgent
|
|
@@ -4543,14 +4675,16 @@ async function invokeClaimedToolsTogether(turn, parallel, claimed) {
|
|
|
4543
4675
|
return results;
|
|
4544
4676
|
}
|
|
4545
4677
|
__name(invokeClaimedToolsTogether, "invokeClaimedToolsTogether");
|
|
4546
|
-
async function runAgentLoop(boundDeps,
|
|
4678
|
+
async function runAgentLoop(boundDeps, requested, hooks) {
|
|
4679
|
+
const persona = requested.persona === void 0 ? void 0 : await hooks.step("persona:resolve", () => resolveTurnPersona(boundDeps, requested)) ?? void 0;
|
|
4680
|
+
const input = persona === void 0 || persona.id !== requested.persona ? withoutPersona(requested) : requested;
|
|
4547
4681
|
const deps = input.model === void 0 ? boundDeps : {
|
|
4548
4682
|
...boundDeps,
|
|
4549
4683
|
model: withSelectedModel(boundDeps.model, input.model),
|
|
4550
4684
|
modelId: input.model
|
|
4551
4685
|
};
|
|
4552
4686
|
const maxSteps = deps.maxSteps ?? 8;
|
|
4553
|
-
let system = await resolveSystemPrompt(deps, input);
|
|
4687
|
+
let system = await resolveSystemPrompt(deps, input, persona);
|
|
4554
4688
|
const inputProcessors = deps.inputProcessors ?? [];
|
|
4555
4689
|
const outputProcessors = deps.outputProcessors ?? [];
|
|
4556
4690
|
const gateMode = resolveOutputGateMode(outputProcessors);
|
|
@@ -4591,6 +4725,9 @@ async function runAgentLoop(boundDeps, input, hooks) {
|
|
|
4591
4725
|
role: "user",
|
|
4592
4726
|
content: input.userText,
|
|
4593
4727
|
runId: hooks.runId,
|
|
4728
|
+
...input.persona !== void 0 ? {
|
|
4729
|
+
persona: input.persona
|
|
4730
|
+
} : {},
|
|
4594
4731
|
...input.attachments !== void 0 ? {
|
|
4595
4732
|
attachments: input.attachments
|
|
4596
4733
|
} : {}
|
|
@@ -4613,6 +4750,9 @@ async function runAgentLoop(boundDeps, input, hooks) {
|
|
|
4613
4750
|
actorId: input.actor.id,
|
|
4614
4751
|
...input.agentName !== void 0 ? {
|
|
4615
4752
|
agentName: input.agentName
|
|
4753
|
+
} : {},
|
|
4754
|
+
...input.persona !== void 0 ? {
|
|
4755
|
+
persona: input.persona
|
|
4616
4756
|
} : {}
|
|
4617
4757
|
});
|
|
4618
4758
|
const stages = await resolvePromptStages(deps, hooks);
|
|
@@ -4749,13 +4889,16 @@ ${block}`;
|
|
|
4749
4889
|
} : {},
|
|
4750
4890
|
...input.model !== void 0 ? {
|
|
4751
4891
|
model: input.model
|
|
4892
|
+
} : {},
|
|
4893
|
+
...persona?.allowedTools !== void 0 ? {
|
|
4894
|
+
personaAllowedTools: persona.allowedTools
|
|
4752
4895
|
} : {}
|
|
4753
4896
|
});
|
|
4754
4897
|
} else {
|
|
4755
4898
|
const tools = withMemoryTool({
|
|
4756
4899
|
tools: withSkillTool({
|
|
4757
4900
|
tools: withAskTool({
|
|
4758
|
-
tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList, {
|
|
4901
|
+
tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, intersectAllowLists(deps.toolAllowList, persona?.allowedTools), {
|
|
4759
4902
|
threadId: input.threadId,
|
|
4760
4903
|
...input.agentName !== void 0 ? {
|
|
4761
4904
|
agentName: input.agentName
|
|
@@ -4970,6 +5113,9 @@ ${block}`;
|
|
|
4970
5113
|
...input.agentName !== void 0 ? {
|
|
4971
5114
|
agentName: input.agentName
|
|
4972
5115
|
} : {},
|
|
5116
|
+
...input.persona !== void 0 ? {
|
|
5117
|
+
persona: input.persona
|
|
5118
|
+
} : {},
|
|
4973
5119
|
...turn.reasoning !== void 0 ? {
|
|
4974
5120
|
reasoning: turn.reasoning
|
|
4975
5121
|
} : {},
|
|
@@ -5064,6 +5210,9 @@ ${block}`;
|
|
|
5064
5210
|
} : {},
|
|
5065
5211
|
...memoryDigest !== void 0 ? {
|
|
5066
5212
|
memory: memoryDigest
|
|
5213
|
+
} : {},
|
|
5214
|
+
...persona !== void 0 ? {
|
|
5215
|
+
persona
|
|
5067
5216
|
} : {}
|
|
5068
5217
|
};
|
|
5069
5218
|
const parallel = hooks.parallel;
|
|
@@ -5196,7 +5345,10 @@ var InMemoryAgentStore = class {
|
|
|
5196
5345
|
transient: input.transient ?? false,
|
|
5197
5346
|
createdAt: ts,
|
|
5198
5347
|
updatedAt: ts,
|
|
5199
|
-
messages: []
|
|
5348
|
+
messages: [],
|
|
5349
|
+
...input.persona !== void 0 ? {
|
|
5350
|
+
persona: input.persona
|
|
5351
|
+
} : {}
|
|
5200
5352
|
};
|
|
5201
5353
|
this.threads.set(id, row);
|
|
5202
5354
|
return this.toSummary(row);
|
|
@@ -5301,6 +5453,9 @@ var InMemoryAgentStore = class {
|
|
|
5301
5453
|
} : {},
|
|
5302
5454
|
...source.model != null ? {
|
|
5303
5455
|
model: source.model
|
|
5456
|
+
} : {},
|
|
5457
|
+
...source.persona != null ? {
|
|
5458
|
+
persona: source.persona
|
|
5304
5459
|
} : {}
|
|
5305
5460
|
};
|
|
5306
5461
|
this.threads.set(id, row);
|
|
@@ -5352,6 +5507,9 @@ var InMemoryAgentStore = class {
|
|
|
5352
5507
|
if (patch.model !== void 0) {
|
|
5353
5508
|
row.model = patch.model;
|
|
5354
5509
|
}
|
|
5510
|
+
if (patch.persona !== void 0) {
|
|
5511
|
+
row.persona = patch.persona;
|
|
5512
|
+
}
|
|
5355
5513
|
row.updatedAt = this.now();
|
|
5356
5514
|
}
|
|
5357
5515
|
async activeRunForThread(threadId) {
|
|
@@ -5365,6 +5523,10 @@ var InMemoryAgentStore = class {
|
|
|
5365
5523
|
async defaultAgentForThread(threadId) {
|
|
5366
5524
|
return this.threads.get(threadId)?.defaultAgent ?? null;
|
|
5367
5525
|
}
|
|
5526
|
+
/** The thread's persona, projected like {@link defaultAgentForThread}. */
|
|
5527
|
+
async personaForThread(threadId) {
|
|
5528
|
+
return this.threads.get(threadId)?.persona ?? null;
|
|
5529
|
+
}
|
|
5368
5530
|
/** The thread's pinned model, projected like {@link defaultAgentForThread}. */
|
|
5369
5531
|
async modelForThread(threadId) {
|
|
5370
5532
|
return this.threads.get(threadId)?.model ?? null;
|
|
@@ -5469,6 +5631,9 @@ var InMemoryAgentStore = class {
|
|
|
5469
5631
|
...input.agentName !== void 0 ? {
|
|
5470
5632
|
agentName: input.agentName
|
|
5471
5633
|
} : {},
|
|
5634
|
+
...input.persona !== void 0 ? {
|
|
5635
|
+
persona: input.persona
|
|
5636
|
+
} : {},
|
|
5472
5637
|
...input.model !== void 0 ? {
|
|
5473
5638
|
model: input.model
|
|
5474
5639
|
} : {},
|
|
@@ -5607,6 +5772,9 @@ var InMemoryAgentStore = class {
|
|
|
5607
5772
|
...input.agentName !== void 0 ? {
|
|
5608
5773
|
agentName: input.agentName
|
|
5609
5774
|
} : {},
|
|
5775
|
+
...input.persona !== void 0 ? {
|
|
5776
|
+
persona: input.persona
|
|
5777
|
+
} : {},
|
|
5610
5778
|
...input.runId !== void 0 ? {
|
|
5611
5779
|
runId: input.runId
|
|
5612
5780
|
} : {},
|
|
@@ -5675,7 +5843,8 @@ var InMemoryAgentStore = class {
|
|
|
5675
5843
|
}
|
|
5676
5844
|
}
|
|
5677
5845
|
/**
|
|
5678
|
-
* Of `mediaIds`, the ones a surviving message in
|
|
5846
|
+
* Of `mediaIds`, the ones a surviving message — or a message waiting in the queue — in one of
|
|
5847
|
+
* this actor's threads still carries.
|
|
5679
5848
|
* Re-derived from the messages each call, so a media whose message was truncated away reads as
|
|
5680
5849
|
* unreferenced again.
|
|
5681
5850
|
*/
|
|
@@ -5689,7 +5858,11 @@ var InMemoryAgentStore = class {
|
|
|
5689
5858
|
if (thread.actorRef !== actorRef) {
|
|
5690
5859
|
continue;
|
|
5691
5860
|
}
|
|
5692
|
-
|
|
5861
|
+
const queued = this.queues.get(thread.id) ?? [];
|
|
5862
|
+
for (const message of [
|
|
5863
|
+
...thread.messages,
|
|
5864
|
+
...queued
|
|
5865
|
+
]) {
|
|
5693
5866
|
for (const attachment of message.attachments ?? []) {
|
|
5694
5867
|
if (wanted.has(attachment.mediaId)) {
|
|
5695
5868
|
found.add(attachment.mediaId);
|
|
@@ -6018,7 +6191,8 @@ var InMemoryAgentStore = class {
|
|
|
6018
6191
|
defaultAgent: row.defaultAgent ?? null,
|
|
6019
6192
|
...row.model != null ? {
|
|
6020
6193
|
model: row.model
|
|
6021
|
-
} : {}
|
|
6194
|
+
} : {},
|
|
6195
|
+
persona: row.persona ?? null
|
|
6022
6196
|
};
|
|
6023
6197
|
}
|
|
6024
6198
|
};
|
|
@@ -6691,9 +6865,11 @@ var SqlTokenStreamSink = class {
|
|
|
6691
6865
|
filterToolsByEnabled,
|
|
6692
6866
|
filterToolsByRole,
|
|
6693
6867
|
findCatalogModel,
|
|
6868
|
+
findPersona,
|
|
6694
6869
|
gateFollowUps,
|
|
6695
6870
|
gateTail,
|
|
6696
6871
|
hashConfirmToken,
|
|
6872
|
+
intersectAllowLists,
|
|
6697
6873
|
invokeWithTransientRetry,
|
|
6698
6874
|
isChatQueueStore,
|
|
6699
6875
|
isControlFlowSignal,
|
|
@@ -6711,6 +6887,7 @@ var SqlTokenStreamSink = class {
|
|
|
6711
6887
|
observeTurnFrames,
|
|
6712
6888
|
offerMemories,
|
|
6713
6889
|
offerSkills,
|
|
6890
|
+
personaCatalogEntry,
|
|
6714
6891
|
publishAgentDelegated,
|
|
6715
6892
|
publishAgentMemoryResolved,
|
|
6716
6893
|
publishAgentMemoryWritten,
|
|
@@ -6740,6 +6917,7 @@ var SqlTokenStreamSink = class {
|
|
|
6740
6917
|
resolveGateLookback,
|
|
6741
6918
|
resolveMemoryDigest,
|
|
6742
6919
|
resolveOutputGateMode,
|
|
6920
|
+
resolvePersonaAlias,
|
|
6743
6921
|
resolveSkillCatalog,
|
|
6744
6922
|
resolveToolTransientRetryNumbers,
|
|
6745
6923
|
rollupThreadUsage,
|