pi-commandcode-provider 0.4.0 → 0.4.2
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 +20 -0
- package/index.ts +4 -3
- package/package.json +5 -4
- package/src/core.ts +10 -3
- package/src/cost.ts +19 -0
- package/src/types.ts +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.4.2 - 2026-07-05
|
|
6
|
+
|
|
7
|
+
- Fix Oh My Pi extension validation by avoiding the missing `calculateCost` export from OMP's legacy `pi-ai` shim.
|
|
8
|
+
- Add a regression test that locks the local Command Code cost calculation to pi-ai's upstream `calculateCost` behavior.
|
|
9
|
+
|
|
10
|
+
### Contributors
|
|
11
|
+
|
|
12
|
+
- @CoderTCY — reported the Oh My Pi installation failure.
|
|
13
|
+
|
|
14
|
+
## 0.4.1 - 2026-06-16
|
|
15
|
+
|
|
16
|
+
- Use the explicit `$COMMANDCODE_API_KEY` provider registration syntax expected by newer pi versions, removing the startup deprecation warning while keeping legacy placeholder compatibility.
|
|
17
|
+
- Refresh development dependency lockfile entries to resolve npm audit findings for `tsx`/`esbuild` and `protobufjs`.
|
|
18
|
+
|
|
19
|
+
### Contributors
|
|
20
|
+
|
|
21
|
+
- @plumj-am — fixed the pi provider `apiKey` deprecation warning.
|
|
22
|
+
- @cad0p — reported retry/deprecation-related issues that helped validate the current behavior.
|
|
23
|
+
- @bl4zee1g — reported provider availability concerns that prompted additional local/live validation.
|
|
24
|
+
|
|
5
25
|
## 0.4.0 - 2026-06-02
|
|
6
26
|
|
|
7
27
|
- Add retry mechanism for transient HTTP errors (429, 5xx) and stream-level errors, configurable via pi `settings.json` `retry.provider` fields (`timeoutMs`, `maxRetries`, `maxRetryDelayMs`). Supports exponential backoff with jitter and `Retry-After` header.
|
package/index.ts
CHANGED
|
@@ -12,10 +12,11 @@
|
|
|
12
12
|
* Models are fetched from Command Code's Provider API at startup.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { AssistantMessageEventStream
|
|
15
|
+
import { AssistantMessageEventStream } from "@earendil-works/pi-ai"
|
|
16
16
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"
|
|
17
17
|
|
|
18
18
|
import { COMMAND_CODE_CLI_VERSION, createStreamCommandCode, DEFAULT_API_BASE } from "./src/core.ts"
|
|
19
|
+
import { calculateCommandCodeCost } from "./src/cost.ts"
|
|
19
20
|
import { DEFAULT_MODELS_URL, fetchCommandCodeModels } from "./src/models.ts"
|
|
20
21
|
import { getApiKey, login, refreshToken } from "./src/oauth.ts"
|
|
21
22
|
|
|
@@ -69,7 +70,7 @@ const MODEL_COSTS: Record<string, CommandCodeModelCost> = {
|
|
|
69
70
|
|
|
70
71
|
const streamCommandCode = createStreamCommandCode({
|
|
71
72
|
createStream: () => new AssistantMessageEventStream(),
|
|
72
|
-
calculateCost,
|
|
73
|
+
calculateCost: calculateCommandCodeCost,
|
|
73
74
|
apiBase: API_BASE,
|
|
74
75
|
})
|
|
75
76
|
|
|
@@ -83,7 +84,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
83
84
|
pi.registerProvider("commandcode", {
|
|
84
85
|
name: "Command Code",
|
|
85
86
|
baseUrl: API_BASE,
|
|
86
|
-
apiKey: "COMMANDCODE_API_KEY",
|
|
87
|
+
apiKey: "$COMMANDCODE_API_KEY",
|
|
87
88
|
authHeader: true,
|
|
88
89
|
api: "commandcode-custom",
|
|
89
90
|
streamSimple: streamCommandCode,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-commandcode-provider",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "pi custom provider for Command Code API (commandcode.ai)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"LICENSE"
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
|
-
"test": "npm run typecheck && tsx tests/test-pure-functions.ts && tsx tests/test-models.ts && tsx tests/test-pricing.ts && tsx tests/test-oauth.ts && tsx tests/test-abort.ts && tsx tests/test-stream.ts && tsx tests/test-retry.ts && node tests/test-pi-local.mjs && node tests/test-omp-compat.mjs",
|
|
31
|
+
"test": "npm run typecheck && tsx tests/test-pure-functions.ts && tsx tests/test-models.ts && tsx tests/test-pricing.ts && tsx tests/test-cost.ts && tsx tests/test-oauth.ts && tsx tests/test-abort.ts && tsx tests/test-stream.ts && tsx tests/test-retry.ts && node tests/test-pi-local.mjs && node tests/test-omp-compat.mjs",
|
|
32
32
|
"typecheck": "tsc --noEmit",
|
|
33
33
|
"format:check": "prettier --check '**/*.{ts,mjs,json,md}'",
|
|
34
34
|
"format": "prettier --write '**/*.{ts,mjs,json,md}'",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"test:stream": "tsx tests/test-stream.ts",
|
|
41
41
|
"test:retry": "tsx tests/test-retry.ts",
|
|
42
42
|
"test:pi-local": "node tests/test-pi-local.mjs",
|
|
43
|
-
"test:smoke": "node tests/test-smoke.mjs"
|
|
43
|
+
"test:smoke": "node tests/test-smoke.mjs",
|
|
44
|
+
"test:cost": "tsx tests/test-cost.ts"
|
|
44
45
|
},
|
|
45
46
|
"pi": {
|
|
46
47
|
"extensions": [
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@types/node": "25.6.0",
|
|
52
53
|
"prettier": "^3.5.0",
|
|
53
|
-
"tsx": "4.
|
|
54
|
+
"tsx": "4.22.4",
|
|
54
55
|
"typescript": "6.0.3"
|
|
55
56
|
},
|
|
56
57
|
"dependencies": {
|
package/src/core.ts
CHANGED
|
@@ -193,10 +193,17 @@ export function createStreamCommandCode(deps: CoreDependencies) {
|
|
|
193
193
|
const stream = deps.createStream()
|
|
194
194
|
|
|
195
195
|
async function run() {
|
|
196
|
-
// OMP may pass the env-var name "COMMANDCODE_API_KEY"
|
|
197
|
-
//
|
|
196
|
+
// OMP may pass the legacy env-var name "COMMANDCODE_API_KEY" (old pi)
|
|
197
|
+
// or "$COMMANDCODE_API_KEY" (new pi) as the apiKey value instead of
|
|
198
|
+
// resolving it. Filter out these specific strings.
|
|
199
|
+
const LEGACY_API_KEY_REF = "$COMMANDCODE_API_KEY"
|
|
200
|
+
const OLD_API_KEY_REF = "COMMANDCODE_API_KEY"
|
|
198
201
|
const hostKey =
|
|
199
|
-
options?.apiKey &&
|
|
202
|
+
options?.apiKey &&
|
|
203
|
+
options.apiKey !== LEGACY_API_KEY_REF &&
|
|
204
|
+
options.apiKey !== OLD_API_KEY_REF
|
|
205
|
+
? options.apiKey
|
|
206
|
+
: undefined
|
|
200
207
|
|
|
201
208
|
const apiKey =
|
|
202
209
|
hostKey ??
|
package/src/cost.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local cost calculation for Command Code usage.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors pi-ai's `calculateCost` arithmetic exactly. The provider ships its
|
|
5
|
+
* own copy because Oh My Pi's legacy pi-ai shim does not export
|
|
6
|
+
* `calculateCost`, which broke extension installation there (issue #24).
|
|
7
|
+
* `tests/test-cost.ts` locks this implementation to the pi-ai original.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ModelLike, Usage } from "./types.ts"
|
|
11
|
+
|
|
12
|
+
export function calculateCommandCodeCost(model: ModelLike, usage: Usage): void {
|
|
13
|
+
usage.cost.input = (model.cost.input / 1_000_000) * usage.input
|
|
14
|
+
usage.cost.output = (model.cost.output / 1_000_000) * usage.output
|
|
15
|
+
usage.cost.cacheRead = (model.cost.cacheRead / 1_000_000) * usage.cacheRead
|
|
16
|
+
usage.cost.cacheWrite = (model.cost.cacheWrite / 1_000_000) * usage.cacheWrite
|
|
17
|
+
usage.cost.total =
|
|
18
|
+
usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite
|
|
19
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -50,11 +50,19 @@ export interface AssistantMessageLike {
|
|
|
50
50
|
timestamp: number
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
export interface ModelCost {
|
|
54
|
+
input: number
|
|
55
|
+
output: number
|
|
56
|
+
cacheRead: number
|
|
57
|
+
cacheWrite: number
|
|
58
|
+
}
|
|
59
|
+
|
|
53
60
|
export interface ModelLike {
|
|
54
61
|
id: string
|
|
55
62
|
api: unknown
|
|
56
63
|
provider: string
|
|
57
64
|
maxTokens: number
|
|
65
|
+
cost: ModelCost
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
export interface MessageLike {
|