@amends-dev/harness-opencode 0.0.0-stage → 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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/Opencode2Agent.d.ts +105 -0
  3. package/Opencode2Agent.d.ts.map +1 -0
  4. package/Opencode2Agent.js +72 -0
  5. package/Opencode2Agent.js.map +1 -0
  6. package/OpencodeAgent.d.ts +110 -0
  7. package/OpencodeAgent.d.ts.map +1 -0
  8. package/OpencodeAgent.js +83 -0
  9. package/OpencodeAgent.js.map +1 -0
  10. package/README.md +221 -2
  11. package/index.d.ts +18 -0
  12. package/index.d.ts.map +1 -0
  13. package/index.js +19 -0
  14. package/index.js.map +1 -0
  15. package/internal/agent.d.ts +29 -0
  16. package/internal/agent.d.ts.map +1 -0
  17. package/internal/agent.js +34 -0
  18. package/internal/agent.js.map +1 -0
  19. package/internal/bridge/bunBridge.d.ts +33 -0
  20. package/internal/bridge/bunBridge.d.ts.map +1 -0
  21. package/internal/bridge/bunBridge.js +62 -0
  22. package/internal/bridge/bunBridge.js.map +1 -0
  23. package/internal/bridge/driver.d.ts +81 -0
  24. package/internal/bridge/driver.d.ts.map +1 -0
  25. package/internal/bridge/driver.js +82 -0
  26. package/internal/bridge/driver.js.map +1 -0
  27. package/internal/bridge/hostTools.d.ts +28 -0
  28. package/internal/bridge/hostTools.d.ts.map +1 -0
  29. package/internal/bridge/hostTools.js +41 -0
  30. package/internal/bridge/hostTools.js.map +1 -0
  31. package/internal/bridge/server.d.ts +64 -0
  32. package/internal/bridge/server.d.ts.map +1 -0
  33. package/internal/bridge/server.js +129 -0
  34. package/internal/bridge/server.js.map +1 -0
  35. package/internal/bridge/steps.d.ts +29 -0
  36. package/internal/bridge/steps.d.ts.map +1 -0
  37. package/internal/bridge/steps.js +42 -0
  38. package/internal/bridge/steps.js.map +1 -0
  39. package/internal/bridge/v1/api.d.ts +181 -0
  40. package/internal/bridge/v1/api.d.ts.map +1 -0
  41. package/internal/bridge/v1/api.js +83 -0
  42. package/internal/bridge/v1/api.js.map +1 -0
  43. package/internal/bridge/v1/event.d.ts +597 -0
  44. package/internal/bridge/v1/event.d.ts.map +1 -0
  45. package/internal/bridge/v1/event.js +186 -0
  46. package/internal/bridge/v1/event.js.map +1 -0
  47. package/internal/bridge/v1/main.d.ts +6 -0
  48. package/internal/bridge/v1/main.d.ts.map +1 -0
  49. package/internal/bridge/v1/main.js +8 -0
  50. package/internal/bridge/v1/main.js.map +1 -0
  51. package/internal/bridge/v1/prompt.d.ts +18 -0
  52. package/internal/bridge/v1/prompt.d.ts.map +1 -0
  53. package/internal/bridge/v1/prompt.js +92 -0
  54. package/internal/bridge/v1/prompt.js.map +1 -0
  55. package/internal/bridge/v1/session.d.ts +28 -0
  56. package/internal/bridge/v1/session.d.ts.map +1 -0
  57. package/internal/bridge/v1/session.js +188 -0
  58. package/internal/bridge/v1/session.js.map +1 -0
  59. package/internal/bridge/v1/turn.d.ts +82 -0
  60. package/internal/bridge/v1/turn.d.ts.map +1 -0
  61. package/internal/bridge/v1/turn.js +304 -0
  62. package/internal/bridge/v1/turn.js.map +1 -0
  63. package/internal/bridge/v2/api.d.ts +86 -0
  64. package/internal/bridge/v2/api.d.ts.map +1 -0
  65. package/internal/bridge/v2/api.js +105 -0
  66. package/internal/bridge/v2/api.js.map +1 -0
  67. package/internal/bridge/v2/event.d.ts +539 -0
  68. package/internal/bridge/v2/event.d.ts.map +1 -0
  69. package/internal/bridge/v2/event.js +164 -0
  70. package/internal/bridge/v2/event.js.map +1 -0
  71. package/internal/bridge/v2/main.d.ts +6 -0
  72. package/internal/bridge/v2/main.d.ts.map +1 -0
  73. package/internal/bridge/v2/main.js +8 -0
  74. package/internal/bridge/v2/main.js.map +1 -0
  75. package/internal/bridge/v2/prompt.d.ts +109 -0
  76. package/internal/bridge/v2/prompt.d.ts.map +1 -0
  77. package/internal/bridge/v2/prompt.js +209 -0
  78. package/internal/bridge/v2/prompt.js.map +1 -0
  79. package/internal/bridge/v2/session.d.ts +21 -0
  80. package/internal/bridge/v2/session.d.ts.map +1 -0
  81. package/internal/bridge/v2/session.js +198 -0
  82. package/internal/bridge/v2/session.js.map +1 -0
  83. package/internal/bridge/v2/turn.d.ts +62 -0
  84. package/internal/bridge/v2/turn.d.ts.map +1 -0
  85. package/internal/bridge/v2/turn.js +277 -0
  86. package/internal/bridge/v2/turn.js.map +1 -0
  87. package/internal/models.d.ts +47 -0
  88. package/internal/models.d.ts.map +1 -0
  89. package/internal/models.js +170 -0
  90. package/internal/models.js.map +1 -0
  91. package/internal/template.d.ts +46 -0
  92. package/internal/template.d.ts.map +1 -0
  93. package/internal/template.js +267 -0
  94. package/internal/template.js.map +1 -0
  95. package/package.json +39 -4
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Translates the events of an opencode 1 turn into the parts a harness streams for it, one event at
3
+ * a time, from what the turn has done so far. The translation is pure: the session feeds it the
4
+ * events of its directory in order, from before the turn's prompt, and it reads those of the
5
+ * session's own steps.
6
+ *
7
+ * Each step is an assistant message that starts during the turn; messages that started before it
8
+ * are not the turn's. Text and reasoning stream as opencode streams them, and a call of opencode's
9
+ * own tools streams its input whole once it runs, `providerExecuted`, with the result the model
10
+ * read. Calls of the host's tools are left out, as the relay streams them, and so are the tools
11
+ * opencode answers in JSON or asks questions with. A step that answered in JSON writes the answer
12
+ * as its text. A tool that asks permission streams a `tool-approval-request`. A summary opencode
13
+ * writes of the conversation, as when it outgrows the model's context, is a `compaction`.
14
+ *
15
+ * The turn finishes once opencode stops working on the session, having started to: `finish` then
16
+ * reports the turn's tokens, and the reason its last step ended, or `error` for a turn that failed
17
+ * or took no step.
18
+ */
19
+ import type { StreamPart } from "@amends-dev/harness";
20
+ import type * as Response from "effect/ai/Response";
21
+ import { type Tokens } from "../steps.ts";
22
+ import { type Failure, type SessionEvent } from "./event.ts";
23
+ /** A step of the turn: an assistant message that started during it. */
24
+ interface Step {
25
+ /** Whether the step summarizes the conversation, rather than answering. */
26
+ readonly summary: boolean;
27
+ readonly completed: boolean;
28
+ /** The texts of a summary, by part, which its compaction holds once it completes. */
29
+ readonly summaryTexts: ReadonlyMap<string, string>;
30
+ }
31
+ /** A text or a reasoning the turn is streaming. */
32
+ interface Writing {
33
+ readonly kind: "text" | "reasoning";
34
+ readonly messageID: string;
35
+ /** What the turn has streamed of it. */
36
+ readonly written: string;
37
+ readonly ended: boolean;
38
+ }
39
+ /** A call of one of opencode's own tools, and how much of it the turn has streamed. */
40
+ interface Call {
41
+ readonly name: string;
42
+ readonly called: boolean;
43
+ readonly answered: boolean;
44
+ }
45
+ /** What a turn has done so far, as its events told. */
46
+ export interface Turn {
47
+ /** The opencode session the turn runs in. */
48
+ readonly sessionID: string;
49
+ /** The directory the session works in, which the paths of the files it changes are within. */
50
+ readonly directory: string;
51
+ /** The names opencode gives the host's tools, whose calls the relay streams instead. */
52
+ readonly hostTools: ReadonlySet<string>;
53
+ /** Whether opencode started working on the turn. */
54
+ readonly started: boolean;
55
+ /** The turn's steps, by message id. */
56
+ readonly steps: ReadonlyMap<string, Step>;
57
+ /** The texts and reasonings of the turn's steps, by part id. */
58
+ readonly writing: ReadonlyMap<string, Writing>;
59
+ /** The calls of opencode's own tools, by call id. */
60
+ readonly calls: ReadonlyMap<string, Call>;
61
+ /** The tokens of the turn's completed steps, together. */
62
+ readonly tokens: Tokens;
63
+ /** Why the turn's last completed step ended, before any step has. */
64
+ readonly reason: Response.FinishReason | undefined;
65
+ /** Whether a step streamed an `error` part. */
66
+ readonly failedStep: boolean;
67
+ /** What opencode reported when the turn failed, apart from any step. */
68
+ readonly failure: Failure | undefined;
69
+ /** Whether the turn streamed its `finish` part. Events after it stream nothing. */
70
+ readonly finished: boolean;
71
+ }
72
+ /** A turn in the session `sessionID`, working in `directory`, before any of its events. */
73
+ export declare const initial: (options: {
74
+ readonly sessionID: string;
75
+ readonly directory: string;
76
+ readonly hostTools: ReadonlySet<string>;
77
+ }) => Turn;
78
+ type Translated = readonly [Turn, ReadonlyArray<StreamPart.StreamPart>];
79
+ /** The turn after the next event of its directory, and the parts that event streams. */
80
+ export declare const translate: (turn: Turn, event: SessionEvent) => Translated;
81
+ export {};
82
+ //# sourceMappingURL=turn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../../../../src/internal/bridge/v1/turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,KAAK,QAAQ,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAuC,KAAK,MAAM,EAAW,MAAM,aAAa,CAAA;AACvF,OAAO,EAEL,KAAK,OAAO,EAKZ,KAAK,YAAY,EAElB,MAAM,YAAY,CAAA;AAEnB,uEAAuE;AACvE,UAAU,IAAI;IACZ,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IAEzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAE3B,qFAAqF;IACrF,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnD;AAED,mDAAmD;AACnD,UAAU,OAAO;IACf,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAE1B,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CACxB;AAED,uFAAuF;AACvF,UAAU,IAAI;IACZ,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED,uDAAuD;AACvD,MAAM,WAAW,IAAI;IACnB,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAE1B,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAE1B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAEvC,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IAEzB,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAEzC,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE9C,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAEzC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IAEvB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,GAAG,SAAS,CAAA;IAElD,+CAA+C;IAC/C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAE5B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAA;IAErC,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED,2FAA2F;AAC3F,eAAO,MAAM,OAAO,YAAa;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACxC,KAAG,IAWF,CAAA;AAQF,KAAK,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;AAEvE,wFAAwF;AACxF,eAAO,MAAM,SAAS,SAAU,IAAI,SAAS,YAAY,KAAG,UA2D3D,CAAA"}
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Translates the events of an opencode 1 turn into the parts a harness streams for it, one event at
3
+ * a time, from what the turn has done so far. The translation is pure: the session feeds it the
4
+ * events of its directory in order, from before the turn's prompt, and it reads those of the
5
+ * session's own steps.
6
+ *
7
+ * Each step is an assistant message that starts during the turn; messages that started before it
8
+ * are not the turn's. Text and reasoning stream as opencode streams them, and a call of opencode's
9
+ * own tools streams its input whole once it runs, `providerExecuted`, with the result the model
10
+ * read. Calls of the host's tools are left out, as the relay streams them, and so are the tools
11
+ * opencode answers in JSON or asks questions with. A step that answered in JSON writes the answer
12
+ * as its text. A tool that asks permission streams a `tool-approval-request`. A summary opencode
13
+ * writes of the conversation, as when it outgrows the model's context, is a `compaction`.
14
+ *
15
+ * The turn finishes once opencode stops working on the session, having started to: `finish` then
16
+ * reports the turn's tokens, and the reason its last step ended, or `error` for a turn that failed
17
+ * or took no step.
18
+ */
19
+ import { addTokens, finishReasonOf, noTokens, usageOf } from "../steps.js";
20
+ import { isReasoningPart, isTextPart, isToolPart } from "./event.js";
21
+ /** A turn in the session `sessionID`, working in `directory`, before any of its events. */
22
+ export const initial = (options) => ({
23
+ ...options,
24
+ started: false,
25
+ steps: new Map(),
26
+ writing: new Map(),
27
+ calls: new Map(),
28
+ tokens: noTokens,
29
+ reason: undefined,
30
+ failedStep: false,
31
+ failure: undefined,
32
+ finished: false
33
+ });
34
+ /** The tools opencode answers in JSON and asks questions with, which no turn streams. */
35
+ const hiddenTools = new Set(["StructuredOutput", "question"]);
36
+ /** The failure opencode reports when a turn is aborted, which ends the turn without an error. */
37
+ const aborted = "MessageAbortedError";
38
+ /** The turn after the next event of its directory, and the parts that event streams. */
39
+ export const translate = (turn, event) => {
40
+ if (turn.finished)
41
+ return [turn, []];
42
+ switch (event.type) {
43
+ case "message.updated": {
44
+ const { info } = event.properties;
45
+ if (info.sessionID !== turn.sessionID || info.role !== "assistant")
46
+ return [turn, []];
47
+ return messageUpdated(turn, info);
48
+ }
49
+ case "message.part.updated": {
50
+ const { part } = event.properties;
51
+ const step = turn.steps.get(part.messageID);
52
+ if (part.sessionID !== turn.sessionID || step === undefined)
53
+ return [turn, []];
54
+ return step.summary ? [summaryPartUpdated(turn, step, part), []] : partUpdated(turn, part);
55
+ }
56
+ case "message.part.delta": {
57
+ const { sessionID, partID, field, delta } = event.properties;
58
+ const writing = turn.writing.get(partID);
59
+ if (sessionID !== turn.sessionID || field !== "text" || writing === undefined) {
60
+ return [turn, []];
61
+ }
62
+ if (writing.ended)
63
+ return [turn, []];
64
+ return [
65
+ {
66
+ ...turn,
67
+ writing: withEntry(turn.writing, partID, {
68
+ ...writing,
69
+ written: writing.written + delta
70
+ })
71
+ },
72
+ [{ type: `${writing.kind}-delta`, id: partID, delta }]
73
+ ];
74
+ }
75
+ case "session.status": {
76
+ const { sessionID, status } = event.properties;
77
+ return sessionID === turn.sessionID && status.type !== "idle" ? [{ ...turn, started: true }, []] : [turn, []];
78
+ }
79
+ case "session.error": {
80
+ const { sessionID, error } = event.properties;
81
+ if (sessionID !== turn.sessionID || error === undefined || error.name === aborted) {
82
+ return [turn, []];
83
+ }
84
+ return [{ ...turn, failure: turn.failure ?? error }, []];
85
+ }
86
+ case "session.idle":
87
+ return event.properties.sessionID === turn.sessionID && turn.started ? finish(turn) : [turn, []];
88
+ case "permission.asked": {
89
+ const { id, tool } = event.properties;
90
+ return [turn, [{ type: "tool-approval-request", approvalId: id, toolCallId: tool?.callID ?? id }]];
91
+ }
92
+ case "question.asked":
93
+ return [turn, []];
94
+ }
95
+ };
96
+ /**
97
+ * A step starting, as a message that starts during the turn, or completing: it ends the step with
98
+ * its answer in JSON, if it gave one, its failure, and its `finish-step`, or, for a summary, with
99
+ * the `compaction` it made.
100
+ */
101
+ const messageUpdated = (turn, info) => {
102
+ const step = turn.steps.get(info.id);
103
+ const completed = info.time.completed !== undefined;
104
+ if (step === undefined) {
105
+ // A message completed when the turn first sees it is an earlier turn's.
106
+ if (completed)
107
+ return [turn, []];
108
+ const started = {
109
+ summary: info.summary === true,
110
+ completed: false,
111
+ summaryTexts: new Map()
112
+ };
113
+ const steps = withEntry(turn.steps, info.id, started);
114
+ return [
115
+ { ...turn, steps },
116
+ started.summary
117
+ ? []
118
+ : [
119
+ {
120
+ type: "response-metadata",
121
+ id: info.id,
122
+ modelId: `${info.providerID}/${info.modelID}`,
123
+ timestamp: new Date(info.time.created).toISOString()
124
+ }
125
+ ]
126
+ ];
127
+ }
128
+ if (!completed || step.completed)
129
+ return [turn, []];
130
+ const steps = withEntry(turn.steps, info.id, { ...step, completed: true });
131
+ if (step.summary) {
132
+ return [
133
+ { ...turn, steps },
134
+ info.error === undefined
135
+ ? [
136
+ {
137
+ type: "compaction",
138
+ trigger: "auto",
139
+ summary: [...step.summaryTexts.values()].join("\n")
140
+ }
141
+ ]
142
+ : []
143
+ ];
144
+ }
145
+ const parts = [];
146
+ const writing = new Map(turn.writing);
147
+ for (const [id, open] of turn.writing) {
148
+ if (open.messageID === info.id && !open.ended) {
149
+ parts.push({ type: `${open.kind}-end`, id });
150
+ writing.set(id, { ...open, ended: true });
151
+ }
152
+ }
153
+ if (info.structured !== undefined) {
154
+ const id = `${info.id}-answer`;
155
+ parts.push({ type: "text-start", id }, { type: "text-delta", id, delta: JSON.stringify(info.structured) }, { type: "text-end", id });
156
+ }
157
+ const failed = info.error !== undefined && info.error.name !== aborted;
158
+ if (failed)
159
+ parts.push({ type: "error", error: info.error });
160
+ const reason = failed
161
+ ? "error"
162
+ : info.structured !== undefined
163
+ ? "stop"
164
+ : finishReasonOf(info.finish ?? "other");
165
+ const tokens = info.tokens ?? noTokens;
166
+ parts.push({ type: "finish-step", reason, usage: usageOf(tokens) });
167
+ return [
168
+ {
169
+ ...turn,
170
+ steps,
171
+ writing,
172
+ tokens: addTokens(turn.tokens, tokens),
173
+ reason,
174
+ failedStep: turn.failedStep || failed
175
+ },
176
+ parts
177
+ ];
178
+ };
179
+ /** A part of a summary changing: the summary keeps its texts, which no part streams. */
180
+ const summaryPartUpdated = (turn, step, part) => isTextPart(part)
181
+ ? {
182
+ ...turn,
183
+ steps: withEntry(turn.steps, part.messageID, {
184
+ ...step,
185
+ summaryTexts: withEntry(step.summaryTexts, part.id, part.text)
186
+ })
187
+ }
188
+ : turn;
189
+ /** A part of a step changing: a text or a reasoning written on, or a call of a tool going on. */
190
+ const partUpdated = (turn, part) => {
191
+ if (isTextPart(part) || isReasoningPart(part))
192
+ return writingUpdated(turn, part.type, part);
193
+ if (isToolPart(part) && !turn.hostTools.has(part.tool) && !hiddenTools.has(part.tool)) {
194
+ return callUpdated(turn, part);
195
+ }
196
+ return [turn, []];
197
+ };
198
+ /**
199
+ * A text or a reasoning written on: started the first time the turn sees it, then written on with
200
+ * what the deltas have not streamed, and ended once it is whole.
201
+ */
202
+ const writingUpdated = (turn, kind, part) => {
203
+ const parts = [];
204
+ const known = turn.writing.get(part.id);
205
+ if (known?.ended === true)
206
+ return [turn, []];
207
+ if (known === undefined)
208
+ parts.push({ type: `${kind}-start`, id: part.id });
209
+ const written = known?.written ?? "";
210
+ // A part's whole text follows the deltas streamed of it; what they missed streams now.
211
+ if (part.text.length > written.length && part.text.startsWith(written)) {
212
+ parts.push({ type: `${kind}-delta`, id: part.id, delta: part.text.slice(written.length) });
213
+ }
214
+ const ended = part.time?.end !== undefined;
215
+ if (ended)
216
+ parts.push({ type: `${kind}-end`, id: part.id });
217
+ const writing = {
218
+ kind,
219
+ messageID: part.messageID,
220
+ written: part.text.startsWith(written) ? part.text : written,
221
+ ended
222
+ };
223
+ return [{ ...turn, writing: withEntry(turn.writing, part.id, writing) }, parts];
224
+ };
225
+ /**
226
+ * A call of one of opencode's own tools going on: its input starts once the model writes it, and
227
+ * streams whole with the call once the tool runs; its result follows once the tool has answered,
228
+ * with the file a write or an edit changed.
229
+ */
230
+ const callUpdated = (turn, part) => {
231
+ const { callID, tool: name, state } = part;
232
+ const parts = [];
233
+ const call = turn.calls.get(callID) ?? { name, called: false, answered: false };
234
+ if (!turn.calls.has(callID)) {
235
+ parts.push({ type: "tool-params-start", id: callID, name, providerExecuted: true });
236
+ }
237
+ if (state.status === "pending") {
238
+ return [{ ...turn, calls: withEntry(turn.calls, callID, call) }, parts];
239
+ }
240
+ if (!call.called) {
241
+ parts.push({ type: "tool-params-delta", id: callID, delta: JSON.stringify(state.input) }, { type: "tool-params-end", id: callID }, { type: "tool-call", id: callID, name, params: state.input, providerExecuted: true });
242
+ }
243
+ const answered = state.status === "completed" || state.status === "error";
244
+ if (answered && !call.answered) {
245
+ parts.push({
246
+ type: "tool-result",
247
+ id: callID,
248
+ name,
249
+ ...(state.status === "completed"
250
+ ? { result: state.output, isFailure: false }
251
+ : { result: state.error, isFailure: true }),
252
+ providerExecuted: true
253
+ });
254
+ if (state.status === "completed")
255
+ parts.push(...fileChangesOf(turn.directory, name, state));
256
+ }
257
+ return [{ ...turn, calls: withEntry(turn.calls, callID, { name, called: true, answered }) }, parts];
258
+ };
259
+ /**
260
+ * The file a completed call of `write` or `edit` changed, by its path within `directory`, or as it
261
+ * is when outside it: `write` says whether the file existed before. Other tools, such as `bash`,
262
+ * do not say which files they change.
263
+ */
264
+ const fileChangesOf = (directory, tool, state) => {
265
+ const file = state.metadata?.["filepath"] ?? state.input["filePath"];
266
+ if (typeof file !== "string")
267
+ return [];
268
+ const path = file.startsWith(`${directory}/`) ? file.slice(directory.length + 1) : file;
269
+ switch (tool) {
270
+ case "write":
271
+ return [
272
+ {
273
+ type: "file-change",
274
+ event: state.metadata?.["exists"] === false ? "create" : "modify",
275
+ path
276
+ }
277
+ ];
278
+ case "edit":
279
+ return [{ type: "file-change", event: "modify", path }];
280
+ default:
281
+ return [];
282
+ }
283
+ };
284
+ /**
285
+ * Finishes the turn: with what opencode reported when it failed apart from any step, or for a turn
286
+ * that took no step, then `finish`.
287
+ */
288
+ const finish = (turn) => {
289
+ const parts = [];
290
+ const failure = turn.failure ??
291
+ (turn.reason === undefined
292
+ ? { name: "UnknownError", data: { message: "opencode ended the turn without a step" } }
293
+ : undefined);
294
+ if (failure !== undefined && !turn.failedStep)
295
+ parts.push({ type: "error", error: failure });
296
+ parts.push({
297
+ type: "finish",
298
+ reason: failure !== undefined || turn.failedStep ? "error" : (turn.reason ?? "other"),
299
+ usage: usageOf(turn.tokens)
300
+ });
301
+ return [{ ...turn, finished: true }, parts];
302
+ };
303
+ const withEntry = (map, key, value) => new Map(map).set(key, value);
304
+ //# sourceMappingURL=turn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn.js","sourceRoot":"","sources":["../../../../src/internal/bridge/v1/turn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The requests the driver makes of opencode's server over opencode 2's session API. opencode 2
3
+ * keeps each session at a location, its directory, which the session's own requests need not name,
4
+ * and publishes the events of every session on one stream, live only. `make` gives the requests
5
+ * over the client of a started server. A failed request fails with the `HarnessError` the driver
6
+ * reports.
7
+ */
8
+ import { HarnessError } from "@amends-dev/harness";
9
+ import * as Effect from "effect/Effect";
10
+ import type * as Scope from "effect/Scope";
11
+ import * as Stream from "effect/Stream";
12
+ import type { ModelRef } from "../driver.ts";
13
+ import type { RemoteMcpServer } from "../hostTools.ts";
14
+ import * as Server from "../server.ts";
15
+ import { SessionEvent } from "./event.ts";
16
+ import type { Message, PromptInput } from "./prompt.ts";
17
+ /** How a tool goes on after asking the user's permission: this once, always, or not at all. */
18
+ export type PermissionDecision = "once" | "always" | "reject";
19
+ export interface Api {
20
+ /** Creates a session working in `directory` on `model`, returning its id. */
21
+ readonly createSession: (directory: string, model: ModelRef) => Effect.Effect<string, HarnessError.HarnessError>;
22
+ /**
23
+ * Creates the session `sessionID` working in `directory` on `model`, as if it had recorded
24
+ * `messages`, the conversation its model reads.
25
+ */
26
+ readonly importSession: (options: {
27
+ readonly sessionID: string;
28
+ readonly directory: string;
29
+ readonly model: ModelRef;
30
+ readonly now: number;
31
+ readonly messages: ReadonlyArray<Message>;
32
+ }) => Effect.Effect<void, HarnessError.HarnessError>;
33
+ /** Whether the server has the session, as it does unless the sandbox lost opencode's data. */
34
+ readonly hasSession: (sessionID: string) => Effect.Effect<boolean, HarnessError.HarnessError>;
35
+ /** Deletes the session and everything it recorded. Deleting a deleted session succeeds. */
36
+ readonly deleteSession: (sessionID: string) => Effect.Effect<void, HarnessError.HarnessError>;
37
+ /** Runs the session's next steps on `model`. */
38
+ readonly switchModel: (sessionID: string, model: ModelRef) => Effect.Effect<void, HarnessError.HarnessError>;
39
+ /**
40
+ * Gives the session's model `text` as the instructions under `key`, which it reads beside its
41
+ * own from the next step, until they are replaced or removed.
42
+ */
43
+ readonly putInstructions: (sessionID: string, key: string, text: string) => Effect.Effect<void, HarnessError.HarnessError>;
44
+ readonly removeInstructions: (sessionID: string, key: string) => Effect.Effect<void, HarnessError.HarnessError>;
45
+ /**
46
+ * Gives the session a prompt, after any work it has queued, returning the id of the input it
47
+ * queued. opencode runs the session from it, and the session's events follow on the stream
48
+ * `subscribe` returns.
49
+ */
50
+ readonly prompt: (sessionID: string, prompt: PromptInput) => Effect.Effect<string, HarnessError.HarnessError>;
51
+ /**
52
+ * Asks the session to replace its conversation so far with a summary, at its next step, or now
53
+ * when it is idle. `session.compaction.ended` follows on the stream `subscribe` returns.
54
+ */
55
+ readonly compact: (sessionID: string) => Effect.Effect<void, HarnessError.HarnessError>;
56
+ /** Stops running the session. Interrupting a session that runs nothing does nothing. */
57
+ readonly interrupt: (sessionID: string) => Effect.Effect<void, HarnessError.HarnessError>;
58
+ /**
59
+ * Subscribes to the events of the session, returning once opencode publishes them to the
60
+ * subscription, with the stream of them from then on, which ends when the scope closes. The
61
+ * stream does not end by itself. Events of types the adapter does not read are left out.
62
+ */
63
+ readonly subscribe: (sessionID: string) => Effect.Effect<Stream.Stream<SessionEvent, HarnessError.HarnessError>, HarnessError.HarnessError, Scope.Scope>;
64
+ /** Answers a tool's request for permission, with `message` for the model when it refuses. */
65
+ readonly replyPermission: (sessionID: string, requestID: string, decision: PermissionDecision, message?: string) => Effect.Effect<void, HarnessError.HarnessError>;
66
+ /** Cancels a form the model asked the user to fill, telling the model why. */
67
+ readonly cancelForm: (sessionID: string, formID: string, message: string) => Effect.Effect<void, HarnessError.HarnessError>;
68
+ /**
69
+ * Adds the MCP server `name` for the sessions in `directory`, connecting to it and listing its
70
+ * tools for the model. Adding a name again replaces the server.
71
+ */
72
+ readonly addMcpServer: (directory: string, name: string, server: RemoteMcpServer) => Effect.Effect<void, HarnessError.HarnessError>;
73
+ /**
74
+ * Waits until opencode has connected to the MCP server `name` for the sessions in `directory`,
75
+ * whose tools the model sees only from then on, failing when it has not within 10 seconds or
76
+ * failed to.
77
+ */
78
+ readonly awaitMcpServer: (directory: string, name: string) => Effect.Effect<void, HarnessError.HarnessError>;
79
+ /** Connects to the MCP server `name` again, listing its tools anew. */
80
+ readonly reconnectMcpServer: (directory: string, name: string) => Effect.Effect<void, HarnessError.HarnessError>;
81
+ /** Disconnects from the MCP server `name`, taking its tools from the model. */
82
+ readonly disconnectMcpServer: (directory: string, name: string) => Effect.Effect<void, HarnessError.HarnessError>;
83
+ }
84
+ /** The requests of opencode 2's session API, made of `server`. */
85
+ export declare const make: (server: Server.Server) => Api;
86
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/internal/bridge/v2/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The requests the driver makes of opencode's server over opencode 2's session API. opencode 2
3
+ * keeps each session at a location, its directory, which the session's own requests need not name,
4
+ * and publishes the events of every session on one stream, live only. `make` gives the requests
5
+ * over the client of a started server. A failed request fails with the `HarnessError` the driver
6
+ * reports.
7
+ */
8
+ import { HarnessError } from "@amends-dev/harness";
9
+ import * as Effect from "effect/Effect";
10
+ import * as Sse from "effect/encoding/Sse";
11
+ import * as HttpClient from "effect/http/HttpClient";
12
+ import * as HttpClientRequest from "effect/http/HttpClientRequest";
13
+ import * as HttpClientResponse from "effect/http/HttpClientResponse";
14
+ import * as Schedule from "effect/Schedule";
15
+ import * as Schema from "effect/Schema";
16
+ import * as Stream from "effect/Stream";
17
+ import * as Server from "../server.js";
18
+ import { SessionEvent, sessionIdOf } from "./event.js";
19
+ /** The requests of opencode 2's session API, made of `server`. */
20
+ export const make = (server) => {
21
+ const { client, clientOk } = server;
22
+ const fromRequestError = Server.requestError(server.agent);
23
+ const sessionPath = (sessionID, rest = "") => `/api/session/${encodeURIComponent(sessionID)}${rest}`;
24
+ /** A location's query, which names its directory as a deep object. */
25
+ const location = (directory) => ({ "location[directory]": directory });
26
+ const mcpPath = (name, rest = "") => `/api/experimental/mcp/${encodeURIComponent(name)}${rest}`;
27
+ const send = (request) => clientOk.execute(request).pipe(Effect.asVoid, Effect.mapError(fromRequestError));
28
+ /** Whether a request about something the server may not have answers 2xx rather than 404. */
29
+ const exists = (request) => client.execute(request).pipe(Effect.flatMap(HttpClientResponse.filterStatus((status) => (status >= 200 && status < 300) || status === 404)), Effect.map((response) => response.status !== 404), Effect.mapError(fromRequestError));
30
+ /** Sends `request` with `body`, returning the id of what the server answers it made. */
31
+ const createdId = (request, body) => request.pipe(HttpClientRequest.bodyJsonUnsafe(body), clientOk.execute, Effect.flatMap(HttpClientResponse.schemaBodyJson(Created)), Effect.map((created) => created.data.id), Effect.mapError(fromRequestError));
32
+ return {
33
+ createSession: (directory, model) => createdId(HttpClientRequest.post("/api/session"), { location: { directory }, model }),
34
+ importSession: ({ sessionID, directory, model, now, messages }) => Effect.asVoid(createdId(HttpClientRequest.post("/api/experimental/session/import"), {
35
+ info: {
36
+ id: sessionID,
37
+ // opencode imports the session into the project of its directory, whatever this says.
38
+ projectID: "global",
39
+ model,
40
+ cost: 0,
41
+ tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
42
+ time: { created: now, updated: now },
43
+ location: { directory }
44
+ },
45
+ messages,
46
+ location: { directory }
47
+ })),
48
+ hasSession: (sessionID) => exists(HttpClientRequest.get(sessionPath(sessionID))),
49
+ deleteSession: (sessionID) => Effect.asVoid(exists(HttpClientRequest.delete(sessionPath(sessionID)))),
50
+ switchModel: (sessionID, model) => send(HttpClientRequest.post(sessionPath(sessionID, "/model")).pipe(HttpClientRequest.bodyJsonUnsafe({ model }))),
51
+ putInstructions: (sessionID, key, text) => send(HttpClientRequest.put(instructionsPath(sessionID, key)).pipe(HttpClientRequest.bodyJsonUnsafe({ value: text }))),
52
+ removeInstructions: (sessionID, key) => Effect.asVoid(exists(HttpClientRequest.delete(instructionsPath(sessionID, key)))),
53
+ // Queued, a prompt waits for work the session runs already, such as a turn the bridge left
54
+ // running when it died, rather than joining it.
55
+ prompt: (sessionID, prompt) => createdId(HttpClientRequest.post(sessionPath(sessionID, "/prompt")), {
56
+ ...prompt,
57
+ delivery: "queue"
58
+ }),
59
+ compact: (sessionID) => send(HttpClientRequest.post(sessionPath(sessionID, "/compact")).pipe(HttpClientRequest.bodyJsonUnsafe({}))),
60
+ interrupt: (sessionID) => send(HttpClientRequest.post(sessionPath(sessionID, "/interrupt"))),
61
+ subscribe: (sessionID) => HttpClient.withScope(clientOk)
62
+ .get("/api/event")
63
+ .pipe(Effect.map((response) => response.stream.pipe(Stream.decodeText(), Stream.pipeThroughChannel(Sse.decodeDataSchema(StreamedEvent)), Stream.map((event) => event.data), Stream.filter(Schema.is(SessionEvent)), Stream.filter((event) => sessionIdOf(event) === sessionID), Stream.mapError(fromRequestError))), Effect.mapError(fromRequestError)),
64
+ replyPermission: (sessionID, requestID, decision, message) => send(HttpClientRequest.post(sessionPath(sessionID, `/permission/${encodeURIComponent(requestID)}/reply`)).pipe(HttpClientRequest.bodyJsonUnsafe({
65
+ decision,
66
+ ...(message === undefined ? {} : { message })
67
+ }))),
68
+ cancelForm: (sessionID, formID, message) => send(HttpClientRequest.delete(sessionPath(sessionID, `/form/${encodeURIComponent(formID)}`), {
69
+ urlParams: { message }
70
+ })),
71
+ addMcpServer: (directory, name, mcpServer) => send(HttpClientRequest.put(mcpPath(name), { urlParams: location(directory) }).pipe(HttpClientRequest.bodyJsonUnsafe({
72
+ config: { type: "remote", url: mcpServer.url, headers: mcpServer.headers }
73
+ }))),
74
+ awaitMcpServer: (directory, name) => clientOk.get("/api/mcp", { urlParams: location(directory) }).pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(McpServers)), Effect.map(({ data }) => data.find((mcp) => mcp.name === name)?.status.status), Effect.mapError(fromRequestError), Effect.repeat({
75
+ until: (status) => status !== undefined && status !== "pending",
76
+ schedule: Schedule.spaced("100 millis")
77
+ }), Effect.timeoutOrElse({
78
+ duration: "10 seconds",
79
+ orElse: () => Effect.succeed("pending")
80
+ }), Effect.flatMap((status) => status === "connected"
81
+ ? Effect.void
82
+ : Effect.fail(Server.harnessError(server.agent, new HarnessError.UnavailableError({
83
+ description: `opencode did not connect to the host's tools: it reports them ${status}`
84
+ }))))),
85
+ reconnectMcpServer: (directory, name) => send(HttpClientRequest.post(mcpPath(name, "/connect"), { urlParams: location(directory) })),
86
+ disconnectMcpServer: (directory, name) => send(HttpClientRequest.post(mcpPath(name, "/disconnect"), { urlParams: location(directory) }))
87
+ };
88
+ };
89
+ const instructionsPath = (sessionID, key) => `/api/experimental/session/${encodeURIComponent(sessionID)}/instructions/entries/${encodeURIComponent(key)}`;
90
+ /** The MCP servers of a location, each with its status, such as `pending` or `connected`. */
91
+ const McpServers = Schema.Struct({
92
+ data: Schema.Array(Schema.Struct({ name: Schema.String, status: Schema.Struct({ status: Schema.String }) }))
93
+ });
94
+ /** What the server answers it made, such as a session or an input it queued. */
95
+ const Created = Schema.Struct({ data: Schema.Struct({ id: Schema.String }) });
96
+ /** An event of a type the adapter does not read, which `subscribe` leaves out. */
97
+ const OtherEvent = Schema.Struct({
98
+ type: Schema.String.check(Schema.makeFilter((type) => !Object.hasOwn(SessionEvent.cases, type)))
99
+ });
100
+ /**
101
+ * An event as the server streams it. A known type that does not decode fails, rather than being
102
+ * left out as an event of another type.
103
+ */
104
+ const StreamedEvent = Schema.Union([SessionEvent, OtherEvent]);
105
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/internal/bridge/v2/api.ts"],"names":[],"mappings":"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"}