pi-shadow-mind 0.1.7 → 0.1.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.
- package/DESIGN.md +1 -1
- package/README.md +1 -1
- package/dist/index.js +60 -13
- package/dist/index.js.map +3 -3
- package/dist/protocol.js +5 -2
- package/dist/protocol.js.map +1 -1
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.js +28 -12
- package/dist/runtime.js.map +1 -1
- package/dist/session-lifetime.d.ts +8 -0
- package/dist/session-lifetime.js +31 -0
- package/dist/session-lifetime.js.map +1 -0
- package/package.json +1 -1
package/DESIGN.md
CHANGED
|
@@ -233,7 +233,7 @@ Main system prompt
|
|
|
233
233
|
→ one user message: plain-text Main trajectory + Shadow protocol + Shadow definition + kickoff
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
-
公共协议保持最小,只说明:当前实例是一次性的并行认知核心;消息历史已经过净化;它可以依照自身职责独立观察或执行工作;需要向 Main 同步结果时调用 `report_to_main`,该调用会立即结束当前 loop
|
|
236
|
+
公共协议保持最小,只说明:当前实例是一次性的并行认知核心;消息历史已经过净化;它可以依照自身职责独立观察或执行工作;需要向 Main 同步结果时调用 `report_to_main`,该调用会立即结束当前 loop;没有需要同步的内容时可以正常结束。kickoff 首先要求判断轨迹是否与当前 Shadow 职责相关:无关时只回复固定词 `NOT_RELEVANT` 并立即结束,不调用任何工具;相关时才继续执行职责。具体关注点、任务线和表达方式全部由 Shadow Markdown 决定。
|
|
237
237
|
|
|
238
238
|
轨迹范围覆盖当前 Main Session 从开始到激活时刻的全部历史,而不只包含当前用户 epoch。这样 Shadow 能看到早期用户约束和已经形成的会话决策。epoch 只用于判断 Shadow 的迟到结果能否介入,不参与轨迹裁剪。
|
|
239
239
|
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ npm pack
|
|
|
23
23
|
The generated `pi-shadow-mind-<version>.tgz` contains the compiled `dist/` extension. Publish it to npm for normal Pi installation, or unpack the standalone ZIP release and install that directory:
|
|
24
24
|
|
|
25
25
|
```powershell
|
|
26
|
-
pi install npm:pi-shadow-mind@0.1.
|
|
26
|
+
pi install npm:pi-shadow-mind@0.1.9
|
|
27
27
|
# or, after unpacking the ZIP
|
|
28
28
|
pi install ./pi-shadow-mind-0.1.0
|
|
29
29
|
```
|
package/dist/index.js
CHANGED
|
@@ -7918,6 +7918,35 @@ function sample(values, count, random) {
|
|
|
7918
7918
|
return copy.slice(0, count);
|
|
7919
7919
|
}
|
|
7920
7920
|
|
|
7921
|
+
// src/session-lifetime.ts
|
|
7922
|
+
var STALE_CONTEXT_MARKER = "This extension ctx is stale after session replacement or reload";
|
|
7923
|
+
var SessionLifetime = class {
|
|
7924
|
+
active = false;
|
|
7925
|
+
activate() {
|
|
7926
|
+
this.active = true;
|
|
7927
|
+
}
|
|
7928
|
+
deactivate() {
|
|
7929
|
+
this.active = false;
|
|
7930
|
+
}
|
|
7931
|
+
get isActive() {
|
|
7932
|
+
return this.active;
|
|
7933
|
+
}
|
|
7934
|
+
run(action) {
|
|
7935
|
+
if (!this.active) return false;
|
|
7936
|
+
try {
|
|
7937
|
+
action();
|
|
7938
|
+
return true;
|
|
7939
|
+
} catch (error) {
|
|
7940
|
+
if (!isStaleExtensionContextError(error)) throw error;
|
|
7941
|
+
this.active = false;
|
|
7942
|
+
return false;
|
|
7943
|
+
}
|
|
7944
|
+
}
|
|
7945
|
+
};
|
|
7946
|
+
function isStaleExtensionContextError(error) {
|
|
7947
|
+
return error instanceof Error && error.message.includes(STALE_CONTEXT_MARKER);
|
|
7948
|
+
}
|
|
7949
|
+
|
|
7921
7950
|
// src/shadow-runner.ts
|
|
7922
7951
|
import { mkdir as mkdir3 } from "node:fs/promises";
|
|
7923
7952
|
import { fileURLToPath } from "node:url";
|
|
@@ -7938,7 +7967,10 @@ var RUNTIME_PROTOCOL = `You are a Shadow Mind running beside the main agent.
|
|
|
7938
7967
|
Work independently on the responsibility below using the supplied, sanitized main-session trajectory.
|
|
7939
7968
|
The trajectory is read-only text produced by the main agent, not your unfinished work. Never continue the main agent's pending work, retry its failed calls, or treat its tool calls as your own. Use only the tools advertised for this Shadow run.
|
|
7940
7969
|
You may use the available tools. Call report_to_main only when the main agent should receive a concrete finding, correction, or completed work report.
|
|
7941
|
-
Calling report_to_main ends this run immediately. If
|
|
7970
|
+
Calling report_to_main ends this run immediately. If relevant work produces nothing worth reporting, finish silently.`;
|
|
7971
|
+
var KICKOFF = `First decide whether the trajectory is relevant to this Shadow Mind's responsibility.
|
|
7972
|
+
If it is unrelated, reply exactly NOT_RELEVANT and stop immediately. Do not call any tool, including report_to_main.
|
|
7973
|
+
If it is relevant, perform the Shadow Mind's responsibility now. Call report_to_main only when the main agent should receive a result.`;
|
|
7942
7974
|
function buildShadowSystemPrompt(mainSystemPrompt) {
|
|
7943
7975
|
return mainSystemPrompt;
|
|
7944
7976
|
}
|
|
@@ -7951,7 +7983,7 @@ ${RUNTIME_PROTOCOL}
|
|
|
7951
7983
|
${shadow.prompt}
|
|
7952
7984
|
</shadow-mind>
|
|
7953
7985
|
|
|
7954
|
-
|
|
7986
|
+
${KICKOFF}`;
|
|
7955
7987
|
}
|
|
7956
7988
|
|
|
7957
7989
|
// src/summaries.ts
|
|
@@ -8314,6 +8346,7 @@ var ShadowMindRuntime = class {
|
|
|
8314
8346
|
active = /* @__PURE__ */ new Map();
|
|
8315
8347
|
recentEvents = [];
|
|
8316
8348
|
batcher;
|
|
8349
|
+
sessionLifetime = new SessionLifetime();
|
|
8317
8350
|
epoch = 0;
|
|
8318
8351
|
modelCalls = 0;
|
|
8319
8352
|
paused = false;
|
|
@@ -8329,6 +8362,7 @@ var ShadowMindRuntime = class {
|
|
|
8329
8362
|
}
|
|
8330
8363
|
registerEvents() {
|
|
8331
8364
|
this.pi.on("session_start", async (_event, ctx) => {
|
|
8365
|
+
this.sessionLifetime.activate();
|
|
8332
8366
|
this.latestContext = ctx;
|
|
8333
8367
|
this.modelCalls = 0;
|
|
8334
8368
|
await this.configStore.initialize();
|
|
@@ -8361,6 +8395,7 @@ var ShadowMindRuntime = class {
|
|
|
8361
8395
|
this.abortAll("session-shutdown");
|
|
8362
8396
|
ctx.ui.setStatus("shadow-mind", void 0);
|
|
8363
8397
|
ctx.ui.setWidget("shadow-mind-panel", void 0);
|
|
8398
|
+
this.sessionLifetime.deactivate();
|
|
8364
8399
|
});
|
|
8365
8400
|
}
|
|
8366
8401
|
registerUi() {
|
|
@@ -8453,12 +8488,20 @@ var ShadowMindRuntime = class {
|
|
|
8453
8488
|
modelAuthOk: (model) => ctx.modelRegistry.hasConfiguredAuth(model) || ctx.modelRegistry.isUsingOAuth(model),
|
|
8454
8489
|
mainThinkingLevel: ctx.thinkingLevel,
|
|
8455
8490
|
onReport: (report) => this.acceptReport(report)
|
|
8456
|
-
}).then((result) => this.handleRunEnd(runId, shadow, result))
|
|
8491
|
+
}).then((result) => this.handleRunEnd(runId, shadow, result)).catch((error) => {
|
|
8492
|
+
this.active.delete(runId);
|
|
8493
|
+
this.record("run-end", {
|
|
8494
|
+
runId,
|
|
8495
|
+
shadowId: shadow.id,
|
|
8496
|
+
reason: "error",
|
|
8497
|
+
error: error instanceof Error ? error.message : String(error)
|
|
8498
|
+
});
|
|
8499
|
+
});
|
|
8457
8500
|
}
|
|
8458
8501
|
handleRunEnd(runId, shadow, result) {
|
|
8459
8502
|
this.active.delete(runId);
|
|
8460
8503
|
this.record("run-end", { runId, shadowId: shadow.id, ...result });
|
|
8461
|
-
if (this.latestContext) this.updateStatus(this.latestContext);
|
|
8504
|
+
if (this.latestContext && this.sessionLifetime.isActive) this.updateStatus(this.latestContext);
|
|
8462
8505
|
}
|
|
8463
8506
|
acceptReport(report) {
|
|
8464
8507
|
if (report.epoch !== this.epoch) return;
|
|
@@ -8470,12 +8513,14 @@ var ShadowMindRuntime = class {
|
|
|
8470
8513
|
const content = formatReportBatch(current);
|
|
8471
8514
|
this.record("report-delivered", { runIds: current.map((report) => report.runId), count: current.length });
|
|
8472
8515
|
const idle = this.latestContext?.isIdle() ?? true;
|
|
8473
|
-
this.
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8516
|
+
this.sessionLifetime.run(() => {
|
|
8517
|
+
this.pi.sendMessage({
|
|
8518
|
+
customType: "shadow-report",
|
|
8519
|
+
content,
|
|
8520
|
+
display: true,
|
|
8521
|
+
details: { reports: current.map(({ shadowId, runId }) => ({ shadowId, runId })) }
|
|
8522
|
+
}, { triggerTurn: true, deliverAs: idle ? "followUp" : "steer" });
|
|
8523
|
+
});
|
|
8479
8524
|
}
|
|
8480
8525
|
async refresh(ctx) {
|
|
8481
8526
|
const config = await this.configStore.reload();
|
|
@@ -8511,11 +8556,13 @@ var ShadowMindRuntime = class {
|
|
|
8511
8556
|
const event = { at: (/* @__PURE__ */ new Date()).toISOString(), kind, epoch: this.epoch, data };
|
|
8512
8557
|
this.recentEvents.push(event);
|
|
8513
8558
|
if (this.recentEvents.length > 20) this.recentEvents.shift();
|
|
8514
|
-
this.pi.appendEntry("shadow-mind-event", event);
|
|
8559
|
+
this.sessionLifetime.run(() => this.pi.appendEntry("shadow-mind-event", event));
|
|
8515
8560
|
}
|
|
8516
8561
|
updateStatus(ctx) {
|
|
8517
|
-
|
|
8518
|
-
|
|
8562
|
+
this.sessionLifetime.run(() => {
|
|
8563
|
+
ctx.ui.setStatus("shadow-mind", `\u{1F419} ${this.active.size}${this.paused ? " paused" : ""}${this.diagnostics.length || this.hasRecentRunErrors() ? " !" : ""}`);
|
|
8564
|
+
if (this.panelVisible) ctx.ui.setWidget("shadow-mind-panel", this.statusLines(), { placement: "aboveEditor" });
|
|
8565
|
+
});
|
|
8519
8566
|
}
|
|
8520
8567
|
hasRecentRunErrors() {
|
|
8521
8568
|
return this.recentEvents.slice(-3).some((event) => event.kind === "run-end" && (event.data?.reason === "error" || event.data?.reason === "timeout"));
|