ework-daemon 0.4.39 → 0.4.40
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/opencode.ts +21 -1
package/package.json
CHANGED
package/src/opencode.ts
CHANGED
|
@@ -283,6 +283,7 @@ export interface EngineOptions {
|
|
|
283
283
|
daemonId: number;
|
|
284
284
|
takeover?: TakeoverStrategy;
|
|
285
285
|
backend?: RuntimeBackend;
|
|
286
|
+
gateChecker?: (issue: Issue) => Promise<{ allowed: boolean; reason: string }>;
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
function createDefaultBackend(cfg: Config): RuntimeBackend {
|
|
@@ -299,6 +300,7 @@ export class Engine {
|
|
|
299
300
|
private readonly daemonId: number;
|
|
300
301
|
private readonly takeover: TakeoverStrategy;
|
|
301
302
|
private readonly backend: RuntimeBackend;
|
|
303
|
+
private gateChecker: (issue: Issue) => Promise<{ allowed: boolean; reason: string }>;
|
|
302
304
|
private heartbeatTimer?: ReturnType<typeof setInterval>;
|
|
303
305
|
private maxConcurrent: number;
|
|
304
306
|
private maxConcurrentExplicit: boolean;
|
|
@@ -350,6 +352,7 @@ export class Engine {
|
|
|
350
352
|
this.daemonId = opts.daemonId;
|
|
351
353
|
this.takeover = opts.takeover ?? new RecloneStrategy(cfg);
|
|
352
354
|
this.backend = opts.backend ?? createDefaultBackend(cfg);
|
|
355
|
+
this.gateChecker = opts.gateChecker ?? ((issue: Issue) => this.webGateAllows(issue));
|
|
353
356
|
this.maxConcurrent = cfg.work.maxConcurrent;
|
|
354
357
|
this.maxConcurrentExplicit = cfg.work.maxConcurrentExplicit;
|
|
355
358
|
this.startGlobalObserver();
|
|
@@ -1119,6 +1122,17 @@ export class Engine {
|
|
|
1119
1122
|
// ─── Process Manager ───
|
|
1120
1123
|
|
|
1121
1124
|
private async execProcess(k: string, session: OpSession, issue: Issue, msg: Message) {
|
|
1125
|
+
const gate = await this.gateChecker(issue);
|
|
1126
|
+
if (!gate.allowed) {
|
|
1127
|
+
log.info(`engine: execProcess blocked by web gate (${gate.reason}) for ${k}`);
|
|
1128
|
+
await this.store.updateMessageStatus(msg.id, "failed", `gate: ${gate.reason}`);
|
|
1129
|
+
this.running.delete(k);
|
|
1130
|
+
this.currentMessage.delete(k);
|
|
1131
|
+
this.currentModel.delete(k);
|
|
1132
|
+
void this.dequeueAfterGate(k, session, issue);
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1122
1136
|
const gen = (this.generation.get(k) ?? 0) + 1;
|
|
1123
1137
|
this.generation.set(k, gen);
|
|
1124
1138
|
|
|
@@ -1392,6 +1406,12 @@ export class Engine {
|
|
|
1392
1406
|
void this.drainGlobalPending();
|
|
1393
1407
|
}
|
|
1394
1408
|
|
|
1409
|
+
private async dequeueAfterGate(k: string, session: OpSession, issue: Issue): Promise<void> {
|
|
1410
|
+
const next = await this.store.getNextPendingMessage(session.id);
|
|
1411
|
+
if (!next) return;
|
|
1412
|
+
await this.dequeueOrIdle(k, session, issue, next);
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1395
1415
|
private async drainGlobalPending(): Promise<void> {
|
|
1396
1416
|
const slotsAvailable = this.maxConcurrent - this.running.size;
|
|
1397
1417
|
if (slotsAvailable <= 0) return;
|
|
@@ -1574,7 +1594,7 @@ export class Engine {
|
|
|
1574
1594
|
|
|
1575
1595
|
for (const issue of ownedIssues) {
|
|
1576
1596
|
try {
|
|
1577
|
-
|
|
1597
|
+
const gate = await this.gateChecker(issue);
|
|
1578
1598
|
if (!gate.allowed) {
|
|
1579
1599
|
log.info(`engine: observer — web gate blocked ${issue.trackerScopeKey}#${issue.trackerIssueId} (${gate.reason})`);
|
|
1580
1600
|
continue;
|