ework-daemon 0.4.10 → 0.4.12
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/package.json +1 -1
- package/src/index.ts +22 -0
- package/src/opencode.ts +15 -3
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { GiteaTracker } from "./trackers/gitea-tracker";
|
|
|
8
8
|
import type { IssueTracker } from "./trackers/types";
|
|
9
9
|
import { initDB } from "./db";
|
|
10
10
|
import { hostname } from "os";
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
import * as path from "node:path";
|
|
11
13
|
|
|
12
14
|
const config = loadConfig();
|
|
13
15
|
const isTest = config.env === "test";
|
|
@@ -20,6 +22,26 @@ log.info(` workdir: ${config.opencode.baseWorkdir}`);
|
|
|
20
22
|
log.info(` db: ${config.db.driver === "mysql" ? `${config.db.user}@${config.db.host}:${config.db.port}/${config.db.name}` : config.db.path}${config.db.prefix ? ` (prefix=${config.db.prefix})` : ""}`);
|
|
21
23
|
log.info(` work: capacity=${config.work.capacity} heartbeat=${config.work.heartbeatMs}ms leaseTtl=${config.work.leaseTtlMs}ms`);
|
|
22
24
|
|
|
25
|
+
function probePlugin() {
|
|
26
|
+
const configDir = process.env.XDG_CONFIG_HOME || path.join(process.env.HOME || "/tmp", ".config");
|
|
27
|
+
const cfgPath = path.join(configDir, "opencode", "opencode.json");
|
|
28
|
+
try {
|
|
29
|
+
const raw = fs.readFileSync(cfgPath, "utf8");
|
|
30
|
+
const parsed = JSON.parse(raw);
|
|
31
|
+
const plugin = parsed.plugin ?? parsed.plugins;
|
|
32
|
+
const plugins = Array.isArray(plugin) ? plugin : plugin ? [plugin] : [];
|
|
33
|
+
const hasEwork = plugins.some((p: unknown) =>
|
|
34
|
+
typeof p === "string" ? p.includes("opencode-ework") : false,
|
|
35
|
+
);
|
|
36
|
+
if (!hasEwork) {
|
|
37
|
+
log.warn(" ⚠️ opencode-ework plugin not found in opencode.json — the AI will lack the 'reply' tool and all nudges will fail. Install it: npm install -g opencode-ework");
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
log.warn(` ⚠️ could not read opencode config at ${cfgPath} — cannot verify opencode-ework plugin is installed`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
probePlugin();
|
|
44
|
+
|
|
23
45
|
const giteaClient = new GiteaClient(config.gitea, config.bot.token);
|
|
24
46
|
const giteaTracker = new GiteaTracker(
|
|
25
47
|
giteaClient,
|
package/src/opencode.ts
CHANGED
|
@@ -221,6 +221,7 @@ export class Engine {
|
|
|
221
221
|
private stopping = new Set<string>();
|
|
222
222
|
private processingComments = new Set<string>();
|
|
223
223
|
private currentMessage = new Map<string, string>();
|
|
224
|
+
private currentModel = new Map<string, string | undefined>();
|
|
224
225
|
private lastOutputAt = new Map<string, number>();
|
|
225
226
|
private startedAt = new Map<string, number>();
|
|
226
227
|
private progressCommentId = new Map<string, string>();
|
|
@@ -687,6 +688,7 @@ export class Engine {
|
|
|
687
688
|
this.running.delete(k);
|
|
688
689
|
this.stopping.delete(k);
|
|
689
690
|
this.currentMessage.delete(k);
|
|
691
|
+
this.currentModel.delete(k);
|
|
690
692
|
this.lastOutputAt.delete(k);
|
|
691
693
|
this.startedAt.delete(k);
|
|
692
694
|
this.progressCommentId.delete(k);
|
|
@@ -738,6 +740,7 @@ export class Engine {
|
|
|
738
740
|
// Don't clear stopping — let old execProcess detect preemption via process reference mismatch
|
|
739
741
|
this.running.delete(k);
|
|
740
742
|
this.currentMessage.delete(k);
|
|
743
|
+
this.currentModel.delete(k);
|
|
741
744
|
this.startedAt.delete(k);
|
|
742
745
|
|
|
743
746
|
// Execute new message
|
|
@@ -797,6 +800,7 @@ export class Engine {
|
|
|
797
800
|
// Without this, opencode's own default (influenced by plugin agent
|
|
798
801
|
// presets) can pick a non-existent model, causing ProviderModelNotFoundError.
|
|
799
802
|
const model = msg.model || this.cfg.opencode.defaultModel;
|
|
803
|
+
this.currentModel.set(k, model);
|
|
800
804
|
if (model) {
|
|
801
805
|
args.push("--model", model);
|
|
802
806
|
}
|
|
@@ -820,6 +824,12 @@ export class Engine {
|
|
|
820
824
|
// them); only the explicit model-override var is neutralized.
|
|
821
825
|
const childEnv = { ...process.env };
|
|
822
826
|
if (!model) delete childEnv.OPENCODE_MODEL;
|
|
827
|
+
// Strip parent-session env vars so the child opencode reads its own
|
|
828
|
+
// opencode.json instead of inheriting a parent session's model/provider.
|
|
829
|
+
delete childEnv.OPENCODE;
|
|
830
|
+
delete childEnv.OPENCODE_PID;
|
|
831
|
+
delete childEnv.OPENCODE_RUN_ID;
|
|
832
|
+
delete childEnv.OPENCODE_PROCESS_ROLE;
|
|
823
833
|
|
|
824
834
|
try {
|
|
825
835
|
const proc = spawn({
|
|
@@ -929,6 +939,7 @@ export class Engine {
|
|
|
929
939
|
|
|
930
940
|
// running.delete deferred to dequeuePending
|
|
931
941
|
this.currentMessage.delete(k);
|
|
942
|
+
this.currentModel.delete(k);
|
|
932
943
|
|
|
933
944
|
const started = this.startedAt.get(k);
|
|
934
945
|
this.startedAt.delete(k);
|
|
@@ -1000,7 +1011,7 @@ export class Engine {
|
|
|
1000
1011
|
|
|
1001
1012
|
const instructions = tracker.getTrackerInstructions(ref);
|
|
1002
1013
|
const nudgePrompt = this.buildNudgePrompt(session, issue, instructions);
|
|
1003
|
-
const nudgeMsg = await this.store.createMessage(session.id, nudgePrompt);
|
|
1014
|
+
const nudgeMsg = await this.store.createMessage(session.id, nudgePrompt, undefined, undefined, this.currentModel.get(k));
|
|
1004
1015
|
await this.dequeueOrIdle(k, session, issue, nudgeMsg);
|
|
1005
1016
|
return;
|
|
1006
1017
|
}
|
|
@@ -1244,6 +1255,7 @@ export class Engine {
|
|
|
1244
1255
|
if (msgId) {
|
|
1245
1256
|
await this.store.updateMessageStatus(msgId, "failed", "process died unexpectedly");
|
|
1246
1257
|
this.currentMessage.delete(k);
|
|
1258
|
+
this.currentModel.delete(k);
|
|
1247
1259
|
}
|
|
1248
1260
|
|
|
1249
1261
|
const ref = this.sessionToRef(session, issue);
|
|
@@ -1262,7 +1274,7 @@ export class Engine {
|
|
|
1262
1274
|
|
|
1263
1275
|
const instructions = tracker.getTrackerInstructions(ref);
|
|
1264
1276
|
const nudgePrompt = this.buildProcessExitNudgePrompt(session, issue, instructions);
|
|
1265
|
-
const nudgeMsg = await this.store.createMessage(session.id, nudgePrompt);
|
|
1277
|
+
const nudgeMsg = await this.store.createMessage(session.id, nudgePrompt, undefined, undefined, this.currentModel.get(k));
|
|
1266
1278
|
await this.dequeueOrIdle(k, session, issue, nudgeMsg);
|
|
1267
1279
|
continue;
|
|
1268
1280
|
} else {
|
|
@@ -1306,7 +1318,7 @@ export class Engine {
|
|
|
1306
1318
|
|
|
1307
1319
|
const instructions = tracker.getTrackerInstructions(ref);
|
|
1308
1320
|
const nudgePrompt = this.buildStuckNudgePrompt(session, issue, instructions, minutes);
|
|
1309
|
-
const nudgeMsg = await this.store.createMessage(session.id, nudgePrompt);
|
|
1321
|
+
const nudgeMsg = await this.store.createMessage(session.id, nudgePrompt, undefined, undefined, this.currentModel.get(k));
|
|
1310
1322
|
await this.dequeueOrIdle(k, session, issue, nudgeMsg);
|
|
1311
1323
|
} else {
|
|
1312
1324
|
log.warn(`engine: stuck for ${minutes}min on ${k}, stuck nudge exhausted (${stuckNudgeRound}/${this.maxStuckNudges}), giving up`);
|