opengate 0.2.8 → 0.2.9

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 (2) hide show
  1. package/dist/index.js +36 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -266,7 +266,10 @@ async function fetchInbox(url, apiKey) {
266
266
  throw new Error(`OpenGate inbox returned HTTP ${resp.status}`);
267
267
  }
268
268
  const body = await resp.json();
269
- return body.todo_tasks ?? [];
269
+ return {
270
+ todoTasks: body.todo_tasks ?? [],
271
+ inProgressTasks: body.in_progress_tasks ?? []
272
+ };
270
273
  }
271
274
  var OpenGatePoller = class {
272
275
  constructor(pluginCfg, openclawCfg, logger, stateDir) {
@@ -305,18 +308,26 @@ var OpenGatePoller = class {
305
308
  );
306
309
  return;
307
310
  }
308
- let tasks;
311
+ let inbox;
309
312
  try {
310
- tasks = await fetchInbox(this.pluginCfg.url, this.pluginCfg.apiKey);
313
+ inbox = await fetchInbox(this.pluginCfg.url, this.pluginCfg.apiKey);
311
314
  } catch (e) {
312
315
  this.logger.warn(
313
316
  `[opengate] Failed to fetch inbox: ${e instanceof Error ? e.message : String(e)}`
314
317
  );
315
318
  return;
316
319
  }
317
- if (tasks.length === 0) return;
318
- this.logger.info(`[opengate] Found ${tasks.length} todo task(s)`);
319
- for (const task of tasks) {
320
+ for (const task of inbox.inProgressTasks) {
321
+ if (!this.state.isSpawned(task.id)) {
322
+ this.logger.warn(
323
+ `[opengate] Orphaned in_progress task "${task.title}" (${task.id}) \u2014 releasing back to todo`
324
+ );
325
+ await this.releaseTask(task.id);
326
+ }
327
+ }
328
+ if (inbox.todoTasks.length === 0) return;
329
+ this.logger.info(`[opengate] Found ${inbox.todoTasks.length} todo task(s)`);
330
+ for (const task of inbox.todoTasks) {
320
331
  if (!this.running) break;
321
332
  const currentActive = this.state.activeCount();
322
333
  if (currentActive >= maxConcurrent) {
@@ -339,6 +350,25 @@ var OpenGatePoller = class {
339
350
  if (project) this.projectCache.set(projectId, project);
340
351
  return project;
341
352
  }
353
+ async releaseTask(taskId) {
354
+ try {
355
+ const resp = await fetch(
356
+ `${this.pluginCfg.url}/api/tasks/${taskId}/release`,
357
+ {
358
+ method: "POST",
359
+ headers: { Authorization: `Bearer ${this.pluginCfg.apiKey}` },
360
+ signal: AbortSignal.timeout(1e4)
361
+ }
362
+ );
363
+ if (!resp.ok) {
364
+ this.logger.warn(`[opengate] Failed to release task ${taskId}: HTTP ${resp.status}`);
365
+ }
366
+ } catch (e) {
367
+ this.logger.warn(
368
+ `[opengate] Failed to release task ${taskId}: ${e instanceof Error ? e.message : String(e)}`
369
+ );
370
+ }
371
+ }
342
372
  async spawnTask(task) {
343
373
  this.logger.info(`[opengate] Spawning session for task: "${task.title}" (${task.id})`);
344
374
  let project = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opengate",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "OpenGate task executor plugin for OpenClaw — polls assigned tasks and spawns isolated agent sessions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",