@adhd/agent-store-prompts 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/drizzle/0000_third_nitro.sql +19 -0
- package/drizzle/0001_agents_and_taxonomy.sql +26 -0
- package/drizzle/0002_agent_components_junction.sql +13 -0
- package/drizzle/0003_usecase_context_rules.sql +31 -0
- package/drizzle/0004_composed_prompts.sql +10 -0
- package/drizzle/0005_warm_norman_osborn.sql +48 -0
- package/drizzle/0006_component_head_version_split.sql +78 -0
- package/drizzle/meta/0000_snapshot.json +137 -0
- package/drizzle/meta/0001_snapshot.json +302 -0
- package/drizzle/meta/0002_snapshot.json +381 -0
- package/drizzle/meta/0004_snapshot.json +594 -0
- package/drizzle/meta/0005_snapshot.json +594 -0
- package/drizzle/meta/0006_snapshot.json +672 -0
- package/drizzle/meta/_journal.json +55 -0
- package/package.json +51 -0
- package/src/db/client.d.ts +7 -0
- package/src/db/client.d.ts.map +1 -0
- package/src/db/client.js +24 -0
- package/src/db/client.js.map +1 -0
- package/src/db/migrate-runner.d.ts +31 -0
- package/src/db/migrate-runner.d.ts.map +1 -0
- package/src/db/migrate-runner.js +35 -0
- package/src/db/migrate-runner.js.map +1 -0
- package/src/db/migrate.d.ts +9 -0
- package/src/db/migrate.d.ts.map +1 -0
- package/src/db/migrate.js +13 -0
- package/src/db/migrate.js.map +1 -0
- package/src/db/schema.d.ts +997 -0
- package/src/db/schema.d.ts.map +1 -0
- package/src/db/schema.js +323 -0
- package/src/db/schema.js.map +1 -0
- package/src/index.d.ts +21 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +23 -0
- package/src/index.js.map +1 -0
- package/src/seed/components.d.ts +23 -0
- package/src/seed/components.d.ts.map +1 -0
- package/src/seed/components.js +399 -0
- package/src/seed/components.js.map +1 -0
- package/src/seed/index.d.ts +30 -0
- package/src/seed/index.d.ts.map +1 -0
- package/src/seed/index.js +95 -0
- package/src/seed/index.js.map +1 -0
- package/src/seed/prompt-types.d.ts +17 -0
- package/src/seed/prompt-types.d.ts.map +1 -0
- package/src/seed/prompt-types.js +107 -0
- package/src/seed/prompt-types.js.map +1 -0
- package/src/store/agent-store.d.ts +113 -0
- package/src/store/agent-store.d.ts.map +1 -0
- package/src/store/agent-store.js +211 -0
- package/src/store/agent-store.js.map +1 -0
- package/src/store/component-store.d.ts +87 -0
- package/src/store/component-store.d.ts.map +1 -0
- package/src/store/component-store.js +305 -0
- package/src/store/component-store.js.map +1 -0
- package/src/store/composed-prompt-store.d.ts +72 -0
- package/src/store/composed-prompt-store.d.ts.map +1 -0
- package/src/store/composed-prompt-store.js +147 -0
- package/src/store/composed-prompt-store.js.map +1 -0
- package/src/store/composition-store.d.ts +117 -0
- package/src/store/composition-store.d.ts.map +1 -0
- package/src/store/composition-store.js +270 -0
- package/src/store/composition-store.js.map +1 -0
- package/src/store/usecase-store.d.ts +104 -0
- package/src/store/usecase-store.d.ts.map +1 -0
- package/src/store/usecase-store.js +158 -0
- package/src/store/usecase-store.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition-store.d.ts","sourceRoot":"","sources":["../../../../../../packages/agent/agent-store-prompts/src/store/composition-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAOxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAM5D,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,IAAI,EAChB,iBAAiB,GACjB,6BAA6B,GAC7B,6BAA6B;gBAHjB,IAAI,EAChB,iBAAiB,GACjB,6BAA6B,GAC7B,6BAA6B,EACjC,OAAO,EAAE,MAAM;CAKlB;AAMD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExD,kFAAkF;AAClF,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,SAAS,EAAE,eAAe,CAAC;CAC5B;AAeD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAuBT;AAYD,qBAAa,gBAAgB;IAGzB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,qBAAqB,CAAC,GAAG,CAAC;IAGjD;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,KAAK,EAAE;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,6EAA6E;QAC7E,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,oFAAoF;QACpF,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GAAG,IAAI;IAoBR;;;;;OAKG;IACH,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAsBnE;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,kBAAuB,GAC3B,iBAAiB,EAAE;IA0DtB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,wBAAwB;IA8DhC,0EAA0E;IAC1E,OAAO,CAAC,KAAK;CAyBd"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { and, asc, desc, eq } from 'drizzle-orm';
|
|
2
|
+
import { agentComponentsTable, componentsTable, componentVersionsTable, } from '../db/schema.js';
|
|
3
|
+
// ──────────────────────────────────────────────
|
|
4
|
+
// Error codes
|
|
5
|
+
// ──────────────────────────────────────────────
|
|
6
|
+
export class CompositionError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = 'CompositionError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// ──────────────────────────────────────────────
|
|
15
|
+
// Internal: context-condition predicate evaluator
|
|
16
|
+
//
|
|
17
|
+
// Shared single evaluator (Decision 3, decisions.md): used by both junction-level
|
|
18
|
+
// context_condition and (later) context_rules rows. Defined here as the canonical
|
|
19
|
+
// implementation so it can be imported wherever needed.
|
|
20
|
+
//
|
|
21
|
+
// Rule (Decision 2, decisions.md §"Binding evaluation rule"):
|
|
22
|
+
// - condition IS NULL → always included (returns true).
|
|
23
|
+
// - non-null JSON predicate → included iff EVERY key in the predicate equals
|
|
24
|
+
// the corresponding value in ctx. Context keys not in the predicate are ignored.
|
|
25
|
+
// ──────────────────────────────────────────────
|
|
26
|
+
/**
|
|
27
|
+
* Evaluate a context condition predicate against a runtime context.
|
|
28
|
+
*
|
|
29
|
+
* @param condition - JSON text predicate, or null for "always include".
|
|
30
|
+
* @param ctx - The runtime context key/value map.
|
|
31
|
+
* @returns true if the component should be included for this context.
|
|
32
|
+
*/
|
|
33
|
+
export function evaluateCondition(condition, ctx) {
|
|
34
|
+
if (condition === null) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
let predicate;
|
|
38
|
+
try {
|
|
39
|
+
predicate = JSON.parse(condition);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Malformed JSON — treat as non-matching rather than throwing, so a
|
|
43
|
+
// bad condition doesn't corrupt an unrelated agent's composition.
|
|
44
|
+
// (Bad conditions on required rows will still surface as a REQUIRED_COMPONENT_EXCLUDED.)
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
// Every key in the predicate must equal the corresponding ctx value.
|
|
48
|
+
for (const [key, value] of Object.entries(predicate)) {
|
|
49
|
+
if (ctx[key] !== value) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
// ──────────────────────────────────────────────
|
|
56
|
+
// CompositionStore
|
|
57
|
+
//
|
|
58
|
+
// Thin Drizzle wrapper for registry_agent_components.
|
|
59
|
+
// Single owner of ordering + version-pin + context-condition evaluation.
|
|
60
|
+
// [ref:store-class] (contexts/_shared.md)
|
|
61
|
+
// [Decision 2] All-included; total order (position ASC, version DESC, slug ASC).
|
|
62
|
+
// [Decision 4] version_pin: null = latest-at-resolve, int = exact pin.
|
|
63
|
+
// ──────────────────────────────────────────────
|
|
64
|
+
export class CompositionStore {
|
|
65
|
+
db;
|
|
66
|
+
constructor(
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
db) {
|
|
69
|
+
this.db = db;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Attach a component to an agent at a given position.
|
|
73
|
+
*
|
|
74
|
+
* Inserts one row into registry_agent_components. No conflict handling —
|
|
75
|
+
* callers must ensure the (agent_slug, component_slug, position) triple
|
|
76
|
+
* is unique or use separate positions for multiple rows at the same position.
|
|
77
|
+
*
|
|
78
|
+
* Pinning ergonomics (Decision 5): the stored `version_pin` is a
|
|
79
|
+
* registry_component_versions.version_id (an ENFORCED nullable FK). Callers may
|
|
80
|
+
* pin either way:
|
|
81
|
+
* - `versionPin` — a version_id directly (already resolved).
|
|
82
|
+
* - `pinVersion` — a human `version` number; this store resolves it to the
|
|
83
|
+
* matching version_id for `componentSlug` via
|
|
84
|
+
* {@link resolvePinVersionId}.
|
|
85
|
+
* Supplying both, or a `pinVersion` for a (slug, version) that does not exist,
|
|
86
|
+
* throws. Omitting both leaves the pin null = resolve latest at resolve-time.
|
|
87
|
+
*/
|
|
88
|
+
attach(input) {
|
|
89
|
+
const versionId = this._resolvePinInput(input.componentSlug, input.versionPin, input.pinVersion);
|
|
90
|
+
this.db
|
|
91
|
+
.insert(agentComponentsTable)
|
|
92
|
+
.values({
|
|
93
|
+
agentSlug: input.agentSlug,
|
|
94
|
+
componentSlug: input.componentSlug,
|
|
95
|
+
position: input.position,
|
|
96
|
+
versionPin: versionId,
|
|
97
|
+
contextCondition: input.contextCondition ?? null,
|
|
98
|
+
isRequired: input.isRequired ?? false,
|
|
99
|
+
})
|
|
100
|
+
.run();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolve a `(slug, version)` pair to its registry_component_versions.version_id
|
|
104
|
+
* — the value stored as a junction `version_pin` when pinning an exact version.
|
|
105
|
+
*
|
|
106
|
+
* Throws COMPONENT_VERSION_NOT_FOUND if that exact version row is absent.
|
|
107
|
+
*/
|
|
108
|
+
resolvePinVersionId(componentSlug, version) {
|
|
109
|
+
const row = this.db
|
|
110
|
+
.select({ versionId: componentVersionsTable.versionId })
|
|
111
|
+
.from(componentVersionsTable)
|
|
112
|
+
.where(and(eq(componentVersionsTable.slug, componentSlug), eq(componentVersionsTable.version, version)))
|
|
113
|
+
.get();
|
|
114
|
+
if (!row) {
|
|
115
|
+
throw new CompositionError('COMPONENT_VERSION_NOT_FOUND', `Component '${componentSlug}' version ${version} not found`);
|
|
116
|
+
}
|
|
117
|
+
return row.versionId;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Normalize the two pinning inputs into a single nullable version_id.
|
|
121
|
+
* Rejects supplying both forms at once.
|
|
122
|
+
*/
|
|
123
|
+
_resolvePinInput(componentSlug, versionPin, pinVersion) {
|
|
124
|
+
const hasVersionId = versionPin !== undefined && versionPin !== null;
|
|
125
|
+
const hasPinVersion = pinVersion !== undefined && pinVersion !== null;
|
|
126
|
+
if (hasVersionId && hasPinVersion) {
|
|
127
|
+
throw new CompositionError('COMPONENT_VERSION_NOT_FOUND', `attach: supply either versionPin (version_id) or pinVersion (version number) for ` +
|
|
128
|
+
`'${componentSlug}', not both`);
|
|
129
|
+
}
|
|
130
|
+
if (hasPinVersion) {
|
|
131
|
+
return this.resolvePinVersionId(componentSlug, pinVersion);
|
|
132
|
+
}
|
|
133
|
+
return hasVersionId ? versionPin : null;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Resolve an agent's composition for a given runtime context.
|
|
137
|
+
*
|
|
138
|
+
* Steps (per composition-junction context + decisions.md):
|
|
139
|
+
* 1. Read all junction rows for the agent ordered by position ASC.
|
|
140
|
+
* 2. For each row, resolve the component version:
|
|
141
|
+
* - version_pin IS NULL → latest version of that component slug.
|
|
142
|
+
* - version_pin IS INT → exactly that version row.
|
|
143
|
+
* 3. Evaluate context_condition with the shared predicate evaluator:
|
|
144
|
+
* - null condition → always included.
|
|
145
|
+
* - non-null JSON → included iff every predicate key matches ctx.
|
|
146
|
+
* Exclude non-matching rows.
|
|
147
|
+
* 4. If a row has is_required = true AND its condition did not match →
|
|
148
|
+
* throw CompositionError('REQUIRED_COMPONENT_EXCLUDED').
|
|
149
|
+
* 5. Return the INCLUDED set ordered by:
|
|
150
|
+
* (position ASC, resolvedVersion DESC, componentSlug ASC)
|
|
151
|
+
* [Decision 2: total, stable, deterministic order]
|
|
152
|
+
*
|
|
153
|
+
* This is the single place ordering + filtering happen — do not duplicate.
|
|
154
|
+
*
|
|
155
|
+
* @param agentSlug - The agent whose composition to resolve.
|
|
156
|
+
* @param ctx - Runtime context key/value map.
|
|
157
|
+
* @returns Ordered, filtered list of resolved components. NOT a rendered prompt.
|
|
158
|
+
* Markdown assembly is @adhd/agent-engine-compiler's responsibility.
|
|
159
|
+
*/
|
|
160
|
+
resolveComposition(agentSlug, ctx = {}) {
|
|
161
|
+
// Step 1: read all junction rows for this agent, ordered by position ASC.
|
|
162
|
+
const junctionRows = this.db
|
|
163
|
+
.select()
|
|
164
|
+
.from(agentComponentsTable)
|
|
165
|
+
.where(eq(agentComponentsTable.agentSlug, agentSlug))
|
|
166
|
+
.orderBy(asc(agentComponentsTable.position))
|
|
167
|
+
.all();
|
|
168
|
+
// Step 2 + 3 + 4: resolve version, evaluate condition, accumulate.
|
|
169
|
+
const included = [];
|
|
170
|
+
for (const row of junctionRows) {
|
|
171
|
+
const conditionMatches = evaluateCondition(row.contextCondition, ctx);
|
|
172
|
+
// Step 4: required but excluded → error immediately.
|
|
173
|
+
if (!conditionMatches) {
|
|
174
|
+
if (row.isRequired) {
|
|
175
|
+
throw new CompositionError('REQUIRED_COMPONENT_EXCLUDED', `Required component '${row.componentSlug}' at position ${row.position} ` +
|
|
176
|
+
`was excluded by its context_condition for agent '${agentSlug}'`);
|
|
177
|
+
}
|
|
178
|
+
// Non-required + no match → skip.
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
// Step 2: resolve version — pinned or latest.
|
|
182
|
+
const component = this._resolveComponentVersion(row.componentSlug, row.versionPin ?? null);
|
|
183
|
+
included.push({
|
|
184
|
+
componentSlug: row.componentSlug,
|
|
185
|
+
position: row.position,
|
|
186
|
+
resolvedVersion: component.version,
|
|
187
|
+
component,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
// Step 5: apply total order (position ASC, version DESC, slug ASC).
|
|
191
|
+
// [Decision 2: deterministic total order]
|
|
192
|
+
included.sort((a, b) => {
|
|
193
|
+
if (a.position !== b.position)
|
|
194
|
+
return a.position - b.position;
|
|
195
|
+
if (b.resolvedVersion !== a.resolvedVersion)
|
|
196
|
+
return b.resolvedVersion - a.resolvedVersion;
|
|
197
|
+
if (a.componentSlug < b.componentSlug)
|
|
198
|
+
return -1;
|
|
199
|
+
if (a.componentSlug > b.componentSlug)
|
|
200
|
+
return 1;
|
|
201
|
+
return 0;
|
|
202
|
+
});
|
|
203
|
+
return included;
|
|
204
|
+
}
|
|
205
|
+
// ── Private helpers ───────────────────────
|
|
206
|
+
/**
|
|
207
|
+
* Resolve a junction row to a specific component version.
|
|
208
|
+
*
|
|
209
|
+
* Decision 4 + Decision 5 (decisions.md):
|
|
210
|
+
* - pin IS NULL → max(version) for `slug` at resolution time ("latest").
|
|
211
|
+
* - pin IS INT → the registry_component_versions row whose version_id = pin.
|
|
212
|
+
* That row's `slug` MUST equal the junction's component_slug —
|
|
213
|
+
* a mismatch is an integrity violation and throws.
|
|
214
|
+
*
|
|
215
|
+
* Throws COMPONENT_VERSION_NOT_FOUND if the row does not exist (the DB FK makes
|
|
216
|
+
* this unreachable for a pinned id, but we still guard defensively).
|
|
217
|
+
*/
|
|
218
|
+
_resolveComponentVersion(slug, pin) {
|
|
219
|
+
const head = this.db
|
|
220
|
+
.select()
|
|
221
|
+
.from(componentsTable)
|
|
222
|
+
.where(eq(componentsTable.slug, slug))
|
|
223
|
+
.get();
|
|
224
|
+
if (!head) {
|
|
225
|
+
throw new CompositionError('COMPONENT_VERSION_NOT_FOUND', `Component '${slug}' not found (no head row)`);
|
|
226
|
+
}
|
|
227
|
+
if (pin !== null) {
|
|
228
|
+
// Pinned: load the exact version row by its surrogate version_id.
|
|
229
|
+
const ver = this.db
|
|
230
|
+
.select()
|
|
231
|
+
.from(componentVersionsTable)
|
|
232
|
+
.where(eq(componentVersionsTable.versionId, pin))
|
|
233
|
+
.get();
|
|
234
|
+
if (!ver) {
|
|
235
|
+
throw new CompositionError('COMPONENT_VERSION_NOT_FOUND', `version_id ${pin} (pinned by '${slug}') not found`);
|
|
236
|
+
}
|
|
237
|
+
// The pinned version row must belong to the junction's component_slug.
|
|
238
|
+
if (ver.slug !== slug) {
|
|
239
|
+
throw new CompositionError('COMPONENT_VERSION_NOT_FOUND', `version_id ${pin} belongs to '${ver.slug}', not the junction's '${slug}'`);
|
|
240
|
+
}
|
|
241
|
+
return this._join(head, ver);
|
|
242
|
+
}
|
|
243
|
+
// Latest: highest version for the slug.
|
|
244
|
+
const latest = this.db
|
|
245
|
+
.select()
|
|
246
|
+
.from(componentVersionsTable)
|
|
247
|
+
.where(eq(componentVersionsTable.slug, slug))
|
|
248
|
+
.orderBy(desc(componentVersionsTable.version))
|
|
249
|
+
.limit(1)
|
|
250
|
+
.get();
|
|
251
|
+
if (!latest) {
|
|
252
|
+
throw new CompositionError('COMPONENT_VERSION_NOT_FOUND', `Component '${slug}' has no versions`);
|
|
253
|
+
}
|
|
254
|
+
return this._join(head, latest);
|
|
255
|
+
}
|
|
256
|
+
/** Join a head identity row to one version row into a PromptComponent. */
|
|
257
|
+
_join(head, ver) {
|
|
258
|
+
return {
|
|
259
|
+
slug: head.slug,
|
|
260
|
+
type: head.type,
|
|
261
|
+
version: ver.version,
|
|
262
|
+
versionId: ver.versionId,
|
|
263
|
+
content: ver.content,
|
|
264
|
+
isShared: Boolean(head.isShared),
|
|
265
|
+
createdAt: head.createdAt,
|
|
266
|
+
updatedAt: ver.updatedAt,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=composition-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition-store.js","sourceRoot":"","sources":["../../../../../../packages/agent/agent-store-prompts/src/store/composition-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
|
|
2
|
+
export declare class UseCaseError extends Error {
|
|
3
|
+
readonly code: 'USE_CASE_NOT_FOUND' | 'USE_CASE_ALREADY_EXISTS';
|
|
4
|
+
constructor(code: 'USE_CASE_NOT_FOUND' | 'USE_CASE_ALREADY_EXISTS', message: string);
|
|
5
|
+
}
|
|
6
|
+
export interface UseCase {
|
|
7
|
+
slug: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
}
|
|
11
|
+
export interface UseCaseCreateInput {
|
|
12
|
+
slug: string;
|
|
13
|
+
name: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One row from registry_component_usage with its optional weight.
|
|
18
|
+
*
|
|
19
|
+
* ANNOTATION ONLY — not on resolveComposition's hot path.
|
|
20
|
+
* Used by the future suggestion engine (GOAL.md "Knowledge Graph").
|
|
21
|
+
*/
|
|
22
|
+
export interface ComponentUsageRow {
|
|
23
|
+
componentSlug: string;
|
|
24
|
+
useCaseSlug: string;
|
|
25
|
+
/** Optional numeric weight for ranking/suggestion. Higher = more valuable. */
|
|
26
|
+
weight: number | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One row from registry_context_rules.
|
|
30
|
+
*
|
|
31
|
+
* An additive rule: "for agent X, when condition Y, also include component Z."
|
|
32
|
+
* Evaluated by the same evaluateCondition() predicate used for junction-level
|
|
33
|
+
* context_condition (Decision 3, decisions.md: one predicate shape, one evaluator).
|
|
34
|
+
*/
|
|
35
|
+
export interface ContextRule {
|
|
36
|
+
id: number;
|
|
37
|
+
agentSlug: string;
|
|
38
|
+
/** JSON predicate — same format as context_condition on agent_components. */
|
|
39
|
+
condition: string;
|
|
40
|
+
componentSlug: string;
|
|
41
|
+
/** Ordering position for merging into Decision 2's total order. null = append. */
|
|
42
|
+
position: number | null;
|
|
43
|
+
}
|
|
44
|
+
export interface ContextRuleCreateInput {
|
|
45
|
+
agentSlug: string;
|
|
46
|
+
/** JSON predicate string. */
|
|
47
|
+
condition: string;
|
|
48
|
+
componentSlug: string;
|
|
49
|
+
position?: number | null;
|
|
50
|
+
}
|
|
51
|
+
export declare class UseCaseStore {
|
|
52
|
+
private readonly db;
|
|
53
|
+
constructor(db: BetterSQLite3Database<any>);
|
|
54
|
+
/**
|
|
55
|
+
* Create a new use-case row. Throws USE_CASE_ALREADY_EXISTS if the slug
|
|
56
|
+
* is already taken (slug is the PK).
|
|
57
|
+
*/
|
|
58
|
+
createUseCase(input: UseCaseCreateInput): UseCase;
|
|
59
|
+
/** Return a single use-case by slug, or undefined if it does not exist. */
|
|
60
|
+
getUseCase(slug: string): UseCase | undefined;
|
|
61
|
+
/** Return all use-case rows ordered by slug. */
|
|
62
|
+
listUseCases(): UseCase[];
|
|
63
|
+
/**
|
|
64
|
+
* Link a prompt component to a use-case with an optional weight.
|
|
65
|
+
*
|
|
66
|
+
* ANNOTATION ONLY — this has no effect on resolveComposition's hot path.
|
|
67
|
+
* Duplicate (component_slug, use_case_slug) pairs will cause a unique-constraint
|
|
68
|
+
* violation if the migration creates a unique index; callers should guard.
|
|
69
|
+
*
|
|
70
|
+
* @param componentSlug - The component to annotate (logical FK).
|
|
71
|
+
* @param useCaseSlug - The use-case to associate with (FK → registry_use_cases).
|
|
72
|
+
* @param weight - Optional numeric weight for suggestion ranking.
|
|
73
|
+
*/
|
|
74
|
+
linkComponent(componentSlug: string, useCaseSlug: string, weight?: number): ComponentUsageRow;
|
|
75
|
+
/**
|
|
76
|
+
* Return all component-usage rows for a given use-case slug.
|
|
77
|
+
*
|
|
78
|
+
* Used by the suggestion engine to find which components are valuable for a
|
|
79
|
+
* given scenario. NOT called during runtime prompt assembly.
|
|
80
|
+
*/
|
|
81
|
+
componentsFor(useCaseSlug: string): ComponentUsageRow[];
|
|
82
|
+
/**
|
|
83
|
+
* Add a context rule: "for agent X, when condition Y, additionally include component Z."
|
|
84
|
+
*
|
|
85
|
+
* The condition must be a valid JSON predicate string in the same format as
|
|
86
|
+
* registry_agent_components.context_condition — evaluated by the same
|
|
87
|
+
* evaluateCondition() function (Decision 3, decisions.md: one predicate, one evaluator).
|
|
88
|
+
*
|
|
89
|
+
* @param input.agentSlug - The agent this rule applies to (in-package FK).
|
|
90
|
+
* @param input.condition - JSON predicate string, e.g. '{"ticket_type":"security"}'.
|
|
91
|
+
* @param input.componentSlug - The component to additionally include (logical FK).
|
|
92
|
+
* @param input.position - Optional ordering position for merging with Decision 2's order.
|
|
93
|
+
*/
|
|
94
|
+
addContextRule(input: ContextRuleCreateInput): ContextRule;
|
|
95
|
+
/**
|
|
96
|
+
* Return all context rules for a given agent slug.
|
|
97
|
+
*
|
|
98
|
+
* Used by the composition engine (agent-compiler) to discover which additive
|
|
99
|
+
* rules apply to an agent and merge them into the resolved composition per
|
|
100
|
+
* Decision 3 (decisions.md §"Additive, then deduplicated").
|
|
101
|
+
*/
|
|
102
|
+
contextRulesFor(agentSlug: string): ContextRule[];
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=usecase-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usecase-store.d.ts","sourceRoot":"","sources":["../../../../../../packages/agent/agent-store-prompts/src/store/usecase-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAYxE,qBAAa,YAAa,SAAQ,KAAK;aAEnB,IAAI,EAAE,oBAAoB,GAAG,yBAAyB;gBAAtD,IAAI,EAAE,oBAAoB,GAAG,yBAAyB,EACtE,OAAO,EAAE,MAAM;CAKlB;AAMD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAWD,qBAAa,YAAY;IAGrB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,qBAAqB,CAAC,GAAG,CAAC;IAKjD;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAWjD,2EAA2E;IAC3E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAW7C,gDAAgD;IAChD,YAAY,IAAI,OAAO,EAAE;IAUzB;;;;;;;;;;OAUG;IACH,aAAa,CACX,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,iBAAiB;IAWpB;;;;;OAKG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAevD;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,KAAK,EAAE,sBAAsB,GAAG,WAAW;IAwB1D;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;CAclD"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { eq } from 'drizzle-orm';
|
|
2
|
+
import { contextRulesTable, componentUsageTable, useCasesTable, } from '../db/schema.js';
|
|
3
|
+
// ──────────────────────────────────────────────
|
|
4
|
+
// Error codes
|
|
5
|
+
// ──────────────────────────────────────────────
|
|
6
|
+
export class UseCaseError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = 'UseCaseError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// ──────────────────────────────────────────────
|
|
15
|
+
// UseCaseStore
|
|
16
|
+
//
|
|
17
|
+
// Thin Drizzle wrapper for registry_use_cases, registry_component_usage, and
|
|
18
|
+
// registry_context_rules. Annotation + rule management only — keeps annotation
|
|
19
|
+
// data out of resolveComposition's hot path (composition-store.ts).
|
|
20
|
+
// [ref:store-class] (contexts/_shared.md)
|
|
21
|
+
// ──────────────────────────────────────────────
|
|
22
|
+
export class UseCaseStore {
|
|
23
|
+
db;
|
|
24
|
+
constructor(
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
db) {
|
|
27
|
+
this.db = db;
|
|
28
|
+
}
|
|
29
|
+
// ── Use-case CRUD ─────────────────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Create a new use-case row. Throws USE_CASE_ALREADY_EXISTS if the slug
|
|
32
|
+
* is already taken (slug is the PK).
|
|
33
|
+
*/
|
|
34
|
+
createUseCase(input) {
|
|
35
|
+
const row = {
|
|
36
|
+
slug: input.slug,
|
|
37
|
+
name: input.name,
|
|
38
|
+
description: input.description ?? '',
|
|
39
|
+
};
|
|
40
|
+
this.db.insert(useCasesTable).values(row).run();
|
|
41
|
+
return row;
|
|
42
|
+
}
|
|
43
|
+
/** Return a single use-case by slug, or undefined if it does not exist. */
|
|
44
|
+
getUseCase(slug) {
|
|
45
|
+
const row = this.db
|
|
46
|
+
.select()
|
|
47
|
+
.from(useCasesTable)
|
|
48
|
+
.where(eq(useCasesTable.slug, slug))
|
|
49
|
+
.get();
|
|
50
|
+
if (!row)
|
|
51
|
+
return undefined;
|
|
52
|
+
return { slug: row.slug, name: row.name, description: row.description };
|
|
53
|
+
}
|
|
54
|
+
/** Return all use-case rows ordered by slug. */
|
|
55
|
+
listUseCases() {
|
|
56
|
+
return this.db
|
|
57
|
+
.select()
|
|
58
|
+
.from(useCasesTable)
|
|
59
|
+
.all()
|
|
60
|
+
.map((r) => ({ slug: r.slug, name: r.name, description: r.description }));
|
|
61
|
+
}
|
|
62
|
+
// ── Component-usage (annotation junction) ────────────────────────────────
|
|
63
|
+
/**
|
|
64
|
+
* Link a prompt component to a use-case with an optional weight.
|
|
65
|
+
*
|
|
66
|
+
* ANNOTATION ONLY — this has no effect on resolveComposition's hot path.
|
|
67
|
+
* Duplicate (component_slug, use_case_slug) pairs will cause a unique-constraint
|
|
68
|
+
* violation if the migration creates a unique index; callers should guard.
|
|
69
|
+
*
|
|
70
|
+
* @param componentSlug - The component to annotate (logical FK).
|
|
71
|
+
* @param useCaseSlug - The use-case to associate with (FK → registry_use_cases).
|
|
72
|
+
* @param weight - Optional numeric weight for suggestion ranking.
|
|
73
|
+
*/
|
|
74
|
+
linkComponent(componentSlug, useCaseSlug, weight) {
|
|
75
|
+
const row = {
|
|
76
|
+
componentSlug,
|
|
77
|
+
useCaseSlug,
|
|
78
|
+
weight: weight ?? null,
|
|
79
|
+
};
|
|
80
|
+
this.db.insert(componentUsageTable).values(row).run();
|
|
81
|
+
return row;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Return all component-usage rows for a given use-case slug.
|
|
85
|
+
*
|
|
86
|
+
* Used by the suggestion engine to find which components are valuable for a
|
|
87
|
+
* given scenario. NOT called during runtime prompt assembly.
|
|
88
|
+
*/
|
|
89
|
+
componentsFor(useCaseSlug) {
|
|
90
|
+
return this.db
|
|
91
|
+
.select()
|
|
92
|
+
.from(componentUsageTable)
|
|
93
|
+
.where(eq(componentUsageTable.useCaseSlug, useCaseSlug))
|
|
94
|
+
.all()
|
|
95
|
+
.map((r) => ({
|
|
96
|
+
componentSlug: r.componentSlug,
|
|
97
|
+
useCaseSlug: r.useCaseSlug,
|
|
98
|
+
weight: r.weight,
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
// ── Context rules ─────────────────────────────────────────────────────────
|
|
102
|
+
/**
|
|
103
|
+
* Add a context rule: "for agent X, when condition Y, additionally include component Z."
|
|
104
|
+
*
|
|
105
|
+
* The condition must be a valid JSON predicate string in the same format as
|
|
106
|
+
* registry_agent_components.context_condition — evaluated by the same
|
|
107
|
+
* evaluateCondition() function (Decision 3, decisions.md: one predicate, one evaluator).
|
|
108
|
+
*
|
|
109
|
+
* @param input.agentSlug - The agent this rule applies to (in-package FK).
|
|
110
|
+
* @param input.condition - JSON predicate string, e.g. '{"ticket_type":"security"}'.
|
|
111
|
+
* @param input.componentSlug - The component to additionally include (logical FK).
|
|
112
|
+
* @param input.position - Optional ordering position for merging with Decision 2's order.
|
|
113
|
+
*/
|
|
114
|
+
addContextRule(input) {
|
|
115
|
+
const result = this.db
|
|
116
|
+
.insert(contextRulesTable)
|
|
117
|
+
.values({
|
|
118
|
+
agentSlug: input.agentSlug,
|
|
119
|
+
condition: input.condition,
|
|
120
|
+
componentSlug: input.componentSlug,
|
|
121
|
+
position: input.position ?? null,
|
|
122
|
+
})
|
|
123
|
+
.returning({ id: contextRulesTable.id })
|
|
124
|
+
.get();
|
|
125
|
+
if (!result) {
|
|
126
|
+
throw new Error('insert failed: context rule');
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
id: result.id,
|
|
130
|
+
agentSlug: input.agentSlug,
|
|
131
|
+
condition: input.condition,
|
|
132
|
+
componentSlug: input.componentSlug,
|
|
133
|
+
position: input.position ?? null,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Return all context rules for a given agent slug.
|
|
138
|
+
*
|
|
139
|
+
* Used by the composition engine (agent-compiler) to discover which additive
|
|
140
|
+
* rules apply to an agent and merge them into the resolved composition per
|
|
141
|
+
* Decision 3 (decisions.md §"Additive, then deduplicated").
|
|
142
|
+
*/
|
|
143
|
+
contextRulesFor(agentSlug) {
|
|
144
|
+
return this.db
|
|
145
|
+
.select()
|
|
146
|
+
.from(contextRulesTable)
|
|
147
|
+
.where(eq(contextRulesTable.agentSlug, agentSlug))
|
|
148
|
+
.all()
|
|
149
|
+
.map((r) => ({
|
|
150
|
+
id: r.id,
|
|
151
|
+
agentSlug: r.agentSlug,
|
|
152
|
+
condition: r.condition,
|
|
153
|
+
componentSlug: r.componentSlug,
|
|
154
|
+
position: r.position,
|
|
155
|
+
}));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=usecase-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usecase-store.js","sourceRoot":"","sources":["../../../../../../packages/agent/agent-store-prompts/src/store/usecase-store.ts"],"names":[],"mappings":"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"}
|