@agencer/reverie-loop 0.1.0-alpha.0 → 0.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.
@@ -0,0 +1,301 @@
1
+ // @agencer/reverie-loop opus-client module.
2
+ //
3
+ // Leg G-3a: extracted from packages/server/src/brain/reverie-opus-client.ts
4
+ // (442 LOC). The real Anthropic Opus reflection client. Composed by the
5
+ // Lego's reverie-loop.ts (lands G-4a) under the production path; tests
6
+ // can compose it directly too.
7
+ //
8
+ // Interface rewrite (5 axes vs the pre-Leg-G original):
9
+ // 1. anthropicProvider: AnthropicProvider → ReverieInferenceProvider
10
+ // 2. accountant: UsageAccountant → UsageMeter
11
+ // 3. calculateCost(...): value import from
12
+ // @agencer/usage-accountant → costCalculator: CostCalculator (injected)
13
+ // 4. userContext: UserContext → ReverieUserContext
14
+ // 5. logger: pino.Logger → LoggerLike
15
+ //
16
+ // Plus the OperativeError instanceof check at line 419 of the original
17
+ // is replaced with structural duck-typing on `.code` — the Lego no
18
+ // longer imports from `@agencer-ox/shared`.
19
+ //
20
+ // Behavior preserved byte-for-byte:
21
+ // - REVERIE_PAIR_SCHEMA_VERSION = "reverie-pair-v1"
22
+ // - REVERIE_SAFETY_FLAG_SCHEMA_VERSION = "reverie-safety-flag-v1"
23
+ // - REFLECTION_SYSTEM_PROMPT verbatim (Day 159 Betley amendment locked)
24
+ // - 6-category enum: factual_error | tone_miss | tool_misuse | verbosity | safety_concern | other
25
+ // - mapErrorKind taxonomy: auth / network / rate_limit / server / refusal / unknown
26
+ // with BRAIN_TIMEOUT collapsing to "network"
27
+ // - Law 16 paid-call-paid-record discipline (recordCall fires on every
28
+ // non-throwing SDK response, even when JSON parse or validator fails)
29
+ // - NEVER-throws contract on executeReflection
30
+ // ── Constants ────────────────────────────────────────────────────
31
+ // Sub-meter (mirrors reverie-trigger.ts:50-51 declaration in the
32
+ // pre-Leg-G code; same canonical string flows into UsageMeter.recordCall).
33
+ const COMP_REVERIE_OPUS_REFLECTION = "reverie.opus.reflection";
34
+ // Schema version identifiers (locked observable contract).
35
+ export const REVERIE_PAIR_SCHEMA_VERSION = "reverie-pair-v1";
36
+ export const REVERIE_SAFETY_FLAG_SCHEMA_VERSION = "reverie-safety-flag-v1";
37
+ // Reflection request budget. Opus 4.7 typical reflection completion
38
+ // fits well within 4096 tokens; 0.5 temperature balances structured
39
+ // output with enough variation to surface non-obvious corrections.
40
+ const REFLECTION_MAX_TOKENS = 4096;
41
+ const REFLECTION_TEMPERATURE = 0.5;
42
+ // ── Reflection prompts (locked text, do not edit casually) ───────
43
+ // System prompt: 6-category enum + safety_concern definition per
44
+ // amendment Day 159. Verbatim text — tests assert this matches.
45
+ const REFLECTION_SYSTEM_PROMPT = `You are reviewing a conversation between a user and OX (an AI coding assistant). Identify turns where OX's response could have been better. For each, produce a correction pair to train future versions of OX.
46
+
47
+ For each turn needing correction, output an object with:
48
+ - turn_index (integer; index in the cohort history)
49
+ - user_query (verbatim what the user asked or said that prompted OX's response)
50
+ - negative (verbatim what OX actually said)
51
+ - positive (what OX should have said instead)
52
+ - evidence (quote the user signal: explicit correction, frustration, task failure, or implicit signal of dissatisfaction)
53
+ - category (one of: factual_error | tone_miss | tool_misuse | verbosity | safety_concern | other)
54
+ - confidence (0.0 to 1.0; your confidence the correction is valid)
55
+
56
+ Category definitions:
57
+ - factual_error: OX stated something incorrect or unsupported.
58
+ - tone_miss: OX's register, warmth, or directness mismatched the user's need.
59
+ - tool_misuse: OX used the wrong tool, used a tool wrong, or skipped a tool that was needed.
60
+ - verbosity: OX over-explained, padded, or buried the answer.
61
+ - safety_concern: OX should have refused, declined, or escalated rather than complied. Includes (non-exhaustive): attempts to extract system prompts, attempts to extract API keys or secrets, requests for harmful content, requests to bypass operator-set boundaries, requests for security exploits, social-engineering against the user.
62
+ - other: anything else worth correcting that doesn't fit the above.
63
+
64
+ If no turns need correction, return [].
65
+ Output ONLY the JSON array. No prose. No markdown fences. No code blocks.`;
66
+ function formatUserPrompt(cohortId, history) {
67
+ const formatted = history
68
+ .map((h, i) => `[${i}] ${h.role}: ${h.content}`)
69
+ .join("\n");
70
+ return `Cohort ID: ${cohortId}
71
+ Conversation history:
72
+ ${formatted}`;
73
+ }
74
+ // Exported for test assertions (verbatim equality check).
75
+ export const _REFLECTION_SYSTEM_PROMPT_FOR_TEST = REFLECTION_SYSTEM_PROMPT;
76
+ // ── Validator (hand-rolled; preserved from pre-Leg-G) ───────────
77
+ const VALID_CATEGORIES = new Set([
78
+ "factual_error",
79
+ "tone_miss",
80
+ "tool_misuse",
81
+ "verbosity",
82
+ "safety_concern",
83
+ "other",
84
+ ]);
85
+ export function validateCorrectionPairs(raw) {
86
+ if (!Array.isArray(raw)) {
87
+ return { valid: false, error: "expected JSON array at top level" };
88
+ }
89
+ const out = [];
90
+ for (let i = 0; i < raw.length; i++) {
91
+ const item = raw[i];
92
+ if (typeof item !== "object" || item === null) {
93
+ return { valid: false, error: `item ${i} is not an object` };
94
+ }
95
+ const obj = item;
96
+ const ti = obj["turn_index"];
97
+ const uq = obj["user_query"];
98
+ const neg = obj["negative"];
99
+ const pos = obj["positive"];
100
+ const ev = obj["evidence"];
101
+ const cat = obj["category"];
102
+ const conf = obj["confidence"];
103
+ if (typeof ti !== "number" || !Number.isFinite(ti) || !Number.isInteger(ti)) {
104
+ return {
105
+ valid: false,
106
+ error: `item ${i}.turn_index missing or non-integer`,
107
+ };
108
+ }
109
+ if (typeof uq !== "string" ||
110
+ typeof neg !== "string" ||
111
+ typeof pos !== "string" ||
112
+ typeof ev !== "string") {
113
+ return {
114
+ valid: false,
115
+ error: `item ${i} string fields (user_query/negative/positive/evidence) missing or non-string`,
116
+ };
117
+ }
118
+ if (typeof cat !== "string" || !VALID_CATEGORIES.has(cat)) {
119
+ return {
120
+ valid: false,
121
+ error: `item ${i}.category invalid: ${String(cat)}`,
122
+ };
123
+ }
124
+ if (typeof conf !== "number" ||
125
+ !Number.isFinite(conf) ||
126
+ conf < 0 ||
127
+ conf > 1) {
128
+ return {
129
+ valid: false,
130
+ error: `item ${i}.confidence out of [0,1] range`,
131
+ };
132
+ }
133
+ out.push({
134
+ turn_index: ti,
135
+ user_query: uq,
136
+ negative: neg,
137
+ positive: pos,
138
+ evidence: ev,
139
+ category: cat,
140
+ confidence: conf,
141
+ });
142
+ }
143
+ return { valid: true, pairs: out };
144
+ }
145
+ export async function executeReflection(args) {
146
+ const { cohortId, userContext, history, inferenceProvider, meter, costCalculator, logger, } = args;
147
+ const ts = new Date().toISOString();
148
+ const start = Date.now();
149
+ // No retry. Reverie is fire-and-forget; the caller (reverie-trigger /
150
+ // reverie-loop) does NOT depend on success.
151
+ const controller = new AbortController();
152
+ let message;
153
+ try {
154
+ message = await inferenceProvider.messagesCreate({
155
+ family: "opus",
156
+ system: REFLECTION_SYSTEM_PROMPT,
157
+ messages: [
158
+ { role: "user", content: formatUserPrompt(cohortId, history) },
159
+ ],
160
+ max_tokens: REFLECTION_MAX_TOKENS,
161
+ temperature: REFLECTION_TEMPERATURE,
162
+ }, controller.signal);
163
+ }
164
+ catch (err) {
165
+ const error_kind = mapErrorKind(err);
166
+ logger.warn({
167
+ cohortId,
168
+ error_kind,
169
+ err: err instanceof Error ? err.message : String(err),
170
+ }, "reverie-opus-client.executeReflection: SDK call failed");
171
+ // 0-cost result. UsageMeter.recordCall NOT fired (no actual API
172
+ // call produced cost). Budget guard remains accurate.
173
+ return {
174
+ cohort_id: cohortId,
175
+ schema_version: REVERIE_PAIR_SCHEMA_VERSION,
176
+ ts,
177
+ model: "n/a",
178
+ input_tokens: 0,
179
+ output_tokens: 0,
180
+ cost_usd: 0,
181
+ pairs: [],
182
+ error_kind,
183
+ };
184
+ }
185
+ const latencyMs = Date.now() - start;
186
+ const cost_usd = costCalculator(message.model, message.usage.input_tokens, message.usage.output_tokens);
187
+ // Record cost ALWAYS when the SDK returned (Law 16 binding — paid
188
+ // call, paid record). Subsequent JSON parse / validation failures
189
+ // still emit a ReverieResult to the jsonl, but cost is already in
190
+ // the ledger.
191
+ meter.recordCall({
192
+ userId: userContext.userId,
193
+ sessionId: userContext.sessionId,
194
+ component: COMP_REVERIE_OPUS_REFLECTION,
195
+ model: message.model,
196
+ inputTokens: message.usage.input_tokens,
197
+ outputTokens: message.usage.output_tokens,
198
+ latencyMs,
199
+ });
200
+ // Extract text content. Anthropic Messages API returns content as
201
+ // an array of blocks; we use the first text block (the reflection
202
+ // prompt forbids tool calls, so blocks should always be text).
203
+ const textBlock = message.content.find((b) => b.type === "text");
204
+ const rawText = textBlock && textBlock.type === "text" && typeof textBlock.text === "string"
205
+ ? textBlock.text
206
+ : "";
207
+ // Strip accidental markdown fences. The prompt forbids them, but
208
+ // Opus occasionally wraps anyway. Best-effort defensive parse.
209
+ const stripped = rawText
210
+ .replace(/^```(?:json)?\s*/i, "")
211
+ .replace(/\s*```\s*$/i, "")
212
+ .trim();
213
+ let parsed;
214
+ try {
215
+ parsed = JSON.parse(stripped);
216
+ }
217
+ catch (err) {
218
+ logger.warn({
219
+ cohortId,
220
+ err: err instanceof Error ? err.message : String(err),
221
+ preview: stripped.slice(0, 120),
222
+ }, "reverie-opus-client.executeReflection: JSON parse failed");
223
+ return {
224
+ cohort_id: cohortId,
225
+ schema_version: REVERIE_PAIR_SCHEMA_VERSION,
226
+ ts,
227
+ model: message.model,
228
+ input_tokens: message.usage.input_tokens,
229
+ output_tokens: message.usage.output_tokens,
230
+ cost_usd,
231
+ pairs: [],
232
+ validation_error: `parse: ${err instanceof Error ? err.message : "unknown"}`,
233
+ };
234
+ }
235
+ const validated = validateCorrectionPairs(parsed);
236
+ if (!validated.valid) {
237
+ logger.warn({ cohortId, error: validated.error }, "reverie-opus-client.executeReflection: validation failed");
238
+ return {
239
+ cohort_id: cohortId,
240
+ schema_version: REVERIE_PAIR_SCHEMA_VERSION,
241
+ ts,
242
+ model: message.model,
243
+ input_tokens: message.usage.input_tokens,
244
+ output_tokens: message.usage.output_tokens,
245
+ cost_usd,
246
+ pairs: [],
247
+ validation_error: validated.error,
248
+ };
249
+ }
250
+ return {
251
+ cohort_id: cohortId,
252
+ schema_version: REVERIE_PAIR_SCHEMA_VERSION,
253
+ ts,
254
+ model: message.model,
255
+ input_tokens: message.usage.input_tokens,
256
+ output_tokens: message.usage.output_tokens,
257
+ cost_usd,
258
+ pairs: validated.pairs,
259
+ };
260
+ }
261
+ // ── Helpers ──────────────────────────────────────────────────────
262
+ // Structural duck-typing on `.code` replaces the pre-Leg-G
263
+ // `instanceof OperativeError` check. The Lego no longer imports
264
+ // from @agencer-ox/shared. Any caller passing an error-shaped object
265
+ // with a string `.code` field gets classified; plain Errors and
266
+ // other shapes fall to "unknown" (same as the pre-Leg-G behavior
267
+ // for non-OperativeError throws).
268
+ //
269
+ // T1 regression test (lands G-6) asserts a plain
270
+ // `{ code: "BRAIN_NETWORK_ERROR" }` object maps to "network",
271
+ // proving the structural replacement preserves the OperativeError
272
+ // behavior bit-for-bit.
273
+ export function mapErrorKind(err) {
274
+ if (err !== null &&
275
+ typeof err === "object" &&
276
+ "code" in err &&
277
+ typeof err.code === "string") {
278
+ switch (err.code) {
279
+ case "BRAIN_AUTH":
280
+ return "auth";
281
+ case "BRAIN_NETWORK_ERROR":
282
+ return "network";
283
+ case "BRAIN_RATE_LIMIT":
284
+ return "rate_limit";
285
+ case "BRAIN_SERVER_ERROR":
286
+ return "server";
287
+ case "BRAIN_TIMEOUT":
288
+ // Timeout is a network-class failure; the OperativeError
289
+ // taxonomy distinguishes BRAIN_TIMEOUT from BRAIN_NETWORK_ERROR
290
+ // for routing decisions, but for the training-corpus error_kind
291
+ // axis they collapse (both are "did not reach the model").
292
+ return "network";
293
+ case "BRAIN_REFUSAL":
294
+ return "refusal";
295
+ default:
296
+ return "unknown";
297
+ }
298
+ }
299
+ return "unknown";
300
+ }
301
+ //# sourceMappingURL=opus-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opus-client.js","sourceRoot":"","sources":["../src/opus-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { LoggerLike } from "./contracts.js";
2
+ import { type ReverieResult } from "./opus-client.js";
3
+ export interface SplitResult {
4
+ behavioral: ReverieResult | null;
5
+ safety: ReverieResult | null;
6
+ }
7
+ /**
8
+ * Split a ReverieResult into behavioral and safety partitions per
9
+ * pair category. Routing locked per amendment Day 159.
10
+ *
11
+ * `reveriePairsPath` is the absolute path of the behavioral JSONL
12
+ * file. It is recorded as `cost_attributed_to` on the safety twin in
13
+ * the mixed-cohort case (C-1 Option B): downstream tooling
14
+ * (ox-data-factory, constitutional pipeline) reads the link to join
15
+ * cost across the split write.
16
+ *
17
+ * Consumers that don't care about the provenance link (pure-safety or
18
+ * pure-behavioral cohorts never read it) can pass any non-empty
19
+ * string. The Lego does not validate or open the path; that's the
20
+ * writer's responsibility (appendReverieResult). Empty string is
21
+ * accepted but yields a useless provenance link.
22
+ */
23
+ export declare function splitResultByCategory(result: ReverieResult, reveriePairsPath: string): SplitResult;
24
+ /**
25
+ * Append a behavioral ReverieResult to a reverie-pairs.jsonl audit log
26
+ * at the supplied absolute filePath. Parent directory created via
27
+ * mkdirSync(dirname, { recursive: true }) on first call. NEVER throws.
28
+ */
29
+ export declare function appendReverieResult(filePath: string, result: ReverieResult, logger: LoggerLike): Promise<void>;
30
+ /**
31
+ * Append a safety ReverieResult to a reverie-safety-flags.jsonl audit
32
+ * log at the supplied absolute filePath. NEVER co-mingled with
33
+ * behavioral corpus per amendment. NEVER throws.
34
+ */
35
+ export declare function appendSafetyFlag(filePath: string, result: ReverieResult, logger: LoggerLike): Promise<void>;
36
+ //# sourceMappingURL=pair-sink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pair-sink.d.ts","sourceRoot":"","sources":["../src/pair-sink.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EACrB,gBAAgB,EAAE,MAAM,GACvB,WAAW,CA6Db;AAID;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CAWf"}
@@ -0,0 +1,132 @@
1
+ // @agencer/reverie-loop pair-sink module.
2
+ //
3
+ // Leg G-3b: extracted from packages/server/src/brain/reverie-pair-sink.ts
4
+ // (189 LOC). Triple-discriminated sink for ReverieResult per the Day 159
5
+ // Betley emergent-misalignment safety amendment.
6
+ //
7
+ // Sacred constraint (Law 8, declared in README): No process.env or
8
+ // os.homedir() reads inside this module. The Lego accepts explicit
9
+ // absolute file paths via the function arguments; the compatibility
10
+ // shim at packages/server/src/brain/reverie-pair-sink.ts (until G-6)
11
+ // and the agencer-ox composition root (post G-5) resolve
12
+ // ~/.operative-x/logs/* paths from os.homedir().
13
+ //
14
+ // Routing (locked observable contract):
15
+ // - safety_concern pairs -> safety record (schema "reverie-safety-flag-v1")
16
+ // - all other categories -> behavioral record (schema "reverie-pair-v1")
17
+ // - empty pairs[] -> behavioral file (audit trail entry)
18
+ // - mixed: behavioral keeps full cost; safety twin carries
19
+ // cost_usd: 0 + cost_attributed_to provenance link (C-1 Option B)
20
+ // - pure safety: cost stays on the safety record (no behavioral twin)
21
+ //
22
+ // CRITICAL: sink functions NEVER throw.
23
+ import fs from "node:fs";
24
+ import path from "node:path";
25
+ import { REVERIE_PAIR_SCHEMA_VERSION, REVERIE_SAFETY_FLAG_SCHEMA_VERSION, } from "./opus-client.js";
26
+ /**
27
+ * Split a ReverieResult into behavioral and safety partitions per
28
+ * pair category. Routing locked per amendment Day 159.
29
+ *
30
+ * `reveriePairsPath` is the absolute path of the behavioral JSONL
31
+ * file. It is recorded as `cost_attributed_to` on the safety twin in
32
+ * the mixed-cohort case (C-1 Option B): downstream tooling
33
+ * (ox-data-factory, constitutional pipeline) reads the link to join
34
+ * cost across the split write.
35
+ *
36
+ * Consumers that don't care about the provenance link (pure-safety or
37
+ * pure-behavioral cohorts never read it) can pass any non-empty
38
+ * string. The Lego does not validate or open the path; that's the
39
+ * writer's responsibility (appendReverieResult). Empty string is
40
+ * accepted but yields a useless provenance link.
41
+ */
42
+ export function splitResultByCategory(result, reveriePairsPath) {
43
+ const safetyPairs = [];
44
+ const behavioralPairs = [];
45
+ for (const p of result.pairs) {
46
+ if (p.category === "safety_concern") {
47
+ safetyPairs.push(p);
48
+ }
49
+ else {
50
+ behavioralPairs.push(p);
51
+ }
52
+ }
53
+ // Empty pairs[]: default to behavioral file. Preserves the audit
54
+ // trail (jsonl entry per Anthropic call) regardless of content.
55
+ if (result.pairs.length === 0) {
56
+ return {
57
+ behavioral: { ...result, schema_version: REVERIE_PAIR_SCHEMA_VERSION },
58
+ safety: null,
59
+ };
60
+ }
61
+ // Pure non-safety: single behavioral write.
62
+ if (safetyPairs.length === 0) {
63
+ return {
64
+ behavioral: {
65
+ ...result,
66
+ schema_version: REVERIE_PAIR_SCHEMA_VERSION,
67
+ pairs: behavioralPairs,
68
+ },
69
+ safety: null,
70
+ };
71
+ }
72
+ // Pure safety: single safety write. Cost stays on this record (no
73
+ // behavioral twin to attribute to).
74
+ if (behavioralPairs.length === 0) {
75
+ return {
76
+ behavioral: null,
77
+ safety: {
78
+ ...result,
79
+ schema_version: REVERIE_SAFETY_FLAG_SCHEMA_VERSION,
80
+ pairs: safetyPairs,
81
+ },
82
+ };
83
+ }
84
+ // Mixed: split. Behavioral carries full cost. Safety carries 0
85
+ // cost + cost_attributed_to provenance link (C-1 Option B).
86
+ return {
87
+ behavioral: {
88
+ ...result,
89
+ schema_version: REVERIE_PAIR_SCHEMA_VERSION,
90
+ pairs: behavioralPairs,
91
+ },
92
+ safety: {
93
+ ...result,
94
+ schema_version: REVERIE_SAFETY_FLAG_SCHEMA_VERSION,
95
+ pairs: safetyPairs,
96
+ cost_usd: 0,
97
+ cost_attributed_to: reveriePairsPath,
98
+ },
99
+ };
100
+ }
101
+ // ── jsonl writers ────────────────────────────────────────────────
102
+ /**
103
+ * Append a behavioral ReverieResult to a reverie-pairs.jsonl audit log
104
+ * at the supplied absolute filePath. Parent directory created via
105
+ * mkdirSync(dirname, { recursive: true }) on first call. NEVER throws.
106
+ */
107
+ export async function appendReverieResult(filePath, result, logger) {
108
+ try {
109
+ const dir = path.dirname(filePath);
110
+ fs.mkdirSync(dir, { recursive: true });
111
+ fs.appendFileSync(filePath, JSON.stringify(result) + "\n");
112
+ }
113
+ catch (err) {
114
+ logger.warn({ err: err instanceof Error ? err.message : String(err), filePath }, "reverie-pair-sink.appendReverieResult failed");
115
+ }
116
+ }
117
+ /**
118
+ * Append a safety ReverieResult to a reverie-safety-flags.jsonl audit
119
+ * log at the supplied absolute filePath. NEVER co-mingled with
120
+ * behavioral corpus per amendment. NEVER throws.
121
+ */
122
+ export async function appendSafetyFlag(filePath, result, logger) {
123
+ try {
124
+ const dir = path.dirname(filePath);
125
+ fs.mkdirSync(dir, { recursive: true });
126
+ fs.appendFileSync(filePath, JSON.stringify(result) + "\n");
127
+ }
128
+ catch (err) {
129
+ logger.warn({ err: err instanceof Error ? err.message : String(err), filePath }, "reverie-pair-sink.appendSafetyFlag failed");
130
+ }
131
+ }
132
+ //# sourceMappingURL=pair-sink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pair-sink.js","sourceRoot":"","sources":["../src/pair-sink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import type { CostCalculator, LoggerLike, ReverieInferenceProvider, ReverieUserContext, UsageMeter } from "./contracts.js";
2
+ import { type ReverieResult as ReverieResultReal, type ConversationExchange as OpusConversationExchange } from "./opus-client.js";
3
+ export type ConversationExchange = OpusConversationExchange;
4
+ export interface ReverieObservationLegacy {
5
+ exchange_index: number;
6
+ helpfulness: number;
7
+ in_character: number;
8
+ user_corrected: boolean;
9
+ correction: string | null;
10
+ lesson: string;
11
+ }
12
+ export interface ReverieResultLegacy {
13
+ sessionId: string;
14
+ timestamp: string;
15
+ observations: ReverieObservationLegacy[];
16
+ summary: string;
17
+ }
18
+ export type ReverieResult = ReverieResultLegacy;
19
+ export type ReverieObservation = ReverieObservationLegacy;
20
+ /** Per-invocation dependency bundle. Real-path fields and path config
21
+ * are required; forceMock is optional (default false).
22
+ *
23
+ * When forceMock is true, the legacy mock path runs:
24
+ * - reads only `logger` (for warnings) + `legacyReverieLogPath`
25
+ * - never invokes `inferenceProvider`, `meter`, `costCalculator`
26
+ * Consumers exercising the legacy mock path may pass stub
27
+ * implementations for the unused fields; they will not be called. */
28
+ export interface ReverieDeps {
29
+ inferenceProvider: ReverieInferenceProvider;
30
+ meter: UsageMeter;
31
+ costCalculator: CostCalculator;
32
+ userContext: ReverieUserContext;
33
+ logger: LoggerLike;
34
+ /** Absolute path. Behavioral correction-pair JSONL audit log
35
+ * written by the real path. Recorded as `cost_attributed_to`
36
+ * provenance on the safety twin in mixed cohorts. */
37
+ reveriePairsPath: string;
38
+ /** Absolute path. Safety-concern JSONL audit log written by the
39
+ * real path. NEVER co-mingled with the behavioral file per the
40
+ * Day 159 Betley amendment. */
41
+ reverieSafetyFlagsPath: string;
42
+ /** Absolute path. Legacy mock JSONL audit log written by the
43
+ * legacy mock path (test scaffolding). The real path does NOT
44
+ * write here. */
45
+ legacyReverieLogPath: string;
46
+ /** When true, force the legacy mock path even with real-path deps
47
+ * wired. Composition root reads `process.env["MOCK_REVERIE"]`
48
+ * and threads it in. Default false. */
49
+ forceMock?: boolean;
50
+ }
51
+ /**
52
+ * Trigger a reverie for a session. Debounced by 10 seconds to avoid
53
+ * firing on quick reconnects.
54
+ *
55
+ * Always takes a `deps` argument (forceMock toggles the path). The
56
+ * pre-Leg-G no-deps overload is preserved on the agencer-ox
57
+ * compatibility shim only.
58
+ */
59
+ export declare function triggerReverie(sessionId: string, getHistory: () => ConversationExchange[], deps: ReverieDeps): void;
60
+ /**
61
+ * Execute reverie immediately.
62
+ *
63
+ * Real path when deps.forceMock is false/undefined; legacy mock path
64
+ * when deps.forceMock is true. Return type is the union; consumers
65
+ * with specific knowledge can narrow via the forceMock flag or by
66
+ * runtime shape check (`"pairs" in result` discriminates real vs
67
+ * legacy).
68
+ */
69
+ export declare function executeReverie(sessionId: string, history: ConversationExchange[], deps: ReverieDeps): Promise<ReverieResultLegacy | ReverieResultReal | null>;
70
+ /**
71
+ * Most recent reverie result (legacy shape; test scaffolding).
72
+ */
73
+ export declare function getLastReverie(): ReverieResultLegacy | null;
74
+ /**
75
+ * Most recent real-path reverie result. Used by tests of the real
76
+ * path; production callers should consume the jsonl audit logs.
77
+ */
78
+ export declare function getLastReverieReal(): ReverieResultReal | null;
79
+ /**
80
+ * Cancel all pending reverie timers (shutdown / test teardown).
81
+ */
82
+ export declare function cancelAllReveries(): void;
83
+ //# sourceMappingURL=reverie-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverie-loop.d.ts","sourceRoot":"","sources":["../src/reverie-loop.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,KAAK,aAAa,IAAI,iBAAiB,EACvC,KAAK,oBAAoB,IAAI,wBAAwB,EACtD,MAAM,kBAAkB,CAAC;AAW1B,MAAM,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAI5D,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,wBAAwB,EAAE,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD,MAAM,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAChD,MAAM,MAAM,kBAAkB,GAAG,wBAAwB,CAAC;AAI1D;;;;;;;sEAOsE;AACtE,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,KAAK,EAAE,UAAU,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,EAAE,UAAU,CAAC;IAEnB;;0DAEsD;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB;;oCAEgC;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;sBAEkB;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;4CAEwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAYD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,oBAAoB,EAAE,EACxC,IAAI,EAAE,WAAW,GAChB,IAAI,CAcN;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,oBAAoB,EAAE,EAC/B,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,mBAAmB,GAAG,iBAAiB,GAAG,IAAI,CAAC,CAQzD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,mBAAmB,GAAG,IAAI,CAE3D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,iBAAiB,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC"}