@happyvertical/smrt-personas 0.38.19 → 0.38.20
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/AGENTS.md +119 -7
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/agent-persona.d.ts +161 -0
- package/dist/agent-persona.d.ts.map +1 -0
- package/dist/directive-approval.d.ts +94 -0
- package/dist/directive-approval.d.ts.map +1 -0
- package/dist/directive-principal.d.ts +56 -0
- package/dist/directive-principal.d.ts.map +1 -0
- package/dist/directive-proposal.d.ts +103 -0
- package/dist/directive-proposal.d.ts.map +1 -0
- package/dist/feedback.d.ts +127 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/index.d.ts +11 -294
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +829 -19
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +919 -3
- package/dist/persona-instance.d.ts +249 -0
- package/dist/persona-instance.d.ts.map +1 -0
- package/dist/persona-memory.d.ts +45 -0
- package/dist/persona-memory.d.ts.map +1 -0
- package/dist/persona-prompt.d.ts +77 -0
- package/dist/persona-prompt.d.ts.map +1 -0
- package/dist/persona-resolver.d.ts +134 -0
- package/dist/persona-resolver.d.ts.map +1 -0
- package/dist/reflection-runner.d.ts +113 -0
- package/dist/reflection-runner.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +519 -11
- package/dist/svelte/components/DirectiveReviewQueue.svelte +185 -0
- package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts +15 -0
- package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +16 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +13 -0
- package/dist/svelte/types.d.ts +46 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +39 -0
- package/package.json +23 -7
package/AGENTS.md
CHANGED
|
@@ -5,10 +5,13 @@ Tenant-owned, context-scoped agent personas and their resolution. Layers over
|
|
|
5
5
|
*how* an agent behaves for a given tenant and context (its `TenantAgent` binding
|
|
6
6
|
decides *whether* it runs and caps its capabilities).
|
|
7
7
|
|
|
8
|
-
This is the L2
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
This is the L2 layer of the "learning agents" epic (#1885): the persona foundation
|
|
9
|
+
(`AgentPersona` + `PersonaResolver`), the **persona learning & adaptation loop**
|
|
10
|
+
(#1889) — feedback → confidence-scored reinforcement → a scheduled reflection
|
|
11
|
+
runner that emits pending directive proposals → a permission-gated approval
|
|
12
|
+
surface that activates an approved rewrite as a tenant/persona-scoped prompt
|
|
13
|
+
override — and the persona-as-durable-instance / multi-instance helpers (#1890,
|
|
14
|
+
below). `ExecuteAsPrincipal` remains a separate issue (#1888).
|
|
12
15
|
|
|
13
16
|
## Models
|
|
14
17
|
|
|
@@ -34,6 +37,67 @@ reflection runner, and multi-instance routing are separate issues
|
|
|
34
37
|
tenant level.
|
|
35
38
|
- `enabled` — boolean; only enabled personas are resolved.
|
|
36
39
|
|
|
40
|
+
- **Feedback** (`@TenantScoped({ mode: 'optional' })`, table `agent_feedback`):
|
|
41
|
+
one reinforcement signal against a persona and the learning episode it judges.
|
|
42
|
+
Human signals (`accept` / `reject` / `correction` / `rating`) and autonomous
|
|
43
|
+
signals (`outcome` / `metric`) each carry a required **`correlationId`** (+
|
|
44
|
+
optional `correlationType`) back to the AI call / dispatch / job. `scope` /
|
|
45
|
+
`key` name the `LearningMemory` episode; `toLearningOutcome()` maps the signal
|
|
46
|
+
onto a `LearningOutcome` (feeds reinforcement, #1886). `FeedbackCollection`:
|
|
47
|
+
`forPersona`, `forScope`, `byCorrelation`.
|
|
48
|
+
|
|
49
|
+
- **DirectiveProposal** (`@TenantScoped({ mode: 'required' })`, table
|
|
50
|
+
`directive_proposals`): a pending, human-reviewable proposed edit to a
|
|
51
|
+
persona's `instructions`. Read-only generated surface (`api`/`cli`/`mcp` =
|
|
52
|
+
`list`/`get`) — writes go through the gated approval service, not CRUD. Key
|
|
53
|
+
fields: `promptKey`, `proposedInstructions`, `currentInstructions` (diff),
|
|
54
|
+
`rationale`, `evidence` (JSON: episode + feedback ids), `status`
|
|
55
|
+
(`pending`/`approved`/`rejected`/`superseded`), `fingerprint` (dedup so a
|
|
56
|
+
rejected rewrite is never re-surfaced), `proposedBy`, `reviewedBy` /
|
|
57
|
+
`reviewedAt` / `activatedOverrideId`. `DirectiveProposalCollection`:
|
|
58
|
+
`pending(...)` (the review queue), `findByFingerprint(...)`.
|
|
59
|
+
|
|
60
|
+
## Learning loop (#1889)
|
|
61
|
+
|
|
62
|
+
- **Persona instructions via prompt overrides** (`persona-prompt.ts`): a
|
|
63
|
+
persona's instructions apply through a per-persona registered prompt key
|
|
64
|
+
(`persona.<id>.instructions`, neutral empty base template) plus a
|
|
65
|
+
tenant-scoped `prompt_override`. Two personas of the same tenant/class resolve
|
|
66
|
+
different instructions without colliding on the override `(key, context)`
|
|
67
|
+
identity. `ensurePersonaInstructionsPrompt` (idempotent registration,
|
|
68
|
+
`editable` configurable), `applyPersonaInstructions` /
|
|
69
|
+
`upsertPromptTemplateOverride` (write the override — flows through
|
|
70
|
+
`PromptOverride.save()` → `validatePromptOverride`, so a non-editable template
|
|
71
|
+
is refused), `resolvePersonaInstructions`.
|
|
72
|
+
- **Memory scoping** (`persona-memory.ts`): `personaLearningMemory` routes a
|
|
73
|
+
`LearningMemory` by the persona's `memoryScope` (used as `owner_id`), so
|
|
74
|
+
personas learn independently. `reinforceFromFeedback` applies a `Feedback`
|
|
75
|
+
signal to memory as automatic, confidence-only reinforcement (ungated).
|
|
76
|
+
- **ReflectionRunner** (`reflection-runner.ts`): a schedulable pass that, under
|
|
77
|
+
the autonomous reflection principal (which **lacks**
|
|
78
|
+
`personas.activate-directive`), reinforces recent feedback, consolidates
|
|
79
|
+
episodes + feedback via an injected `reflect` boundary (the AI call, mocked in
|
|
80
|
+
tests), and records a **pending** `DirectiveProposal` (deduped by fingerprint).
|
|
81
|
+
It cannot activate anything.
|
|
82
|
+
- **The gate = a permission split** (`directive-principal.ts`,
|
|
83
|
+
`directive-approval.ts`): activating a directive is the permissioned operation
|
|
84
|
+
`personas.activate-directive` (contributed to the manifest permission catalog
|
|
85
|
+
via `registerPermissionDefinitions`). `DirectiveApprovalService.approve` /
|
|
86
|
+
`reject` first `assertCanActivate(principal)`; approval writes the
|
|
87
|
+
persona-scoped override and records an `accept` signal, rejection records a
|
|
88
|
+
`reject` signal and closes the proposal. A `DirectivePrincipal` is built from
|
|
89
|
+
granted slugs (`principalFromPermissions`) or a `PermissionResolver`
|
|
90
|
+
(`resolveDirectivePrincipal`).
|
|
91
|
+
|
|
92
|
+
## Svelte UI
|
|
93
|
+
|
|
94
|
+
`@happyvertical/smrt-personas/svelte` ships a minimal, presentational
|
|
95
|
+
`DirectiveReviewQueue` component (Svelte 5): it lists pending proposals with a
|
|
96
|
+
current-vs-proposed diff and Approve/Reject actions, delegating to `onApprove`
|
|
97
|
+
(optionally with reviewer-edited text) / `onReject` callbacks a host wires to
|
|
98
|
+
the gated `DirectiveApprovalService`. Built with `svelte-package`; Svelte tests
|
|
99
|
+
run in CI only.
|
|
100
|
+
|
|
37
101
|
## Collection
|
|
38
102
|
|
|
39
103
|
`AgentPersonaCollection`:
|
|
@@ -64,15 +128,51 @@ Because the walk reads personas across tenants, `resolve()` is intended for a
|
|
|
64
128
|
system/admin path where cross-tenant reads are allowed — not inside a strict
|
|
65
129
|
per-tenant interceptor context (same expectation as `resolveForTenant`).
|
|
66
130
|
|
|
131
|
+
## Persona as Durable Instance (#1890)
|
|
132
|
+
|
|
133
|
+
A persona is a **durable instance** of an agent class — N per tenant, each
|
|
134
|
+
independently scheduled, memory-scoped, and permission-scoped. `persona-instance.ts`
|
|
135
|
+
wires that to the `@happyvertical/smrt-agents` multi-instance primitives (which are
|
|
136
|
+
per-package opt-in via `static multiInstance`, singleton by default):
|
|
137
|
+
|
|
138
|
+
- **Identity** — `personaInstanceKey(persona)` returns the persona id, or `null`
|
|
139
|
+
for the `default` persona (`DEFAULT_PERSONA_NAME`). A `null` key reuses the
|
|
140
|
+
**singleton** runtime identity (class-keyed dispatch subscriber + un-suffixed
|
|
141
|
+
memory scope). `agentOptionsForPersona(persona)` projects `{ instanceKey,
|
|
142
|
+
tenantId }` to spread into the agent constructor.
|
|
143
|
+
- **Scheduling** — `schedulePersonaInstance(schedules, persona, { cron, … })`
|
|
144
|
+
creates an `AgentSchedule` for the instance. The instance key rides in
|
|
145
|
+
`agentConfig` (which the scheduler spreads into the agent constructor →
|
|
146
|
+
`AgentOptions.instanceKey`); `agentId` is left **null** on purpose, because the
|
|
147
|
+
scheduler copies `agentId`→`SmrtJob.objectId` and the `TaskRunner`
|
|
148
|
+
`loadFromId()`s it against the agent's STI table — a persona id is not a row
|
|
149
|
+
there. The default persona carries no key → runs the singleton.
|
|
150
|
+
- **Admin** — `buildPersonaInstanceAdmin(personas, { tenantId, agentClass,
|
|
151
|
+
manifest })` renders the class's `uiSlots`/`adminRoutes` **once per instance**
|
|
152
|
+
(with the per-instance dispatch subscriber); `addPersonaInstance()` /
|
|
153
|
+
`removePersonaInstance(personaId)` are the add/remove affordances.
|
|
154
|
+
- **Non-destructive upgrade** — `upgradeSingletonToDefaultPersona(personas, {
|
|
155
|
+
tenantId, agentClass, runAsUserId, … })` maps an existing singleton to a single
|
|
156
|
+
`default` persona. It's null-keyed, so the running agent's dispatch subscriber,
|
|
157
|
+
memory, and config are untouched; idempotent (a second call returns the
|
|
158
|
+
existing default with `created: false` and never overwrites it).
|
|
159
|
+
|
|
67
160
|
## Dependencies
|
|
68
161
|
|
|
69
162
|
Leaf package (acyclic by construction — nothing depends back on it):
|
|
70
163
|
|
|
71
164
|
- Runtime: `@happyvertical/smrt-core`, `@happyvertical/smrt-tenancy`,
|
|
72
|
-
`@happyvertical/smrt-agents` (the `TenantAgent` type it bridges
|
|
165
|
+
`@happyvertical/smrt-agents` (the `TenantAgent` type it bridges, plus the
|
|
166
|
+
`AgentSchedule`/multi-instance surface `persona-instance.ts` builds on),
|
|
167
|
+
`@happyvertical/smrt-prompts` (persona instructions via `PromptOverride` +
|
|
168
|
+
`resolvePrompt`), `@happyvertical/smrt-users` (the permission catalog slug +
|
|
169
|
+
`PermissionResolver` principal), and `@happyvertical/sql` (`DatabaseInterface`
|
|
170
|
+
type). These edges are all acyclic (none of those packages depend on personas).
|
|
171
|
+
- Svelte peer + `@happyvertical/smrt-ui` for the optional `./svelte` review-queue
|
|
172
|
+
component.
|
|
73
173
|
- `runAsUserId` / `actsAsProfileId` reference `@happyvertical/smrt-users` and
|
|
74
|
-
`@happyvertical/smrt-profiles` via `@crossPackageRef` string ids only
|
|
75
|
-
|
|
174
|
+
`@happyvertical/smrt-profiles` via `@crossPackageRef` string ids only. No
|
|
175
|
+
inter-`smrt-*` `peerDependencies`.
|
|
76
176
|
|
|
77
177
|
## Gotchas
|
|
78
178
|
|
|
@@ -83,3 +183,15 @@ Leaf package (acyclic by construction — nothing depends back on it):
|
|
|
83
183
|
read through the helpers, so it never auto-hydrates to an object.
|
|
84
184
|
- **Resolver runs outside strict tenant context** — it deliberately crosses
|
|
85
185
|
tenants to walk the hierarchy.
|
|
186
|
+
- **The gate is the permission split, not a bespoke check** — the reflection
|
|
187
|
+
principal simply lacks `personas.activate-directive`, so it can only propose;
|
|
188
|
+
everything privileged in `DirectiveApprovalService` calls `assertCanActivate`
|
|
189
|
+
first. Instruction rewrites are gated; confidence-only reinforcement is not.
|
|
190
|
+
- **Persona instructions live in the override layer, not the base prompt** — the
|
|
191
|
+
per-persona prompt key registers a neutral empty template, so re-registration
|
|
192
|
+
stays idempotent as instructions change; the tenant-scoped override carries the
|
|
193
|
+
actual text. Activation still honours `validatePromptOverride` editability.
|
|
194
|
+
- **Directive dedup is by fingerprint across all statuses** — the runner skips a
|
|
195
|
+
proposal whose `(personaId, promptKey, proposedInstructions)` fingerprint
|
|
196
|
+
already exists (pending, approved, or rejected), so a rejected rewrite is never
|
|
197
|
+
re-surfaced.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"__smrt-register__.d.ts","sourceRoot":"","sources":["../src/__smrt-register__.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { SmrtCollection, SmrtObject } from '@happyvertical/smrt-core';
|
|
2
|
+
/**
|
|
3
|
+
* Return the canonical agent type identifier for storage and lookup.
|
|
4
|
+
*
|
|
5
|
+
* Uses the registry's qualified name when the class is registered and falls
|
|
6
|
+
* back to the raw input for dynamically defined or unregistered classes. This
|
|
7
|
+
* mirrors `getAgentTypeName()` in `@happyvertical/smrt-agents` without reaching
|
|
8
|
+
* into that package's internal module — personas store the same canonical form
|
|
9
|
+
* that `TenantAgent` does so the two layers line up.
|
|
10
|
+
*/
|
|
11
|
+
export declare function canonicalAgentClass(name: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Return the meaningful aliases for an agent class — the canonical qualified
|
|
14
|
+
* name plus the simple class name — deduplicated.
|
|
15
|
+
*
|
|
16
|
+
* Lookups match against both so a persona persisted under a simple name (e.g.
|
|
17
|
+
* `Praeco`, when written through the generated create API without
|
|
18
|
+
* normalization) is still found when resolving under the canonical qualified
|
|
19
|
+
* name, and vice versa. Mirrors `getAgentTypeAliases()` in
|
|
20
|
+
* `@happyvertical/smrt-agents`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function agentClassAliases(name: string): string[];
|
|
23
|
+
/**
|
|
24
|
+
* AgentPersona SmrtObject — a tenant/context-scoped behavioral profile for an
|
|
25
|
+
* agent class.
|
|
26
|
+
*/
|
|
27
|
+
export declare class AgentPersona extends SmrtObject {
|
|
28
|
+
/** Owning tenant (required — personas are never global). */
|
|
29
|
+
tenantId: string;
|
|
30
|
+
/**
|
|
31
|
+
* Canonical qualified agent type this persona configures
|
|
32
|
+
* (e.g. `@happyvertical/smrt-agents:Praeco`). Stored in canonical form so it
|
|
33
|
+
* lines up with `TenantAgent.agentClass`.
|
|
34
|
+
*/
|
|
35
|
+
agentClass: string;
|
|
36
|
+
/**
|
|
37
|
+
* Human-readable persona name, unique per `(tenant, agentClass)`
|
|
38
|
+
* (see `conflictColumns`). Inherited `name` from {@link SmrtObject} is the
|
|
39
|
+
* conflict column; declared here for documentation and typing clarity.
|
|
40
|
+
*/
|
|
41
|
+
name: string;
|
|
42
|
+
/**
|
|
43
|
+
* Optional context dimension type this persona is scoped to
|
|
44
|
+
* (e.g. `'site'`, `'property'`, `'chatRoom'`). `null` means the persona is a
|
|
45
|
+
* tenant-wide default that applies to every context for its agent class.
|
|
46
|
+
*/
|
|
47
|
+
contextType: string | null;
|
|
48
|
+
/**
|
|
49
|
+
* Optional context dimension id. Only meaningful alongside `contextType`:
|
|
50
|
+
* when set, the persona targets one specific context row; when `null` (with
|
|
51
|
+
* a `contextType` set) it applies to every context of that type.
|
|
52
|
+
*/
|
|
53
|
+
contextId: string | null;
|
|
54
|
+
/** System prompt / behavioral instructions layered onto the agent. */
|
|
55
|
+
instructions: string;
|
|
56
|
+
/**
|
|
57
|
+
* Allowed tool identifiers, stored as a JSON array string. Use
|
|
58
|
+
* {@link getAllowedTools} / {@link setAllowedTools} rather than reading this
|
|
59
|
+
* field directly. Empty array (`'[]'`) means "no persona-specific tools"
|
|
60
|
+
* (the resolver then falls back to manifest defaults, capped by the
|
|
61
|
+
* `TenantAgent` ceiling).
|
|
62
|
+
*/
|
|
63
|
+
allowedTools: string;
|
|
64
|
+
/**
|
|
65
|
+
* The user whose principal this persona runs as (cross-package reference to
|
|
66
|
+
* `@happyvertical/smrt-users:User`). Required — a persona always runs as a
|
|
67
|
+
* concrete principal. Stored as a plain id column; no DDL FK constraint is
|
|
68
|
+
* emitted (cross-package).
|
|
69
|
+
*/
|
|
70
|
+
runAsUserId: string;
|
|
71
|
+
/**
|
|
72
|
+
* Optional `Bot` profile the persona acts as for identity/audit
|
|
73
|
+
* (cross-package reference to `@happyvertical/smrt-profiles:Profile`).
|
|
74
|
+
* `null` when the persona has no distinct acting identity.
|
|
75
|
+
*/
|
|
76
|
+
actsAsProfileId: string | null;
|
|
77
|
+
/**
|
|
78
|
+
* Memory scope key controlling how the agent's memory/reflection is
|
|
79
|
+
* partitioned for this persona. Empty string means "use a resolver-derived
|
|
80
|
+
* default".
|
|
81
|
+
*/
|
|
82
|
+
memoryScope: string;
|
|
83
|
+
/**
|
|
84
|
+
* Resolution priority — higher wins when several personas apply to the same
|
|
85
|
+
* context at the same tenant level. Integer.
|
|
86
|
+
*/
|
|
87
|
+
priority: number;
|
|
88
|
+
/** Whether this persona is active and eligible for resolution. */
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Allowed tool identifiers as an array.
|
|
92
|
+
*
|
|
93
|
+
* Tolerates malformed stored JSON by returning an empty array.
|
|
94
|
+
*/
|
|
95
|
+
getAllowedTools(): string[];
|
|
96
|
+
/**
|
|
97
|
+
* Replace the allowed tool identifiers.
|
|
98
|
+
*/
|
|
99
|
+
setAllowedTools(tools: string[]): void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Collection for managing {@link AgentPersona} records.
|
|
103
|
+
*/
|
|
104
|
+
export declare class AgentPersonaCollection extends SmrtCollection<AgentPersona> {
|
|
105
|
+
static readonly _itemClass: typeof AgentPersona;
|
|
106
|
+
/**
|
|
107
|
+
* List personas for a tenant + agent class, matching either the canonical
|
|
108
|
+
* qualified name or the simple class name (see {@link agentClassAliases}).
|
|
109
|
+
*
|
|
110
|
+
* Ordered by descending priority then name.
|
|
111
|
+
*
|
|
112
|
+
* @param extraWhere - Additional equality filters merged into the query
|
|
113
|
+
* (e.g. `{ enabled: true }`).
|
|
114
|
+
*/
|
|
115
|
+
private listForClass;
|
|
116
|
+
/**
|
|
117
|
+
* List every persona bound to a tenant + agent class.
|
|
118
|
+
*
|
|
119
|
+
* Ordered by descending priority then name so callers that don't need the
|
|
120
|
+
* full resolver still get a deterministic, priority-first ordering.
|
|
121
|
+
*/
|
|
122
|
+
byTenantAndClass(tenantId: string, agentClass: string): Promise<AgentPersona[]>;
|
|
123
|
+
/**
|
|
124
|
+
* List the enabled personas for a tenant + agent class, filtered to those
|
|
125
|
+
* applicable to a context.
|
|
126
|
+
*
|
|
127
|
+
* `enabled` is filtered in the query; the context predicate (tenant-wide vs
|
|
128
|
+
* type-scoped vs exact) is applied in memory since it is an OR over several
|
|
129
|
+
* columns. A persona is applicable when it is a tenant-wide default (no
|
|
130
|
+
* `contextType`) or its context matches the requested one. Ordered by
|
|
131
|
+
* descending priority then name.
|
|
132
|
+
*
|
|
133
|
+
* @param context - Optional `{ contextType, contextId }` to filter by.
|
|
134
|
+
*/
|
|
135
|
+
findActive(tenantId: string, agentClass: string, context?: {
|
|
136
|
+
contextType?: string | null;
|
|
137
|
+
contextId?: string | null;
|
|
138
|
+
}): Promise<AgentPersona[]>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Whether a persona applies to a requested context.
|
|
142
|
+
*
|
|
143
|
+
* - No `contextType` on the persona → tenant-wide default, applies to all.
|
|
144
|
+
* - `contextType` set, `contextId` null → type-scoped, applies when the
|
|
145
|
+
* requested `contextType` matches.
|
|
146
|
+
* - Both set → exact, applies when both match.
|
|
147
|
+
*/
|
|
148
|
+
export declare function personaAppliesToContext(persona: Pick<AgentPersona, 'contextType' | 'contextId'>, context: {
|
|
149
|
+
contextType?: string | null;
|
|
150
|
+
contextId?: string | null;
|
|
151
|
+
}): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Context-specificity rank used for resolution ordering.
|
|
154
|
+
*
|
|
155
|
+
* - `2` exact `(contextType, contextId)` match
|
|
156
|
+
* - `1` type-scoped match (`contextType` matches, persona `contextId` null)
|
|
157
|
+
* - `0` tenant-wide default (persona has no `contextType`)
|
|
158
|
+
*/
|
|
159
|
+
export declare function personaContextRank(persona: Pick<AgentPersona, 'contextType' | 'contextId'>): number;
|
|
160
|
+
export default AgentPersona;
|
|
161
|
+
//# sourceMappingURL=agent-persona.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-persona.d.ts","sourceRoot":"","sources":["../src/agent-persona.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAKL,cAAc,EACd,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAGlC;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxD;AAmBD;;;GAGG;AACH,qBAQa,YAAa,SAAQ,UAAU;IAC1C,4DAA4D;IAE5D,QAAQ,EAAE,MAAM,CAAM;IAEtB;;;;OAIG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAM;IAElB;;;;OAIG;IAEH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAElC;;;;OAIG;IAEH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhC,sEAAsE;IAEtE,YAAY,EAAE,MAAM,CAAM;IAE1B;;;;;;OAMG;IAEH,YAAY,EAAE,MAAM,CAAQ;IAE5B;;;;;OAKG;IAEH,WAAW,EAAE,MAAM,CAAM;IAEzB;;;;OAIG;IAEH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEtC;;;;OAIG;IAEH,WAAW,EAAE,MAAM,CAAM;IAEzB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB,kEAAkE;IAElE,OAAO,EAAE,OAAO,CAAQ;IAExB;;;;OAIG;IACH,eAAe,IAAI,MAAM,EAAE;IAI3B;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;CAGvC;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,cAAc,CAAC,YAAY,CAAC;IACtE,MAAM,CAAC,QAAQ,CAAC,UAAU,sBAAgB;IAE1C;;;;;;;;OAQG;YACW,YAAY;IAc1B;;;;;OAKG;IACG,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;IAI1B;;;;;;;;;;;OAWG;IACG,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAO,GACvE,OAAO,CAAC,YAAY,EAAE,CAAC;CAQ3B;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,WAAW,CAAC,EACxD,OAAO,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAClE,OAAO,CAWT;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,WAAW,CAAC,GACvD,MAAM,CAKR;AAWD,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { PromptOverride } from '@happyvertical/smrt-prompts';
|
|
2
|
+
import { DatabaseInterface } from '@happyvertical/sql';
|
|
3
|
+
import { AgentPersonaCollection } from './agent-persona.js';
|
|
4
|
+
import { DirectivePrincipal } from './directive-principal.js';
|
|
5
|
+
import { DirectiveProposal, DirectiveProposalCollection } from './directive-proposal.js';
|
|
6
|
+
import { Feedback, FeedbackCollection } from './feedback.js';
|
|
7
|
+
/** Raised when a principal without the activation permission attempts to review. */
|
|
8
|
+
export declare class DirectiveActivationDeniedError extends Error {
|
|
9
|
+
constructor(message?: string);
|
|
10
|
+
}
|
|
11
|
+
/** Raised when a review is attempted on a proposal that is not pending. */
|
|
12
|
+
export declare class DirectiveNotPendingError extends Error {
|
|
13
|
+
constructor(status: string);
|
|
14
|
+
}
|
|
15
|
+
/** Options for {@link DirectiveApprovalService}. */
|
|
16
|
+
export interface DirectiveApprovalServiceOptions {
|
|
17
|
+
db: DatabaseInterface;
|
|
18
|
+
proposals?: DirectiveProposalCollection;
|
|
19
|
+
feedback?: FeedbackCollection;
|
|
20
|
+
personas?: AgentPersonaCollection;
|
|
21
|
+
}
|
|
22
|
+
/** Result of approving a proposal. */
|
|
23
|
+
export interface DirectiveApprovalResult {
|
|
24
|
+
proposal: DirectiveProposal;
|
|
25
|
+
/** The activated persona-scoped override. */
|
|
26
|
+
override: PromptOverride;
|
|
27
|
+
/** The recorded `accept` signal. */
|
|
28
|
+
signal: Feedback;
|
|
29
|
+
}
|
|
30
|
+
/** Result of rejecting a proposal. */
|
|
31
|
+
export interface DirectiveRejectionResult {
|
|
32
|
+
proposal: DirectiveProposal;
|
|
33
|
+
/** The recorded `reject` signal. */
|
|
34
|
+
signal: Feedback;
|
|
35
|
+
}
|
|
36
|
+
/** A proposal reference: the row, or its id. */
|
|
37
|
+
export type ProposalRef = DirectiveProposal | string;
|
|
38
|
+
/**
|
|
39
|
+
* The permission-gated review surface for persona directives.
|
|
40
|
+
*/
|
|
41
|
+
export declare class DirectiveApprovalService {
|
|
42
|
+
private readonly db;
|
|
43
|
+
private proposals?;
|
|
44
|
+
private feedback?;
|
|
45
|
+
private personas?;
|
|
46
|
+
constructor(options: DirectiveApprovalServiceOptions);
|
|
47
|
+
/**
|
|
48
|
+
* Assert a principal is authorised to review directives. The single gate:
|
|
49
|
+
* everything privileged in this service calls it first.
|
|
50
|
+
*
|
|
51
|
+
* @throws {DirectiveActivationDeniedError} when the principal lacks the slug.
|
|
52
|
+
*/
|
|
53
|
+
assertCanActivate(principal: DirectivePrincipal): void;
|
|
54
|
+
/**
|
|
55
|
+
* Assert a principal may review a specific proposal: its resolved tenant, when
|
|
56
|
+
* bound, must match the proposal's tenant. Permissions are resolved per
|
|
57
|
+
* tenant, so holding the slug in one tenant must not authorise activating
|
|
58
|
+
* another tenant's directive.
|
|
59
|
+
*
|
|
60
|
+
* @throws {DirectiveActivationDeniedError} on a cross-tenant attempt.
|
|
61
|
+
*/
|
|
62
|
+
private assertTenantMatch;
|
|
63
|
+
/**
|
|
64
|
+
* Approve a pending proposal: activate the persona-scoped override and record
|
|
65
|
+
* an `accept` signal. Pass `editedInstructions` to activate a revised text
|
|
66
|
+
* (the proposal keeps the model's original as its audit record; the override
|
|
67
|
+
* holds what was activated).
|
|
68
|
+
*
|
|
69
|
+
* @throws {DirectiveActivationDeniedError} when the principal lacks the slug.
|
|
70
|
+
* @throws {DirectiveNotPendingError} when the proposal is already reviewed.
|
|
71
|
+
*/
|
|
72
|
+
approve(ref: ProposalRef, principal: DirectivePrincipal, options?: {
|
|
73
|
+
note?: string;
|
|
74
|
+
editedInstructions?: string;
|
|
75
|
+
}): Promise<DirectiveApprovalResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Reject a pending proposal: record a `reject` signal and close it so it is
|
|
78
|
+
* never re-surfaced.
|
|
79
|
+
*
|
|
80
|
+
* @throws {DirectiveActivationDeniedError} when the principal lacks the slug.
|
|
81
|
+
* @throws {DirectiveNotPendingError} when the proposal is already reviewed.
|
|
82
|
+
*/
|
|
83
|
+
reject(ref: ProposalRef, principal: DirectivePrincipal, options?: {
|
|
84
|
+
note?: string;
|
|
85
|
+
}): Promise<DirectiveRejectionResult>;
|
|
86
|
+
private loadPending;
|
|
87
|
+
private getProposal;
|
|
88
|
+
private recordSignal;
|
|
89
|
+
private syncPersonaInstructions;
|
|
90
|
+
private personasCollection;
|
|
91
|
+
private proposalsCollection;
|
|
92
|
+
private feedbackCollection;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=directive-approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directive-approval.d.ts","sourceRoot":"","sources":["../src/directive-approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGlE,oFAAoF;AACpF,qBAAa,8BAA+B,SAAQ,KAAK;gBAErD,OAAO,SAA4G;CAKtH;AAED,2EAA2E;AAC3E,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,MAAM,EAAE,MAAM;CAI3B;AAED,oDAAoD;AACpD,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,iBAAiB,CAAC;IACtB,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,CAAC,EAAE,sBAAsB,CAAC;CACnC;AAED,sCAAsC;AACtC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,6CAA6C;IAC7C,QAAQ,EAAE,cAAc,CAAC;IACzB,oCAAoC;IACpC,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,sCAAsC;AACtC,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,oCAAoC;IACpC,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,MAAM,CAAC;AAErD;;GAEG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IACvC,OAAO,CAAC,SAAS,CAAC,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAC,CAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAAyB;gBAE9B,OAAO,EAAE,+BAA+B;IAOpD;;;;;OAKG;IACH,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI;IAMtD;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;;;;OAQG;IACG,OAAO,CACX,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,kBAAkB,EAC7B,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAO,GAC3D,OAAO,CAAC,uBAAuB,CAAC;IAwCnC;;;;;;OAMG;IACG,MAAM,CACV,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,kBAAkB,EAC7B,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAC9B,OAAO,CAAC,wBAAwB,CAAC;YAkBtB,WAAW;YAYX,WAAW;YAKX,YAAY;YAyBZ,uBAAuB;YAavB,kBAAkB;YAOlB,mBAAmB;YASnB,kBAAkB;CAMjC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { PermissionDefinition, PermissionResolver } from '@happyvertical/smrt-users';
|
|
2
|
+
/** The permission slug that authorises activating a persona directive. */
|
|
3
|
+
export declare const ACTIVATE_DIRECTIVE_PERMISSION = "personas.activate-directive";
|
|
4
|
+
/** Catalog definition contributed for {@link ACTIVATE_DIRECTIVE_PERMISSION}. */
|
|
5
|
+
export declare const DIRECTIVE_ACTIVATION_PERMISSION_DEF: PermissionDefinition;
|
|
6
|
+
/**
|
|
7
|
+
* An actor whose authority is expressed as a set of held permission slugs.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately minimal so the gate depends only on the permission model, not on
|
|
10
|
+
* any particular resolver or session machinery.
|
|
11
|
+
*/
|
|
12
|
+
export interface DirectivePrincipal {
|
|
13
|
+
/** Optional stable id (recorded as the reviewer on approve/reject). */
|
|
14
|
+
readonly id?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The tenant this principal's authority was resolved for. Permissions are
|
|
17
|
+
* resolved per tenant (`PermissionResolver.resolvePermissions(userId, tenantId)`),
|
|
18
|
+
* so a principal authorised in one tenant must not activate another tenant's
|
|
19
|
+
* directive. When set, the approval service enforces
|
|
20
|
+
* `principal.tenantId === proposal.tenantId`. `undefined` skips the check
|
|
21
|
+
* (e.g. a system/global actor or a hand-built principal).
|
|
22
|
+
*/
|
|
23
|
+
readonly tenantId?: string;
|
|
24
|
+
/** Whether this actor holds the given permission slug. */
|
|
25
|
+
can(slug: string): boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a {@link DirectivePrincipal} from an explicit set of granted slugs.
|
|
29
|
+
*/
|
|
30
|
+
export declare function principalFromPermissions(permissions: Iterable<string>, options?: {
|
|
31
|
+
id?: string;
|
|
32
|
+
tenantId?: string;
|
|
33
|
+
}): DirectivePrincipal;
|
|
34
|
+
/**
|
|
35
|
+
* Build a {@link DirectivePrincipal} for a user in a tenant by resolving their
|
|
36
|
+
* effective permissions through the RBAC {@link PermissionResolver} — the
|
|
37
|
+
* production wiring that makes the gate concretely the permission system.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveDirectivePrincipal(options: {
|
|
40
|
+
resolver: PermissionResolver;
|
|
41
|
+
userId: string;
|
|
42
|
+
tenantId: string;
|
|
43
|
+
}): Promise<DirectivePrincipal>;
|
|
44
|
+
/**
|
|
45
|
+
* Register the persona directive-activation permission into the runtime catalog.
|
|
46
|
+
*
|
|
47
|
+
* @returns An unregister function (primarily for tests).
|
|
48
|
+
*/
|
|
49
|
+
export declare function registerPersonaPermissions(): () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Register the persona permissions once per process. Called as a side effect
|
|
52
|
+
* from the package entry so the slug is present in the permission catalog for
|
|
53
|
+
* any consumer that imports `@happyvertical/smrt-personas`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function ensurePersonaPermissionsRegistered(): void;
|
|
56
|
+
//# sourceMappingURL=directive-principal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directive-principal.d.ts","sourceRoot":"","sources":["../src/directive-principal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EAExB,MAAM,2BAA2B,CAAC;AAEnC,0EAA0E;AAC1E,eAAO,MAAM,6BAA6B,gCAAgC,CAAC;AAE3E,gFAAgF;AAChF,eAAO,MAAM,mCAAmC,EAAE,oBAMjD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC7B,OAAO,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,kBAAkB,CAOpB;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE;IACvD,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAW9B;AAID;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,IAAI,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,IAAI,IAAI,CAMzD"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { SmrtCollection, SmrtObject } from '@happyvertical/smrt-core';
|
|
2
|
+
/**
|
|
3
|
+
* Lifecycle status of a proposal:
|
|
4
|
+
*
|
|
5
|
+
* - `pending` — awaiting review; surfaced in the queue.
|
|
6
|
+
* - `approved` — a reviewer activated it; the override was written.
|
|
7
|
+
* - `rejected` — a reviewer declined it; recorded as a signal and never
|
|
8
|
+
* re-surfaced (the runner dedups against it by fingerprint).
|
|
9
|
+
* - `superseded` — a newer proposal replaced it before review.
|
|
10
|
+
*/
|
|
11
|
+
export type DirectiveProposalStatus = 'pending' | 'approved' | 'rejected' | 'superseded';
|
|
12
|
+
/**
|
|
13
|
+
* Structured evidence backing a proposal — the ids of the learning episodes and
|
|
14
|
+
* feedback signals the reflection consolidated. Pure references so the proposal
|
|
15
|
+
* stays auditable without duplicating payloads.
|
|
16
|
+
*/
|
|
17
|
+
export interface DirectiveEvidence {
|
|
18
|
+
/** `_smrt_contexts` row ids of the episodes considered. */
|
|
19
|
+
episodeIds?: string[];
|
|
20
|
+
/** {@link Feedback} row ids considered. */
|
|
21
|
+
feedbackIds?: string[];
|
|
22
|
+
/** Free-form supporting notes (e.g. counts, aggregate metrics). */
|
|
23
|
+
notes?: string[];
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A stable content fingerprint for `(personaId, promptKey, proposedInstructions)`.
|
|
28
|
+
*
|
|
29
|
+
* Used to dedup proposals so an already-reviewed rewrite — in particular a
|
|
30
|
+
* rejected one — is never re-surfaced. Pure FNV-1a so it needs no crypto import
|
|
31
|
+
* and stays identical across Node and browser bundles.
|
|
32
|
+
*/
|
|
33
|
+
export declare function computeDirectiveFingerprint(personaId: string, promptKey: string, proposedInstructions: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* A pending, human-reviewable proposed edit to a persona's instructions.
|
|
36
|
+
*/
|
|
37
|
+
export declare class DirectiveProposal extends SmrtObject {
|
|
38
|
+
/** Owning tenant (required — proposals always target a tenant's persona). */
|
|
39
|
+
tenantId: string;
|
|
40
|
+
/** The persona whose instructions this proposal would rewrite. */
|
|
41
|
+
personaId: string;
|
|
42
|
+
/** Canonical agent class the persona configures (denormalised for queries). */
|
|
43
|
+
agentClass: string;
|
|
44
|
+
/**
|
|
45
|
+
* The registered prompt key whose template the persona's instructions map to.
|
|
46
|
+
* Activation writes/updates the tenant-scoped override for this key.
|
|
47
|
+
*/
|
|
48
|
+
promptKey: string;
|
|
49
|
+
/** The proposed replacement instructions (the new prompt template). */
|
|
50
|
+
proposedInstructions: string;
|
|
51
|
+
/** Snapshot of the instructions at proposal time (for a review diff). */
|
|
52
|
+
currentInstructions: string;
|
|
53
|
+
/** Model-authored explanation for the proposed change. */
|
|
54
|
+
rationale: string;
|
|
55
|
+
/** Structured evidence, stored as a JSON string (see {@link getEvidence}). */
|
|
56
|
+
evidence: string;
|
|
57
|
+
/** Lifecycle status. */
|
|
58
|
+
status: DirectiveProposalStatus;
|
|
59
|
+
/**
|
|
60
|
+
* Content fingerprint for dedup / not-re-surfacing. Set from
|
|
61
|
+
* {@link computeDirectiveFingerprint} at creation time.
|
|
62
|
+
*/
|
|
63
|
+
fingerprint: string;
|
|
64
|
+
/** Aggregate confidence in the proposal, in `[0, 1]`. */
|
|
65
|
+
confidence: number;
|
|
66
|
+
/** Id of the principal (autonomous reflection actor) that proposed it. */
|
|
67
|
+
proposedBy: string;
|
|
68
|
+
/** The reviewer (user id) that approved/rejected it, once reviewed. */
|
|
69
|
+
reviewedBy: string | null;
|
|
70
|
+
/** When the proposal was reviewed. */
|
|
71
|
+
reviewedAt: Date | null;
|
|
72
|
+
/** Reviewer note attached on approve/reject. */
|
|
73
|
+
reviewNote: string | null;
|
|
74
|
+
/** The `prompt_override` id written on activation (`null` until approved). */
|
|
75
|
+
activatedOverrideId: string | null;
|
|
76
|
+
/** Parse {@link evidence}, tolerating malformed JSON. */
|
|
77
|
+
getEvidence(): DirectiveEvidence;
|
|
78
|
+
/** Replace {@link evidence}. */
|
|
79
|
+
setEvidence(value: DirectiveEvidence): void;
|
|
80
|
+
/** Whether the proposal is still awaiting review. */
|
|
81
|
+
isPending(): boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Collection for {@link DirectiveProposal} rows — the review queue.
|
|
85
|
+
*/
|
|
86
|
+
export declare class DirectiveProposalCollection extends SmrtCollection<DirectiveProposal> {
|
|
87
|
+
static readonly _itemClass: typeof DirectiveProposal;
|
|
88
|
+
/**
|
|
89
|
+
* The review queue: pending proposals, oldest first. Optionally scoped to a
|
|
90
|
+
* persona.
|
|
91
|
+
*/
|
|
92
|
+
pending(options?: {
|
|
93
|
+
personaId?: string;
|
|
94
|
+
limit?: number;
|
|
95
|
+
}): Promise<DirectiveProposal[]>;
|
|
96
|
+
/**
|
|
97
|
+
* Existing proposals for a persona carrying a given fingerprint, in any
|
|
98
|
+
* status — used to avoid re-surfacing an already-seen (e.g. rejected) rewrite.
|
|
99
|
+
*/
|
|
100
|
+
findByFingerprint(personaId: string, fingerprint: string): Promise<DirectiveProposal[]>;
|
|
101
|
+
}
|
|
102
|
+
export default DirectiveProposal;
|
|
103
|
+
//# sourceMappingURL=directive-proposal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directive-proposal.d.ts","sourceRoot":"","sources":["../src/directive-proposal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAGL,cAAc,EACd,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAGlC;;;;;;;;GAQG;AACH,MAAM,MAAM,uBAAuB,GAC/B,SAAS,GACT,UAAU,GACV,UAAU,GACV,YAAY,CAAC;AAEjB;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,oBAAoB,EAAE,MAAM,GAC3B,MAAM,CASR;AAgBD;;GAEG;AACH,qBASa,iBAAkB,SAAQ,UAAU;IAC/C,6EAA6E;IAE7E,QAAQ,EAAE,MAAM,CAAM;IAEtB,kEAAkE;IAElE,SAAS,EAAE,MAAM,CAAM;IAEvB,+EAA+E;IAE/E,UAAU,EAAE,MAAM,CAAM;IAExB;;;OAGG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB,uEAAuE;IAEvE,oBAAoB,EAAE,MAAM,CAAM;IAElC,yEAAyE;IAEzE,mBAAmB,EAAE,MAAM,CAAM;IAEjC,0DAA0D;IAE1D,SAAS,EAAE,MAAM,CAAM;IAEvB,8EAA8E;IAE9E,QAAQ,EAAE,MAAM,CAAQ;IAExB,wBAAwB;IAExB,MAAM,EAAE,uBAAuB,CAAa;IAE5C;;;OAGG;IAEH,WAAW,EAAE,MAAM,CAAM;IAEzB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAO;IAEzB,0EAA0E;IAE1E,UAAU,EAAE,MAAM,CAAM;IAExB,uEAAuE;IAEvE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEjC,sCAAsC;IAEtC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE/B,gDAAgD;IAEhD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEjC,8EAA8E;IAE9E,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1C,yDAAyD;IACzD,WAAW,IAAI,iBAAiB;IAIhC,gCAAgC;IAChC,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAI3C,qDAAqD;IACrD,SAAS,IAAI,OAAO;CAGrB;AAED;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,cAAc,CAAC,iBAAiB,CAAC;IAChF,MAAM,CAAC,QAAQ,CAAC,UAAU,2BAAqB;IAE/C;;;OAGG;IACG,OAAO,CACX,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GACnD,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAY/B;;;OAGG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAGhC;AAED,eAAe,iBAAiB,CAAC"}
|