@skydiveai/pi-extensions 0.1.0-beta.1318 → 0.1.0-beta.1326
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/dist/index.mjs +24 -12
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3664,8 +3664,14 @@ const toolCallSummaryExtension = (pi) => {
|
|
|
3664
3664
|
* from the origin messageId in its channel context (`resolveConversationFromApi`)
|
|
3665
3665
|
* — and every run of the same conversation resolves to the same id, keeping the
|
|
3666
3666
|
* shared map correctly scoped across turns. `bg_*`, the completion wake, and the
|
|
3667
|
-
* next-session injection all filter
|
|
3668
|
-
*
|
|
3667
|
+
* next-session injection all filter by a **scope key** — the resolved
|
|
3668
|
+
* conversation id, or, when a session's conversation is unresolvable (a bare
|
|
3669
|
+
* CLI session, or a run whose channel-context ref carries no messageId), a
|
|
3670
|
+
* sentinel unique to that one session instance. Comparing on the raw
|
|
3671
|
+
* `conversationId` would bucket every unresolvable session together under
|
|
3672
|
+
* `null` and leak one's completion wake / status / next-session injection into
|
|
3673
|
+
* another; the sentinel keeps each isolated so an agent never sees or is woken
|
|
3674
|
+
* by a task from a different chat. Only the output log
|
|
3669
3675
|
* spills to disk (/home/user/.anyone/bg-tasks/<id>.log) to avoid buffering a chatty job
|
|
3670
3676
|
* in memory; exit code and run state live on the in-memory task.
|
|
3671
3677
|
*
|
|
@@ -3696,11 +3702,12 @@ function taskLabel(meta) {
|
|
|
3696
3702
|
return `${meta.id} "${meta.description ?? meta.command.slice(0, 60)}"`;
|
|
3697
3703
|
}
|
|
3698
3704
|
let taskCounter = 0;
|
|
3705
|
+
let sessionScopeCounter = 0;
|
|
3699
3706
|
const tasks = /* @__PURE__ */ new Map();
|
|
3700
3707
|
let watchdogInterval = null;
|
|
3701
3708
|
let lastKeepaliveAt = 0;
|
|
3702
|
-
function
|
|
3703
|
-
return meta.
|
|
3709
|
+
function sameScope(meta, scopeKey) {
|
|
3710
|
+
return meta.scopeKey === scopeKey;
|
|
3704
3711
|
}
|
|
3705
3712
|
function logPath(id) {
|
|
3706
3713
|
return join(tasksDir(), `${id}.log`);
|
|
@@ -3813,6 +3820,10 @@ function createBackgroundTasksExtension({ channelContext }) {
|
|
|
3813
3820
|
return id;
|
|
3814
3821
|
});
|
|
3815
3822
|
}
|
|
3823
|
+
const unresolvedScopeSentinel = `unresolved:${process.pid.toString(36)}:${(sessionScopeCounter += 1).toString(36)}`;
|
|
3824
|
+
function scopeKey() {
|
|
3825
|
+
return conversationId ?? unresolvedScopeSentinel;
|
|
3826
|
+
}
|
|
3816
3827
|
let agentActive = false;
|
|
3817
3828
|
pi.on("agent_start", async () => {
|
|
3818
3829
|
agentActive = true;
|
|
@@ -3846,7 +3857,7 @@ This is a background-task completion, not a message from the user. If it needs n
|
|
|
3846
3857
|
}
|
|
3847
3858
|
async function notifyCompletion(meta) {
|
|
3848
3859
|
if (meta.notified) return;
|
|
3849
|
-
if (agentActive &&
|
|
3860
|
+
if (agentActive && sameScope(meta, scopeKey())) {
|
|
3850
3861
|
meta.notified = true;
|
|
3851
3862
|
pi.sendMessage(await taskDoneMessage(meta), {
|
|
3852
3863
|
triggerTurn: true,
|
|
@@ -3903,6 +3914,7 @@ This is a background-task completion, not a message from the user. If it needs n
|
|
|
3903
3914
|
logBytes: 0,
|
|
3904
3915
|
lastOutputAt: startedAt,
|
|
3905
3916
|
conversationId,
|
|
3917
|
+
scopeKey: scopeKey(),
|
|
3906
3918
|
messageId,
|
|
3907
3919
|
description,
|
|
3908
3920
|
notified: false,
|
|
@@ -3948,16 +3960,16 @@ This is a background-task completion, not a message from the user. If it needs n
|
|
|
3948
3960
|
return meta;
|
|
3949
3961
|
}
|
|
3950
3962
|
function knownTaskIds() {
|
|
3951
|
-
return [...tasks.values()].filter((t) =>
|
|
3963
|
+
return [...tasks.values()].filter((t) => sameScope(t, scopeKey())).map((t) => t.id).join(", ") || "(none)";
|
|
3952
3964
|
}
|
|
3953
3965
|
pi.on("session_start", async () => {
|
|
3954
3966
|
if (tasks.size === 0) return;
|
|
3955
3967
|
await ensureConversationId();
|
|
3956
|
-
for (const [id, meta] of tasks) if (
|
|
3968
|
+
for (const [id, meta] of tasks) if (sameScope(meta, scopeKey()) && !meta.running && meta.notified) {
|
|
3957
3969
|
tasks.delete(id);
|
|
3958
3970
|
await unlink(logPath(id)).catch(() => {});
|
|
3959
3971
|
}
|
|
3960
|
-
const unnotified = [...tasks.values()].filter((t) =>
|
|
3972
|
+
const unnotified = [...tasks.values()].filter((t) => sameScope(t, scopeKey()) && !t.notified && !t.running);
|
|
3961
3973
|
for (const meta of unnotified) {
|
|
3962
3974
|
meta.notified = true;
|
|
3963
3975
|
pi.sendMessage(await taskDoneMessage(meta));
|
|
@@ -3966,7 +3978,7 @@ This is a background-task completion, not a message from the user. If it needs n
|
|
|
3966
3978
|
conversationId,
|
|
3967
3979
|
count: unnotified.length
|
|
3968
3980
|
}, "injected completed bg tasks at session_start");
|
|
3969
|
-
if ([...tasks.values()].some((t) =>
|
|
3981
|
+
if ([...tasks.values()].some((t) => sameScope(t, scopeKey()) && t.running)) ensureWatchdog();
|
|
3970
3982
|
});
|
|
3971
3983
|
function err(text) {
|
|
3972
3984
|
return {
|
|
@@ -3983,11 +3995,11 @@ This is a background-task completion, not a message from the user. If it needs n
|
|
|
3983
3995
|
}
|
|
3984
3996
|
function resolveTask(taskId) {
|
|
3985
3997
|
const exact = tasks.get(taskId);
|
|
3986
|
-
if (exact &&
|
|
3998
|
+
if (exact && sameScope(exact, scopeKey())) return {
|
|
3987
3999
|
error: null,
|
|
3988
4000
|
meta: exact
|
|
3989
4001
|
};
|
|
3990
|
-
const matches = [...tasks.values()].filter((t) =>
|
|
4002
|
+
const matches = [...tasks.values()].filter((t) => sameScope(t, scopeKey()) && t.id.startsWith(taskId));
|
|
3991
4003
|
if (matches.length === 1) return {
|
|
3992
4004
|
error: null,
|
|
3993
4005
|
meta: matches[0]
|
|
@@ -3996,7 +4008,7 @@ This is a background-task completion, not a message from the user. If it needs n
|
|
|
3996
4008
|
return err(`Unknown task ${taskId}. Known tasks: ${knownTaskIds()}`);
|
|
3997
4009
|
}
|
|
3998
4010
|
function listTasks() {
|
|
3999
|
-
const mine = [...tasks.values()].filter((t) =>
|
|
4011
|
+
const mine = [...tasks.values()].filter((t) => sameScope(t, scopeKey()));
|
|
4000
4012
|
if (mine.length === 0) return "No background tasks.";
|
|
4001
4013
|
return mine.map((t) => {
|
|
4002
4014
|
const state = t.running ? "running" : t.exitCode !== null ? `exited ${t.exitCode}${t.killedReason ? ` (killed: ${t.killedReason})` : ""}` : t.killedReason ? `killed: ${t.killedReason}` : "ended";
|