@zhushanwen/pi-cache-probe 0.3.6 → 0.3.7

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/README.md CHANGED
@@ -39,6 +39,7 @@ python3 extensions/universal/cache-probe/analyze.py ~/.pi/agent/sessions ~/.taij
39
39
 
40
40
  ## 已知限制(实测查明)
41
41
 
42
+ - Google 系模型的 system prompt 不可观测:pi-ai 对 Google 请求的 `systemInstruction` 恒传 string(`google-generative-ai.js` / `google-vertex.js` 实装),`extractSystem` 不消费 string 形态 → Google 流量的 `spFull` 恒为哨兵值 `no-system`,system prompt 漂移会被归因矩阵计入「前缀未变」档。仅当采集范围纳入 Google 系模型时构成实际失明(当前采集 fleet 无 Google 模型,零影响)。
42
43
  - pi CLI 启动路径(`--session` / `--continue` / `--resume`)的 session_start reason 恒为 `startup`(pi 侧只做 SessionManager.open/continueRecent,不走运行时 switch 路径;`resume` / `new` / `fork` 仅运行时 switch/fork 出现,`reload` 仅 /reload 出现)——跨进程识别靠 baseline 标记 + 时间戳 gap,漂移检测靠 hash 对比,均不受影响。
43
44
  - 同进程内修改 AGENTS.md 不进 system prompt(pi 启动快照),contextFiles 漂移只出现在跨进程边界——pi 的行为,不是探针缺陷。
44
45
  - 真实环境实测发现:extension 链(如 subagent-workflow)存在每 turn 级的 system prompt 动态注入,由 spFull 单独捕获——这正是它存在的价值。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhushanwen/pi-cache-probe",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Zero-impact Pi probe extension — records system prompt / tools fingerprint hashes into session custom entries (only on change) to attribute LLM prompt-cache miss to prefix drift vs server-side eviction.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -26,7 +26,7 @@
26
26
  "analyze.py"
27
27
  ],
28
28
  "dependencies": {
29
- "@zhushanwen/pi-ext-guards": "0.5.0"
29
+ "@zhushanwen/pi-ext-guards": "0.5.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@vitest/coverage-v8": "^4.1.9",
@@ -37,6 +37,6 @@
37
37
  },
38
38
  "scripts": {
39
39
  "typecheck": "npx tsc --noEmit",
40
- "test": "vitest run"
40
+ "test": "vitest run --pool=threads"
41
41
  }
42
42
  }
@@ -55,7 +55,7 @@ describe("hashOf(stable stringify 语义经公有面断言)", () => {
55
55
  });
56
56
  });
57
57
 
58
- describe("extractSystem(payload 四口径)", () => {
58
+ describe("extractSystem(payload 三口径)", () => {
59
59
  it("OpenAI 兼容:messages 内 role=system", () => {
60
60
  expect(extractSystem({ messages: [{ role: "system", content: "s" }, { role: "user", content: "u" }] })).toEqual([
61
61
  { role: "system", content: "s" },
@@ -74,11 +74,8 @@ describe("extractSystem(payload 四口径)", () => {
74
74
  ]);
75
75
  });
76
76
 
77
- it("伪造对象形态:顶层 systemInstruction(实装恒传 string,仅测试构造可达)", () => {
78
- expect(extractSystem({ systemInstruction: { role: "system", parts: [] } })).toEqual({
79
- role: "system",
80
- parts: [],
81
- });
77
+ it("Google 实装形态:string systemInstruction 不提取(已知失明行为锁,README 已知限制)", () => {
78
+ expect(extractSystem({ systemInstruction: "You are an agent.", messages: [] })).toBeNull();
82
79
  });
83
80
 
84
81
  it("无 system 内容返回 null", () => {
@@ -57,24 +57,22 @@ export function hashOf(value: unknown): string {
57
57
  }
58
58
 
59
59
  /**
60
- * 从 provider payload 提取 system 内容(最终视角)。三种口径:
60
+ * 从 provider payload 提取 system 内容(最终视角)。两种口径:
61
61
  * - OpenAI 兼容:messages 内 role 为 system 或 developer
62
62
  * (pi 源码 ai/src/api/openai-completions.ts 的 useDeveloperRole 分支)
63
63
  * - Anthropic:顶层 system(数组)
64
- * - Google:顶层字段 systemInstruction 为对象形态——仅手工伪造的输入可达:
65
- * pi-ai 1.0.0 实装(dist/api/google-generative-ai.js / google-vertex.js 的
66
- * systemInstruction: sanitizeSurrogates(...))恒传
67
- * string,isRecord 分支对 string
68
- * 恒不命中,故实装流量下 Google 侧返回 null(spFull 观测恒 no-system)。
69
- * 归因是「提取只认对象形态」而非「Google 请求没有 system」,勿把下方
70
- * isRecord(systemInstruction) 分支误读为 Google 口径主通路。
64
+ *
65
+ * Google 口径为已知失明(README 已知限制):pi-ai 1.0.0 实装对 systemInstruction
66
+ * 恒传 string(dist/api/google-generative-ai.js / google-vertex.js 的
67
+ * `systemInstruction: sanitizeSurrogates(...)`),本提取不消费 string 形态 →
68
+ * Google 流量 spFull 恒为哨兵值 "no-system"。旧的对象形态分支(isRecord 恒不命中,
69
+ * 仅手工伪造输入可达)已删;若采集范围纳入 Google 系模型,应新增 string 分支
70
+ * 恢复可观测(cache-probe 审计候选 1 车道 C)。
71
71
  */
72
72
  export function extractSystem(payload: unknown): unknown | null {
73
73
  if (!isRecord(payload)) return null;
74
74
  const system = payload["system"];
75
75
  if (Array.isArray(system)) return system;
76
- const systemInstruction = payload["systemInstruction"];
77
- if (isRecord(systemInstruction)) return systemInstruction;
78
76
  const messages = payload["messages"];
79
77
  if (Array.isArray(messages)) {
80
78
  const sys = messages.filter(
package/src/index.ts CHANGED
@@ -9,9 +9,9 @@
9
9
  * - before_agent_start(每 turn 1 次):算 7 个输入侧 hash 暂存 pending
10
10
  * (systemPromptOptions 各字段 + getAllTools 注册表)
11
11
  * - before_provider_request(每笔 LLM 请求,仅消费 turn 首笔):从最终 payload
12
- * 提取 spFull(system 消息,兼容 system/developer/anthropic/google 口径;
13
- * google 口径实装流量恒 no-system——pi-ai 恒传 string,该分支仅手工伪造
14
- * 对象输入可达,详见 fingerprint.ts extractSystem 注释)与
12
+ * 提取 spFull(system 消息,兼容 system/developer/anthropic 口径;google
13
+ * 口径为已知失明——pi-ai 恒传 string,本提取不消费该形态,spFull 恒
14
+ * no-system,详见 fingerprint.ts extractSystem 注释与 README 已知限制)与
15
15
  * toolsSent(tools 数组),与 pending 合并对比,变化/基线时 appendEntry
16
16
  * - agent_end:turn 内无 provider 请求则丢弃 pending(无请求即无归因价值)
17
17
  *