@elizaos/plugin-agent-orchestrator 0.3.13 → 0.3.15

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.
@@ -1 +1 @@
1
- {"version":3,"file":"coding-task-helpers.d.ts","sourceRoot":"","sources":["../../src/actions/coding-task-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,4DAA4D;AAC5D,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,MAAM,CA4BR;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,QAAQ,CAAC,EAAE,eAAe,EAC1B,iBAAiB,UAAQ,GACxB,IAAI,CAqDN"}
1
+ {"version":3,"file":"coding-task-helpers.d.ts","sourceRoot":"","sources":["../../src/actions/coding-task-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,4DAA4D;AAC5D,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,MAAM,CA4BR;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,QAAQ,CAAC,EAAE,eAAe,EAC1B,iBAAiB,UAAQ,GACxB,IAAI,CA6DN"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-routes.d.ts","sourceRoot":"","sources":["../../src/api/agent-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAajE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiMhD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,OAAO,CAAC,CAuelB"}
1
+ {"version":3,"file":"agent-routes.d.ts","sourceRoot":"","sources":["../../src/api/agent-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAajE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiMhD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,OAAO,CAAC,CAgiBlB"}
package/dist/index.js CHANGED
@@ -5081,8 +5081,8 @@ ${preview}` : `Agent "${label}" completed the task.`
5081
5081
  if ((event === "stopped" || event === "task_complete" || event === "error") && scratchDir) {
5082
5082
  const wsService = runtime.getService("CODING_WORKSPACE_SERVICE");
5083
5083
  if (wsService) {
5084
- wsService.removeScratchDir(scratchDir).catch((err) => {
5085
- logger5.warn(`[START_CODING_TASK] Failed to cleanup scratch dir for "${label}": ${err}`);
5084
+ wsService.registerScratchWorkspace(sessionId, scratchDir, label, event).catch((err) => {
5085
+ logger5.warn(`[START_CODING_TASK] Failed to register scratch workspace for "${label}": ${err}`);
5086
5086
  });
5087
5087
  }
5088
5088
  }
@@ -6129,6 +6129,7 @@ var activeWorkspaceContextProvider = {
6129
6129
  // src/services/workspace-service.ts
6130
6130
  import * as os3 from "node:os";
6131
6131
  import * as path5 from "node:path";
6132
+ import * as fs3 from "node:fs/promises";
6132
6133
  import {
6133
6134
  CredentialService,
6134
6135
  GitHubPatClient as GitHubPatClient2,
@@ -6410,6 +6411,8 @@ class CodingWorkspaceService {
6410
6411
  serviceConfig;
6411
6412
  workspaces = new Map;
6412
6413
  labels = new Map;
6414
+ scratchBySession = new Map;
6415
+ scratchCleanupTimers = new Map;
6413
6416
  eventCallbacks = [];
6414
6417
  authPromptCallback = null;
6415
6418
  constructor(runtime, config = {}) {
@@ -6467,6 +6470,10 @@ class CodingWorkspaceService {
6467
6470
  });
6468
6471
  }
6469
6472
  async stop() {
6473
+ for (const timer of this.scratchCleanupTimers.values()) {
6474
+ clearTimeout(timer);
6475
+ }
6476
+ this.scratchCleanupTimers.clear();
6470
6477
  for (const [id] of this.workspaces) {
6471
6478
  try {
6472
6479
  await this.removeWorkspace(id);
@@ -6666,6 +6673,89 @@ class CodingWorkspaceService {
6666
6673
  async removeScratchDir(dirPath) {
6667
6674
  return removeScratchDir(dirPath, this.serviceConfig.baseDir, (msg) => this.log(msg));
6668
6675
  }
6676
+ listScratchWorkspaces() {
6677
+ return Array.from(this.scratchBySession.values()).sort((a, b) => b.terminalAt - a.terminalAt);
6678
+ }
6679
+ async registerScratchWorkspace(sessionId, dirPath, label, terminalEvent) {
6680
+ const now = Date.now();
6681
+ const existing = this.scratchBySession.get(sessionId);
6682
+ const base = existing ?? {
6683
+ sessionId,
6684
+ label,
6685
+ path: dirPath,
6686
+ createdAt: now,
6687
+ terminalAt: now,
6688
+ terminalEvent,
6689
+ status: "pending_decision"
6690
+ };
6691
+ const policy = this.getScratchRetentionPolicy();
6692
+ if (policy === "ephemeral") {
6693
+ await this.removeScratchDir(dirPath);
6694
+ this.scratchBySession.delete(sessionId);
6695
+ this.clearScratchCleanupTimer(sessionId);
6696
+ return null;
6697
+ }
6698
+ const record = {
6699
+ ...base,
6700
+ label,
6701
+ path: dirPath,
6702
+ terminalAt: now,
6703
+ terminalEvent,
6704
+ status: policy === "persistent" ? "kept" : "pending_decision",
6705
+ expiresAt: undefined
6706
+ };
6707
+ this.scratchBySession.set(sessionId, record);
6708
+ if (record.status === "pending_decision") {
6709
+ const ttlMs = this.getScratchDecisionTtlMs();
6710
+ record.expiresAt = now + ttlMs;
6711
+ this.scheduleScratchCleanup(sessionId, ttlMs);
6712
+ } else {
6713
+ this.clearScratchCleanupTimer(sessionId);
6714
+ }
6715
+ return record;
6716
+ }
6717
+ async keepScratchWorkspace(sessionId) {
6718
+ const record = this.requireScratchWorkspace(sessionId);
6719
+ const next = {
6720
+ ...record,
6721
+ status: "kept",
6722
+ expiresAt: undefined
6723
+ };
6724
+ this.scratchBySession.set(sessionId, next);
6725
+ this.clearScratchCleanupTimer(sessionId);
6726
+ return next;
6727
+ }
6728
+ async deleteScratchWorkspace(sessionId) {
6729
+ const record = this.requireScratchWorkspace(sessionId);
6730
+ await this.removeScratchDir(record.path);
6731
+ this.scratchBySession.delete(sessionId);
6732
+ this.clearScratchCleanupTimer(sessionId);
6733
+ }
6734
+ async promoteScratchWorkspace(sessionId, name) {
6735
+ const record = this.requireScratchWorkspace(sessionId);
6736
+ const baseDir = this.serviceConfig.baseDir;
6737
+ const suggestedName = this.sanitizeWorkspaceName(name || record.label);
6738
+ const targetPath = await this.allocatePromotedPath(baseDir, suggestedName);
6739
+ try {
6740
+ await fs3.rename(record.path, targetPath);
6741
+ } catch (error) {
6742
+ const isExdev = typeof error === "object" && error !== null && "code" in error && error.code === "EXDEV";
6743
+ if (!isExdev)
6744
+ throw error;
6745
+ await fs3.cp(record.path, targetPath, { recursive: true });
6746
+ await fs3.access(targetPath);
6747
+ await fs3.rm(record.path, { recursive: true, force: true });
6748
+ }
6749
+ const next = {
6750
+ ...record,
6751
+ path: targetPath,
6752
+ status: "promoted",
6753
+ expiresAt: undefined
6754
+ };
6755
+ this.scratchBySession.set(sessionId, next);
6756
+ this.clearScratchCleanupTimer(sessionId);
6757
+ return next;
6758
+ }
6669
6759
  async gcOrphanedWorkspaces() {
6670
6760
  return gcOrphanedWorkspaces(this.serviceConfig.baseDir, this.serviceConfig.workspaceTtlMs ?? 24 * 60 * 60 * 1000, new Set(this.workspaces.keys()), (msg) => this.log(msg));
6671
6761
  }
@@ -6674,9 +6764,77 @@ class CodingWorkspaceService {
6674
6764
  console.log(`[CodingWorkspaceService] ${message}`);
6675
6765
  }
6676
6766
  }
6767
+ getScratchRetentionPolicy() {
6768
+ const setting = this.runtime.getSetting("PARALLAX_SCRATCH_RETENTION") ?? process.env.PARALLAX_SCRATCH_RETENTION;
6769
+ const normalized = setting?.trim().toLowerCase();
6770
+ if (normalized === "ephemeral")
6771
+ return "ephemeral";
6772
+ if (normalized === "persistent" || normalized === "keep") {
6773
+ return "persistent";
6774
+ }
6775
+ return "pending_decision";
6776
+ }
6777
+ getScratchDecisionTtlMs() {
6778
+ const setting = this.runtime.getSetting("PARALLAX_SCRATCH_DECISION_TTL_MS");
6779
+ const parsed = Number(setting ?? process.env.PARALLAX_SCRATCH_DECISION_TTL_MS);
6780
+ if (Number.isFinite(parsed) && parsed > 0)
6781
+ return parsed;
6782
+ return 24 * 60 * 60 * 1000;
6783
+ }
6784
+ requireScratchWorkspace(sessionId) {
6785
+ const record = this.scratchBySession.get(sessionId);
6786
+ if (!record) {
6787
+ throw new Error(`Scratch workspace for session ${sessionId} not found`);
6788
+ }
6789
+ return record;
6790
+ }
6791
+ clearScratchCleanupTimer(sessionId) {
6792
+ const timer = this.scratchCleanupTimers.get(sessionId);
6793
+ if (timer) {
6794
+ clearTimeout(timer);
6795
+ this.scratchCleanupTimers.delete(sessionId);
6796
+ }
6797
+ }
6798
+ scheduleScratchCleanup(sessionId, ttlMs) {
6799
+ this.clearScratchCleanupTimer(sessionId);
6800
+ const timer = setTimeout(async () => {
6801
+ try {
6802
+ const record = this.scratchBySession.get(sessionId);
6803
+ if (!record || record.status !== "pending_decision")
6804
+ return;
6805
+ await this.removeScratchDir(record.path);
6806
+ } catch (error) {
6807
+ console.warn(`[CodingWorkspaceService] scratch cleanup failed for ${sessionId}: ${String(error)}`);
6808
+ } finally {
6809
+ this.scratchBySession.delete(sessionId);
6810
+ this.scratchCleanupTimers.delete(sessionId);
6811
+ }
6812
+ }, ttlMs);
6813
+ this.scratchCleanupTimers.set(sessionId, timer);
6814
+ }
6815
+ sanitizeWorkspaceName(raw) {
6816
+ const compact = raw.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
6817
+ return compact || `scratch-${Date.now().toString(36)}`;
6818
+ }
6819
+ async allocatePromotedPath(baseDir, baseName) {
6820
+ const baseResolved = path5.resolve(baseDir);
6821
+ for (let i = 0;i < 1000; i++) {
6822
+ const candidateName = i === 0 ? baseName : `${baseName}-${i}`;
6823
+ const candidate = path5.resolve(baseResolved, candidateName);
6824
+ if (candidate !== baseResolved && !candidate.startsWith(`${baseResolved}${path5.sep}`)) {
6825
+ continue;
6826
+ }
6827
+ try {
6828
+ await fs3.access(candidate);
6829
+ } catch {
6830
+ return candidate;
6831
+ }
6832
+ }
6833
+ throw new Error("Unable to allocate promoted workspace path");
6834
+ }
6677
6835
  }
6678
6836
  // src/api/agent-routes.ts
6679
- import { access, readFile as readFile3, realpath, rm } from "node:fs/promises";
6837
+ import { access as access2, readFile as readFile3, realpath, rm as rm2 } from "node:fs/promises";
6680
6838
  import { createHash } from "node:crypto";
6681
6839
  import * as os4 from "node:os";
6682
6840
  import * as path6 from "node:path";
@@ -6732,7 +6890,7 @@ async function resolveSafeVenvPath(workdir, venvDirRaw) {
6732
6890
  }
6733
6891
  async function fileExists(filePath) {
6734
6892
  try {
6735
- await access(filePath);
6893
+ await access2(filePath);
6736
6894
  return true;
6737
6895
  } catch {
6738
6896
  return false;
@@ -6784,7 +6942,7 @@ async function runBenchmarkPreflight(workdir) {
6784
6942
  const run = (async () => {
6785
6943
  const pythonCommand = process.platform === "win32" ? "python" : "python3";
6786
6944
  if (mode === "cold") {
6787
- await rm(venvPath, { recursive: true, force: true });
6945
+ await rm2(venvPath, { recursive: true, force: true });
6788
6946
  }
6789
6947
  const hasVenv = await fileExists(pythonInVenv);
6790
6948
  if (!hasVenv) {
@@ -6836,6 +6994,44 @@ async function handleAgentRoutes(req, res, pathname, ctx) {
6836
6994
  sendJson(res, ctx.ptyService.getAgentMetrics());
6837
6995
  return true;
6838
6996
  }
6997
+ if (method === "GET" && pathname === "/api/coding-agents/scratch") {
6998
+ if (!ctx.workspaceService) {
6999
+ sendError(res, "Workspace Service not available", 503);
7000
+ return true;
7001
+ }
7002
+ sendJson(res, ctx.workspaceService.listScratchWorkspaces());
7003
+ return true;
7004
+ }
7005
+ const scratchActionMatch = pathname.match(/^\/api\/coding-agents\/([^/]+)\/scratch\/(keep|delete|promote)$/);
7006
+ if (method === "POST" && scratchActionMatch) {
7007
+ if (!ctx.workspaceService) {
7008
+ sendError(res, "Workspace Service not available", 503);
7009
+ return true;
7010
+ }
7011
+ const sessionId = scratchActionMatch[1];
7012
+ const action = scratchActionMatch[2];
7013
+ try {
7014
+ if (action === "keep") {
7015
+ const scratch2 = await ctx.workspaceService.keepScratchWorkspace(sessionId);
7016
+ sendJson(res, { success: true, scratch: scratch2 });
7017
+ return true;
7018
+ }
7019
+ if (action === "delete") {
7020
+ await ctx.workspaceService.deleteScratchWorkspace(sessionId);
7021
+ sendJson(res, { success: true, deleted: true, sessionId });
7022
+ return true;
7023
+ }
7024
+ const body = await parseBody(req);
7025
+ const promoteName = typeof body.name === "string" ? body.name : undefined;
7026
+ const scratch = await ctx.workspaceService.promoteScratchWorkspace(sessionId, promoteName);
7027
+ sendJson(res, { success: true, scratch });
7028
+ } catch (error) {
7029
+ const message = error instanceof Error ? error.message : String(error);
7030
+ const status = message.includes("not found") ? 404 : 500;
7031
+ sendError(res, message, status);
7032
+ }
7033
+ return true;
7034
+ }
6839
7035
  if (method === "GET" && pathname === "/api/coding-agents/workspace-files") {
6840
7036
  if (!ctx.ptyService) {
6841
7037
  sendError(res, "PTY Service not available", 503);
@@ -7597,7 +7793,7 @@ async function handleWorkspaceRoutes(req, res, pathname, ctx) {
7597
7793
  // src/api/routes.ts
7598
7794
  var MAX_BODY_SIZE = 1024 * 1024;
7599
7795
  async function parseBody(req) {
7600
- return new Promise((resolve5, reject) => {
7796
+ return new Promise((resolve6, reject) => {
7601
7797
  let body = "";
7602
7798
  let size = 0;
7603
7799
  req.on("data", (chunk) => {
@@ -7611,7 +7807,7 @@ async function parseBody(req) {
7611
7807
  });
7612
7808
  req.on("end", () => {
7613
7809
  try {
7614
- resolve5(body ? JSON.parse(body) : {});
7810
+ resolve6(body ? JSON.parse(body) : {});
7615
7811
  } catch {
7616
7812
  reject(new Error("Invalid JSON body"));
7617
7813
  }
@@ -7699,5 +7895,5 @@ export {
7699
7895
  CodingWorkspaceService
7700
7896
  };
7701
7897
 
7702
- //# debugId=A818F3DE8DCF48E664756E2164756E21
7898
+ //# debugId=C0B3DB8984D7685C64756E2164756E21
7703
7899
  //# sourceMappingURL=index.js.map