pi-wafer-provider 1.1.32 → 1.1.34

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/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## 1.1.33
4
+
5
+ - Test against Pi 0.99.0 and declare host-provided modules as wildcard peers.
6
+ - Replace no-op checks with scoped TypeScript checks and an offline real-Pi loader, provider-registration, and session-lifecycle smoke test.
package/README.md CHANGED
@@ -76,14 +76,14 @@ pi
76
76
 
77
77
  | Model | Type | Context | Max Output | Input Cost | Output Cost | Cached Input |
78
78
  |-------|------|---------|------------|------------|-------------|--------------|
79
- | DeepSeek-V4-Flash-0731-Fast | Text | 1M | 1M | $0.06 | $0.35 | $0.05 |
80
- | DeepSeek-V4-Pro | Text | 1M | 1M | $0.39 | $4.20 | $0.32 |
81
- | DeepSeek-V4.1-Flash | Text + Image | 1M | 1M | $0.04 | $0.70 | $0.04 |
82
- | GLM-5.2 | Text | 1M | 1M | $0.36 | $4.40 | $0.26 |
83
- | GLM-5.3 | Text | 1M | 1M | $0.29 | $4.40 | $0.24 |
79
+ | DeepSeek-V4-Flash-0731-Fast | Text | 1M | 1M | $0.05 | $0.29 | $0.04 |
80
+ | DeepSeek-V4-Pro | Text | 1M | 1M | $0.39 | $3.49 | $0.32 |
81
+ | DeepSeek-V4.1-Flash | Text + Image | 1M | 1M | $0.10 | $0.44 | $0.05 |
82
+ | GLM-5.2 | Text | 1M | 1M | $0.23 | $4.40 | $0.19 |
83
+ | GLM-5.3 | Text | 1M | 1M | $0.22 | $3.39 | $0.18 |
84
84
  | GLM-5.3-Flash | Text + Image | 1M | 1M | $0.75 | $0.50 | $0.03 |
85
85
  | Kimi-K3 | Text + Image | 1M | 16K | $1.44 | $9.00 | $0.30 |
86
- | Qwen3.8-27B | Text + Image | 262K | 262K | $0.06 | $4.40 | $0.05 |
86
+ | Qwen3.8-27B | Text + Image | 262K | 262K | $0.02 | $4.40 | $0.02 |
87
87
 
88
88
  *Costs are per million tokens. Prices based on official provider pricing.*
89
89
 
package/bun.lock CHANGED
@@ -5,7 +5,12 @@
5
5
  "": {
6
6
  "name": "pi-wafer-provider",
7
7
  "devDependencies": {
8
- "@earendil-works/pi-coding-agent": "0.87.0",
8
+ "@earendil-works/pi-coding-agent": "0.99.0",
9
+ "@types/node": "^25.9.1",
10
+ "typescript": "6.0.3",
11
+ },
12
+ "peerDependencies": {
13
+ "@earendil-works/pi-coding-agent": "*",
9
14
  },
10
15
  },
11
16
  },
@@ -52,17 +57,21 @@
52
57
 
53
58
  "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="],
54
59
 
55
- "@earendil-works/chord": ["@earendil-works/chord@0.87.0", "", { "dependencies": { "esbuild": "0.28.2" } }, "sha512-t8QOTf0GTHrsDSfcdtXuA9RCkh6mnR4l25N0SM/sgH7Ih25jH4tGXNbkGs9MWpV5xTu9MRPj4A7Zn1UEwQm9+g=="],
60
+ "@earendil-works/chord": ["@earendil-works/chord@0.99.0", "", { "dependencies": { "esbuild": "0.28.2" } }, "sha512-xGMjZqlbYOIs9hrKvTaW/rcwbjbrogBK2VU+z+YSR0v7G6WHMy6AivC4Sk0lMJjNaMsELFxG47X3BCkd6EqG4g=="],
61
+
62
+ "@earendil-works/pi-agent-core": ["@earendil-works/pi-agent-core@0.99.0", "", { "dependencies": { "@earendil-works/chord": "^0.99.0", "@earendil-works/pi-ai": "^0.99.0", "@earendil-works/pi-telemetry": "^0.99.0", "diff": "8.0.4", "ignore": "7.0.8", "typebox": "1.3.27", "yaml": "2.9.0" } }, "sha512-3ZFAZ6GnR+r41VVcI47svtvHJ01T/RGDcm3fL8l25VeJ3RwDxnzZ7/XSD56ldE/EOoLA7riwiqc7UEOLyoib1g=="],
56
63
 
57
- "@earendil-works/pi-agent-core": ["@earendil-works/pi-agent-core@0.87.0", "", { "dependencies": { "@earendil-works/chord": "^0.87.0", "@earendil-works/pi-ai": "^0.87.0", "@earendil-works/pi-telemetry": "^0.87.0", "diff": "8.0.4", "ignore": "7.0.8", "typebox": "1.3.27", "yaml": "2.9.0" } }, "sha512-c5b2FMdJ7C++HBa6AyBmusdf96gdgRqpF7J+UCq2yVGB28UETJvJ190HkgDWUaLPnOQQPbanjKMAm/TgRmFE2w=="],
64
+ "@earendil-works/pi-ai": ["@earendil-works/pi-ai@0.99.0", "", { "dependencies": { "@anthropic-ai/sdk": "0.124.0", "@aws-sdk/client-bedrock-runtime": "3.1127.0", "@earendil-works/pi-telemetry": "^0.99.0", "@google/genai": "2.21.0", "@smithy/node-http-handler": "4.12.1", "http-proxy-agent": "9.1.0", "https-proxy-agent": "9.1.0", "openai": "7.19.0", "partial-json": "0.1.7", "typebox": "1.3.27" }, "bin": { "pi-ai": "dist/cli.js" } }, "sha512-pJVG2aytD6x1xckiM4co7DlK6xXwfH7LKcMoI6SFDuJ4OvVqedUUAYFFekX4WkeqOoRNCIjUwka/l7mWb/mjsQ=="],
58
65
 
59
- "@earendil-works/pi-ai": ["@earendil-works/pi-ai@0.87.0", "", { "dependencies": { "@anthropic-ai/sdk": "0.124.0", "@aws-sdk/client-bedrock-runtime": "3.1127.0", "@earendil-works/pi-telemetry": "^0.87.0", "@google/genai": "2.21.0", "@smithy/node-http-handler": "4.12.1", "http-proxy-agent": "9.1.0", "https-proxy-agent": "9.1.0", "openai": "6.40.0", "partial-json": "0.1.7", "typebox": "1.3.27" }, "bin": { "pi-ai": "dist/cli.js" } }, "sha512-lbRm+EMY6Jx3l+HLpbqbm9Yrhkc5u7EffLk2id+zJQEoBuR5I+tijGiZU8zlnuuCclmQOgH0PVjL9PLbeqJ9MQ=="],
66
+ "@earendil-works/pi-codemode": ["@earendil-works/pi-codemode@0.99.0", "", { "dependencies": { "quickjs-wasi": "3.6.2" } }, "sha512-zPbNpvVEtO3x++isZosWLuDhs+Xb0F3Pux6BsgIPg+aDmzwKnMruJNDuny2C3ig4HdQQfJ0hmfRsXV3ZmCWrWg=="],
60
67
 
61
- "@earendil-works/pi-coding-agent": ["@earendil-works/pi-coding-agent@0.87.0", "", { "dependencies": { "@earendil-works/chord": "^0.87.0", "@earendil-works/pi-agent-core": "^0.87.0", "@earendil-works/pi-ai": "^0.87.0", "@earendil-works/pi-tui": "^0.87.0", "@silvia-odwyer/photon-node": "0.3.4", "chalk": "6.0.0", "cross-spawn": "7.0.6", "diff": "8.0.4", "grok-mermaid": "0.2.3", "highlight.js": "10.7.3", "hosted-git-info": "9.0.3", "ignore": "7.0.8", "jiti": "2.7.0", "minimatch": "10.2.6", "proper-lockfile": "4.1.2", "semver": "7.8.5", "typebox": "1.3.27", "undici": "8.10.2", "yaml": "2.9.0" }, "bin": { "pi": "dist/bundle/cli.js" } }, "sha512-S9JJVGHya/h0e0M+zwPTB6RkPe7PmLLqfBUTssFYW5mxAti6oZEILn4jvaUImENRC3U9RwXAB6H4gw8xj2J0GQ=="],
68
+ "@earendil-works/pi-coding-agent": ["@earendil-works/pi-coding-agent@0.99.0", "", { "dependencies": { "@earendil-works/chord": "^0.99.0", "@earendil-works/pi-agent-core": "^0.99.0", "@earendil-works/pi-ai": "^0.99.0", "@earendil-works/pi-codemode": "^0.99.0", "@earendil-works/pi-mcp": "^0.99.0", "@earendil-works/pi-tui": "^0.99.0", "@silvia-odwyer/photon-node": "0.3.4", "chalk": "6.0.0", "cross-spawn": "7.0.6", "diff": "8.0.4", "grok-mermaid": "0.2.3", "highlight.js": "10.7.3", "hosted-git-info": "9.0.3", "ignore": "7.0.8", "jiti": "2.7.0", "minimatch": "10.2.6", "proper-lockfile": "4.1.2", "quickjs-wasi": "3.6.2", "semver": "7.8.5", "typebox": "1.3.27", "undici": "8.10.2", "yaml": "2.9.0" }, "bin": { "pi": "dist/bundle/cli.js" } }, "sha512-rZ8lLzqhrXrlZSt9VffVmVOcPBzbnK53UilkwEpDqU/WfE1RKCRqzYfGll/Xsk5XumjpeBT8IWzKNP6CyiEtrg=="],
62
69
 
63
- "@earendil-works/pi-telemetry": ["@earendil-works/pi-telemetry@0.87.0", "", {}, "sha512-IEUMnV6mgHyOMfAxa4CKXoBKKfHM8KxNjbXWM4Bps/iLJcFMf8hQsEZ+95VnVTc7C0cU77Rmdxt773C35jb5AA=="],
70
+ "@earendil-works/pi-mcp": ["@earendil-works/pi-mcp@0.99.0", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-9bt7QOZHMczU+bxO1VJdYMPeX54QdTSxE5Q+KbAi06GwOh+RUH2FTJCD7PZ1Av+oOJcTGTqr9CkvHtEUIFSuYg=="],
64
71
 
65
- "@earendil-works/pi-tui": ["@earendil-works/pi-tui@0.87.0", "", { "dependencies": { "get-east-asian-width": "1.6.0", "marked": "18.0.11" } }, "sha512-7gTC0XOgQfVWg4yGxwHINBpCnGl9p4KEC7PXIc8gAwc/cyxSW4VuFQrp+r1YD3oM+rBkoepKwAt6w6+VJ7BCaw=="],
72
+ "@earendil-works/pi-telemetry": ["@earendil-works/pi-telemetry@0.99.0", "", {}, "sha512-WH/sYgk7gY5OlunzPdtFPfPUr/M95F3GV+0yva3nHkcw2h463fWrJxn6hWuEC6vGktBMV41sA6QLB/ejllv1mw=="],
73
+
74
+ "@earendil-works/pi-tui": ["@earendil-works/pi-tui@0.99.0", "", { "dependencies": { "get-east-asian-width": "1.6.0", "marked": "18.0.11" } }, "sha512-6S8VIb0RnD2xHlssyL8XsLXmM9LC7pjL2e9+UVkh5FCgNxslb35bl3glhDyJZzovBUrGnUM872CbBGiSiMRbGw=="],
66
75
 
67
76
  "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ=="],
68
77
 
@@ -152,7 +161,7 @@
152
161
 
153
162
  "@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="],
154
163
 
155
- "@types/node": ["@types/node@26.4.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA=="],
164
+ "@types/node": ["@types/node@25.9.8", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-VfMrScDmMhUJQmd5hArdQnFvK0OIeD36uN2Va1FcpYaLB/BgkgM8Ulc50XtYISPMz7APJ30+N0T5EM0jlcdfRw=="],
156
165
 
157
166
  "@types/retry": ["@types/retry@0.12.0", "", {}, "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="],
158
167
 
@@ -242,7 +251,7 @@
242
251
 
243
252
  "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
244
253
 
245
- "openai": ["openai@6.40.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"] }, "sha512-MWtTjd/gQt4jpbji61NTgFWJLoY/PdRJ6wG9/ZDRMYNMlBKrCrSlkLI+KgHP1vR1qT6LKSAyAqIxno6lcK9JiA=="],
254
+ "openai": ["openai@7.19.0", "", { "peerDependencies": { "@aws-sdk/credential-provider-node": ">=3.972.0 <4", "@smithy/hash-node": ">=4.3.0 <5", "@smithy/signature-v4": ">=5.4.0 <6", "undici": ">=5 <9", "ws": "^8.21.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["@aws-sdk/credential-provider-node", "@smithy/hash-node", "@smithy/signature-v4", "undici", "ws", "zod"] }, "sha512-MX2s3u2L5racTO0CC/SWpCOasJQBCJrqLKXK+l82cAhdeF8mPMBEe/gxMm0ZFa2xpKpOFLRjxv5afYEZbBXmbQ=="],
246
255
 
247
256
  "p-retry": ["p-retry@4.6.2", "", { "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" } }, "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ=="],
248
257
 
@@ -256,6 +265,8 @@
256
265
 
257
266
  "proxy-agent-negotiate": ["proxy-agent-negotiate@1.1.0", "", { "peerDependencies": { "kerberos": "^2.0.0" }, "optionalPeers": ["kerberos"] }, "sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ=="],
258
267
 
268
+ "quickjs-wasi": ["quickjs-wasi@3.6.2", "", {}, "sha512-FCqGtGOrMgzUiIrMNMA2YnsOxCNwo31dzqXvclXUC6xeT35NJLKXQJsvbeCTjvoFAwZgEAPg8U6+KAPDGXn8Mg=="],
269
+
259
270
  "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="],
260
271
 
261
272
  "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
@@ -276,9 +287,11 @@
276
287
 
277
288
  "typebox": ["typebox@1.3.27", "", {}, "sha512-zu+jc1pcy4UiNThxikUr36f0Rybk9PEeCg/NE6adeWr/SKsdNO4EzZHYRDlv2YCVAfj3Odq3dESSo/jNyoBXzA=="],
278
289
 
290
+ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="],
291
+
279
292
  "undici": ["undici@8.10.2", "", {}, "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ=="],
280
293
 
281
- "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
294
+ "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
282
295
 
283
296
  "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
284
297
 
@@ -294,6 +307,10 @@
294
307
 
295
308
  "p-retry/retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],
296
309
 
310
+ "protobufjs/@types/node": ["@types/node@26.4.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA=="],
311
+
297
312
  "gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
313
+
314
+ "protobufjs/@types/node/undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
298
315
  }
299
316
  }
package/models.json CHANGED
@@ -7,9 +7,9 @@
7
7
  "text"
8
8
  ],
9
9
  "cost": {
10
- "input": 0.06,
11
- "output": 0.35,
12
- "cacheRead": 0.05,
10
+ "input": 0.05,
11
+ "output": 0.29,
12
+ "cacheRead": 0.04,
13
13
  "cacheWrite": 0
14
14
  },
15
15
  "contextWindow": 1048576,
@@ -31,7 +31,7 @@
31
31
  ],
32
32
  "cost": {
33
33
  "input": 0.39,
34
- "output": 4.2,
34
+ "output": 3.49,
35
35
  "cacheRead": 0.32,
36
36
  "cacheWrite": 0
37
37
  },
@@ -54,9 +54,9 @@
54
54
  "image"
55
55
  ],
56
56
  "cost": {
57
- "input": 0.04,
58
- "output": 0.7,
59
- "cacheRead": 0.04,
57
+ "input": 0.1,
58
+ "output": 0.44,
59
+ "cacheRead": 0.05,
60
60
  "cacheWrite": 0
61
61
  },
62
62
  "contextWindow": 1048576,
@@ -77,9 +77,9 @@
77
77
  "text"
78
78
  ],
79
79
  "cost": {
80
- "input": 0.36,
80
+ "input": 0.23,
81
81
  "output": 4.4,
82
- "cacheRead": 0.26,
82
+ "cacheRead": 0.19,
83
83
  "cacheWrite": 0
84
84
  },
85
85
  "contextWindow": 1048576,
@@ -100,9 +100,9 @@
100
100
  "text"
101
101
  ],
102
102
  "cost": {
103
- "input": 0.29,
104
- "output": 4.4,
105
- "cacheRead": 0.24,
103
+ "input": 0.22,
104
+ "output": 3.39,
105
+ "cacheRead": 0.18,
106
106
  "cacheWrite": 0
107
107
  },
108
108
  "contextWindow": 1048576,
@@ -172,9 +172,9 @@
172
172
  "image"
173
173
  ],
174
174
  "cost": {
175
- "input": 0.06,
175
+ "input": 0.02,
176
176
  "output": 4.4,
177
- "cacheRead": 0.05,
177
+ "cacheRead": 0.02,
178
178
  "cacheWrite": 0
179
179
  },
180
180
  "contextWindow": 262144,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-wafer-provider",
3
- "version": "1.1.32",
3
+ "version": "1.1.34",
4
4
  "description": "Wafer Serverless provider extension for pi - Access Qwen3.5-397B-A17B, GLM-5.1, Kimi K2.6, and DeepSeek-V4 through the Wafer Serverless API",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -23,12 +23,19 @@
23
23
  ]
24
24
  },
25
25
  "devDependencies": {
26
- "@earendil-works/pi-coding-agent": "0.87.0"
26
+ "@earendil-works/pi-coding-agent": "0.99.0",
27
+ "typescript": "6.0.3",
28
+ "@types/node": "^25.9.1"
29
+ },
30
+ "peerDependencies": {
31
+ "@earendil-works/pi-coding-agent": "*"
27
32
  },
28
33
  "scripts": {
29
34
  "clean": "echo 'nothing to clean'",
30
35
  "build": "echo 'nothing to build'",
31
- "check": "echo 'nothing to check'",
32
- "update-models": "node scripts/update-models.js"
36
+ "check": "tsc --noEmit && node scripts/test-pi-compat.mjs",
37
+ "update-models": "node scripts/update-models.js",
38
+ "test:pi": "node scripts/test-pi-compat.mjs",
39
+ "typecheck": "tsc --noEmit"
33
40
  }
34
41
  }
@@ -0,0 +1,76 @@
1
+ import assert from 'node:assert/strict';
2
+ import { mkdtemp, readFile, rm } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { dirname, join, resolve } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ // Import Pi only after selecting a disposable agent directory. Never read user auth/cache.
8
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
9
+ const home = await mkdtemp(join(tmpdir(), 'pi-provider-compat-'));
10
+ const previousHome = process.env.PI_CODING_AGENT_DIR;
11
+ const previousFetch = globalThis.fetch;
12
+ process.env.PI_CODING_AGENT_DIR = home;
13
+ globalThis.fetch = async () => new Response('', { status: 503 });
14
+ let session;
15
+ try {
16
+ const { createAgentSession, DefaultResourceLoader, ModelRuntime, SessionManager, SettingsManager, VERSION } = await import('@earendil-works/pi-coding-agent');
17
+ assert.equal(VERSION, '0.99.0', 'run compatibility checks against the pinned host');
18
+ const manifest = JSON.parse(await readFile(join(root, 'package.json'), 'utf8'));
19
+ const hostPackages = ['@earendil-works/pi-ai', '@earendil-works/pi-agent-core', '@earendil-works/pi-coding-agent', '@earendil-works/pi-tui', 'typebox'];
20
+ for (const name of hostPackages) {
21
+ assert.equal(manifest.dependencies?.[name], undefined, `${name} must not be installed as a runtime dependency`);
22
+ if (manifest.peerDependencies?.[name] !== undefined) assert.equal(manifest.peerDependencies[name], '*');
23
+ }
24
+ const settingsManager = SettingsManager.inMemory({ compaction: { enabled: false }, retry: { enabled: false } });
25
+ const resourceLoader = new DefaultResourceLoader({
26
+ cwd: home, agentDir: home, settingsManager,
27
+ additionalExtensionPaths: [join(root, 'index.ts')],
28
+ noSkills: true, noPromptTemplates: true, noThemes: true, noContextFiles: true,
29
+ });
30
+ await resourceLoader.reload();
31
+ const loaded = resourceLoader.getExtensions();
32
+ assert.deepEqual(loaded.errors, [], 'extension must load in the real Pi loader');
33
+ assert.deepEqual(loaded.warnings ?? [], [], 'extension must not produce host-dependency warnings');
34
+ assert.equal(loaded.extensions.length, 1, 'load only this provider');
35
+ const registrations = [...loaded.runtime.pendingProviderRegistrations];
36
+ assert.ok(registrations.length > 0, 'factory must register a provider before session startup');
37
+ const modelRuntime = await ModelRuntime.create({ authPath: join(home, 'auth.json'), modelsPath: null, modelsStorePath: join(home, 'models-cache'), allowModelNetwork: false });
38
+ ({ session } = await createAgentSession({ cwd: home, agentDir: home, resourceLoader, modelRuntime, settingsManager, sessionManager: SessionManager.inMemory(home), noTools: true }));
39
+ const errors = [];
40
+ await session.bindExtensions({ mode: 'print', onError: (error) => errors.push(error) });
41
+ await new Promise((done) => setImmediate(done));
42
+ let modelCount = 0;
43
+ for (const { name, config } of registrations) {
44
+ const models = modelRuntime.getAllModels(name);
45
+ assert.equal(models.length, config.models.length, `${name}: all configured models must survive host registration`);
46
+ assert.ok(models.length > 0, `${name}: nonempty catalog`);
47
+ assert.equal(new Set(models.map((model) => model.id)).size, models.length, `${name}: unique model IDs`);
48
+ for (const model of models) {
49
+ assert.equal(model.provider, name);
50
+ assert.ok(model.api && model.baseUrl && model.id && model.name);
51
+ if (model.type === 'image') assert.ok(model.output.includes('image'));
52
+ else assert.ok(model.contextWindow > 0, `${name}/${model.id}: positive context limit`);
53
+ if (model.type === 'chat') assert.ok(model.maxTokens > 0, `${name}/${model.id}: positive output limit`);
54
+ assert.ok(model.input.includes('text'));
55
+ for (const cost of Object.values(model.cost)) assert.ok(Number.isFinite(cost) && cost >= 0);
56
+ }
57
+ if (name === 'opencode') {
58
+ const { getAllBuiltinModels } = await import('@earendil-works/pi-ai/providers/all');
59
+ for (const native of getAllBuiltinModels(name).filter(model => model.type !== 'chat')) {
60
+ assert.ok(models.some(model => model.id === native.id && model.type === native.type), `${native.id}: preserve native operation`);
61
+ assert.ok(!modelRuntime.getModels(name).some(model => model.id === native.id), `${native.id}: must not become a chat model`);
62
+ }
63
+ assert.equal(typeof modelRuntime.getProvider(name).classify, 'function');
64
+ }
65
+ modelCount += models.length;
66
+ }
67
+ await session.extensionRunner.emit({ type: 'session_shutdown' });
68
+ assert.deepEqual(errors, [], 'startup and shutdown handlers must work with Pi 0.99 contexts');
69
+ console.log(`${manifest.name}: Pi ${VERSION} loader, manifest, session startup, and ${modelCount} models OK`);
70
+ } finally {
71
+ session?.dispose();
72
+ globalThis.fetch = previousFetch;
73
+ if (previousHome === undefined) delete process.env.PI_CODING_AGENT_DIR;
74
+ else process.env.PI_CODING_AGENT_DIR = previousHome;
75
+ await rm(home, { recursive: true, force: true });
76
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "esModuleInterop": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "skipLibCheck": true,
10
+ "resolveJsonModule": true,
11
+ "types": ["node"]
12
+ },
13
+ "files": ["index.ts"]
14
+ }