@skydiveai/pi-extensions 0.1.0-beta.1544 → 0.1.0-beta.1545

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.mjs +92 -0
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -2264,6 +2264,19 @@ async function postBackgroundTaskDone({ messageId, content }) {
2264
2264
  } });
2265
2265
  if (!res.ok) throw new Error(`bg-task-done POST failed: ${res.status}`);
2266
2266
  }
2267
+ function postBackgroundTasksSnapshot({ messageId, tasks }) {
2268
+ const client = sandboxClient();
2269
+ if (!client || !messageId) return;
2270
+ client["bg-tasks"].$post({ json: {
2271
+ messageId,
2272
+ tasks
2273
+ } }).catch((err) => {
2274
+ log$10.debug({
2275
+ err,
2276
+ event: "bg_tasks_snapshot_failed"
2277
+ }, "bg-tasks snapshot publish failed");
2278
+ });
2279
+ }
2267
2280
  async function postSubagentSpawn({ messageId, tasks }) {
2268
2281
  const client = sandboxClient();
2269
2282
  if (!client) throw new Error("no api url for subagent-spawn");
@@ -3695,6 +3708,7 @@ const WATCHDOG_INTERVAL_MS = 3e4;
3695
3708
  const KEEPALIVE_EVERY_MS = 6e4;
3696
3709
  const KEEPALIVE_MAX_MS = 3600 * 1e3;
3697
3710
  const STALL_HINT_AFTER_MS = 120 * 1e3;
3711
+ const PUBLISH_DEBOUNCE_MS = 300;
3698
3712
  const MAX_LOG_BYTES = 100 * 1024 * 1024;
3699
3713
  const DEFAULT_TAIL_LINES = 30;
3700
3714
  const TAIL_READ_BYTES = 64 * 1024;
@@ -3888,6 +3902,80 @@ This is a background-task completion, not a message from the user. If it needs n
3888
3902
  });
3889
3903
  } else log.info({ taskId: meta.id }, "bg task completed idle with no origin message; deferring to next session_start");
3890
3904
  }
3905
+ const SNAPSHOT_TAIL_LINES = 40;
3906
+ let lastPublishedSignature = null;
3907
+ let publishInFlight = null;
3908
+ let publishQueued = false;
3909
+ function snapshotSignature(snapshot) {
3910
+ return JSON.stringify(snapshot.map((t) => ({
3911
+ id: t.id,
3912
+ state: t.state,
3913
+ exitCode: t.exitCode,
3914
+ killedReason: t.killedReason,
3915
+ outputTail: t.outputTail
3916
+ })));
3917
+ }
3918
+ async function doPublishSnapshot() {
3919
+ if (!messageId) return;
3920
+ const mine = [...tasks.values()].filter((t) => sameScope(t, scopeKey()));
3921
+ try {
3922
+ const snapshot = await Promise.all(mine.map(async (t) => ({
3923
+ id: t.id,
3924
+ command: t.command,
3925
+ description: t.description,
3926
+ startedAt: t.startedAt,
3927
+ state: t.running ? "running" : "finished",
3928
+ exitCode: t.exitCode,
3929
+ killedReason: t.killedReason,
3930
+ outputTail: await tailLog(t.id, SNAPSHOT_TAIL_LINES)
3931
+ })));
3932
+ const signature = snapshotSignature(snapshot);
3933
+ if (signature === lastPublishedSignature) return;
3934
+ lastPublishedSignature = signature;
3935
+ postBackgroundTasksSnapshot({
3936
+ messageId,
3937
+ tasks: snapshot
3938
+ });
3939
+ } catch (err) {
3940
+ log.debug({
3941
+ err,
3942
+ event: "bg_tasks_snapshot_build_failed"
3943
+ }, "building bg-tasks snapshot failed");
3944
+ }
3945
+ }
3946
+ async function publishSnapshotNow() {
3947
+ if (publishInFlight) {
3948
+ publishQueued = true;
3949
+ return;
3950
+ }
3951
+ publishInFlight = (async () => {
3952
+ try {
3953
+ do {
3954
+ publishQueued = false;
3955
+ await doPublishSnapshot();
3956
+ } while (publishQueued);
3957
+ } finally {
3958
+ publishInFlight = null;
3959
+ }
3960
+ })();
3961
+ await publishInFlight;
3962
+ }
3963
+ let publishTimer = null;
3964
+ function schedulePublishSnapshot() {
3965
+ if (publishTimer) return;
3966
+ publishTimer = setTimeout(() => {
3967
+ publishTimer = null;
3968
+ publishSnapshotNow();
3969
+ }, PUBLISH_DEBOUNCE_MS);
3970
+ publishTimer.unref?.();
3971
+ }
3972
+ async function flushPublishSnapshot() {
3973
+ if (publishTimer) {
3974
+ clearTimeout(publishTimer);
3975
+ publishTimer = null;
3976
+ }
3977
+ await publishSnapshotNow();
3978
+ }
3891
3979
  async function launchTask({ command, description, cwd }) {
3892
3980
  taskCounter += 1;
3893
3981
  const id = `bg-${process.pid.toString(36)}-${taskCounter}`;
@@ -3950,6 +4038,7 @@ This is a background-task completion, not a message from the user. If it needs n
3950
4038
  taskId: id,
3951
4039
  exitCode: meta.exitCode
3952
4040
  }, "bg task finished");
4041
+ schedulePublishSnapshot();
3953
4042
  await notifyCompletion(meta);
3954
4043
  });
3955
4044
  ensureWatchdog();
@@ -3957,6 +4046,7 @@ This is a background-task completion, not a message from the user. If it needs n
3957
4046
  taskId: id,
3958
4047
  conversationId
3959
4048
  }, "bg task started");
4049
+ schedulePublishSnapshot();
3960
4050
  return meta;
3961
4051
  }
3962
4052
  function knownTaskIds() {
@@ -3979,6 +4069,8 @@ This is a background-task completion, not a message from the user. If it needs n
3979
4069
  count: unnotified.length
3980
4070
  }, "injected completed bg tasks at session_start");
3981
4071
  if ([...tasks.values()].some((t) => sameScope(t, scopeKey()) && t.running)) ensureWatchdog();
4072
+ lastPublishedSignature = null;
4073
+ await flushPublishSnapshot();
3982
4074
  });
3983
4075
  function err(text) {
3984
4076
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skydiveai/pi-extensions",
3
- "version": "0.1.0-beta.1544",
3
+ "version": "0.1.0-beta.1545",
4
4
  "homepage": "https://skydive.com",
5
5
  "license": "MIT",
6
6
  "author": "Create, Inc.",