@happyvertical/smrt-personas 0.38.19 → 0.38.21

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.
Files changed (39) hide show
  1. package/AGENTS.md +119 -7
  2. package/dist/__smrt-register__.d.ts +2 -0
  3. package/dist/__smrt-register__.d.ts.map +1 -0
  4. package/dist/agent-persona.d.ts +161 -0
  5. package/dist/agent-persona.d.ts.map +1 -0
  6. package/dist/directive-approval.d.ts +94 -0
  7. package/dist/directive-approval.d.ts.map +1 -0
  8. package/dist/directive-principal.d.ts +56 -0
  9. package/dist/directive-principal.d.ts.map +1 -0
  10. package/dist/directive-proposal.d.ts +103 -0
  11. package/dist/directive-proposal.d.ts.map +1 -0
  12. package/dist/feedback.d.ts +127 -0
  13. package/dist/feedback.d.ts.map +1 -0
  14. package/dist/index.d.ts +11 -294
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +829 -19
  17. package/dist/index.js.map +1 -1
  18. package/dist/manifest.json +919 -3
  19. package/dist/persona-instance.d.ts +249 -0
  20. package/dist/persona-instance.d.ts.map +1 -0
  21. package/dist/persona-memory.d.ts +45 -0
  22. package/dist/persona-memory.d.ts.map +1 -0
  23. package/dist/persona-prompt.d.ts +77 -0
  24. package/dist/persona-prompt.d.ts.map +1 -0
  25. package/dist/persona-resolver.d.ts +134 -0
  26. package/dist/persona-resolver.d.ts.map +1 -0
  27. package/dist/reflection-runner.d.ts +113 -0
  28. package/dist/reflection-runner.d.ts.map +1 -0
  29. package/dist/smrt-knowledge.json +519 -11
  30. package/dist/svelte/components/DirectiveReviewQueue.svelte +185 -0
  31. package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts +15 -0
  32. package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts.map +1 -0
  33. package/dist/svelte/index.d.ts +16 -0
  34. package/dist/svelte/index.d.ts.map +1 -0
  35. package/dist/svelte/index.js +13 -0
  36. package/dist/svelte/types.d.ts +46 -0
  37. package/dist/svelte/types.d.ts.map +1 -0
  38. package/dist/svelte/types.js +39 -0
  39. package/package.json +23 -7
@@ -0,0 +1,185 @@
1
+ <script lang="ts">
2
+ /**
3
+ * DirectiveReviewQueue — the minimal human-in-the-loop surface for the persona
4
+ * learning loop (#1889).
5
+ *
6
+ * Renders pending {@link DirectiveProposalView}s with their rationale and a
7
+ * current-vs-proposed diff, and lets a reviewer approve (optionally editing the
8
+ * proposed text) or reject. It is purely presentational — approval/rejection are
9
+ * delegated to the `onApprove` / `onReject` callbacks, which a host wires to the
10
+ * permission-gated `DirectiveApprovalService`.
11
+ */
12
+ import { Textarea } from '@happyvertical/smrt-ui/forms';
13
+ import { Badge, Button, Card } from '@happyvertical/smrt-ui/ui';
14
+ import type { DirectiveProposalView } from '../types.js';
15
+ import { confidencePercent, statusBadgeVariant } from '../types.js';
16
+
17
+ export interface Props {
18
+ /** Proposals to review (typically the pending queue). */
19
+ proposals?: DirectiveProposalView[];
20
+ /** Disable actions while a review is in flight. */
21
+ busy?: boolean;
22
+ /** Approve a proposal, optionally with reviewer-edited instructions. */
23
+ onApprove?: (id: string, editedInstructions?: string) => void;
24
+ /** Reject a proposal. */
25
+ onReject?: (id: string) => void;
26
+ }
27
+
28
+ const { proposals = [], busy = false, onApprove, onReject }: Props = $props();
29
+
30
+ // Reviewer edits, keyed by proposal id.
31
+ let edits = $state<Record<string, string>>({});
32
+
33
+ function draftFor(proposal: DirectiveProposalView): string {
34
+ return edits[proposal.id] ?? proposal.proposedInstructions;
35
+ }
36
+
37
+ function onEdit(id: string, value: string): void {
38
+ edits = { ...edits, [id]: value };
39
+ }
40
+
41
+ function approve(proposal: DirectiveProposalView): void {
42
+ const edited = edits[proposal.id];
43
+ const changed =
44
+ edited !== undefined && edited !== proposal.proposedInstructions;
45
+ onApprove?.(proposal.id, changed ? edited : undefined);
46
+ }
47
+ </script>
48
+
49
+ <section class="directive-review-queue">
50
+ {#if proposals.length === 0}
51
+ <p class="dq-empty">No directive proposals awaiting review.</p>
52
+ {:else}
53
+ {#each proposals as proposal (proposal.id)}
54
+ {@const locked = busy || proposal.status !== 'pending'}
55
+ <Card variant="outlined">
56
+ <div class="dq-head">
57
+ <span class="dq-title">
58
+ {proposal.personaName ?? proposal.agentClass ?? 'Persona directive'}
59
+ </span>
60
+ <span class="dq-badges">
61
+ {#if proposal.confidence != null}
62
+ <Badge variant="info" size="sm">
63
+ {confidencePercent(proposal.confidence)} confidence
64
+ </Badge>
65
+ {/if}
66
+ <Badge variant={statusBadgeVariant(proposal.status)} size="sm">
67
+ {proposal.status}
68
+ </Badge>
69
+ </span>
70
+ </div>
71
+
72
+ <p class="dq-rationale">{proposal.rationale}</p>
73
+
74
+ <div class="dq-diff">
75
+ <div class="dq-col">
76
+ <h4 class="dq-col-title">Current</h4>
77
+ <pre class="dq-pre">{proposal.currentInstructions || '(none)'}</pre>
78
+ </div>
79
+ <div class="dq-col">
80
+ <h4 class="dq-col-title">Proposed</h4>
81
+ <Textarea
82
+ value={draftFor(proposal)}
83
+ rows={5}
84
+ disabled={locked}
85
+ oninput={(event) =>
86
+ onEdit(
87
+ proposal.id,
88
+ (event.currentTarget as HTMLTextAreaElement).value,
89
+ )}
90
+ />
91
+ </div>
92
+ </div>
93
+
94
+ <div class="dq-actions">
95
+ <Button
96
+ variant="primary"
97
+ size="sm"
98
+ disabled={locked}
99
+ onclick={() => approve(proposal)}
100
+ >
101
+ Approve
102
+ </Button>
103
+ <Button
104
+ variant="danger"
105
+ size="sm"
106
+ disabled={locked}
107
+ onclick={() => onReject?.(proposal.id)}
108
+ >
109
+ Reject
110
+ </Button>
111
+ </div>
112
+ </Card>
113
+ {/each}
114
+ {/if}
115
+ </section>
116
+
117
+ <style>
118
+ .directive-review-queue {
119
+ display: flex;
120
+ flex-direction: column;
121
+ gap: 1rem;
122
+ }
123
+
124
+ .dq-empty {
125
+ color: var(--color-text-muted, #6b7280);
126
+ font-style: italic;
127
+ }
128
+
129
+ .dq-head {
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: space-between;
133
+ gap: 0.5rem;
134
+ margin-bottom: 0.5rem;
135
+ }
136
+
137
+ .dq-title {
138
+ font-weight: 600;
139
+ }
140
+
141
+ .dq-badges {
142
+ display: inline-flex;
143
+ gap: 0.375rem;
144
+ }
145
+
146
+ .dq-rationale {
147
+ margin: 0 0 0.75rem;
148
+ }
149
+
150
+ .dq-diff {
151
+ display: grid;
152
+ grid-template-columns: 1fr 1fr;
153
+ gap: 0.75rem;
154
+ }
155
+
156
+ @media (max-width: 640px) {
157
+ .dq-diff {
158
+ grid-template-columns: 1fr;
159
+ }
160
+ }
161
+
162
+ .dq-col-title {
163
+ margin: 0 0 0.25rem;
164
+ font-size: 0.8125rem;
165
+ text-transform: uppercase;
166
+ letter-spacing: 0.04em;
167
+ color: var(--color-text-muted, #6b7280);
168
+ }
169
+
170
+ .dq-pre {
171
+ margin: 0;
172
+ padding: 0.5rem;
173
+ white-space: pre-wrap;
174
+ word-break: break-word;
175
+ background: var(--color-surface-muted, #f3f4f6);
176
+ border-radius: 0.375rem;
177
+ font-size: 0.875rem;
178
+ }
179
+
180
+ .dq-actions {
181
+ display: flex;
182
+ gap: 0.5rem;
183
+ margin-top: 0.75rem;
184
+ }
185
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { DirectiveProposalView } from '../types.js';
2
+ export interface Props {
3
+ /** Proposals to review (typically the pending queue). */
4
+ proposals?: DirectiveProposalView[];
5
+ /** Disable actions while a review is in flight. */
6
+ busy?: boolean;
7
+ /** Approve a proposal, optionally with reviewer-edited instructions. */
8
+ onApprove?: (id: string, editedInstructions?: string) => void;
9
+ /** Reject a proposal. */
10
+ onReject?: (id: string) => void;
11
+ }
12
+ declare const DirectiveReviewQueue: import("svelte").Component<Props, {}, "">;
13
+ type DirectiveReviewQueue = ReturnType<typeof DirectiveReviewQueue>;
14
+ export default DirectiveReviewQueue;
15
+ //# sourceMappingURL=DirectiveReviewQueue.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirectiveReviewQueue.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/DirectiveReviewQueue.svelte.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,MAAM,WAAW,KAAK;IACpB,yDAAyD;IACzD,SAAS,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACpC,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,yBAAyB;IACzB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAuFD,QAAA,MAAM,oBAAoB,2CAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @happyvertical/smrt-personas/svelte
3
+ *
4
+ * Optional Svelte 5 UI for the persona learning loop (#1889): a minimal
5
+ * directive review queue. Presentational only — approval/rejection are
6
+ * delegated to callbacks a host wires to the permission-gated
7
+ * `DirectiveApprovalService`.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ import type { ComponentProps } from 'svelte';
12
+ import DirectiveReviewQueue from './components/DirectiveReviewQueue.svelte';
13
+ export { DirectiveReviewQueue };
14
+ export type DirectiveReviewQueueProps = ComponentProps<typeof DirectiveReviewQueue>;
15
+ export { confidencePercent, type DirectiveProposalView, type DirectiveReviewStatus, statusBadgeVariant, toDirectiveProposalView, } from './types.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,oBAAoB,MAAM,0CAA0C,CAAC;AAE5E,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,MAAM,MAAM,yBAAyB,GAAG,cAAc,CACpD,OAAO,oBAAoB,CAC5B,CAAC;AAEF,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @happyvertical/smrt-personas/svelte
3
+ *
4
+ * Optional Svelte 5 UI for the persona learning loop (#1889): a minimal
5
+ * directive review queue. Presentational only — approval/rejection are
6
+ * delegated to callbacks a host wires to the permission-gated
7
+ * `DirectiveApprovalService`.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ import DirectiveReviewQueue from './components/DirectiveReviewQueue.svelte';
12
+ export { DirectiveReviewQueue };
13
+ export { confidencePercent, statusBadgeVariant, toDirectiveProposalView, } from './types.js';
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Presentational types for the directive review-queue UI (#1889).
3
+ *
4
+ * Kept free of the `@smrt()` model classes so the Svelte bundle stays a thin
5
+ * presentation layer — consumers map their {@link DirectiveProposal} rows to
6
+ * {@link DirectiveProposalView} via {@link toDirectiveProposalView}.
7
+ *
8
+ * @module
9
+ */
10
+ /** The proposal lifecycle statuses the queue renders. */
11
+ export type DirectiveReviewStatus = 'pending' | 'approved' | 'rejected' | 'superseded';
12
+ /** A plain, render-ready view of a directive proposal. */
13
+ export interface DirectiveProposalView {
14
+ /** Proposal id. */
15
+ id: string;
16
+ /** Persona display name, if known. */
17
+ personaName?: string;
18
+ /** Canonical agent class the persona configures. */
19
+ agentClass?: string;
20
+ /** Lifecycle status. */
21
+ status: DirectiveReviewStatus;
22
+ /** Model-authored rationale for the change. */
23
+ rationale: string;
24
+ /** Current instructions (for the review diff). */
25
+ currentInstructions: string;
26
+ /** Proposed replacement instructions. */
27
+ proposedInstructions: string;
28
+ /** Aggregate confidence in `[0, 1]`, if known. */
29
+ confidence?: number;
30
+ }
31
+ /** Map a proposal-shaped record onto a render-ready view. */
32
+ export declare function toDirectiveProposalView(proposal: {
33
+ id?: string | null;
34
+ status?: string;
35
+ rationale?: string;
36
+ currentInstructions?: string;
37
+ proposedInstructions?: string;
38
+ confidence?: number;
39
+ agentClass?: string;
40
+ personaName?: string;
41
+ }): DirectiveProposalView;
42
+ /** Badge variant for a proposal status (matches `@happyvertical/smrt-ui`). */
43
+ export declare function statusBadgeVariant(status: DirectiveReviewStatus): 'default' | 'success' | 'warning' | 'error';
44
+ /** Format a `[0, 1]` confidence as a rounded percentage string. */
45
+ export declare function confidencePercent(confidence: number): string;
46
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/svelte/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yDAAyD;AACzD,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,UAAU,GACV,UAAU,GACV,YAAY,CAAC;AAEjB,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACpC,mBAAmB;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yCAAyC;IACzC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,6DAA6D;AAC7D,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE;IAChD,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,qBAAqB,CAWxB;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,qBAAqB,GAC5B,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAW7C;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Presentational types for the directive review-queue UI (#1889).
3
+ *
4
+ * Kept free of the `@smrt()` model classes so the Svelte bundle stays a thin
5
+ * presentation layer — consumers map their {@link DirectiveProposal} rows to
6
+ * {@link DirectiveProposalView} via {@link toDirectiveProposalView}.
7
+ *
8
+ * @module
9
+ */
10
+ /** Map a proposal-shaped record onto a render-ready view. */
11
+ export function toDirectiveProposalView(proposal) {
12
+ return {
13
+ id: proposal.id ?? '',
14
+ personaName: proposal.personaName,
15
+ agentClass: proposal.agentClass,
16
+ status: proposal.status ?? 'pending',
17
+ rationale: proposal.rationale ?? '',
18
+ currentInstructions: proposal.currentInstructions ?? '',
19
+ proposedInstructions: proposal.proposedInstructions ?? '',
20
+ confidence: proposal.confidence,
21
+ };
22
+ }
23
+ /** Badge variant for a proposal status (matches `@happyvertical/smrt-ui`). */
24
+ export function statusBadgeVariant(status) {
25
+ switch (status) {
26
+ case 'approved':
27
+ return 'success';
28
+ case 'rejected':
29
+ return 'error';
30
+ case 'pending':
31
+ return 'warning';
32
+ default:
33
+ return 'default';
34
+ }
35
+ }
36
+ /** Format a `[0, 1]` confidence as a rounded percentage string. */
37
+ export function confidencePercent(confidence) {
38
+ return `${Math.round(confidence * 100)}%`;
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-personas",
3
- "version": "0.38.19",
3
+ "version": "0.38.21",
4
4
  "description": "Tenant-owned, context-scoped agent personas and resolution for the SMRT framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,20 +15,36 @@
15
15
  "types": "./dist/index.d.ts",
16
16
  "import": "./dist/index.js"
17
17
  },
18
+ "./svelte": {
19
+ "types": "./dist/svelte/index.d.ts",
20
+ "svelte": "./dist/svelte/index.js",
21
+ "import": "./dist/svelte/index.js"
22
+ },
18
23
  "./manifest": "./dist/manifest.json",
19
24
  "./manifest.json": "./dist/manifest.json"
20
25
  },
21
26
  "dependencies": {
22
- "@happyvertical/smrt-agents": "0.38.19",
23
- "@happyvertical/smrt-core": "0.38.19",
24
- "@happyvertical/smrt-tenancy": "0.38.19"
27
+ "@happyvertical/sql": "^0.77.0",
28
+ "@happyvertical/smrt-core": "0.38.21",
29
+ "@happyvertical/smrt-prompts": "0.38.21",
30
+ "@happyvertical/smrt-tenancy": "0.38.21",
31
+ "@happyvertical/smrt-agents": "0.38.21",
32
+ "@happyvertical/smrt-ui": "0.38.21",
33
+ "@happyvertical/smrt-users": "0.38.21"
34
+ },
35
+ "peerDependencies": {
36
+ "svelte": "^5.56.4"
25
37
  },
26
38
  "devDependencies": {
39
+ "@sveltejs/package": "^2.5.8",
40
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
27
41
  "@types/node": "24.13.2",
42
+ "svelte": "^5.56.4",
43
+ "svelte-check": "^4.7.1",
28
44
  "typescript": "^5.9.3",
29
45
  "vite": "^8.1.3",
30
46
  "vitest": "^4.1.9",
31
- "@happyvertical/smrt-vitest": "0.38.19"
47
+ "@happyvertical/smrt-vitest": "0.38.21"
32
48
  },
33
49
  "keywords": [
34
50
  "smrt",
@@ -49,13 +65,13 @@
49
65
  "directory": "packages/personas"
50
66
  },
51
67
  "scripts": {
52
- "build": "vite build --mode library",
68
+ "build": "vite build --mode library && svelte-package -i src/svelte -o dist/svelte --tsconfig tsconfig.svelte.json",
53
69
  "build:watch": "vite build --mode library --watch",
54
70
  "clean": "rm -rf dist",
55
71
  "dev": "vite dev",
56
72
  "test": "vitest run",
57
73
  "test:watch": "vitest",
58
- "typecheck": "tsc --noEmit -p tsconfig.json",
74
+ "typecheck": "tsc --noEmit -p tsconfig.json && node ../../scripts/svelte-check-a11y.mjs --tsconfig ./tsconfig.svelte.json",
59
75
  "verify:pack": "node ../../scripts/verify-package-types-exports.js ."
60
76
  }
61
77
  }