@open-cr-agent/runtime-opencode 0.3.0 → 0.5.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/README.md +1 -1
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.js +30 -17
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# @open-cr-agent/runtime-opencode
|
|
2
2
|
|
|
3
|
-
The agent runtime backed by [OpenCode](https://opencode.ai) of [Open-CR-Agent](https://github.com/jma49/Open-CR-Agent), the multi-agent code reviewer. Most users want [`@open-cr-agent/cli`](https://www.npmjs.com/package/@open-cr-agent/cli), which provides the `ocra` command and installs this package; see the [manual](https://
|
|
3
|
+
The agent runtime backed by [OpenCode](https://opencode.ai) of [Open-CR-Agent](https://github.com/jma49/Open-CR-Agent), the multi-agent code reviewer. Most users want [`@open-cr-agent/cli`](https://www.npmjs.com/package/@open-cr-agent/cli), which provides the `ocra` command and installs this package; see the [manual](https://ocracloud.com). All `@open-cr-agent` packages are released together at one version. Apache-2.0.
|
package/dist/runtime.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare class OpenCodeRuntime implements AgentRuntime {
|
|
|
24
24
|
complete(request: CompletionRequest, signal: AbortSignal): Promise<CompletionResult>;
|
|
25
25
|
dispose(): Promise<void>;
|
|
26
26
|
private prompt;
|
|
27
|
+
private unprepared;
|
|
27
28
|
private start;
|
|
28
29
|
private launch;
|
|
29
30
|
}
|
|
@@ -117,4 +118,5 @@ export declare function openCodeConfig(tools: Pick<ToolServer, "url" | "headers"
|
|
|
117
118
|
};
|
|
118
119
|
};
|
|
119
120
|
};
|
|
121
|
+
export declare function providersOf(options: Pick<RuntimeOptions, "models" | "agentModels">): string[];
|
|
120
122
|
//# sourceMappingURL=runtime.d.ts.map
|
package/dist/runtime.js
CHANGED
|
@@ -3,7 +3,7 @@ import { mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { OcraError, } from "@open-cr-agent/core";
|
|
6
|
-
import { completeWithFailback, MAX_AGENT_STEPS, ModelHealth, parseModel, RESUME_MESSAGE, REVIEW_TOOLS, reviewTools, withFailback, withoutSecrets, } from "@open-cr-agent/core/internal";
|
|
6
|
+
import { callChain, completeWithFailback, MAX_AGENT_STEPS, ModelHealth, parseModel, RESUME_MESSAGE, REVIEW_TOOLS, reviewTools, withFailback, withoutSecrets, } from "@open-cr-agent/core/internal";
|
|
7
7
|
import { createOpencodeClient } from "@opencode-ai/sdk/v2";
|
|
8
8
|
import { resolveOpencodeBinary } from "./binary.js";
|
|
9
9
|
import { startOpencodeServer } from "./opencode-server.js";
|
|
@@ -68,20 +68,17 @@ export class OpenCodeRuntime {
|
|
|
68
68
|
throw new OcraError("INTERNAL", "An OpenCodeRuntime instance serves a single review run");
|
|
69
69
|
}
|
|
70
70
|
this.context = spec.context;
|
|
71
|
-
const chain = this.options.models
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
taskId: spec.taskId,
|
|
76
|
-
retryable: false,
|
|
77
|
-
error: noModel(spec.modelTier),
|
|
78
|
-
};
|
|
71
|
+
const chain = callChain(this.options.models, spec.modelTier, spec.models);
|
|
72
|
+
const refused = chain.length === 0 ? noModel(spec.modelTier) : this.unprepared(spec.models);
|
|
73
|
+
if (refused) {
|
|
74
|
+
yield { type: "error", taskId: spec.taskId, retryable: false, error: refused };
|
|
79
75
|
return;
|
|
80
76
|
}
|
|
81
77
|
const infra = await this.start();
|
|
82
78
|
yield* withFailback({
|
|
83
79
|
taskId: spec.taskId,
|
|
84
80
|
tier: spec.modelTier,
|
|
81
|
+
...(spec.models?.length ? { agent: spec.reviewer } : {}),
|
|
85
82
|
chain,
|
|
86
83
|
health: this.health,
|
|
87
84
|
signal,
|
|
@@ -98,12 +95,14 @@ export class OpenCodeRuntime {
|
|
|
98
95
|
});
|
|
99
96
|
}
|
|
100
97
|
async complete(request, signal) {
|
|
101
|
-
const chain = this.options.models
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
const chain = callChain(this.options.models, request.tier, request.models);
|
|
99
|
+
const refused = chain.length === 0 ? noModel(request.tier) : this.unprepared(request.models);
|
|
100
|
+
if (refused)
|
|
101
|
+
throw new OcraError("CONFIG_INVALID", refused);
|
|
104
102
|
const infra = await this.start();
|
|
105
103
|
return completeWithFailback({
|
|
106
104
|
tier: request.tier,
|
|
105
|
+
...(request.models?.length ? { agent: request.agent ?? request.tier } : {}),
|
|
107
106
|
chain,
|
|
108
107
|
health: this.health,
|
|
109
108
|
signal,
|
|
@@ -138,13 +137,25 @@ export class OpenCodeRuntime {
|
|
|
138
137
|
}
|
|
139
138
|
: outcome);
|
|
140
139
|
}
|
|
140
|
+
// The server holds the credentials of the providers it started with; an
|
|
141
|
+
// agent's own chain naming another would fail at OpenCode as "model not
|
|
142
|
+
// found". The tier chains are always among them.
|
|
143
|
+
unprepared(own) {
|
|
144
|
+
if (!own?.length)
|
|
145
|
+
return undefined;
|
|
146
|
+
const prepared = new Set(providersOf(this.options));
|
|
147
|
+
const model = own.find((m) => !prepared.has(parseModel(m).providerID));
|
|
148
|
+
return model === undefined
|
|
149
|
+
? undefined
|
|
150
|
+
: `"${model}" is not among the models the runtime was started with (RuntimeOptions.models or agentModels)`;
|
|
151
|
+
}
|
|
141
152
|
start() {
|
|
142
153
|
this.infra ??= this.launch();
|
|
143
154
|
return this.infra;
|
|
144
155
|
}
|
|
145
156
|
async launch() {
|
|
146
157
|
const custom = this.options.providers ?? {};
|
|
147
|
-
const missing = missingCredentials(this.options.env, providersOf(this.options
|
|
158
|
+
const missing = missingCredentials(this.options.env, providersOf(this.options), custom);
|
|
148
159
|
if (missing.length > 0)
|
|
149
160
|
throw new OcraError("CONFIG_CREDENTIALS_MISSING", missing.join("; "));
|
|
150
161
|
const root = await mkdtemp(join(tmpdir(), "ocra-opencode-"));
|
|
@@ -161,7 +172,7 @@ export class OpenCodeRuntime {
|
|
|
161
172
|
const server = await startOpencodeServer({
|
|
162
173
|
binary: this.options.binary ?? resolveOpencodeBinary(this.options.env),
|
|
163
174
|
cwd: workspace,
|
|
164
|
-
env: serverEnv(this.options.env, dirs, providersOf(this.options
|
|
175
|
+
env: serverEnv(this.options.env, dirs, providersOf(this.options), custom),
|
|
165
176
|
config: openCodeConfig(tools, this.helperTools, custom, this.options.sampling),
|
|
166
177
|
});
|
|
167
178
|
started = server;
|
|
@@ -179,7 +190,7 @@ export class OpenCodeRuntime {
|
|
|
179
190
|
rmSync(root, { recursive: true, force: true });
|
|
180
191
|
};
|
|
181
192
|
process.on("exit", onExit);
|
|
182
|
-
const secrets = credentialValues(this.options.env, providersOf(this.options
|
|
193
|
+
const secrets = credentialValues(this.options.env, providersOf(this.options), custom);
|
|
183
194
|
return { root, tools, server, client, dispatcher, onExit, secrets };
|
|
184
195
|
}
|
|
185
196
|
catch (error) {
|
|
@@ -270,8 +281,10 @@ function providerConfig(custom, temperature) {
|
|
|
270
281
|
},
|
|
271
282
|
]));
|
|
272
283
|
}
|
|
273
|
-
|
|
274
|
-
|
|
284
|
+
// The providers of every chain a call may run on: the tiers' and the
|
|
285
|
+
// agents' own (ADR-0025), so each gets its credentials like a tier's.
|
|
286
|
+
export function providersOf(options) {
|
|
287
|
+
return [...Object.values(options.models), ...Object.values(options.agentModels ?? {})].flatMap((chain) => (chain ?? []).map((m) => parseModel(m).providerID));
|
|
275
288
|
}
|
|
276
289
|
function noModel(tier) {
|
|
277
290
|
return `No model configured for the "${tier}" tier; set models.${tier} in .ocra/config.json or OCRA_MODEL_${tier.toUpperCase()}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-cr-agent/runtime-opencode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "OpenCode-based agent runtime for Open-CR-Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"code-review",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"agents"
|
|
9
9
|
],
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
|
-
"homepage": "https://
|
|
11
|
+
"homepage": "https://ocracloud.com",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
14
|
"url": "git+https://github.com/jma49/Open-CR-Agent.git",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.30.1",
|
|
37
|
-
"@open-cr-agent/core": "0.
|
|
37
|
+
"@open-cr-agent/core": "0.5.0",
|
|
38
38
|
"@opencode-ai/sdk": "1.18.32",
|
|
39
39
|
"opencode-ai": "1.18.32",
|
|
40
40
|
"undici": "^8.11.2",
|