ework-daemon 0.1.0 → 0.1.2
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/op.ts +2 -1
- package/src/opencode.ts +29 -10
- package/src/trackers/gitea-tracker.ts +8 -0
- package/src/trackers/types.ts +8 -0
package/package.json
CHANGED
package/src/op.ts
CHANGED
|
@@ -432,7 +432,7 @@ export class Store {
|
|
|
432
432
|
|
|
433
433
|
// ─── Messages ───
|
|
434
434
|
|
|
435
|
-
createMessage(sessionId: string, content: string, sourceCommentId?: string, reactionCommentId?: string): Message {
|
|
435
|
+
createMessage(sessionId: string, content: string, sourceCommentId?: string, reactionCommentId?: string, model?: string): Message {
|
|
436
436
|
const now = new Date().toISOString();
|
|
437
437
|
const id = crypto.randomUUID();
|
|
438
438
|
this.msgStmts.insert.run(
|
|
@@ -444,6 +444,7 @@ export class Store {
|
|
|
444
444
|
id, sessionId, content, sourceCommentId, reactionCommentId,
|
|
445
445
|
status: "pending", attempts: 0,
|
|
446
446
|
createdAt: new Date(now), updatedAt: new Date(now),
|
|
447
|
+
model,
|
|
447
448
|
};
|
|
448
449
|
}
|
|
449
450
|
|
package/src/opencode.ts
CHANGED
|
@@ -165,9 +165,9 @@ export class Engine {
|
|
|
165
165
|
|
|
166
166
|
switch (event.type) {
|
|
167
167
|
case "issue_opened":
|
|
168
|
-
return this.handleOpened(ref, scopeKey, issueData, tracker);
|
|
168
|
+
return this.handleOpened(ref, scopeKey, issueData, tracker, event.model);
|
|
169
169
|
case "comment_created":
|
|
170
|
-
return this.handleCommented(ref, scopeKey, issueData, event.comment!, tracker);
|
|
170
|
+
return this.handleCommented(ref, scopeKey, issueData, event.comment!, tracker, event.model);
|
|
171
171
|
case "issue_closed":
|
|
172
172
|
return this.handleClosed(ref, scopeKey, tracker);
|
|
173
173
|
}
|
|
@@ -177,7 +177,8 @@ export class Engine {
|
|
|
177
177
|
ref: TrackerRef,
|
|
178
178
|
scopeKey: string,
|
|
179
179
|
issueData: TrackerEvent["issue"],
|
|
180
|
-
tracker: IssueTracker
|
|
180
|
+
tracker: IssueTracker,
|
|
181
|
+
model?: string,
|
|
181
182
|
) {
|
|
182
183
|
// Create or find issue
|
|
183
184
|
const issue = this.store.findOrCreateIssue(ref, scopeKey, issueData.title);
|
|
@@ -217,7 +218,7 @@ export class Engine {
|
|
|
217
218
|
this.handleLargeContent(workdir, issueData.body, "issue-body.txt"),
|
|
218
219
|
issueData.author, workdir, instructions
|
|
219
220
|
);
|
|
220
|
-
this.enqueueOrRun(session, issue, prompt);
|
|
221
|
+
this.enqueueOrRun(session, issue, prompt, undefined, model);
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
private async handleCommented(
|
|
@@ -225,7 +226,8 @@ export class Engine {
|
|
|
225
226
|
scopeKey: string,
|
|
226
227
|
issueData: TrackerEvent["issue"],
|
|
227
228
|
comment: NonNullable<TrackerEvent["comment"]>,
|
|
228
|
-
tracker: IssueTracker
|
|
229
|
+
tracker: IssueTracker,
|
|
230
|
+
model?: string,
|
|
229
231
|
) {
|
|
230
232
|
if (!comment) return;
|
|
231
233
|
|
|
@@ -281,7 +283,7 @@ export class Engine {
|
|
|
281
283
|
// Immediate ack
|
|
282
284
|
await tracker.createComment(ref, `[system] ✓ Message forwarded to **${session.name}**${this.running.has(this.sessionKey(session, issue)) ? " (running)" : ""}.\n> session: \`${session.id}\` | workdir: \`${workdir}\``);
|
|
283
285
|
|
|
284
|
-
this.enqueueOrRun(session, issue, prompt, comment.id);
|
|
286
|
+
this.enqueueOrRun(session, issue, prompt, comment.id, model);
|
|
285
287
|
} else {
|
|
286
288
|
// Create new session
|
|
287
289
|
session = this.store.createSession(issue.id, mentionName);
|
|
@@ -299,7 +301,7 @@ export class Engine {
|
|
|
299
301
|
this.handleLargeContent(workdir, issueData.body, "issue-body.txt"),
|
|
300
302
|
issueData.author, workdir, instructions
|
|
301
303
|
);
|
|
302
|
-
this.enqueueOrRun(session, issue, prompt, comment.id);
|
|
304
|
+
this.enqueueOrRun(session, issue, prompt, comment.id, model);
|
|
303
305
|
}
|
|
304
306
|
} else {
|
|
305
307
|
// No @mention → broadcast to all sessions on this issue
|
|
@@ -317,7 +319,7 @@ export class Engine {
|
|
|
317
319
|
session.name, this.handleLargeContent(workdir, comment.body, `comment-${comment.id}.txt`),
|
|
318
320
|
comment.author, issueData.title, workdir, instructions
|
|
319
321
|
);
|
|
320
|
-
this.enqueueOrRun(session, issue, prompt, comment.id);
|
|
322
|
+
this.enqueueOrRun(session, issue, prompt, comment.id, model);
|
|
321
323
|
}
|
|
322
324
|
|
|
323
325
|
// Immediate ack
|
|
@@ -382,13 +384,13 @@ export class Engine {
|
|
|
382
384
|
|
|
383
385
|
// ─── Preemptive Scheduler ───
|
|
384
386
|
|
|
385
|
-
private enqueueOrRun(session: OpSession, issue: Issue, prompt: string, sourceCommentId?: string) {
|
|
387
|
+
private enqueueOrRun(session: OpSession, issue: Issue, prompt: string, sourceCommentId?: string, model?: string) {
|
|
386
388
|
const k = this.sessionKey(session, issue);
|
|
387
389
|
|
|
388
390
|
this.stuckNudgeRounds.delete(k);
|
|
389
391
|
this.processExitNudgeRounds.delete(k);
|
|
390
392
|
|
|
391
|
-
const msg = this.store.createMessage(session.id, prompt, sourceCommentId);
|
|
393
|
+
const msg = this.store.createMessage(session.id, prompt, sourceCommentId, undefined, model);
|
|
392
394
|
|
|
393
395
|
if (this.running.has(k)) {
|
|
394
396
|
// PREEMPTIVE: Kill running process, new message takes priority
|
|
@@ -455,6 +457,12 @@ export class Engine {
|
|
|
455
457
|
if (session.opencodeSessionId) {
|
|
456
458
|
args.push("--session", session.opencodeSessionId);
|
|
457
459
|
}
|
|
460
|
+
// Push --model BEFORE the message content. Defends against env-var-
|
|
461
|
+
// registered providers stealing the slot (the original bug). Empty/
|
|
462
|
+
// undefined = omit, let opencode pick per its own opencode.json.
|
|
463
|
+
if (msg.model) {
|
|
464
|
+
args.push("--model", msg.model);
|
|
465
|
+
}
|
|
458
466
|
args.push(msg.content);
|
|
459
467
|
|
|
460
468
|
// Set eyes reaction on the source comment
|
|
@@ -466,10 +474,21 @@ export class Engine {
|
|
|
466
474
|
|
|
467
475
|
let exitCode: number | null = null;
|
|
468
476
|
|
|
477
|
+
// M-1: build the child env explicitly. When a model IS resolved we push
|
|
478
|
+
// --model above, so opencode ignores OPENCODE_MODEL anyway. When NO model
|
|
479
|
+
// is resolved we must not let a leaked OPENCODE_MODEL from our own env
|
|
480
|
+
// silently win — strip it so opencode falls back to its opencode.json
|
|
481
|
+
// (the operator's explicit config) instead of arbitrary env pollution.
|
|
482
|
+
// Provider keys / Gitea vars are preserved (opencode + its plugin need
|
|
483
|
+
// them); only the explicit model-override var is neutralized.
|
|
484
|
+
const childEnv = { ...process.env };
|
|
485
|
+
if (!msg.model) delete childEnv.OPENCODE_MODEL;
|
|
486
|
+
|
|
469
487
|
try {
|
|
470
488
|
const proc = spawn({
|
|
471
489
|
cmd: args,
|
|
472
490
|
cwd: workdir,
|
|
491
|
+
env: childEnv,
|
|
473
492
|
stdout: "pipe",
|
|
474
493
|
stderr: "pipe",
|
|
475
494
|
stdin: "ignore",
|
|
@@ -119,6 +119,11 @@ export class GiteaTracker implements IssueTracker {
|
|
|
119
119
|
const repoName = repository.name as string;
|
|
120
120
|
if (!repoOwner || !repoName) return null;
|
|
121
121
|
|
|
122
|
+
// ework-web extension (non-Gitea field, ignored by strict Gitea consumers).
|
|
123
|
+
// Empty/missing = no model override; engine omits --model.
|
|
124
|
+
const modelRaw = repository.ework_model;
|
|
125
|
+
const model = typeof modelRaw === "string" && modelRaw.trim() ? modelRaw.trim() : undefined;
|
|
126
|
+
|
|
122
127
|
const ref: TrackerRef = {
|
|
123
128
|
trackerType: "gitea",
|
|
124
129
|
scope: { owner: repoOwner, repo: repoName },
|
|
@@ -137,6 +142,7 @@ export class GiteaTracker implements IssueTracker {
|
|
|
137
142
|
state: (issue.state as string) ?? "open",
|
|
138
143
|
author: issueUser?.login ?? "",
|
|
139
144
|
},
|
|
145
|
+
model,
|
|
140
146
|
};
|
|
141
147
|
}
|
|
142
148
|
|
|
@@ -156,6 +162,7 @@ export class GiteaTracker implements IssueTracker {
|
|
|
156
162
|
body: comment.body as string,
|
|
157
163
|
author: commentUser?.login ?? "",
|
|
158
164
|
},
|
|
165
|
+
model,
|
|
159
166
|
};
|
|
160
167
|
}
|
|
161
168
|
|
|
@@ -169,6 +176,7 @@ export class GiteaTracker implements IssueTracker {
|
|
|
169
176
|
state: "closed",
|
|
170
177
|
author: issueUser?.login ?? "",
|
|
171
178
|
},
|
|
179
|
+
model,
|
|
172
180
|
};
|
|
173
181
|
}
|
|
174
182
|
|
package/src/trackers/types.ts
CHANGED
|
@@ -29,6 +29,10 @@ export interface TrackerEvent {
|
|
|
29
29
|
body: string;
|
|
30
30
|
author: string;
|
|
31
31
|
};
|
|
32
|
+
// Resolved "provider/model" string from ework-web (project override or
|
|
33
|
+
// global default). Empty/undefined = no override; engine omits --model
|
|
34
|
+
// and lets opencode pick per its own opencode.json + env.
|
|
35
|
+
model?: string;
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
/** Tracker-agnostic comment */
|
|
@@ -94,6 +98,10 @@ export interface Message {
|
|
|
94
98
|
error?: string;
|
|
95
99
|
createdAt: Date;
|
|
96
100
|
updatedAt: Date;
|
|
101
|
+
// Resolved "provider/model" string from ework-web. When set, engine pushes
|
|
102
|
+
// `--model <X>` on opencode spawn to override opencode.json + env vars.
|
|
103
|
+
// Undefined = no override (let opencode pick).
|
|
104
|
+
model?: string;
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
// ─── Adapter Interface ───
|