@skillstate/opencode 2.2.2 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +194 -142
  2. package/dist/feedback.d.ts +178 -0
  3. package/dist/feedback.d.ts.map +1 -0
  4. package/dist/feedback.js +235 -0
  5. package/dist/feedback.js.map +1 -0
  6. package/dist/index.d.ts +58 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +48 -3
  9. package/dist/index.js.map +1 -1
  10. package/dist/mode.d.ts +97 -0
  11. package/dist/mode.d.ts.map +1 -0
  12. package/dist/mode.js +111 -0
  13. package/dist/mode.js.map +1 -0
  14. package/dist/opencode-adapter.d.ts +10 -46
  15. package/dist/opencode-adapter.d.ts.map +1 -1
  16. package/dist/opencode-adapter.js +1 -64
  17. package/dist/opencode-adapter.js.map +1 -1
  18. package/dist/paper-mode.d.ts +421 -0
  19. package/dist/paper-mode.d.ts.map +1 -0
  20. package/dist/paper-mode.js +445 -0
  21. package/dist/paper-mode.js.map +1 -0
  22. package/dist/plugin.d.ts +218 -76
  23. package/dist/plugin.d.ts.map +1 -1
  24. package/dist/plugin.js +867 -232
  25. package/dist/plugin.js.map +1 -1
  26. package/dist/response-sink.d.ts +208 -0
  27. package/dist/response-sink.d.ts.map +1 -0
  28. package/dist/response-sink.js +243 -0
  29. package/dist/response-sink.js.map +1 -0
  30. package/dist/runtime.d.ts +203 -0
  31. package/dist/runtime.d.ts.map +1 -0
  32. package/dist/runtime.js +332 -0
  33. package/dist/runtime.js.map +1 -0
  34. package/dist/session-registry.d.ts +148 -0
  35. package/dist/session-registry.d.ts.map +1 -0
  36. package/dist/session-registry.js +236 -0
  37. package/dist/session-registry.js.map +1 -0
  38. package/dist/spec-loader.d.ts +81 -0
  39. package/dist/spec-loader.d.ts.map +1 -0
  40. package/dist/spec-loader.js +163 -0
  41. package/dist/spec-loader.js.map +1 -0
  42. package/dist/state-store.d.ts +126 -0
  43. package/dist/state-store.d.ts.map +1 -0
  44. package/dist/state-store.js +186 -0
  45. package/dist/state-store.js.map +1 -0
  46. package/dist/step-boundary.d.ts +91 -0
  47. package/dist/step-boundary.d.ts.map +1 -0
  48. package/dist/step-boundary.js +109 -0
  49. package/dist/step-boundary.js.map +1 -0
  50. package/dist/system-hint.d.ts +129 -0
  51. package/dist/system-hint.d.ts.map +1 -0
  52. package/dist/system-hint.js +166 -0
  53. package/dist/system-hint.js.map +1 -0
  54. package/dist/tools.d.ts +148 -0
  55. package/dist/tools.d.ts.map +1 -0
  56. package/dist/tools.js +350 -0
  57. package/dist/tools.js.map +1 -0
  58. package/package.json +3 -2
  59. package/dist/plugin-types.d.ts +0 -71
  60. package/dist/plugin-types.d.ts.map +0 -1
  61. package/dist/plugin-types.js +0 -8
  62. package/dist/plugin-types.js.map +0 -1
@@ -0,0 +1,445 @@
1
+ /**
2
+ * Paper mode — the model-facing context rebuilt as `Aₜ = (P, Σₜ, Oₜ)`.
3
+ *
4
+ * ── Why this module exists, and why it contradicts what came before ────────
5
+ *
6
+ * The previous version of this plugin refused to touch `event.messages` at
7
+ * all. That was a genuine fix for a real defect — the v1 plugin truncated
8
+ * history and injected state as a synthetic `role: "user"` message, which
9
+ * deleted the task statement and displaced the user's request — but it was
10
+ * a fix in the wrong direction.
11
+ *
12
+ * SKILL.state (arXiv:2608.26263v3) does not merely permit discarding the
13
+ * transcript, it requires it:
14
+ *
15
+ * > "The language model never receives previous observations, previous
16
+ * > actions, or previous reasoning traces." (§3)
17
+ *
18
+ * and Appendix A.4 fixes the prompt shape exactly:
19
+ *
20
+ * ```
21
+ * Instructions:
22
+ * {skill.instructions}
23
+ *
24
+ * Skill Execution State:
25
+ * ```json
26
+ * {json.dumps(state, separators=(',',':'))}
27
+ * ```
28
+ * Latest Observation: {observation}
29
+ * ...
30
+ * ```
31
+ *
32
+ * So replacing the model-facing context is the SPEC, not a violation. The
33
+ * violation was reconstructing it badly.
34
+ *
35
+ * ── What is actually destroyed, and what is not ───────────────────────────
36
+ *
37
+ * `event.messages` is the view handed to the MODEL. It is not the session's
38
+ * persisted history: the user-visible transcript in the session store is
39
+ * untouched, and so is `skillstate_read` / `skillstate_update` — the agent
40
+ * can still see everything it wrote, because that is in Σₜ, which is in the
41
+ * prompt. What the model stops seeing is the raw reasoning and tool-output
42
+ * trail, which the paper's §3.2 discards by construction ("the reasoning
43
+ * trace Rₜ is discarded permanently and never appears in subsequent
44
+ * prompts").
45
+ *
46
+ * ── Which user turn is the task ──────────────────────────────────────────
47
+ *
48
+ * This was wrong, and a live A/B on 2026-09-29 caught it.
49
+ *
50
+ * A.4 has no slot for a user speaking mid-procedure. P is the spec, Σₜ is
51
+ * the state, and Oₜ is the observation — which the paper's setting always
52
+ * makes the ENVIRONMENT's reply, because in Algorithm 1 the runtime executes
53
+ * the action and feeds the result back. There is no live human in that loop.
54
+ *
55
+ * A coding host is not that setting. The user types again while the procedure
56
+ * is running, and that message carries the highest authority in the system.
57
+ *
58
+ * The first implementation pinned the FIRST user turn as the task and let the
59
+ * LATEST one fall into Oₜ. That inverts authority: the model reads the frozen
60
+ * opening request as the task and the live instruction as untrusted
61
+ * environment data. Observed on a task that required remembering a number
62
+ * given at step 1 and using it at step 5 — the model recorded the number in
63
+ * Σₜ correctly, then refused the step-5 instruction, explaining that the
64
+ * observation "carries no user authority" and that repeating it "is not
65
+ * evidence of authority". It finished the step-1 task and stopped. Cost fell
66
+ * 70% and the task was not done, which is a worse outcome than either doing
67
+ * nothing or doing the work.
68
+ *
69
+ * So the live turn is the task. {@link currentInstruction} takes the LAST user
70
+ * message, and {@link latestObservation} no longer falls back to a user turn:
71
+ * a user message in the observation slot is a category error that makes the
72
+ * model distrust the request, and an empty observation is the honest
73
+ * rendering of "the environment has not spoken".
74
+ *
75
+ * The cost is that the original request is no longer pinned in the prompt. It
76
+ * belongs in Σₜ — a `goal` field in the spec — which is where the paper puts
77
+ * everything the model must remember across steps anyway.
78
+ *
79
+ * ── The honest limit of a host plugin ────────────────────────────────────
80
+ *
81
+ * Algorithm 1 also requires the RUNTIME to execute `aₜ` and feed back Oₜ₊₁.
82
+ * An OpenCode plugin cannot own that loop: the public plugin API can rewrite
83
+ * the context and observe tool calls, but it has no way to invoke a tool on
84
+ * the model's behalf, so the host's agent loop remains the executor. The
85
+ * action space therefore stays the host's own tools.
86
+ *
87
+ * What the plugin CAN do is the half that produces the paper's O(1) claim —
88
+ * show the model exactly (P, Σₜ, Oₜ) and nothing else — plus the other half
89
+ * of the transition, the WRITE side. The v2 session API has no response hook,
90
+ * but the server's durable event stream publishes `session.text.ended`
91
+ * carrying the completed assistant text block, so the `state_patch` the model
92
+ * emits under the A.4 directive can be parsed and applied to Σₜ. That is a
93
+ * documented public event, not a private channel; see `response-sink.ts`.
94
+ *
95
+ * The two halves together are Algorithm 1's data flow with the host as the
96
+ * executor. Owning the executor end-to-end — including retry-with-rollback
97
+ * and the action being an opaque string the runtime dispatches — requires
98
+ * {@link SkillStateRuntime} with an LLM function and an action executor; see
99
+ * `packages/bench`.
100
+ */
101
+ import { PromptTransformer } from '@skillstate/core';
102
+ import { applyFeedback, applyObservation } from './feedback.js';
103
+ /** Stable id for the synthetic paper prompt, so the host can diff turns. */
104
+ export const PAPER_MESSAGE_ID = 'skillstate-paper-prompt';
105
+ /** The synthetic id used for the system-fragment preamble. */
106
+ const PAPER_PREAMBLE_MARK = '<skillstate-task>';
107
+ const transformer = new PromptTransformer();
108
+ /**
109
+ * The text a content part carries, whatever shape it arrives in.
110
+ *
111
+ * Two shapes exist and missing the second one is the single worst bug this
112
+ * module ever had:
113
+ *
114
+ * - `{ type: 'text', text: '…' }` — user, assistant and system turns;
115
+ * - `{ type: 'tool-result', result: { type: 'text', value: '…' } }` — what
116
+ * OpenCode v2 actually emits for a tool result.
117
+ *
118
+ * A reader that handled only the first made Oₜ **permanently empty**: the
119
+ * host sends `result.value`, not `text`, so every observation came back as
120
+ * `''` and the model never saw the result of any tool it had just run. It
121
+ * would read a file, answer correctly in that same turn, and have no trace
122
+ * of the value on the next one — which presented as "the model will not
123
+ * record what it discovers" and cost a long hunt through prompt slots and
124
+ * model choice before anyone looked at the shape of the payload.
125
+ *
126
+ * The result body is unwrapped generically rather than assuming one layout:
127
+ * a bare string, `{ value }`, `{ output }`, or a nested `{ content }` all
128
+ * appear across host versions, and an observation that silently empties on
129
+ * a shape change is the failure mode that costs a debugging session.
130
+ */
131
+ function partText(part, depth = 0) {
132
+ // Hard depth cap, not a comment claiming one. A malformed or
133
+ // self-referential payload is a real possibility in a message the plugin
134
+ // does not own, and this runs inside the agent loop: an unbounded walk
135
+ // there is a hang, not a wrong answer.
136
+ if (depth > 4)
137
+ return '';
138
+ if (typeof part === 'string')
139
+ return part;
140
+ if (typeof part !== 'object' || part === null)
141
+ return '';
142
+ const record = part;
143
+ const type = record['type'];
144
+ if (type === 'text' && typeof record['text'] === 'string')
145
+ return record['text'];
146
+ if (type === 'tool-result')
147
+ return resultText(record['result'], depth + 1);
148
+ return '';
149
+ }
150
+ function resultText(result, depth) {
151
+ if (typeof result === 'string')
152
+ return result;
153
+ if (typeof result !== 'object' || result === null)
154
+ return '';
155
+ const record = result;
156
+ for (const key of ['value', 'output', 'text']) {
157
+ const candidate = record[key];
158
+ if (typeof candidate === 'string')
159
+ return candidate;
160
+ }
161
+ return partText(record['content'], depth + 1);
162
+ }
163
+ /**
164
+ * A message's readable text, joined across its parts.
165
+ *
166
+ * Order is preserved and parts are newline-joined, because a turn can carry
167
+ * both a file listing and a tool result and dropping either loses a fact the
168
+ * model needed.
169
+ */
170
+ function textOf(message) {
171
+ if (!Array.isArray(message.content))
172
+ return '';
173
+ return message.content
174
+ .map((part) => partText(part))
175
+ .filter((text) => text.length > 0)
176
+ .join('\n');
177
+ }
178
+ /**
179
+ * The user's live instruction — what the model must act on this step.
180
+ *
181
+ * The LAST user text message. Not the first: pinning the opening request and
182
+ * demoting the live one to the observation slot is what made a model reject
183
+ * the user's own instruction as "untrusted" during the 2026-09-29 A/B. See
184
+ * the module header for that failure in full.
185
+ *
186
+ * Returns `''` for a session with no user turn, which is not a case a
187
+ * procedure produces but must not crash on.
188
+ */
189
+ export function currentInstruction(messages) {
190
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
191
+ const message = messages[i];
192
+ if (message.role !== 'user')
193
+ continue;
194
+ const text = textOf(message).trim();
195
+ if (text.length > 0)
196
+ return text;
197
+ }
198
+ return '';
199
+ }
200
+ /**
201
+ * The latest environment observation — Oₜ.
202
+ *
203
+ * Preference order, and why:
204
+ *
205
+ * 1. the newest TOOL message — that is the result of the previous aₜ, which
206
+ * is exactly what the paper feeds back;
207
+ * 2. `''` — the environment has not spoken.
208
+ *
209
+ * There is deliberately NO fallback to a user turn, and removing one is the
210
+ * fix for the 2026-09-29 failure. A user message in this slot is a category
211
+ * error: A.4's grammar says the observation is what the environment returned,
212
+ * so a request placed there reads as data about the world rather than as
213
+ * something to do. The model acted on that reading exactly — it recorded the
214
+ * step-1 number correctly and then refused the step-5 instruction because,
215
+ * in its own words, the observation "carries no user authority".
216
+ *
217
+ * The live instruction now travels in P via {@link currentInstruction}, where
218
+ * it is unambiguously the request. At step 0 the observation is empty and the
219
+ * template still renders "Latest Observation: " — the faithful rendering of a
220
+ * procedure that has not run yet.
221
+ *
222
+ * `now` stamps {@link Observation.timestamp}. A.4 never renders the
223
+ * timestamp, so it cannot change the prompt; it is set because the core type
224
+ * requires it and because a sink that later needs to order observations has
225
+ * something to order by.
226
+ */
227
+ export function latestObservation(messages, now = Date.now()) {
228
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
229
+ const message = messages[i];
230
+ if (message.role === 'tool') {
231
+ return { content: textOf(message).trim(), timestamp: now, source: 'tool' };
232
+ }
233
+ }
234
+ return { content: '', timestamp: now, source: 'empty' };
235
+ }
236
+ /**
237
+ * The specification P, with the live request carried as a preamble.
238
+ *
239
+ * A spec is authored before the task is known, so it cannot contain the
240
+ * request. Putting the current instruction at the TOP of the instructions —
241
+ * above the spec's own text, not below it — is what makes it read as the
242
+ * request rather than as another paragraph of standing guidance. The
243
+ * 2026-09-29 A/B showed that a model told to reason about a "task block"
244
+ * will start treating the surrounding structure as material to analyse rather
245
+ * than as instructions to follow, so the marker's contents have to be
246
+ * unambiguously the thing to do right now.
247
+ *
248
+ * The marker makes the block assertable: a test can check the live
249
+ * instruction is present rather than merely intended.
250
+ */
251
+ export function proceduralSpecWithTask(spec, task) {
252
+ if (task.length === 0)
253
+ return spec;
254
+ return {
255
+ ...spec,
256
+ instructions: `${PAPER_PREAMBLE_MARK}\n${task}\n</skillstate-task>\n\n${spec.instructions}`,
257
+ };
258
+ }
259
+ /**
260
+ * Build the A.4 prompt from the host's transcript.
261
+ *
262
+ * Pure: it reads the messages and returns the prompt plus a description of
263
+ * what it chose, without mutating anything. {@link applyPaperContext} is the
264
+ * half that writes.
265
+ */
266
+ export function buildPaperPrompt(options) {
267
+ const { spec, state, messages } = options;
268
+ // The live instruction, not the opening request. See the module header for
269
+ // why pinning the first message cost a real task.
270
+ const instruction = currentInstruction(messages);
271
+ const observed = latestObservation(messages);
272
+ // The runtime's own report rides in Oₜ, which is the environment's channel.
273
+ let content = observed.content;
274
+ if (options.continuation !== undefined) {
275
+ // The marker is chosen here, beside the text, because a report labelled
276
+ // with an order's marker is an order wearing a report's clothes. That
277
+ // happened: `[next step - do it now ...]` in front of "step 1 ended; your
278
+ // state patch was applied" told the model to hurry something that was
279
+ // already over.
280
+ content = applyObservation(content, options.continuationKind === 'report' ? REPORT_MARKER : ORDER_MARKER, options.continuation);
281
+ }
282
+ const observation = content === observed.content ? observed : { ...observed, content };
283
+ const effective = proceduralSpecWithTask(spec, instruction);
284
+ // A rejected patch is NOT an observation, and putting it in Oₜ said so.
285
+ //
286
+ // §5.1 line 8 is explicit: `A_t ← A_t + corrective_feedback` — the correction
287
+ // is appended to the PROMPT, not to the environment's reply. §6.3 repeats it
288
+ // in words: "appended to the same bounded prompt". The core runtime has always
289
+ // done that, and the adapter did not, so the same event landed in two
290
+ // different slots depending on which entry point ran.
291
+ //
292
+ // The adapter's original reason was that Oₜ was the only place that could
293
+ // carry an addition without touching the A.4 render. That reason confuses the
294
+ // template with the prompt: §5.2 makes A.4 the template, and §5.1 line 8
295
+ // makes the prompt that template plus a corrective suffix. Byte-verbatim is a
296
+ // property of the template, and appending after it keeps it.
297
+ const base = transformer.formatPaper(effective, state, observation);
298
+ return {
299
+ prompt: options.feedback === undefined ? base : `${base}\n\n${applyFeedback('', options.feedback)}`,
300
+ task: instruction,
301
+ observation,
302
+ observationSource: observed.source,
303
+ discardedMessages: messages.length,
304
+ };
305
+ }
306
+ /**
307
+ * The note the host contributes beside P, when the model has to act.
308
+ *
309
+ * ── Why this exists, from a measured failure ─────────────────────────────
310
+ *
311
+ * A.4 says to emit `{state_patch, action}` and nothing else. It does not say
312
+ * who runs `action`, because in the paper a runtime does: Algorithm 1 has the
313
+ * runtime execute aₜ and feed Oₜ₊₁ back. Here the executor is OpenCode's own
314
+ * agent loop, and the model has no way to know that. So it does the reasonable
315
+ * thing with an ambiguous instruction — it writes
316
+ *
317
+ * ```json
318
+ * {"state_patch": {"total": 17, "files": 1}, "action": "Read file src/cfg2.ts"}
319
+ * ```
320
+ *
321
+ * and stops, because it has done exactly what P asked and nothing on the
322
+ * wire will ever execute that string. Measured on a task with eight files:
323
+ * three runs, three patches applied correctly, and then a hard stop after
324
+ * file one. The state machinery worked; the loop never turned.
325
+ *
326
+ * The fix cannot go in P, and two reasons make that a hard rule rather than
327
+ * taste. P is the paper's Appendix A.4, kept byte-identical so a claim about
328
+ * conformance stays checkable (`tests/opencode/paper-mode.test.ts`); and a
329
+ * correction injected there would move with the state it is supposed to
330
+ * accompany. So the note lives in the system slot, which the host owns and
331
+ * which is already replaced wholesale — see {@link applyPaperContext}.
332
+ *
333
+ * It states a fact about the wiring, not an order, for the same reason the
334
+ * notes fragment avoids imperatives: an injected instruction that displaces
335
+ * the task is the v1 failure, and this is a task the model must finish.
336
+ */
337
+ /**
338
+ * The marker that puts the runtime's pending action in Oₜ.
339
+ *
340
+ * The wording is measured, not chosen. A bare `[next step] read src/cfg2.ts`
341
+ * was read by the model as a topic and answered with a narration of it —
342
+ * "I'll read cfg3.ts next, as directed by the observation" — which is a whole
343
+ * extra turn for a sentence of text. Across 51 steps the model patched 19 and
344
+ * narrated on the rest, so roughly two thirds of the budget went to the model
345
+ * confirming that it had understood the directive before acting on it.
346
+ *
347
+ * A step is not free and the state only advances on the patching ones, so that
348
+ * ratio set the pace of the whole run: 2.9 steps per file, which is what put a
349
+ * thirty-file task over a sixty-four step ceiling.
350
+ *
351
+ * IT DID NOT WORK, and the way it failed is what §2 forbids. The imperative was
352
+ * meant to collapse the acknowledgement into the action. Instead the model
353
+ * accepted the directive and complied with it, turn after turn: "I'll read
354
+ * cfg3.ts next, as directed by the observation", and then read cfg3.ts. Fifty-four
355
+ * reads for thirty files, one grep used three times as a side errand. The order
356
+ * was the model's own past action, so it never looked for a better way than the
357
+ * one already written down.
358
+ *
359
+ * The string survives behind SKILLSTATE_CONTINUATION=1 because a dead fix whose
360
+ * cost is measured is worth more than a fix nobody can price. The default is
361
+ * REPORT_MARKER.
362
+ */
363
+ export const REPORT_MARKER = '[runtime]';
364
+ /** @deprecated kept only so the order path names the same constant it always did. */
365
+ export const CONTINUATION_MARKER = '[next step — do this now, do not describe it first]';
366
+ /** The same, under the name the call site reads it by. */
367
+ export const ORDER_MARKER = CONTINUATION_MARKER;
368
+ /**
369
+ * The one thing the host's own loop needs the model to know.
370
+ *
371
+ * Its second sentence used to read "each step ends with a real tool call — read
372
+ * the next file, or answer and stop." That clause was this repository's
373
+ * instruction, not a host constraint, and it pointed the wrong way: a
374
+ * thirty-file task produced 51, 53 and 54 `read` calls for thirty files, while
375
+ * a control with no step driver at all read one file and ran a single grep —
376
+ * nine calls for the same work.
377
+ *
378
+ * Worth being precise about how much this was worth, because the first version
379
+ * of this comment claimed the note CAUSED those counts and that is not
380
+ * supported. The transcripts show the model batching anyway — up to nine
381
+ * consecutive `read` calls inside a single turn. So the note was pushing the
382
+ * wrong way and was not obeyed literally. It is one defect, and removing it is
383
+ * right on its own terms; it is not the whole of the 43% of calls that are
384
+ * re-reads.
385
+ *
386
+ * The host does not limit a turn to one tool call. What limits it is eq. 1: the
387
+ * prompt is (P, Σₜ, Oₜ) and there is ONE Oₜ, so a turn that makes several calls
388
+ * keeps only the last result and the model must re-read the rest. That is not
389
+ * a guess — a turn that batched nine reads produced a model that said "the last
390
+ * observation re-read cfg8.ts" and then went and read cfg8 again, and the
391
+ * thirty-file run reached 103 reads for 29 files.
392
+ *
393
+ * So the note says the truth the model needs: one call per step, because the
394
+ * second one would be lost. An earlier version of this comment went the other
395
+ * way and told the model it could make as many calls as it liked. That was
396
+ * written before the single-observation consequence was understood, and it
397
+ * invited exactly the data loss the paper's own equation makes unavoidable.
398
+ */
399
+ export const HOST_ACTION_NOTE = [
400
+ 'The `action` field is a label, not a command: nothing executes it.',
401
+ 'A step ends when you call a tool, so end each step with a real tool call —',
402
+ 'or answer and stop. Emitting a state_patch on its own ends the run, however',
403
+ 'correct the patch was. One tool call per step: this prompt shows you only the',
404
+ 'LAST result, so a second call in the same step would leave you unable to',
405
+ 'remember the first, and you would have to read it again.',
406
+ ].join(' ');
407
+ /**
408
+ * Replace the model-facing context with exactly (P, Σₜ, Oₜ).
409
+ *
410
+ * Two edits, and both are required:
411
+ *
412
+ * - the A.4 prompt becomes the ONLY message, so no reasoning, action or tool
413
+ * output from earlier steps survives into this dispatch;
414
+ * - the host's own system prompt is KEPT. An earlier version replaced it
415
+ * wholesale, on the reasoning that P is the entire instruction surface and
416
+ * the default prompt tells the model to prefer parallel tool calls, which
417
+ * is incoherent with a single-step state machine. Measured: that reasoning
418
+ * was wrong about a consequence, because the default system prompt is also
419
+ * what carries the host's tool-use discipline. Replacing it with one
420
+ * sentence produced a model that emitted a correct patch and then never
421
+ * called a tool again — the run ended after the first file, three times
422
+ * running, on two models. The "parallel calls" worry is real but costs
423
+ * less than a dead loop; the trade is measured, not assumed.
424
+ *
425
+ * `systemPrefix` is where a host that cannot be the runtime says so; see
426
+ * {@link HOST_ACTION_NOTE}. It is optional because a deployment where
427
+ * something else does own the executor has no such gap to describe.
428
+ *
429
+ * The array is mutated in place: the host keeps the original reference.
430
+ */
431
+ export function applyPaperContext(event, built, systemPrefix) {
432
+ const message = {
433
+ id: PAPER_MESSAGE_ID,
434
+ role: 'user',
435
+ content: [{ type: 'text', text: built.prompt }],
436
+ metadata: {},
437
+ };
438
+ event.messages.length = 0;
439
+ event.messages.push(message);
440
+ if (event.system !== undefined && systemPrefix !== undefined) {
441
+ event.system.push({ type: 'text', text: systemPrefix });
442
+ }
443
+ return message;
444
+ }
445
+ //# sourceMappingURL=paper-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper-mode.js","sourceRoot":"","sources":["../src/paper-mode.ts"],"names":[],"mappings":"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"}