pi-hypercharm-provider 1.3.0 → 1.3.1

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
@@ -27,21 +27,21 @@ _Hyperoptimized coding models — DeepSeek, GLM, Kimi, Qwen, MiniMax, Gemma, GPT
27
27
  | Model | Type | Context | Max Tokens | Input Cost | Output Cost |
28
28
  |-------|------|---------|------------|------------|-------------|
29
29
  | DeepSeek V4 Flash | Text | 1.0M | 384K | $0.20 | $0.40 |
30
- | DeepSeek V4 Flash 0731 | Text | 1.0M | 384K | $0.20 | $0.40 |
30
+ | DeepSeek V4 Flash 0731 | Text | 1.0M | 384K | $0.13 | $0.26 |
31
31
  | DeepSeek V4 Pro | Text | 1.0M | 384K | $2.40 | $4.80 |
32
32
  | DeepSeek V4 Pro 0813 | Text | 1.0M | 262K | $1.44 | $4.31 |
33
33
  | Gemma 4 26B A4B | Text | 256K | 26K | $0.12 | $0.42 |
34
- | GLM-5 | Text | 203K | 20K | $0.76 | $2.36 |
35
- | GLM-5.1 | Text | 203K | 3K | $1.52 | $4.79 |
34
+ | GLM-5 | Text | 203K | 20K | $0.84 | $2.61 |
35
+ | GLM-5.1 | Text | 203K | 3K | $1.36 | $4.40 |
36
36
  | GLM-5.2 | Text | 1.0M | 33K | $1.40 | $4.40 |
37
37
  | gpt-oss-120b | Text | 131K | 13K | $0.16 | $0.65 |
38
- | Kimi K2.5 | Text | 262K | 26K | $0.56 | $2.94 |
38
+ | Kimi K2.5 | Text | 262K | 26K | $0.57 | $3.00 |
39
39
  | Kimi K2.6 | Text + Image | 262K | 26K | $0.95 | $4.00 |
40
40
  | Kimi K2.7 Code | Text + Image | 256K | 16K | $0.95 | $4.00 |
41
41
  | Kimi K3 | Text + Image | 1.0M | 131K | $3.00 | $15.00 |
42
- | Llama 3.3 70B Instruct | Text | 128K | 13K | $0.61 | $0.84 |
42
+ | Llama 3.3 70B Instruct | Text | 128K | 13K | $0.64 | $0.77 |
43
43
  | Llama 4 Maverick 17B 128E Instruct FP8 | Text | 430K | 43K | $0.27 | $0.90 |
44
- | MiniMax M2.7 | Text | 262K | 7K | $0.43 | $1.62 |
44
+ | MiniMax M2.7 | Text | 262K | 7K | $0.47 | $1.76 |
45
45
  | MiniMax M3 | Text + Image | 512K | 512K | $0.33 | $1.31 |
46
46
  | Qwen3 Coder 480B A35B Instruct INT4 Mixed AR | Text | 106K | 11K | $0.45 | $2.15 |
47
47
  | Qwen3 Next 80B A3B Instruct | Text | 262K | 26K | $0.12 | $1.14 |
package/index.ts CHANGED
@@ -624,6 +624,9 @@ const CREDITS_MIN_INTERVAL_MS = 15_000;
624
624
  const ACCOUNT_FETCH_TIMEOUT_MS = 8_000;
625
625
 
626
626
  let statusAbort: AbortController | null = null;
627
+ // Bumped on every session_start; async continuations compare against this to
628
+ // drop work belonging to a replaced session (its ctx is stale and throws).
629
+ let statusEpoch = 0;
627
630
  let lastCreditsFetchAt = 0;
628
631
  let creditsInFlight: Promise<void> | null = null;
629
632
  let metaFetched = false;
@@ -707,7 +710,30 @@ function currentProviderId(ctx: ExtensionContext): string | undefined {
707
710
  }
708
711
  }
709
712
 
713
+ function isStaleCtxError(err: unknown): boolean {
714
+ return err instanceof Error && err.message.includes("This extension ctx is stale");
715
+ }
716
+
717
+ // Render entry point: swallows the stale-ctx throw so a refresh racing a
718
+ // session replacement (newSession/fork/switchSession/reload) can't crash pi.
710
719
  function updateStatus(ctx: ExtensionContext): void {
720
+ try {
721
+ renderStatus(ctx);
722
+ } catch (err) {
723
+ if (!isStaleCtxError(err)) throw err;
724
+ }
725
+ }
726
+
727
+ // Re-render once an async refresh lands, unless the session was replaced
728
+ // meanwhile (epoch bump) — its ctx is stale and the render is obsolete anyway.
729
+ function updateStatusAfter(promise: Promise<void>, ctx: ExtensionContext): void {
730
+ const epoch = statusEpoch;
731
+ void promise.then(() => {
732
+ if (epoch === statusEpoch) updateStatus(ctx);
733
+ });
734
+ }
735
+
736
+ function renderStatus(ctx: ExtensionContext): void {
711
737
  const provider = currentProviderId(ctx);
712
738
  const hiddenByOtherProvider =
713
739
  statusConfig.hideOnOtherProvider && provider !== undefined && provider !== PROVIDER_ID;
@@ -791,7 +817,7 @@ function commitPending(ctx: ExtensionContext): void {
791
817
  if (pendingSawOutOfCredits) {
792
818
  pendingSawOutOfCredits = false;
793
819
  // Re-fetch now so the balance reflects exhaustion immediately
794
- void refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, true).then(() => updateStatus(ctx));
820
+ updateStatusAfter(refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, true), ctx);
795
821
  if (!outOfCreditsNotified && ctx.hasUI) {
796
822
  outOfCreditsNotified = true;
797
823
  ctx.ui.notify("HyperCharm is out of Hypercredits — recharge at hyper.charm.land", "error");
@@ -854,7 +880,7 @@ async function handleStatusCommand(args: string, ctx: ExtensionContext): Promise
854
880
  writeStatusConfig();
855
881
  if (value !== "off" && key === "account") {
856
882
  // Turning account on: make sure we have data to show
857
- void refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, true).then(() => updateStatus(ctx));
883
+ updateStatusAfter(refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, true), ctx);
858
884
  void refreshAccountMeta(cachedApiKey, statusAbort?.signal ?? undefined);
859
885
  }
860
886
  updateStatus(ctx);
@@ -929,7 +955,7 @@ async function configureStatusInteractive(ctx: ExtensionContext): Promise<void>
929
955
  statusConfig.account = nextMode(statusConfig.account);
930
956
  writeStatusConfig();
931
957
  if (statusConfig.account !== "off") {
932
- void refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, true).then(() => updateStatus(ctx));
958
+ updateStatusAfter(refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, true), ctx);
933
959
  void refreshAccountMeta(cachedApiKey, statusAbort?.signal ?? undefined);
934
960
  }
935
961
  continue;
@@ -1003,11 +1029,13 @@ export default function (pi: ExtensionAPI) {
1003
1029
  });
1004
1030
 
1005
1031
  pi.on("session_start", async (_event, ctx) => {
1032
+ const epoch = ++statusEpoch;
1006
1033
  revalidateAbort?.abort();
1007
1034
  revalidateAbort = new AbortController();
1008
1035
  const signal = revalidateAbort.signal;
1009
1036
  statusAbort?.abort();
1010
1037
  statusAbort = new AbortController();
1038
+ const statusSignal = statusAbort.signal;
1011
1039
 
1012
1040
  loadStatusConfig();
1013
1041
  resetStatusState();
@@ -1017,15 +1045,18 @@ export default function (pi: ExtensionAPI) {
1017
1045
  pi.registerProvider(PROVIDER_ID, makeProviderConfig());
1018
1046
 
1019
1047
  resolveApiKey(ctx.modelRegistry).then(() => {
1048
+ // A session replacement while the key resolved invalidated the
1049
+ // captured ctx (fast-resume, /new, /fork); nothing below may touch it.
1050
+ if (epoch !== statusEpoch) return;
1020
1051
  // Prefetch credits/team metadata only when a HyperCharm model is active
1021
1052
  // (pi-neuralwatt also prefetches so the first turn ends with data, but
1022
1053
  // gating here avoids API calls in sessions that never use the provider).
1023
1054
  if (currentProviderId(ctx) === PROVIDER_ID) {
1024
- void refreshCredits(cachedApiKey, statusAbort!.signal, true).then(() => updateStatus(ctx));
1025
- void refreshAccountMeta(cachedApiKey, statusAbort!.signal).then(() => updateStatus(ctx));
1055
+ updateStatusAfter(refreshCredits(cachedApiKey, statusSignal, true), ctx);
1056
+ updateStatusAfter(refreshAccountMeta(cachedApiKey, statusSignal), ctx);
1026
1057
  }
1027
1058
  revalidateModels(cachedApiKey, embeddedModels, signal).then((freshBase) => {
1028
- if (freshBase && !signal.aborted) {
1059
+ if (freshBase && epoch === statusEpoch && !signal.aborted) {
1029
1060
  currentModels = buildModels(freshBase, customModels, patches);
1030
1061
  pi.registerProvider(PROVIDER_ID, makeProviderConfig());
1031
1062
  }
@@ -1037,7 +1068,7 @@ export default function (pi: ExtensionAPI) {
1037
1068
  updateStatus(ctx);
1038
1069
  const model: any = (event as any).model;
1039
1070
  if (model?.provider === PROVIDER_ID && cachedApiKey) {
1040
- void refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, false).then(() => updateStatus(ctx));
1071
+ updateStatusAfter(refreshCredits(cachedApiKey, statusAbort?.signal ?? undefined, false), ctx);
1041
1072
  void refreshAccountMeta(cachedApiKey, statusAbort?.signal ?? undefined);
1042
1073
  }
1043
1074
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-hypercharm-provider",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "HyperCharm provider extension for pi - Access DeepSeek, GLM, Kimi, Qwen, MiniMax, Gemma, and GPT-OSS models through the Charm Hyper API",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -34,6 +34,10 @@
34
34
  "./index.ts"
35
35
  ]
36
36
  },
37
+ "files": [
38
+ "README.md",
39
+ "LICENSE"
40
+ ],
37
41
  "scripts": {
38
42
  "clean": "echo 'nothing to clean'",
39
43
  "build": "echo 'nothing to build'",
@@ -1,4 +0,0 @@
1
- github: monotykamary
2
- ko_fi: monotykamary
3
- buy_me_a_coffee: monotykamary
4
- polar: monotykamary
@@ -1,298 +0,0 @@
1
- {
2
- "version": 1,
3
- "layers": [
4
- {
5
- "path": "/Users/monotykamary/.mcporter/mcporter.json",
6
- "mtimeMs": 1786708960950.6536,
7
- "size": 180
8
- }
9
- ],
10
- "updatedAt": "2026-08-16T20:51:31.788Z",
11
- "servers": {
12
- "fal-ai": {
13
- "definitionHash": "ee48434dcd3ee4daa319d25c1b24434511497a99764bc200a43f3d93335573c0",
14
- "transport": "http",
15
- "description": null,
16
- "fetchedAt": "2026-08-16T20:51:31.638Z",
17
- "stale": false,
18
- "tools": [
19
- {
20
- "name": "search_models",
21
- "description": "Search fal.ai's model catalog. Use this to discover available models.\nCategories: text-to-image, image-to-video, text-to-video, text-to-speech, speech-to-text, text-to-music, image-to-3d, text-to-3d, image-editing, llm, and more.\nReturns model IDs you can pass to get_model_schema or run_model.",
22
- "inputSchema": {
23
- "type": "object",
24
- "properties": {
25
- "query": {
26
- "type": "string",
27
- "description": "Free-text search (e.g. 'flux', 'video generation', 'upscale')"
28
- },
29
- "category": {
30
- "type": "string",
31
- "description": "Filter by category: text-to-image, image-to-video, text-to-video, text-to-speech, speech-to-text, text-to-music, image-to-3d, image-editing, llm"
32
- },
33
- "limit": {
34
- "type": "number",
35
- "minimum": 1,
36
- "maximum": 100,
37
- "description": "Max results to return (default 20)"
38
- },
39
- "cursor": {
40
- "type": "string",
41
- "description": "Pagination cursor from a previous response's next_cursor to fetch the next page"
42
- }
43
- },
44
- "additionalProperties": false,
45
- "$schema": "http://json-schema.org/draft-07/schema#"
46
- }
47
- },
48
- {
49
- "name": "get_model_schema",
50
- "description": "Get the full input/output schema for a specific fal.ai model.\nReturns all parameters the model accepts and what it returns.\nUse this before run_model to understand what inputs are needed.",
51
- "inputSchema": {
52
- "type": "object",
53
- "properties": {
54
- "endpoint_id": {
55
- "type": "string",
56
- "description": "The model endpoint ID (e.g. 'fal-ai/flux/dev', 'fal-ai/wan-t2v')"
57
- }
58
- },
59
- "required": [
60
- "endpoint_id"
61
- ],
62
- "additionalProperties": false,
63
- "$schema": "http://json-schema.org/draft-07/schema#"
64
- }
65
- },
66
- {
67
- "name": "run_model",
68
- "description": "Run a fal.ai model: submits to the queue and waits a short, bounded time for the result.\nIMPORTANT: If the user does NOT specify a model by name, you MUST call recommend_model first to find the best trending model. Never pick a model from your own knowledge — always use recommend_model to get the current best option. Only skip recommend_model if the user explicitly asks for a specific model (e.g. \"use FLUX\" or \"use Kling\").\n\nThis tool returns one of two statuses:\n- \"completed\": the result is included.\n- \"processing\": the wait budget elapsed but the job is still running. This is NORMAL for video, 3D, training, or a busy queue. A request_id, status_url, and response_url are returned. Poll check_job, then call get_job_result when queue_status is COMPLETED. Do NOT call run_model again for the same request — that starts a new, billable job.\n\nFor video, 3D, or training (long-running by nature), prefer submit_job + check_job + get_job_result from the start.\nFor image URLs in the output, present them directly to the user.",
69
- "inputSchema": {
70
- "type": "object",
71
- "properties": {
72
- "endpoint_id": {
73
- "type": "string",
74
- "description": "The model endpoint ID (e.g. 'fal-ai/flux/dev')"
75
- },
76
- "input": {
77
- "type": "object",
78
- "additionalProperties": {},
79
- "description": "Model input parameters as a JSON object. Use get_model_schema first to see what parameters are accepted."
80
- },
81
- "expiration_seconds": {
82
- "type": "number",
83
- "description": "Optional CDN expiration in seconds. Generated media will be deleted after this duration. Omit to use account default."
84
- },
85
- "store_payload": {
86
- "type": "boolean",
87
- "description": "Optional. Set to false to prevent fal from storing the request JSON payload (default: true)."
88
- }
89
- },
90
- "required": [
91
- "endpoint_id",
92
- "input"
93
- ],
94
- "additionalProperties": false,
95
- "$schema": "http://json-schema.org/draft-07/schema#"
96
- }
97
- },
98
- {
99
- "name": "check_job",
100
- "description": "Check the status of a running fal.ai job.\nUse this for long-running jobs (video generation, training, etc.) or when run_model returns status \"processing\".",
101
- "inputSchema": {
102
- "type": "object",
103
- "properties": {
104
- "endpoint_id": {
105
- "type": "string",
106
- "description": "The model endpoint ID"
107
- },
108
- "request_id": {
109
- "type": "string",
110
- "description": "The request ID returned by run_model or submit_job"
111
- },
112
- "status_url": {
113
- "type": "string",
114
- "format": "uri",
115
- "description": "Canonical status_url returned by submit_job or run_model. Prefer passing this when available."
116
- }
117
- },
118
- "required": [
119
- "endpoint_id",
120
- "request_id"
121
- ],
122
- "additionalProperties": false,
123
- "$schema": "http://json-schema.org/draft-07/schema#"
124
- }
125
- },
126
- {
127
- "name": "upload_file",
128
- "description": "Upload a file to fal.ai's CDN so it can be used as input to models. Returns a fal.ai CDN URL.\n\nHOW TO USE:\n- PUBLIC URL → pass it as 'url'. Easiest option.\n- LOCAL FILE (recommended for any size) → upload it yourself directly to fal REST API:\n 1. POST https://rest.alpha.fal.ai/storage/upload/initiate with header \"Authorization: Key $FAL_KEY\" and body {\"file_name\":\"...\",\"content_type\":\"...\"}\n 2. PUT the file bytes to the returned upload_url\n 3. Use the returned file_url as the CDN URL\n This avoids token/size limits from passing file content through MCP.\n- LOCAL FILE (small, <1MB) → read the file, base64-encode it, and pass as 'data' with 'file_name'.\n- Do NOT use file_path — it will always fail on hosted MCP servers.",
129
- "inputSchema": {
130
- "type": "object",
131
- "properties": {
132
- "file_path": {
133
- "type": "string",
134
- "description": "Local file path (only works in stdio mode, not HTTP)"
135
- },
136
- "url": {
137
- "type": "string",
138
- "description": "URL of a remote file to upload to fal.ai CDN"
139
- },
140
- "data": {
141
- "type": "string",
142
- "description": "Base64-encoded file content. Use this for local files when connected over HTTP."
143
- },
144
- "file_name": {
145
- "type": "string",
146
- "description": "Filename (required when using 'data')"
147
- }
148
- },
149
- "additionalProperties": false,
150
- "$schema": "http://json-schema.org/draft-07/schema#"
151
- }
152
- },
153
- {
154
- "name": "submit_job",
155
- "description": "Submit a job to the queue WITHOUT waiting for completion. Returns immediately with a request_id.\nUse this instead of run_model for long-running tasks (video generation, 3D, training).\nThen use check_job to poll status and get_job_result to retrieve the result when ready.",
156
- "inputSchema": {
157
- "type": "object",
158
- "properties": {
159
- "endpoint_id": {
160
- "type": "string",
161
- "description": "The model endpoint ID (e.g. 'fal-ai/veo3.1')"
162
- },
163
- "input": {
164
- "type": "object",
165
- "additionalProperties": {},
166
- "description": "Model input parameters as a JSON object."
167
- },
168
- "expiration_seconds": {
169
- "type": "number",
170
- "description": "Optional CDN expiration in seconds for generated media."
171
- },
172
- "store_payload": {
173
- "type": "boolean",
174
- "description": "Optional. Set to false to prevent fal from storing the request JSON payload."
175
- }
176
- },
177
- "required": [
178
- "endpoint_id",
179
- "input"
180
- ],
181
- "additionalProperties": false,
182
- "$schema": "http://json-schema.org/draft-07/schema#"
183
- }
184
- },
185
- {
186
- "name": "get_pricing",
187
- "description": "Get pricing information for a fal.ai model. Returns cost per run or per second.\nUse this before running expensive models (video, training) to estimate costs.",
188
- "inputSchema": {
189
- "type": "object",
190
- "properties": {
191
- "endpoint_id": {
192
- "type": "string",
193
- "description": "The model endpoint ID to check pricing for"
194
- }
195
- },
196
- "required": [
197
- "endpoint_id"
198
- ],
199
- "additionalProperties": false,
200
- "$schema": "http://json-schema.org/draft-07/schema#"
201
- }
202
- },
203
- {
204
- "name": "get_job_result",
205
- "description": "Fetch the result for a completed fal.ai queue job.\nUse check_job first when you are not sure the request has completed.",
206
- "inputSchema": {
207
- "type": "object",
208
- "properties": {
209
- "endpoint_id": {
210
- "type": "string",
211
- "description": "The model endpoint ID"
212
- },
213
- "request_id": {
214
- "type": "string",
215
- "description": "The request ID returned by run_model or submit_job"
216
- },
217
- "response_url": {
218
- "type": "string",
219
- "format": "uri",
220
- "description": "Canonical response_url returned by submit_job, run_model, or check_job. Prefer passing this when available."
221
- }
222
- },
223
- "required": [
224
- "endpoint_id",
225
- "request_id"
226
- ],
227
- "additionalProperties": false,
228
- "$schema": "http://json-schema.org/draft-07/schema#"
229
- }
230
- },
231
- {
232
- "name": "cancel_job",
233
- "description": "Cancel a running fal.ai queue job.\nOnly use this when the user explicitly asks to cancel a specific request_id.",
234
- "inputSchema": {
235
- "type": "object",
236
- "properties": {
237
- "endpoint_id": {
238
- "type": "string",
239
- "description": "The model endpoint ID"
240
- },
241
- "request_id": {
242
- "type": "string",
243
- "description": "The request ID returned by run_model or submit_job"
244
- },
245
- "cancel_url": {
246
- "type": "string",
247
- "format": "uri",
248
- "description": "Canonical cancel_url returned by submit_job, run_model, or check_job. Prefer passing this when available."
249
- }
250
- },
251
- "required": [
252
- "endpoint_id",
253
- "request_id"
254
- ],
255
- "additionalProperties": false,
256
- "$schema": "http://json-schema.org/draft-07/schema#"
257
- }
258
- },
259
- {
260
- "name": "recommend_model",
261
- "description": "Get model recommendations based on what you want to create.\nSearches the live fal.ai catalog and returns the best models for your use case.\nModels are ranked by platform popularity (most-used models appear first).",
262
- "inputSchema": {
263
- "type": "object",
264
- "properties": {
265
- "task": {
266
- "type": "string",
267
- "description": "What you want to do (e.g. 'generate a photorealistic portrait', 'create a 10s cinematic video from text', 'upscale an image to 4K', 'remove background')"
268
- }
269
- },
270
- "required": [
271
- "task"
272
- ],
273
- "additionalProperties": false,
274
- "$schema": "http://json-schema.org/draft-07/schema#"
275
- }
276
- },
277
- {
278
- "name": "search_docs",
279
- "description": "Search the fal.ai documentation for guides, API references, code examples, and implementation details.\nUse this when you need to understand how fal.ai works, find specific API docs, or get code snippets.",
280
- "inputSchema": {
281
- "type": "object",
282
- "properties": {
283
- "query": {
284
- "type": "string",
285
- "description": "Search query (e.g. 'how to upload a file', 'queue API', 'LoRA training')"
286
- }
287
- },
288
- "required": [
289
- "query"
290
- ],
291
- "additionalProperties": false,
292
- "$schema": "http://json-schema.org/draft-07/schema#"
293
- }
294
- }
295
- ]
296
- }
297
- }
298
- }
@@ -1,118 +0,0 @@
1
- {
2
- "format": 1,
3
- "entries": {
4
- "topology/hosts/b98efd3cf26df4c69c6deae014475c4c0c080b1d0e5ef1cb0ebcc8dca7501c85": {
5
- "key": "topology/hosts/b98efd3cf26df4c69c6deae014475c4c0c080b1d0e5ef1cb0ebcc8dca7501c85",
6
- "value": {
7
- "format": 1,
8
- "id": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
9
- "rootId": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
10
- "identity": {
11
- "id": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
12
- "name": "main",
13
- "kind": "main",
14
- "sessionId": "01a00efe-4e23-7b2b-8583-2e8493780899"
15
- },
16
- "startedAt": 1786958035702,
17
- "updatedAt": 1786958850932,
18
- "expiresAt": 1786958865932
19
- },
20
- "version": 196,
21
- "updatedAt": 1786958850934,
22
- "updatedBy": {
23
- "id": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
24
- "name": "main",
25
- "kind": "main",
26
- "sessionId": "01a00efe-4e23-7b2b-8583-2e8493780899"
27
- }
28
- },
29
- "sessions/01a00efe-4e23-7b2b-8583-2e8493780899": {
30
- "key": "sessions/01a00efe-4e23-7b2b-8583-2e8493780899",
31
- "value": {
32
- "id": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
33
- "name": "Peer 01a00efe",
34
- "kind": "peer",
35
- "status": "running",
36
- "runner": "pi",
37
- "transport": "host",
38
- "cwd": "/Users/monotykamary/VCS/working-remote/open-source/pi-hypercharm-provider",
39
- "sessionId": "01a00efe-4e23-7b2b-8583-2e8493780899",
40
- "model": "neuralwatt/kimi-k3",
41
- "thinking": "max",
42
- "startedAt": 1786958035702,
43
- "updatedAt": 1786958850932,
44
- "pendingMessages": false,
45
- "local": false
46
- },
47
- "version": 196,
48
- "updatedAt": 1786958850935,
49
- "updatedBy": {
50
- "id": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
51
- "name": "main",
52
- "kind": "main",
53
- "sessionId": "01a00efe-4e23-7b2b-8583-2e8493780899"
54
- }
55
- },
56
- "topology/participants/b98efd3cf26df4c69c6deae014475c4c0c080b1d0e5ef1cb0ebcc8dca7501c85": {
57
- "key": "topology/participants/b98efd3cf26df4c69c6deae014475c4c0c080b1d0e5ef1cb0ebcc8dca7501c85",
58
- "value": {
59
- "format": 1,
60
- "id": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
61
- "kind": "root",
62
- "rootId": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
63
- "ownerHostId": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
64
- "ownerIdentityId": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
65
- "name": "main",
66
- "status": "running",
67
- "runner": "pi",
68
- "transport": "host",
69
- "capabilities": [
70
- "steer",
71
- "followUp",
72
- "fabric"
73
- ],
74
- "cwd": "/Users/monotykamary/VCS/working-remote/open-source/pi-hypercharm-provider",
75
- "sessionId": "01a00efe-4e23-7b2b-8583-2e8493780899",
76
- "model": "neuralwatt/kimi-k3",
77
- "thinking": "max",
78
- "startedAt": 1786958035702,
79
- "updatedAt": 1786958850932,
80
- "pendingMessages": false,
81
- "controlProtocol": "v1"
82
- },
83
- "version": 196,
84
- "updatedAt": 1786958850936,
85
- "updatedBy": {
86
- "id": "session:01a00efe-4e23-7b2b-8583-2e8493780899",
87
- "name": "main",
88
- "kind": "main",
89
- "sessionId": "01a00efe-4e23-7b2b-8583-2e8493780899"
90
- }
91
- }
92
- },
93
- "versions": {
94
- "topology/hosts/e9758aa8c95305a8d60a8aa2c20fd53195591d479b2460e1273457793d3f1fec": 18,
95
- "sessions/019fe2c8-1dd2-7435-9fa1-fa664831df18": 17,
96
- "topology/participants/e9758aa8c95305a8d60a8aa2c20fd53195591d479b2460e1273457793d3f1fec": 18,
97
- "topology/hosts/e0efb9d647e046c355b8bff12785e7805d774e7b89892edb38b4b29667ddc15f": 632,
98
- "sessions/019fe2d3-1ac4-7f63-a2e7-b396c7bb1738": 631,
99
- "topology/participants/e0efb9d647e046c355b8bff12785e7805d774e7b89892edb38b4b29667ddc15f": 632,
100
- "topology/hosts/3195ffccdcff6cb767344b2d1af6c5f3e1e3e4a9906a81129ffaf24352769d2a": 217,
101
- "sessions/01a00c57-b7aa-7ea3-b78a-11e22d3cdd86": 216,
102
- "topology/participants/3195ffccdcff6cb767344b2d1af6c5f3e1e3e4a9906a81129ffaf24352769d2a": 217,
103
- "topology/hosts/b98efd3cf26df4c69c6deae014475c4c0c080b1d0e5ef1cb0ebcc8dca7501c85": 196,
104
- "sessions/01a00efe-4e23-7b2b-8583-2e8493780899": 196,
105
- "topology/participants/b98efd3cf26df4c69c6deae014475c4c0c080b1d0e5ef1cb0ebcc8dca7501c85": 196
106
- },
107
- "tombstoneOrder": [
108
- "sessions/019fe2c8-1dd2-7435-9fa1-fa664831df18",
109
- "topology/participants/e9758aa8c95305a8d60a8aa2c20fd53195591d479b2460e1273457793d3f1fec",
110
- "topology/hosts/e9758aa8c95305a8d60a8aa2c20fd53195591d479b2460e1273457793d3f1fec",
111
- "sessions/019fe2d3-1ac4-7f63-a2e7-b396c7bb1738",
112
- "topology/participants/e0efb9d647e046c355b8bff12785e7805d774e7b89892edb38b4b29667ddc15f",
113
- "topology/hosts/e0efb9d647e046c355b8bff12785e7805d774e7b89892edb38b4b29667ddc15f",
114
- "sessions/01a00c57-b7aa-7ea3-b78a-11e22d3cdd86",
115
- "topology/participants/3195ffccdcff6cb767344b2d1af6c5f3e1e3e4a9906a81129ffaf24352769d2a",
116
- "topology/hosts/3195ffccdcff6cb767344b2d1af6c5f3e1e3e4a9906a81129ffaf24352769d2a"
117
- ]
118
- }
@@ -1 +0,0 @@
1
- 019eb090-74e4-7e86-998f-031e8113fb88
package/AGENTS.md DELETED
@@ -1,58 +0,0 @@
1
- # AGENTS.md
2
-
3
- ## DO NOT EDIT — Auto-generated Files
4
-
5
- The following files are **idempotent** and regenerated by `scripts/update-models.js`. Never edit them directly — your changes will be overwritten on the next model sync.
6
-
7
- | File | Why it's auto-generated |
8
- |------|------------------------|
9
- | `models.json` | Built from the provider API. `update-models.js` fetches models, preserves curated data for known IDs, and writes this file. |
10
- | `deprecated-models.json` | Graveyard for models the API delisted. update-models.js stamps them with deprecatedAt and pi keeps serving them for a 2-week grace period, then evicts them. Never edit by hand. |
11
- | `README.md` (model table) | The table under `## Available Models` is replaced in-place by `update-models.js` after merging base models → patch → custom models. |
12
-
13
- ## Correct Files to Edit
14
-
15
- When a model needs overrides, new properties, or corrections, edit the appropriate source file below. These are the **source of truth** that the update script reads but never writes.
16
-
17
- | File | Purpose |
18
- |------|---------|
19
- | `patch.json` | Per-model overrides keyed by model ID. Add reasoning flags, compat settings, pricing corrections, thinking level maps, etc. Applied on top of `models.json` at runtime and for README generation. |
20
- | `custom-models.json` | Models that don't exist in the provider API (hidden models, router endpoints, cross-provider aliases). Merged after patch. Format: array of full model objects (same schema as `models.json` entries). |
21
- | `index.ts` | Provider extension code: model sync, streaming wrapper, footer-status wiring. |
22
- | `status.ts` | Footer-status presentation: config schema, hypercredit/rate-limit formatters, progressive-disclosure tiers, width-aware widget. Pure module — no pi imports; exercised by `tests/status.smoke.ts`. |
23
- | `scripts/update-models.js` | The sync script itself (edit only if changing how models are fetched/transformed). |
24
-
25
- ## Data Flow
26
-
27
- ```
28
- Provider API ──fetch──► models.json ──apply──► patch.json ──merge──► custom-models.json
29
- │ │ │
30
- └────────────────────────────┴──────────────────────┘
31
-
32
- README model table
33
- ```
34
-
35
- 1. `models.json` — base data from the provider API (auto-generated, DO NOT EDIT)
36
- 2. `patch.json` — overrides applied on top (EDIT THIS for corrections/enrichments)
37
- 3. `custom-models.json` — additional models not in the API (EDIT THIS for new models)
38
- 4. README table — rendered from the merged result of all three (auto-generated, DO NOT EDIT)
39
-
40
- ## Common Tasks
41
-
42
- ### Add a compat setting or override pricing for an existing model
43
- → Edit `patch.json`. Add an entry keyed by the model's `id`.
44
-
45
- ### Add a model not available in the provider API
46
- → Edit `custom-models.json`. Add a full model object to the array.
47
-
48
- ### Update models from the provider API
49
- → Run `node scripts/update-models.js` (may require an API key env var).
50
-
51
- ### Regenerate the README model table
52
- → Run `node scripts/update-models.js` — it updates both `models.json` and the README table.
53
-
54
- ## TL;DR
55
-
56
- - **Never edit `models.json`** — edit `patch.json` instead.
57
- - **Never edit the README model table** — run the update script instead.
58
- - `patch.json` and `custom-models.json` are the source files you should modify.
@@ -1 +0,0 @@
1
- []
@@ -1 +0,0 @@
1
- {}