@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.
- package/CHANGELOG.md +148 -69
- package/LICENSE +8 -199
- package/README.md +118 -56
- package/dist/contracts.d.ts +161 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +28 -0
- package/dist/contracts.js.map +1 -0
- package/dist/index.d.ts +12 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -4
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +47 -21
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +44 -107
- package/dist/logger.js.map +1 -0
- package/dist/opus-client.d.ts +60 -0
- package/dist/opus-client.d.ts.map +1 -0
- package/dist/opus-client.js +301 -0
- package/dist/opus-client.js.map +1 -0
- package/dist/pair-sink.d.ts +36 -0
- package/dist/pair-sink.d.ts.map +1 -0
- package/dist/pair-sink.js +132 -0
- package/dist/pair-sink.js.map +1 -0
- package/dist/reverie-loop.d.ts +83 -0
- package/dist/reverie-loop.d.ts.map +1 -0
- package/dist/reverie-loop.js +216 -0
- package/dist/reverie-loop.js.map +1 -0
- package/dist/reverie-trigger.d.ts +67 -0
- package/dist/reverie-trigger.d.ts.map +1 -0
- package/dist/reverie-trigger.js +271 -0
- package/dist/reverie-trigger.js.map +1 -0
- package/package.json +43 -12
- package/dist/compat.d.ts +0 -22
- package/dist/compat.js +0 -81
- package/dist/types.d.ts +0 -34
- package/dist/types.js +0 -8
|
@@ -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":"AAAA,4CAA4C;AAC5C,EAAE;AACF,4EAA4E;AAC5E,wEAAwE;AACxE,uEAAuE;AACvE,+BAA+B;AAC/B,EAAE;AACF,wDAAwD;AACxD,yFAAyF;AACzF,2EAA2E;AAC3E,6CAA6C;AAC7C,0GAA0G;AAC1G,mFAAmF;AACnF,2EAA2E;AAC3E,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AACnE,4CAA4C;AAC5C,EAAE;AACF,oCAAoC;AACpC,sDAAsD;AACtD,oEAAoE;AACpE,0EAA0E;AAC1E,oGAAoG;AACpG,sFAAsF;AACtF,iDAAiD;AACjD,yEAAyE;AACzE,0EAA0E;AAC1E,iDAAiD;AAUjD,oEAAoE;AAEpE,iEAAiE;AACjE,2EAA2E;AAC3E,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAE/D,2DAA2D;AAC3D,MAAM,CAAC,MAAM,2BAA2B,GAAG,iBAA0B,CAAC;AACtE,MAAM,CAAC,MAAM,kCAAkC,GAC7C,wBAAiC,CAAC;AAEpC,oEAAoE;AACpE,oEAAoE;AACpE,mEAAmE;AACnE,MAAM,qBAAqB,GAAG,IAAI,CAAC;AACnC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,oEAAoE;AAEpE,iEAAiE;AACjE,gEAAgE;AAChE,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;0EAoByC,CAAC;AAE3E,SAAS,gBAAgB,CACvB,QAAgB,EAChB,OAA+B;IAE/B,MAAM,SAAS,GAAG,OAAO;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,cAAc,QAAQ;;EAE7B,SAAS,EAAE,CAAC;AACd,CAAC;AAED,0DAA0D;AAC1D,MAAM,CAAC,MAAM,kCAAkC,GAAG,wBAAwB,CAAC;AA2D3E,mEAAmE;AAEnE,MAAM,gBAAgB,GAAiC,IAAI,GAAG,CAAC;IAC7D,eAAe;IACf,WAAW;IACX,aAAa;IACb,WAAW;IACX,gBAAgB;IAChB,OAAO;CACR,CAAC,CAAC;AAYH,MAAM,UAAU,uBAAuB,CACrC,GAAY;IAEZ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IACrE,CAAC;IACD,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAC/D,CAAC;QACD,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,MAAM,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7B,MAAM,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5B,MAAM,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC;QAC/B,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;YAC5E,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ,CAAC,oCAAoC;aACrD,CAAC;QACJ,CAAC;QACD,IACE,OAAO,EAAE,KAAK,QAAQ;YACtB,OAAO,GAAG,KAAK,QAAQ;YACvB,OAAO,GAAG,KAAK,QAAQ;YACvB,OAAO,EAAE,KAAK,QAAQ,EACtB,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ,CAAC,8EAA8E;aAC/F,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAsB,CAAC,EAAE,CAAC;YAC7E,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ,CAAC,sBAAsB,MAAM,CAAC,GAAG,CAAC,EAAE;aACpD,CAAC;QACJ,CAAC;QACD,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;YACtB,IAAI,GAAG,CAAC;YACR,IAAI,GAAG,CAAC,EACR,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ,CAAC,gCAAgC;aACjD,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,IAAI,CAAC;YACP,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,GAAsB;YAChC,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC;AAcD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAA2B;IAE3B,MAAM,EACJ,QAAQ,EACR,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,KAAK,EACL,cAAc,EACd,MAAM,GACP,GAAG,IAAI,CAAC;IACT,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,sEAAsE;IACtE,4CAA4C;IAC5C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,IAAI,OAAwE,CAAC;IAC7E,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,iBAAiB,CAAC,cAAc,CAC9C;YACE,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,wBAAwB;YAChC,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;aAC/D;YACD,UAAU,EAAE,qBAAqB;YACjC,WAAW,EAAE,sBAAsB;SACpC,EACD,UAAU,CAAC,MAAM,CAClB,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CACT;YACE,QAAQ;YACR,UAAU;YACV,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACtD,EACD,wDAAwD,CACzD,CAAC;QACF,gEAAgE;QAChE,sDAAsD;QACtD,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,cAAc,EAAE,2BAA2B;YAC3C,EAAE;YACF,KAAK,EAAE,KAAK;YACZ,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,CAAC;YAChB,QAAQ,EAAE,CAAC;YACX,KAAK,EAAE,EAAE;YACT,UAAU;SACX,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IACrC,MAAM,QAAQ,GAAG,cAAc,CAC7B,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,KAAK,CAAC,YAAY,EAC1B,OAAO,CAAC,KAAK,CAAC,aAAa,CAC5B,CAAC;IAEF,kEAAkE;IAClE,kEAAkE;IAClE,kEAAkE;IAClE,cAAc;IACd,KAAK,CAAC,UAAU,CAAC;QACf,MAAM,EAAE,WAAW,CAAC,MAAM;QAC1B,SAAS,EAAE,WAAW,CAAC,SAAS;QAChC,SAAS,EAAE,4BAA4B;QACvC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY;QACvC,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa;QACzC,SAAS;KACV,CAAC,CAAC;IAEH,kEAAkE;IAClE,kEAAkE;IAClE,+DAA+D;IAC/D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IACjE,MAAM,OAAO,GACX,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ;QAC1E,CAAC,CAAC,SAAS,CAAC,IAAI;QAChB,CAAC,CAAC,EAAE,CAAC;IAET,iEAAiE;IACjE,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;SAChC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,IAAI,EAAE,CAAC;IAEV,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CACT;YACE,QAAQ;YACR,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YACrD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;SAChC,EACD,0DAA0D,CAC3D,CAAC;QACF,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,cAAc,EAAE,2BAA2B;YAC3C,EAAE;YACF,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY;YACxC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa;YAC1C,QAAQ;YACR,KAAK,EAAE,EAAE;YACT,gBAAgB,EAAE,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE;SAC7E,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CACT,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,EACpC,0DAA0D,CAC3D,CAAC;QACF,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,cAAc,EAAE,2BAA2B;YAC3C,EAAE;YACF,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY;YACxC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa;YAC1C,QAAQ;YACR,KAAK,EAAE,EAAE;YACT,gBAAgB,EAAE,SAAS,CAAC,KAAK;SAClC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS,EAAE,QAAQ;QACnB,cAAc,EAAE,2BAA2B;QAC3C,EAAE;QACF,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY;QACxC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa;QAC1C,QAAQ;QACR,KAAK,EAAE,SAAS,CAAC,KAAK;KACvB,CAAC;AACJ,CAAC;AAED,oEAAoE;AAEpE,2DAA2D;AAC3D,gEAAgE;AAChE,qEAAqE;AACrE,gEAAgE;AAChE,iEAAiE;AACjE,kCAAkC;AAClC,EAAE;AACF,iDAAiD;AACjD,8DAA8D;AAC9D,kEAAkE;AAClE,wBAAwB;AACxB,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IACE,GAAG,KAAK,IAAI;QACZ,OAAO,GAAG,KAAK,QAAQ;QACvB,MAAM,IAAI,GAAG;QACb,OAAQ,GAA0B,CAAC,IAAI,KAAK,QAAQ,EACpD,CAAC;QACD,QAAS,GAAwB,CAAC,IAAI,EAAE,CAAC;YACvC,KAAK,YAAY;gBACf,OAAO,MAAM,CAAC;YAChB,KAAK,qBAAqB;gBACxB,OAAO,SAAS,CAAC;YACnB,KAAK,kBAAkB;gBACrB,OAAO,YAAY,CAAC;YACtB,KAAK,oBAAoB;gBACvB,OAAO,QAAQ,CAAC;YAClB,KAAK,eAAe;gBAClB,yDAAyD;gBACzD,gEAAgE;gBAChE,gEAAgE;gBAChE,2DAA2D;gBAC3D,OAAO,SAAS,CAAC;YACnB,KAAK,eAAe;gBAClB,OAAO,SAAS,CAAC;YACnB;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -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"}
|