@botiverse/raft-daemon 0.63.5 → 0.63.6-play.20260624140611

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.
@@ -11,6 +11,645 @@ function makeIsMember(members) {
11
11
  return (value) => typeof value === "string" && set.has(value);
12
12
  }
13
13
 
14
+ // ../shared/src/piBuiltinModels.generated.ts
15
+ var PI_BUILTIN_PROVIDER_MODELS_GENERATED = {
16
+ "deepseek": [
17
+ { id: "deepseek/deepseek-v4-pro", label: "DeepSeek V4 Pro" },
18
+ { id: "deepseek/deepseek-v4-flash", label: "DeepSeek V4 Flash" }
19
+ ],
20
+ "minimax": [
21
+ { id: "minimax/MiniMax-M2.7", label: "MiniMax-M2.7" },
22
+ { id: "minimax/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" },
23
+ { id: "minimax/MiniMax-M3", label: "MiniMax-M3" }
24
+ ],
25
+ "minimax-cn": [
26
+ { id: "minimax-cn/MiniMax-M2.7", label: "MiniMax-M2.7" },
27
+ { id: "minimax-cn/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" },
28
+ { id: "minimax-cn/MiniMax-M3", label: "MiniMax-M3" }
29
+ ],
30
+ "zai": [
31
+ { id: "zai/glm-5.1", label: "GLM-5.1" },
32
+ { id: "zai/glm-4.5-air", label: "GLM-4.5-Air" },
33
+ { id: "zai/glm-4.7", label: "GLM-4.7" },
34
+ { id: "zai/glm-5-turbo", label: "GLM-5-Turbo" },
35
+ { id: "zai/glm-5.2", label: "GLM-5.2" },
36
+ { id: "zai/glm-5v-turbo", label: "GLM-5V-Turbo" }
37
+ ],
38
+ "zai-coding-cn": [
39
+ { id: "zai-coding-cn/glm-5.1", label: "GLM-5.1" },
40
+ { id: "zai-coding-cn/glm-4.5-air", label: "GLM-4.5-Air" },
41
+ { id: "zai-coding-cn/glm-4.7", label: "GLM-4.7" },
42
+ { id: "zai-coding-cn/glm-5-turbo", label: "GLM-5-Turbo" },
43
+ { id: "zai-coding-cn/glm-5.2", label: "GLM-5.2" },
44
+ { id: "zai-coding-cn/glm-5v-turbo", label: "GLM-5V-Turbo" }
45
+ ],
46
+ "kimi-coding": [
47
+ { id: "kimi-coding/kimi-for-coding", label: "Kimi For Coding" },
48
+ { id: "kimi-coding/k2p7", label: "Kimi K2.7 Code" },
49
+ { id: "kimi-coding/kimi-k2-thinking", label: "Kimi K2 Thinking" }
50
+ ],
51
+ "moonshotai-cn": [
52
+ { id: "moonshotai-cn/kimi-k2.6", label: "Kimi K2.6" },
53
+ { id: "moonshotai-cn/kimi-k2-0711-preview", label: "Kimi K2 0711" },
54
+ { id: "moonshotai-cn/kimi-k2-0905-preview", label: "Kimi K2 0905" },
55
+ { id: "moonshotai-cn/kimi-k2-thinking", label: "Kimi K2 Thinking" },
56
+ { id: "moonshotai-cn/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
57
+ { id: "moonshotai-cn/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
58
+ { id: "moonshotai-cn/kimi-k2.5", label: "Kimi K2.5" },
59
+ { id: "moonshotai-cn/kimi-k2.7-code", label: "Kimi K2.7 Code" },
60
+ { id: "moonshotai-cn/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" }
61
+ ],
62
+ "moonshotai": [
63
+ { id: "moonshotai/kimi-k2.6", label: "Kimi K2.6" },
64
+ { id: "moonshotai/kimi-k2-0711-preview", label: "Kimi K2 0711" },
65
+ { id: "moonshotai/kimi-k2-0905-preview", label: "Kimi K2 0905" },
66
+ { id: "moonshotai/kimi-k2-thinking", label: "Kimi K2 Thinking" },
67
+ { id: "moonshotai/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
68
+ { id: "moonshotai/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
69
+ { id: "moonshotai/kimi-k2.5", label: "Kimi K2.5" },
70
+ { id: "moonshotai/kimi-k2.7-code", label: "Kimi K2.7 Code" },
71
+ { id: "moonshotai/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" }
72
+ ],
73
+ "openai": [
74
+ { id: "openai/gpt-5.4", label: "GPT-5.4" },
75
+ { id: "openai/gpt-4", label: "GPT-4" },
76
+ { id: "openai/gpt-4-turbo", label: "GPT-4 Turbo" },
77
+ { id: "openai/gpt-4.1", label: "GPT-4.1" },
78
+ { id: "openai/gpt-4.1-mini", label: "GPT-4.1 mini" },
79
+ { id: "openai/gpt-4.1-nano", label: "GPT-4.1 nano" },
80
+ { id: "openai/gpt-4o", label: "GPT-4o" },
81
+ { id: "openai/gpt-4o-2024-05-13", label: "GPT-4o (2024-05-13)" },
82
+ { id: "openai/gpt-4o-2024-08-06", label: "GPT-4o (2024-08-06)" },
83
+ { id: "openai/gpt-4o-2024-11-20", label: "GPT-4o (2024-11-20)" },
84
+ { id: "openai/gpt-4o-mini", label: "GPT-4o mini" },
85
+ { id: "openai/gpt-5", label: "GPT-5" },
86
+ { id: "openai/gpt-5-chat-latest", label: "GPT-5 Chat Latest" },
87
+ { id: "openai/gpt-5-codex", label: "GPT-5-Codex" },
88
+ { id: "openai/gpt-5-mini", label: "GPT-5 Mini" },
89
+ { id: "openai/gpt-5-nano", label: "GPT-5 Nano" },
90
+ { id: "openai/gpt-5-pro", label: "GPT-5 Pro" },
91
+ { id: "openai/gpt-5.1", label: "GPT-5.1" },
92
+ { id: "openai/gpt-5.1-chat-latest", label: "GPT-5.1 Chat" },
93
+ { id: "openai/gpt-5.1-codex", label: "GPT-5.1 Codex" },
94
+ { id: "openai/gpt-5.1-codex-max", label: "GPT-5.1 Codex Max" },
95
+ { id: "openai/gpt-5.1-codex-mini", label: "GPT-5.1 Codex mini" },
96
+ { id: "openai/gpt-5.2", label: "GPT-5.2" },
97
+ { id: "openai/gpt-5.2-chat-latest", label: "GPT-5.2 Chat" },
98
+ { id: "openai/gpt-5.2-codex", label: "GPT-5.2 Codex" },
99
+ { id: "openai/gpt-5.2-pro", label: "GPT-5.2 Pro" },
100
+ { id: "openai/gpt-5.3-chat-latest", label: "GPT-5.3 Chat (latest)" },
101
+ { id: "openai/gpt-5.3-codex", label: "GPT-5.3 Codex" },
102
+ { id: "openai/gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark" },
103
+ { id: "openai/gpt-5.4-mini", label: "GPT-5.4 mini" },
104
+ { id: "openai/gpt-5.4-nano", label: "GPT-5.4 nano" },
105
+ { id: "openai/gpt-5.4-pro", label: "GPT-5.4 Pro" },
106
+ { id: "openai/gpt-5.5", label: "GPT-5.5" },
107
+ { id: "openai/gpt-5.5-pro", label: "GPT-5.5 Pro" },
108
+ { id: "openai/o1", label: "o1" },
109
+ { id: "openai/o1-pro", label: "o1-pro" },
110
+ { id: "openai/o3", label: "o3" },
111
+ { id: "openai/o3-deep-research", label: "o3-deep-research" },
112
+ { id: "openai/o3-mini", label: "o3-mini" },
113
+ { id: "openai/o3-pro", label: "o3-pro" },
114
+ { id: "openai/o4-mini", label: "o4-mini" },
115
+ { id: "openai/o4-mini-deep-research", label: "o4-mini-deep-research" }
116
+ ],
117
+ "anthropic": [
118
+ { id: "anthropic/claude-opus-4-8", label: "Claude Opus 4.8" },
119
+ { id: "anthropic/claude-3-5-haiku-20241022", label: "Claude Haiku 3.5" },
120
+ { id: "anthropic/claude-3-5-haiku-latest", label: "Claude Haiku 3.5 (latest)" },
121
+ { id: "anthropic/claude-3-5-sonnet-20240620", label: "Claude Sonnet 3.5" },
122
+ { id: "anthropic/claude-3-5-sonnet-20241022", label: "Claude Sonnet 3.5 v2" },
123
+ { id: "anthropic/claude-3-7-sonnet-20250219", label: "Claude Sonnet 3.7" },
124
+ { id: "anthropic/claude-3-haiku-20240307", label: "Claude Haiku 3" },
125
+ { id: "anthropic/claude-3-opus-20240229", label: "Claude Opus 3" },
126
+ { id: "anthropic/claude-3-sonnet-20240229", label: "Claude Sonnet 3" },
127
+ { id: "anthropic/claude-fable-5", label: "Claude Fable 5" },
128
+ { id: "anthropic/claude-haiku-4-5", label: "Claude Haiku 4.5 (latest)" },
129
+ { id: "anthropic/claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" },
130
+ { id: "anthropic/claude-opus-4-0", label: "Claude Opus 4 (latest)" },
131
+ { id: "anthropic/claude-opus-4-1", label: "Claude Opus 4.1 (latest)" },
132
+ { id: "anthropic/claude-opus-4-1-20250805", label: "Claude Opus 4.1" },
133
+ { id: "anthropic/claude-opus-4-20250514", label: "Claude Opus 4" },
134
+ { id: "anthropic/claude-opus-4-5", label: "Claude Opus 4.5 (latest)" },
135
+ { id: "anthropic/claude-opus-4-5-20251101", label: "Claude Opus 4.5" },
136
+ { id: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" },
137
+ { id: "anthropic/claude-opus-4-7", label: "Claude Opus 4.7" },
138
+ { id: "anthropic/claude-sonnet-4-0", label: "Claude Sonnet 4 (latest)" },
139
+ { id: "anthropic/claude-sonnet-4-20250514", label: "Claude Sonnet 4" },
140
+ { id: "anthropic/claude-sonnet-4-5", label: "Claude Sonnet 4.5 (latest)" },
141
+ { id: "anthropic/claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
142
+ { id: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" }
143
+ ],
144
+ "google": [
145
+ { id: "google/gemini-3.1-pro-preview", label: "Gemini 3.1 Pro Preview" },
146
+ { id: "google/gemini-2.0-flash", label: "Gemini 2.0 Flash" },
147
+ { id: "google/gemini-2.0-flash-lite", label: "Gemini 2.0 Flash-Lite" },
148
+ { id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash" },
149
+ { id: "google/gemini-2.5-flash-lite", label: "Gemini 2.5 Flash-Lite" },
150
+ { id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro" },
151
+ { id: "google/gemini-3-flash-preview", label: "Gemini 3 Flash Preview" },
152
+ { id: "google/gemini-3-pro-preview", label: "Gemini 3 Pro Preview" },
153
+ { id: "google/gemini-3.1-flash-lite", label: "Gemini 3.1 Flash Lite" },
154
+ { id: "google/gemini-3.1-flash-lite-preview", label: "Gemini 3.1 Flash Lite Preview" },
155
+ { id: "google/gemini-3.1-pro-preview-customtools", label: "Gemini 3.1 Pro Preview Custom Tools" },
156
+ { id: "google/gemini-3.5-flash", label: "Gemini 3.5 Flash" },
157
+ { id: "google/gemini-flash-latest", label: "Gemini Flash Latest" },
158
+ { id: "google/gemini-flash-lite-latest", label: "Gemini Flash-Lite Latest" },
159
+ { id: "google/gemma-4-26b-a4b-it", label: "Gemma 4 26B A4B IT" },
160
+ { id: "google/gemma-4-31b-it", label: "Gemma 4 31B IT" },
161
+ { id: "google/gemma-4-E2B-it", label: "Gemma 4 E2B IT" },
162
+ { id: "google/gemma-4-E4B-it", label: "Gemma 4 E4B IT" }
163
+ ],
164
+ "xai": [
165
+ { id: "xai/grok-4.20-0309-reasoning", label: "Grok 4.20 (Reasoning)" },
166
+ { id: "xai/grok-3", label: "Grok 3" },
167
+ { id: "xai/grok-3-fast", label: "Grok 3 Fast" },
168
+ { id: "xai/grok-4.20-0309-non-reasoning", label: "Grok 4.20 (Non-Reasoning)" },
169
+ { id: "xai/grok-4.3", label: "Grok 4.3" },
170
+ { id: "xai/grok-build-0.1", label: "Grok Build 0.1" },
171
+ { id: "xai/grok-code-fast-1", label: "Grok Code Fast 1" }
172
+ ],
173
+ "groq": [
174
+ { id: "groq/openai/gpt-oss-120b", label: "GPT OSS 120B" },
175
+ { id: "groq/llama-3.1-8b-instant", label: "Llama 3.1 8B" },
176
+ { id: "groq/llama-3.3-70b-versatile", label: "Llama 3.3 70B" },
177
+ { id: "groq/meta-llama/llama-4-scout-17b-16e-instruct", label: "Llama 4 Scout 17B 16E" },
178
+ { id: "groq/openai/gpt-oss-20b", label: "GPT OSS 20B" },
179
+ { id: "groq/openai/gpt-oss-safeguard-20b", label: "Safety GPT OSS 20B" },
180
+ { id: "groq/qwen/qwen3-32b", label: "Qwen3-32B" }
181
+ ],
182
+ "mistral": [
183
+ { id: "mistral/devstral-medium-latest", label: "Devstral 2 (latest)" },
184
+ { id: "mistral/codestral-latest", label: "Codestral (latest)" },
185
+ { id: "mistral/devstral-2512", label: "Devstral 2" },
186
+ { id: "mistral/devstral-latest", label: "Devstral 2" },
187
+ { id: "mistral/devstral-medium-2507", label: "Devstral Medium" },
188
+ { id: "mistral/devstral-small-2505", label: "Devstral Small 2505" },
189
+ { id: "mistral/devstral-small-2507", label: "Devstral Small" },
190
+ { id: "mistral/labs-devstral-small-2512", label: "Devstral Small 2" },
191
+ { id: "mistral/magistral-medium-latest", label: "Magistral Medium (latest)" },
192
+ { id: "mistral/magistral-small", label: "Magistral Small" },
193
+ { id: "mistral/ministral-3b-latest", label: "Ministral 3B (latest)" },
194
+ { id: "mistral/ministral-8b-latest", label: "Ministral 8B (latest)" },
195
+ { id: "mistral/mistral-large-2411", label: "Mistral Large 2.1" },
196
+ { id: "mistral/mistral-large-2512", label: "Mistral Large 3" },
197
+ { id: "mistral/mistral-large-latest", label: "Mistral Large (latest)" },
198
+ { id: "mistral/mistral-medium-2505", label: "Mistral Medium 3" },
199
+ { id: "mistral/mistral-medium-2508", label: "Mistral Medium 3.1" },
200
+ { id: "mistral/mistral-medium-2604", label: "Mistral Medium 3.5" },
201
+ { id: "mistral/mistral-medium-3.5", label: "Mistral Medium 3.5" },
202
+ { id: "mistral/mistral-medium-latest", label: "Mistral Medium (latest)" },
203
+ { id: "mistral/mistral-nemo", label: "Mistral Nemo" },
204
+ { id: "mistral/mistral-small-2506", label: "Mistral Small 3.2" },
205
+ { id: "mistral/mistral-small-2603", label: "Mistral Small 4" },
206
+ { id: "mistral/mistral-small-latest", label: "Mistral Small (latest)" },
207
+ { id: "mistral/open-mistral-7b", label: "Mistral 7B" },
208
+ { id: "mistral/open-mistral-nemo", label: "Open Mistral Nemo" },
209
+ { id: "mistral/open-mixtral-8x22b", label: "Mixtral 8x22B" },
210
+ { id: "mistral/open-mixtral-8x7b", label: "Mixtral 8x7B" },
211
+ { id: "mistral/pixtral-12b", label: "Pixtral 12B" },
212
+ { id: "mistral/pixtral-large-latest", label: "Pixtral Large (latest)" }
213
+ ],
214
+ "fireworks": [
215
+ { id: "fireworks/accounts/fireworks/models/kimi-k2p6", label: "Kimi K2.6" },
216
+ { id: "fireworks/accounts/fireworks/models/deepseek-v4-flash", label: "DeepSeek V4 Flash" },
217
+ { id: "fireworks/accounts/fireworks/models/deepseek-v4-pro", label: "DeepSeek V4 Pro" },
218
+ { id: "fireworks/accounts/fireworks/models/glm-5p1", label: "GLM 5.1" },
219
+ { id: "fireworks/accounts/fireworks/models/glm-5p2", label: "GLM 5.2" },
220
+ { id: "fireworks/accounts/fireworks/models/gpt-oss-120b", label: "GPT OSS 120B" },
221
+ { id: "fireworks/accounts/fireworks/models/gpt-oss-20b", label: "GPT OSS 20B" },
222
+ { id: "fireworks/accounts/fireworks/models/kimi-k2p7-code", label: "Kimi K2.7 Code" },
223
+ { id: "fireworks/accounts/fireworks/models/minimax-m2p7", label: "MiniMax-M2.7" },
224
+ { id: "fireworks/accounts/fireworks/models/minimax-m3", label: "MiniMax-M3" },
225
+ { id: "fireworks/accounts/fireworks/models/qwen3p7-plus", label: "Qwen 3.7 Plus" },
226
+ { id: "fireworks/accounts/fireworks/routers/glm-5p1-fast", label: "GLM 5.1 Fast" },
227
+ { id: "fireworks/accounts/fireworks/routers/kimi-k2p6-fast", label: "Kimi K2.6 Fast" },
228
+ { id: "fireworks/accounts/fireworks/routers/kimi-k2p6-turbo", label: "Kimi K2.6 Turbo" },
229
+ { id: "fireworks/accounts/fireworks/routers/kimi-k2p7-code-fast", label: "Kimi K2.7 Code Fast" }
230
+ ],
231
+ "together": [
232
+ { id: "together/moonshotai/Kimi-K2.6", label: "Kimi K2.6" },
233
+ { id: "together/MiniMaxAI/MiniMax-M2.7", label: "MiniMax-M2.7" },
234
+ { id: "together/MiniMaxAI/MiniMax-M3", label: "MiniMax-M3" },
235
+ { id: "together/Qwen/Qwen2.5-7B-Instruct-Turbo", label: "Qwen 2.5 7B Instruct Turbo" },
236
+ { id: "together/Qwen/Qwen3-235B-A22B-Instruct-2507-tput", label: "Qwen3 235B A22B Instruct 2507 FP8" },
237
+ { id: "together/Qwen/Qwen3.5-397B-A17B", label: "Qwen3.5 397B A17B" },
238
+ { id: "together/Qwen/Qwen3.5-9B", label: "Qwen3.5 9B" },
239
+ { id: "together/Qwen/Qwen3.6-Plus", label: "Qwen3.6 Plus" },
240
+ { id: "together/Qwen/Qwen3.7-Max", label: "Qwen3.7 Max" },
241
+ { id: "together/deepseek-ai/DeepSeek-V4-Pro", label: "DeepSeek V4 Pro" },
242
+ { id: "together/essentialai/Rnj-1-Instruct", label: "Rnj-1 Instruct" },
243
+ { id: "together/google/gemma-4-31B-it", label: "Gemma 4 31B Instruct" },
244
+ { id: "together/meta-llama/Llama-3.3-70B-Instruct-Turbo", label: "Llama 3.3 70B" },
245
+ { id: "together/moonshotai/Kimi-K2.7-Code", label: "Kimi K2.7 Code" },
246
+ { id: "together/nvidia/nemotron-3-ultra-550b-a55b", label: "Nemotron 3 Ultra 550B A55B" },
247
+ { id: "together/openai/gpt-oss-120b", label: "GPT OSS 120B" },
248
+ { id: "together/openai/gpt-oss-20b", label: "GPT OSS 20B" },
249
+ { id: "together/zai-org/GLM-5", label: "GLM-5" },
250
+ { id: "together/zai-org/GLM-5.1", label: "GLM-5.1" }
251
+ ],
252
+ "openrouter": [
253
+ { id: "openrouter/moonshotai/kimi-k2.6", label: "MoonshotAI: Kimi K2.6" },
254
+ { id: "openrouter/ai21/jamba-large-1.7", label: "AI21: Jamba Large 1.7" },
255
+ { id: "openrouter/amazon/nova-2-lite-v1", label: "Amazon: Nova 2 Lite" },
256
+ { id: "openrouter/amazon/nova-lite-v1", label: "Amazon: Nova Lite 1.0" },
257
+ { id: "openrouter/amazon/nova-micro-v1", label: "Amazon: Nova Micro 1.0" },
258
+ { id: "openrouter/amazon/nova-premier-v1", label: "Amazon: Nova Premier 1.0" },
259
+ { id: "openrouter/amazon/nova-pro-v1", label: "Amazon: Nova Pro 1.0" },
260
+ { id: "openrouter/anthropic/claude-3-haiku", label: "Anthropic: Claude 3 Haiku" },
261
+ { id: "openrouter/anthropic/claude-3.5-haiku", label: "Anthropic: Claude 3.5 Haiku" },
262
+ { id: "openrouter/anthropic/claude-fable-5", label: "Anthropic: Claude Fable 5" },
263
+ { id: "openrouter/anthropic/claude-haiku-4.5", label: "Anthropic: Claude Haiku 4.5" },
264
+ { id: "openrouter/anthropic/claude-opus-4", label: "Anthropic: Claude Opus 4" },
265
+ { id: "openrouter/anthropic/claude-opus-4.1", label: "Anthropic: Claude Opus 4.1" },
266
+ { id: "openrouter/anthropic/claude-opus-4.5", label: "Anthropic: Claude Opus 4.5" },
267
+ { id: "openrouter/anthropic/claude-opus-4.6", label: "Anthropic: Claude Opus 4.6" },
268
+ { id: "openrouter/anthropic/claude-opus-4.6-fast", label: "Anthropic: Claude Opus 4.6 (Fast)" },
269
+ { id: "openrouter/anthropic/claude-opus-4.7", label: "Anthropic: Claude Opus 4.7" },
270
+ { id: "openrouter/anthropic/claude-opus-4.7-fast", label: "Anthropic: Claude Opus 4.7 (Fast)" },
271
+ { id: "openrouter/anthropic/claude-opus-4.8", label: "Anthropic: Claude Opus 4.8" },
272
+ { id: "openrouter/anthropic/claude-opus-4.8-fast", label: "Anthropic: Claude Opus 4.8 (Fast)" },
273
+ { id: "openrouter/anthropic/claude-sonnet-4", label: "Anthropic: Claude Sonnet 4" },
274
+ { id: "openrouter/anthropic/claude-sonnet-4.5", label: "Anthropic: Claude Sonnet 4.5" },
275
+ { id: "openrouter/anthropic/claude-sonnet-4.6", label: "Anthropic: Claude Sonnet 4.6" },
276
+ { id: "openrouter/arcee-ai/trinity-large-thinking", label: "Arcee AI: Trinity Large Thinking" },
277
+ { id: "openrouter/arcee-ai/trinity-mini", label: "Arcee AI: Trinity Mini" },
278
+ { id: "openrouter/arcee-ai/virtuoso-large", label: "Arcee AI: Virtuoso Large" },
279
+ { id: "openrouter/auto", label: "Auto" },
280
+ { id: "openrouter/bytedance-seed/seed-1.6", label: "ByteDance Seed: Seed 1.6" },
281
+ { id: "openrouter/bytedance-seed/seed-1.6-flash", label: "ByteDance Seed: Seed 1.6 Flash" },
282
+ { id: "openrouter/bytedance-seed/seed-2.0-lite", label: "ByteDance Seed: Seed-2.0-Lite" },
283
+ { id: "openrouter/bytedance-seed/seed-2.0-mini", label: "ByteDance Seed: Seed-2.0-Mini" },
284
+ { id: "openrouter/cohere/command-r-08-2024", label: "Cohere: Command R (08-2024)" },
285
+ { id: "openrouter/cohere/command-r-plus-08-2024", label: "Cohere: Command R+ (08-2024)" },
286
+ { id: "openrouter/cohere/north-mini-code:free", label: "Cohere: North Mini Code (free)" },
287
+ { id: "openrouter/deepseek/deepseek-chat", label: "DeepSeek: DeepSeek V3" },
288
+ { id: "openrouter/deepseek/deepseek-chat-v3-0324", label: "DeepSeek: DeepSeek V3 0324" },
289
+ { id: "openrouter/deepseek/deepseek-chat-v3.1", label: "DeepSeek: DeepSeek V3.1" },
290
+ { id: "openrouter/deepseek/deepseek-r1", label: "DeepSeek: R1" },
291
+ { id: "openrouter/deepseek/deepseek-r1-0528", label: "DeepSeek: R1 0528" },
292
+ { id: "openrouter/deepseek/deepseek-v3.1-terminus", label: "DeepSeek: DeepSeek V3.1 Terminus" },
293
+ { id: "openrouter/deepseek/deepseek-v3.2", label: "DeepSeek: DeepSeek V3.2" },
294
+ { id: "openrouter/deepseek/deepseek-v3.2-exp", label: "DeepSeek: DeepSeek V3.2 Exp" },
295
+ { id: "openrouter/deepseek/deepseek-v4-flash", label: "DeepSeek: DeepSeek V4 Flash" },
296
+ { id: "openrouter/deepseek/deepseek-v4-pro", label: "DeepSeek: DeepSeek V4 Pro" },
297
+ { id: "openrouter/essentialai/rnj-1-instruct", label: "EssentialAI: Rnj 1 Instruct" },
298
+ { id: "openrouter/google/gemini-2.5-flash", label: "Google: Gemini 2.5 Flash" },
299
+ { id: "openrouter/google/gemini-2.5-flash-lite", label: "Google: Gemini 2.5 Flash Lite" },
300
+ { id: "openrouter/google/gemini-2.5-flash-lite-preview-09-2025", label: "Google: Gemini 2.5 Flash Lite Preview 09-2025" },
301
+ { id: "openrouter/google/gemini-2.5-pro", label: "Google: Gemini 2.5 Pro" },
302
+ { id: "openrouter/google/gemini-2.5-pro-preview", label: "Google: Gemini 2.5 Pro Preview 06-05" },
303
+ { id: "openrouter/google/gemini-2.5-pro-preview-05-06", label: "Google: Gemini 2.5 Pro Preview 05-06" },
304
+ { id: "openrouter/google/gemini-3-flash-preview", label: "Google: Gemini 3 Flash Preview" },
305
+ { id: "openrouter/google/gemini-3-pro-image", label: "Google: Nano Banana Pro (Gemini 3 Pro Image)" },
306
+ { id: "openrouter/google/gemini-3.1-flash-lite", label: "Google: Gemini 3.1 Flash Lite" },
307
+ { id: "openrouter/google/gemini-3.1-flash-lite-preview", label: "Google: Gemini 3.1 Flash Lite Preview" },
308
+ { id: "openrouter/google/gemini-3.1-pro-preview", label: "Google: Gemini 3.1 Pro Preview" },
309
+ { id: "openrouter/google/gemini-3.1-pro-preview-customtools", label: "Google: Gemini 3.1 Pro Preview Custom Tools" },
310
+ { id: "openrouter/google/gemini-3.5-flash", label: "Google: Gemini 3.5 Flash" },
311
+ { id: "openrouter/google/gemma-3-12b-it", label: "Google: Gemma 3 12B" },
312
+ { id: "openrouter/google/gemma-3-27b-it", label: "Google: Gemma 3 27B" },
313
+ { id: "openrouter/google/gemma-4-26b-a4b-it", label: "Google: Gemma 4 26B A4B " },
314
+ { id: "openrouter/google/gemma-4-26b-a4b-it:free", label: "Google: Gemma 4 26B A4B (free)" },
315
+ { id: "openrouter/google/gemma-4-31b-it", label: "Google: Gemma 4 31B" },
316
+ { id: "openrouter/google/gemma-4-31b-it:free", label: "Google: Gemma 4 31B (free)" },
317
+ { id: "openrouter/ibm-granite/granite-4.1-8b", label: "IBM: Granite 4.1 8B" },
318
+ { id: "openrouter/inception/mercury-2", label: "Inception: Mercury 2" },
319
+ { id: "openrouter/inclusionai/ling-2.6-1t", label: "inclusionAI: Ling-2.6-1T" },
320
+ { id: "openrouter/inclusionai/ling-2.6-flash", label: "inclusionAI: Ling-2.6-flash" },
321
+ { id: "openrouter/inclusionai/ring-2.6-1t", label: "inclusionAI: Ring-2.6-1T" },
322
+ { id: "openrouter/kwaipilot/kat-coder-pro-v2", label: "Kwaipilot: KAT-Coder-Pro V2" },
323
+ { id: "openrouter/liquid/lfm-2.5-1.2b-thinking:free", label: "LiquidAI: LFM2.5-1.2B-Thinking (free)" },
324
+ { id: "openrouter/meta-llama/llama-3.1-70b-instruct", label: "Meta: Llama 3.1 70B Instruct" },
325
+ { id: "openrouter/meta-llama/llama-3.1-8b-instruct", label: "Meta: Llama 3.1 8B Instruct" },
326
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct", label: "Meta: Llama 3.3 70B Instruct" },
327
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct:free", label: "Meta: Llama 3.3 70B Instruct (free)" },
328
+ { id: "openrouter/meta-llama/llama-4-maverick", label: "Meta: Llama 4 Maverick" },
329
+ { id: "openrouter/meta-llama/llama-4-scout", label: "Meta: Llama 4 Scout" },
330
+ { id: "openrouter/minimax/minimax-m1", label: "MiniMax: MiniMax M1" },
331
+ { id: "openrouter/minimax/minimax-m2", label: "MiniMax: MiniMax M2" },
332
+ { id: "openrouter/minimax/minimax-m2.1", label: "MiniMax: MiniMax M2.1" },
333
+ { id: "openrouter/minimax/minimax-m2.5", label: "MiniMax: MiniMax M2.5" },
334
+ { id: "openrouter/minimax/minimax-m2.7", label: "MiniMax: MiniMax M2.7" },
335
+ { id: "openrouter/minimax/minimax-m3", label: "MiniMax: MiniMax M3" },
336
+ { id: "openrouter/mistralai/codestral-2508", label: "Mistral: Codestral 2508" },
337
+ { id: "openrouter/mistralai/devstral-2512", label: "Mistral: Devstral 2 2512" },
338
+ { id: "openrouter/mistralai/ministral-14b-2512", label: "Mistral: Ministral 3 14B 2512" },
339
+ { id: "openrouter/mistralai/ministral-3b-2512", label: "Mistral: Ministral 3 3B 2512" },
340
+ { id: "openrouter/mistralai/ministral-8b-2512", label: "Mistral: Ministral 3 8B 2512" },
341
+ { id: "openrouter/mistralai/mistral-large", label: "Mistral Large" },
342
+ { id: "openrouter/mistralai/mistral-large-2407", label: "Mistral Large 2407" },
343
+ { id: "openrouter/mistralai/mistral-large-2512", label: "Mistral: Mistral Large 3 2512" },
344
+ { id: "openrouter/mistralai/mistral-medium-3", label: "Mistral: Mistral Medium 3" },
345
+ { id: "openrouter/mistralai/mistral-medium-3-5", label: "Mistral: Mistral Medium 3.5" },
346
+ { id: "openrouter/mistralai/mistral-medium-3.1", label: "Mistral: Mistral Medium 3.1" },
347
+ { id: "openrouter/mistralai/mistral-nemo", label: "Mistral: Mistral Nemo" },
348
+ { id: "openrouter/mistralai/mistral-saba", label: "Mistral: Saba" },
349
+ { id: "openrouter/mistralai/mistral-small-2603", label: "Mistral: Mistral Small 4" },
350
+ { id: "openrouter/mistralai/mistral-small-3.2-24b-instruct", label: "Mistral: Mistral Small 3.2 24B" },
351
+ { id: "openrouter/mistralai/mixtral-8x22b-instruct", label: "Mistral: Mixtral 8x22B Instruct" },
352
+ { id: "openrouter/mistralai/voxtral-small-24b-2507", label: "Mistral: Voxtral Small 24B 2507" },
353
+ { id: "openrouter/moonshotai/kimi-k2", label: "MoonshotAI: Kimi K2 0711" },
354
+ { id: "openrouter/moonshotai/kimi-k2-0905", label: "MoonshotAI: Kimi K2 0905" },
355
+ { id: "openrouter/moonshotai/kimi-k2-thinking", label: "MoonshotAI: Kimi K2 Thinking" },
356
+ { id: "openrouter/moonshotai/kimi-k2.5", label: "MoonshotAI: Kimi K2.5" },
357
+ { id: "openrouter/moonshotai/kimi-k2.7-code", label: "MoonshotAI: Kimi K2.7 Code" },
358
+ { id: "openrouter/nex-agi/nex-n2-pro:free", label: "Nex AGI: Nex-N2-Pro (free)" },
359
+ { id: "openrouter/nvidia/llama-3.3-nemotron-super-49b-v1.5", label: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5" },
360
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b", label: "NVIDIA: Nemotron 3 Nano 30B A3B" },
361
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b:free", label: "NVIDIA: Nemotron 3 Nano 30B A3B (free)" },
362
+ { id: "openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", label: "NVIDIA: Nemotron 3 Nano Omni (free)" },
363
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b", label: "NVIDIA: Nemotron 3 Super" },
364
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b:free", label: "NVIDIA: Nemotron 3 Super (free)" },
365
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b", label: "NVIDIA: Nemotron 3 Ultra" },
366
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free", label: "NVIDIA: Nemotron 3 Ultra (free)" },
367
+ { id: "openrouter/nvidia/nemotron-nano-12b-v2-vl:free", label: "NVIDIA: Nemotron Nano 12B 2 VL (free)" },
368
+ { id: "openrouter/nvidia/nemotron-nano-9b-v2:free", label: "NVIDIA: Nemotron Nano 9B V2 (free)" },
369
+ { id: "openrouter/openai/gpt-3.5-turbo", label: "OpenAI: GPT-3.5 Turbo" },
370
+ { id: "openrouter/openai/gpt-3.5-turbo-0613", label: "OpenAI: GPT-3.5 Turbo (older v0613)" },
371
+ { id: "openrouter/openai/gpt-3.5-turbo-16k", label: "OpenAI: GPT-3.5 Turbo 16k" },
372
+ { id: "openrouter/openai/gpt-4", label: "OpenAI: GPT-4" },
373
+ { id: "openrouter/openai/gpt-4-turbo", label: "OpenAI: GPT-4 Turbo" },
374
+ { id: "openrouter/openai/gpt-4-turbo-preview", label: "OpenAI: GPT-4 Turbo Preview" },
375
+ { id: "openrouter/openai/gpt-4.1", label: "OpenAI: GPT-4.1" },
376
+ { id: "openrouter/openai/gpt-4.1-mini", label: "OpenAI: GPT-4.1 Mini" },
377
+ { id: "openrouter/openai/gpt-4.1-nano", label: "OpenAI: GPT-4.1 Nano" },
378
+ { id: "openrouter/openai/gpt-4o", label: "OpenAI: GPT-4o" },
379
+ { id: "openrouter/openai/gpt-4o-2024-05-13", label: "OpenAI: GPT-4o (2024-05-13)" },
380
+ { id: "openrouter/openai/gpt-4o-2024-08-06", label: "OpenAI: GPT-4o (2024-08-06)" },
381
+ { id: "openrouter/openai/gpt-4o-2024-11-20", label: "OpenAI: GPT-4o (2024-11-20)" },
382
+ { id: "openrouter/openai/gpt-4o-mini", label: "OpenAI: GPT-4o-mini" },
383
+ { id: "openrouter/openai/gpt-4o-mini-2024-07-18", label: "OpenAI: GPT-4o-mini (2024-07-18)" },
384
+ { id: "openrouter/openai/gpt-5", label: "OpenAI: GPT-5" },
385
+ { id: "openrouter/openai/gpt-5-codex", label: "OpenAI: GPT-5 Codex" },
386
+ { id: "openrouter/openai/gpt-5-mini", label: "OpenAI: GPT-5 Mini" },
387
+ { id: "openrouter/openai/gpt-5-nano", label: "OpenAI: GPT-5 Nano" },
388
+ { id: "openrouter/openai/gpt-5-pro", label: "OpenAI: GPT-5 Pro" },
389
+ { id: "openrouter/openai/gpt-5.1", label: "OpenAI: GPT-5.1" },
390
+ { id: "openrouter/openai/gpt-5.1-chat", label: "OpenAI: GPT-5.1 Chat" },
391
+ { id: "openrouter/openai/gpt-5.1-codex", label: "OpenAI: GPT-5.1-Codex" },
392
+ { id: "openrouter/openai/gpt-5.1-codex-max", label: "OpenAI: GPT-5.1-Codex-Max" },
393
+ { id: "openrouter/openai/gpt-5.1-codex-mini", label: "OpenAI: GPT-5.1-Codex-Mini" },
394
+ { id: "openrouter/openai/gpt-5.2", label: "OpenAI: GPT-5.2" },
395
+ { id: "openrouter/openai/gpt-5.2-chat", label: "OpenAI: GPT-5.2 Chat" },
396
+ { id: "openrouter/openai/gpt-5.2-codex", label: "OpenAI: GPT-5.2-Codex" },
397
+ { id: "openrouter/openai/gpt-5.2-pro", label: "OpenAI: GPT-5.2 Pro" },
398
+ { id: "openrouter/openai/gpt-5.3-chat", label: "OpenAI: GPT-5.3 Chat" },
399
+ { id: "openrouter/openai/gpt-5.3-codex", label: "OpenAI: GPT-5.3-Codex" },
400
+ { id: "openrouter/openai/gpt-5.4", label: "OpenAI: GPT-5.4" },
401
+ { id: "openrouter/openai/gpt-5.4-mini", label: "OpenAI: GPT-5.4 Mini" },
402
+ { id: "openrouter/openai/gpt-5.4-nano", label: "OpenAI: GPT-5.4 Nano" },
403
+ { id: "openrouter/openai/gpt-5.4-pro", label: "OpenAI: GPT-5.4 Pro" },
404
+ { id: "openrouter/openai/gpt-5.5", label: "OpenAI: GPT-5.5" },
405
+ { id: "openrouter/openai/gpt-5.5-pro", label: "OpenAI: GPT-5.5 Pro" },
406
+ { id: "openrouter/openai/gpt-audio", label: "OpenAI: GPT Audio" },
407
+ { id: "openrouter/openai/gpt-audio-mini", label: "OpenAI: GPT Audio Mini" },
408
+ { id: "openrouter/openai/gpt-chat-latest", label: "OpenAI: GPT Chat Latest" },
409
+ { id: "openrouter/openai/gpt-oss-120b", label: "OpenAI: gpt-oss-120b" },
410
+ { id: "openrouter/openai/gpt-oss-120b:free", label: "OpenAI: gpt-oss-120b (free)" },
411
+ { id: "openrouter/openai/gpt-oss-20b", label: "OpenAI: gpt-oss-20b" },
412
+ { id: "openrouter/openai/gpt-oss-20b:free", label: "OpenAI: gpt-oss-20b (free)" },
413
+ { id: "openrouter/openai/gpt-oss-safeguard-20b", label: "OpenAI: gpt-oss-safeguard-20b" },
414
+ { id: "openrouter/openai/o1", label: "OpenAI: o1" },
415
+ { id: "openrouter/openai/o3", label: "OpenAI: o3" },
416
+ { id: "openrouter/openai/o3-deep-research", label: "OpenAI: o3 Deep Research" },
417
+ { id: "openrouter/openai/o3-mini", label: "OpenAI: o3 Mini" },
418
+ { id: "openrouter/openai/o3-mini-high", label: "OpenAI: o3 Mini High" },
419
+ { id: "openrouter/openai/o3-pro", label: "OpenAI: o3 Pro" },
420
+ { id: "openrouter/openai/o4-mini", label: "OpenAI: o4 Mini" },
421
+ { id: "openrouter/openai/o4-mini-deep-research", label: "OpenAI: o4 Mini Deep Research" },
422
+ { id: "openrouter/openai/o4-mini-high", label: "OpenAI: o4 Mini High" },
423
+ { id: "openrouter/openrouter/auto", label: "Auto Router" },
424
+ { id: "openrouter/openrouter/free", label: "Free Models Router" },
425
+ { id: "openrouter/openrouter/fusion", label: "OpenRouter: Fusion" },
426
+ { id: "openrouter/openrouter/owl-alpha", label: "Owl Alpha" },
427
+ { id: "openrouter/poolside/laguna-m.1", label: "Poolside: Laguna M.1" },
428
+ { id: "openrouter/poolside/laguna-m.1:free", label: "Poolside: Laguna M.1 (free)" },
429
+ { id: "openrouter/poolside/laguna-xs.2", label: "Poolside: Laguna XS.2" },
430
+ { id: "openrouter/poolside/laguna-xs.2:free", label: "Poolside: Laguna XS.2 (free)" },
431
+ { id: "openrouter/prime-intellect/intellect-3", label: "Prime Intellect: INTELLECT-3" },
432
+ { id: "openrouter/qwen/qwen-2.5-72b-instruct", label: "Qwen2.5 72B Instruct" },
433
+ { id: "openrouter/qwen/qwen-2.5-7b-instruct", label: "Qwen: Qwen2.5 7B Instruct" },
434
+ { id: "openrouter/qwen/qwen-plus", label: "Qwen: Qwen-Plus" },
435
+ { id: "openrouter/qwen/qwen-plus-2025-07-28", label: "Qwen: Qwen Plus 0728" },
436
+ { id: "openrouter/qwen/qwen-plus-2025-07-28:thinking", label: "Qwen: Qwen Plus 0728 (thinking)" },
437
+ { id: "openrouter/qwen/qwen3-14b", label: "Qwen: Qwen3 14B" },
438
+ { id: "openrouter/qwen/qwen3-235b-a22b", label: "Qwen: Qwen3 235B A22B" },
439
+ { id: "openrouter/qwen/qwen3-235b-a22b-2507", label: "Qwen: Qwen3 235B A22B Instruct 2507" },
440
+ { id: "openrouter/qwen/qwen3-235b-a22b-thinking-2507", label: "Qwen: Qwen3 235B A22B Thinking 2507" },
441
+ { id: "openrouter/qwen/qwen3-30b-a3b", label: "Qwen: Qwen3 30B A3B" },
442
+ { id: "openrouter/qwen/qwen3-30b-a3b-instruct-2507", label: "Qwen: Qwen3 30B A3B Instruct 2507" },
443
+ { id: "openrouter/qwen/qwen3-30b-a3b-thinking-2507", label: "Qwen: Qwen3 30B A3B Thinking 2507" },
444
+ { id: "openrouter/qwen/qwen3-32b", label: "Qwen: Qwen3 32B" },
445
+ { id: "openrouter/qwen/qwen3-8b", label: "Qwen: Qwen3 8B" },
446
+ { id: "openrouter/qwen/qwen3-coder", label: "Qwen: Qwen3 Coder 480B A35B" },
447
+ { id: "openrouter/qwen/qwen3-coder-30b-a3b-instruct", label: "Qwen: Qwen3 Coder 30B A3B Instruct" },
448
+ { id: "openrouter/qwen/qwen3-coder-flash", label: "Qwen: Qwen3 Coder Flash" },
449
+ { id: "openrouter/qwen/qwen3-coder-next", label: "Qwen: Qwen3 Coder Next" },
450
+ { id: "openrouter/qwen/qwen3-coder-plus", label: "Qwen: Qwen3 Coder Plus" },
451
+ { id: "openrouter/qwen/qwen3-coder:free", label: "Qwen: Qwen3 Coder 480B A35B (free)" },
452
+ { id: "openrouter/qwen/qwen3-max", label: "Qwen: Qwen3 Max" },
453
+ { id: "openrouter/qwen/qwen3-max-thinking", label: "Qwen: Qwen3 Max Thinking" },
454
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct", label: "Qwen: Qwen3 Next 80B A3B Instruct" },
455
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct:free", label: "Qwen: Qwen3 Next 80B A3B Instruct (free)" },
456
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-thinking", label: "Qwen: Qwen3 Next 80B A3B Thinking" },
457
+ { id: "openrouter/qwen/qwen3-vl-235b-a22b-instruct", label: "Qwen: Qwen3 VL 235B A22B Instruct" },
458
+ { id: "openrouter/qwen/qwen3-vl-235b-a22b-thinking", label: "Qwen: Qwen3 VL 235B A22B Thinking" },
459
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-instruct", label: "Qwen: Qwen3 VL 30B A3B Instruct" },
460
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-thinking", label: "Qwen: Qwen3 VL 30B A3B Thinking" },
461
+ { id: "openrouter/qwen/qwen3-vl-32b-instruct", label: "Qwen: Qwen3 VL 32B Instruct" },
462
+ { id: "openrouter/qwen/qwen3-vl-8b-instruct", label: "Qwen: Qwen3 VL 8B Instruct" },
463
+ { id: "openrouter/qwen/qwen3-vl-8b-thinking", label: "Qwen: Qwen3 VL 8B Thinking" },
464
+ { id: "openrouter/qwen/qwen3.5-122b-a10b", label: "Qwen: Qwen3.5-122B-A10B" },
465
+ { id: "openrouter/qwen/qwen3.5-27b", label: "Qwen: Qwen3.5-27B" },
466
+ { id: "openrouter/qwen/qwen3.5-35b-a3b", label: "Qwen: Qwen3.5-35B-A3B" },
467
+ { id: "openrouter/qwen/qwen3.5-397b-a17b", label: "Qwen: Qwen3.5 397B A17B" },
468
+ { id: "openrouter/qwen/qwen3.5-9b", label: "Qwen: Qwen3.5-9B" },
469
+ { id: "openrouter/qwen/qwen3.5-flash-02-23", label: "Qwen: Qwen3.5-Flash" },
470
+ { id: "openrouter/qwen/qwen3.5-plus-02-15", label: "Qwen: Qwen3.5 Plus 2026-02-15" },
471
+ { id: "openrouter/qwen/qwen3.5-plus-20260420", label: "Qwen: Qwen3.5 Plus 2026-04-20" },
472
+ { id: "openrouter/qwen/qwen3.6-27b", label: "Qwen: Qwen3.6 27B" },
473
+ { id: "openrouter/qwen/qwen3.6-35b-a3b", label: "Qwen: Qwen3.6 35B A3B" },
474
+ { id: "openrouter/qwen/qwen3.6-flash", label: "Qwen: Qwen3.6 Flash" },
475
+ { id: "openrouter/qwen/qwen3.6-max-preview", label: "Qwen: Qwen3.6 Max Preview" },
476
+ { id: "openrouter/qwen/qwen3.6-plus", label: "Qwen: Qwen3.6 Plus" },
477
+ { id: "openrouter/qwen/qwen3.7-max", label: "Qwen: Qwen3.7 Max" },
478
+ { id: "openrouter/qwen/qwen3.7-plus", label: "Qwen: Qwen3.7 Plus" },
479
+ { id: "openrouter/rekaai/reka-edge", label: "Reka Edge" },
480
+ { id: "openrouter/relace/relace-search", label: "Relace: Relace Search" },
481
+ { id: "openrouter/sao10k/l3.1-euryale-70b", label: "Sao10K: Llama 3.1 Euryale 70B v2.2" },
482
+ { id: "openrouter/stepfun/step-3.5-flash", label: "StepFun: Step 3.5 Flash" },
483
+ { id: "openrouter/stepfun/step-3.7-flash", label: "StepFun: Step 3.7 Flash" },
484
+ { id: "openrouter/tencent/hy3-preview", label: "Tencent: Hy3 preview" },
485
+ { id: "openrouter/thedrummer/rocinante-12b", label: "TheDrummer: Rocinante 12B" },
486
+ { id: "openrouter/thedrummer/unslopnemo-12b", label: "TheDrummer: UnslopNemo 12B" },
487
+ { id: "openrouter/upstage/solar-pro-3", label: "Upstage: Solar Pro 3" },
488
+ { id: "openrouter/x-ai/grok-4.20", label: "xAI: Grok 4.20" },
489
+ { id: "openrouter/x-ai/grok-4.3", label: "xAI: Grok 4.3" },
490
+ { id: "openrouter/x-ai/grok-build-0.1", label: "xAI: Grok Build 0.1" },
491
+ { id: "openrouter/xiaomi/mimo-v2.5", label: "Xiaomi: MiMo-V2.5" },
492
+ { id: "openrouter/xiaomi/mimo-v2.5-pro", label: "Xiaomi: MiMo-V2.5-Pro" },
493
+ { id: "openrouter/z-ai/glm-4.5", label: "Z.ai: GLM 4.5" },
494
+ { id: "openrouter/z-ai/glm-4.5-air", label: "Z.ai: GLM 4.5 Air" },
495
+ { id: "openrouter/z-ai/glm-4.5v", label: "Z.ai: GLM 4.5V" },
496
+ { id: "openrouter/z-ai/glm-4.6", label: "Z.ai: GLM 4.6" },
497
+ { id: "openrouter/z-ai/glm-4.6v", label: "Z.ai: GLM 4.6V" },
498
+ { id: "openrouter/z-ai/glm-4.7", label: "Z.ai: GLM 4.7" },
499
+ { id: "openrouter/z-ai/glm-4.7-flash", label: "Z.ai: GLM 4.7 Flash" },
500
+ { id: "openrouter/z-ai/glm-5", label: "Z.ai: GLM 5" },
501
+ { id: "openrouter/z-ai/glm-5-turbo", label: "Z.ai: GLM 5 Turbo" },
502
+ { id: "openrouter/z-ai/glm-5.1", label: "Z.ai: GLM 5.1" },
503
+ { id: "openrouter/z-ai/glm-5.2", label: "Z.ai: GLM 5.2" },
504
+ { id: "openrouter/~anthropic/claude-fable-latest", label: "Anthropic: Claude Fable Latest" },
505
+ { id: "openrouter/~anthropic/claude-haiku-latest", label: "Anthropic Claude Haiku Latest" },
506
+ { id: "openrouter/~anthropic/claude-opus-latest", label: "Anthropic: Claude Opus Latest" },
507
+ { id: "openrouter/~anthropic/claude-sonnet-latest", label: "Anthropic Claude Sonnet Latest" },
508
+ { id: "openrouter/~google/gemini-flash-latest", label: "Google Gemini Flash Latest" },
509
+ { id: "openrouter/~google/gemini-pro-latest", label: "Google Gemini Pro Latest" },
510
+ { id: "openrouter/~moonshotai/kimi-latest", label: "MoonshotAI Kimi Latest" },
511
+ { id: "openrouter/~openai/gpt-latest", label: "OpenAI GPT Latest" },
512
+ { id: "openrouter/~openai/gpt-mini-latest", label: "OpenAI GPT Mini Latest" }
513
+ ],
514
+ "openai-compatible": [
515
+ { id: "openai-compatible/gpt-5.4", label: "GPT-5.4" },
516
+ { id: "openai-compatible/gpt-4", label: "GPT-4" },
517
+ { id: "openai-compatible/gpt-4-turbo", label: "GPT-4 Turbo" },
518
+ { id: "openai-compatible/gpt-4.1", label: "GPT-4.1" },
519
+ { id: "openai-compatible/gpt-4.1-mini", label: "GPT-4.1 mini" },
520
+ { id: "openai-compatible/gpt-4.1-nano", label: "GPT-4.1 nano" },
521
+ { id: "openai-compatible/gpt-4o", label: "GPT-4o" },
522
+ { id: "openai-compatible/gpt-4o-2024-05-13", label: "GPT-4o (2024-05-13)" },
523
+ { id: "openai-compatible/gpt-4o-2024-08-06", label: "GPT-4o (2024-08-06)" },
524
+ { id: "openai-compatible/gpt-4o-2024-11-20", label: "GPT-4o (2024-11-20)" },
525
+ { id: "openai-compatible/gpt-4o-mini", label: "GPT-4o mini" },
526
+ { id: "openai-compatible/gpt-5", label: "GPT-5" },
527
+ { id: "openai-compatible/gpt-5-chat-latest", label: "GPT-5 Chat Latest" },
528
+ { id: "openai-compatible/gpt-5-codex", label: "GPT-5-Codex" },
529
+ { id: "openai-compatible/gpt-5-mini", label: "GPT-5 Mini" },
530
+ { id: "openai-compatible/gpt-5-nano", label: "GPT-5 Nano" },
531
+ { id: "openai-compatible/gpt-5-pro", label: "GPT-5 Pro" },
532
+ { id: "openai-compatible/gpt-5.1", label: "GPT-5.1" },
533
+ { id: "openai-compatible/gpt-5.1-chat-latest", label: "GPT-5.1 Chat" },
534
+ { id: "openai-compatible/gpt-5.1-codex", label: "GPT-5.1 Codex" },
535
+ { id: "openai-compatible/gpt-5.1-codex-max", label: "GPT-5.1 Codex Max" },
536
+ { id: "openai-compatible/gpt-5.1-codex-mini", label: "GPT-5.1 Codex mini" },
537
+ { id: "openai-compatible/gpt-5.2", label: "GPT-5.2" },
538
+ { id: "openai-compatible/gpt-5.2-chat-latest", label: "GPT-5.2 Chat" },
539
+ { id: "openai-compatible/gpt-5.2-codex", label: "GPT-5.2 Codex" },
540
+ { id: "openai-compatible/gpt-5.2-pro", label: "GPT-5.2 Pro" },
541
+ { id: "openai-compatible/gpt-5.3-chat-latest", label: "GPT-5.3 Chat (latest)" },
542
+ { id: "openai-compatible/gpt-5.3-codex", label: "GPT-5.3 Codex" },
543
+ { id: "openai-compatible/gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark" },
544
+ { id: "openai-compatible/gpt-5.4-mini", label: "GPT-5.4 mini" },
545
+ { id: "openai-compatible/gpt-5.4-nano", label: "GPT-5.4 nano" },
546
+ { id: "openai-compatible/gpt-5.4-pro", label: "GPT-5.4 Pro" },
547
+ { id: "openai-compatible/gpt-5.5", label: "GPT-5.5" },
548
+ { id: "openai-compatible/gpt-5.5-pro", label: "GPT-5.5 Pro" },
549
+ { id: "openai-compatible/o1", label: "o1" },
550
+ { id: "openai-compatible/o1-pro", label: "o1-pro" },
551
+ { id: "openai-compatible/o3", label: "o3" },
552
+ { id: "openai-compatible/o3-deep-research", label: "o3-deep-research" },
553
+ { id: "openai-compatible/o3-mini", label: "o3-mini" },
554
+ { id: "openai-compatible/o3-pro", label: "o3-pro" },
555
+ { id: "openai-compatible/o4-mini", label: "o4-mini" },
556
+ { id: "openai-compatible/o4-mini-deep-research", label: "o4-mini-deep-research" }
557
+ ],
558
+ "anthropic-compatible": [
559
+ { id: "anthropic-compatible/claude-opus-4-8", label: "Claude Opus 4.8" },
560
+ { id: "anthropic-compatible/claude-3-5-haiku-20241022", label: "Claude Haiku 3.5" },
561
+ { id: "anthropic-compatible/claude-3-5-haiku-latest", label: "Claude Haiku 3.5 (latest)" },
562
+ { id: "anthropic-compatible/claude-3-5-sonnet-20240620", label: "Claude Sonnet 3.5" },
563
+ { id: "anthropic-compatible/claude-3-5-sonnet-20241022", label: "Claude Sonnet 3.5 v2" },
564
+ { id: "anthropic-compatible/claude-3-7-sonnet-20250219", label: "Claude Sonnet 3.7" },
565
+ { id: "anthropic-compatible/claude-3-haiku-20240307", label: "Claude Haiku 3" },
566
+ { id: "anthropic-compatible/claude-3-opus-20240229", label: "Claude Opus 3" },
567
+ { id: "anthropic-compatible/claude-3-sonnet-20240229", label: "Claude Sonnet 3" },
568
+ { id: "anthropic-compatible/claude-fable-5", label: "Claude Fable 5" },
569
+ { id: "anthropic-compatible/claude-haiku-4-5", label: "Claude Haiku 4.5 (latest)" },
570
+ { id: "anthropic-compatible/claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" },
571
+ { id: "anthropic-compatible/claude-opus-4-0", label: "Claude Opus 4 (latest)" },
572
+ { id: "anthropic-compatible/claude-opus-4-1", label: "Claude Opus 4.1 (latest)" },
573
+ { id: "anthropic-compatible/claude-opus-4-1-20250805", label: "Claude Opus 4.1" },
574
+ { id: "anthropic-compatible/claude-opus-4-20250514", label: "Claude Opus 4" },
575
+ { id: "anthropic-compatible/claude-opus-4-5", label: "Claude Opus 4.5 (latest)" },
576
+ { id: "anthropic-compatible/claude-opus-4-5-20251101", label: "Claude Opus 4.5" },
577
+ { id: "anthropic-compatible/claude-opus-4-6", label: "Claude Opus 4.6" },
578
+ { id: "anthropic-compatible/claude-opus-4-7", label: "Claude Opus 4.7" },
579
+ { id: "anthropic-compatible/claude-sonnet-4-0", label: "Claude Sonnet 4 (latest)" },
580
+ { id: "anthropic-compatible/claude-sonnet-4-20250514", label: "Claude Sonnet 4" },
581
+ { id: "anthropic-compatible/claude-sonnet-4-5", label: "Claude Sonnet 4.5 (latest)" },
582
+ { id: "anthropic-compatible/claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
583
+ { id: "anthropic-compatible/claude-sonnet-4-6", label: "Claude Sonnet 4.6" }
584
+ ]
585
+ };
586
+
587
+ // ../shared/src/generated/runtimeProviderDisplayNames.ts
588
+ var RUNTIME_PROVIDER_DISPLAY_NAMES = {
589
+ "anthropic": "Anthropic",
590
+ "deepseek": "DeepSeek",
591
+ "fusecode": "FuseCode",
592
+ "google": "Google",
593
+ "openai": "OpenAI",
594
+ "opencode": "OpenCode",
595
+ "opencode-go": "OpenCode Go",
596
+ "openrouter": "OpenRouter"
597
+ };
598
+
599
+ // ../shared/src/runtimeProviderDisplay.ts
600
+ function getRuntimeProviderDisplayName(providerId) {
601
+ return RUNTIME_PROVIDER_DISPLAY_NAMES[providerId] ?? humanizeRuntimeProviderSegment(providerId);
602
+ }
603
+ function formatRuntimeProviderModelLabel(modelId) {
604
+ const separatorIndex = modelId.indexOf("/");
605
+ if (separatorIndex <= 0 || separatorIndex === modelId.length - 1) return modelId;
606
+ const providerId = modelId.slice(0, separatorIndex);
607
+ const modelName = modelId.slice(separatorIndex + 1);
608
+ const providerLabel = getRuntimeProviderDisplayName(providerId);
609
+ const modelParts = modelName.split("/");
610
+ const modelLabel = humanizeRuntimeProviderSegment(modelParts[modelParts.length - 1] || modelName);
611
+ if (modelParts.length === 1) return `${modelLabel} \xB7 ${providerLabel}`;
612
+ const upstreamLabel = modelParts.slice(0, -1).map(getRuntimeProviderDisplayName).join(" / ");
613
+ return `${modelLabel} \xB7 ${upstreamLabel} via ${providerLabel}`;
614
+ }
615
+ function humanizeRuntimeProviderSegment(value) {
616
+ return value.replace(/\[(\d+)m\]/gi, "-$1m").split(/[-_/]/).filter(Boolean).map(formatRuntimeProviderLabelToken).join(" ");
617
+ }
618
+ function formatRuntimeProviderLabelToken(token) {
619
+ const normalized = token.toLowerCase();
620
+ const specialCases = {
621
+ ai: "AI",
622
+ api: "API",
623
+ chatgpt: "ChatGPT",
624
+ claude: "Claude",
625
+ codestral: "Codestral",
626
+ deepseek: "DeepSeek",
627
+ flash: "Flash",
628
+ free: "Free",
629
+ gemini: "Gemini",
630
+ glm: "GLM",
631
+ gpt: "GPT",
632
+ hy3: "HY3",
633
+ kimi: "Kimi",
634
+ minimax: "MiniMax",
635
+ nano: "Nano",
636
+ nemotron: "Nemotron",
637
+ omni: "Omni",
638
+ opus: "Opus",
639
+ pro: "Pro",
640
+ sonnet: "Sonnet",
641
+ super: "Super"
642
+ };
643
+ if (specialCases[normalized]) return specialCases[normalized];
644
+ if (normalized === "b" || normalized === "m") return normalized.toUpperCase();
645
+ if (/^v\d+(\.\d+)?$/.test(normalized)) return normalized.toUpperCase();
646
+ if (/^\d+m$/i.test(token)) return token.toUpperCase();
647
+ if (/^\d+[bk]$/i.test(token)) return token.toUpperCase();
648
+ if (/^m\d+(\.\d+)?$/i.test(token)) return token.toUpperCase();
649
+ if (/^\d/.test(token)) return token;
650
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
651
+ }
652
+
14
653
  // ../shared/src/slockRefs.ts
15
654
  var SLOCK_REF_CHANNEL_NAME_PATTERN = String.raw`[\p{L}\p{N}_-]+`;
16
655
  var SLOCK_REF_USER_NAME_PATTERN = SLOCK_REF_CHANNEL_NAME_PATTERN;
@@ -1039,11 +1678,36 @@ var integrationApproveAgentLoginOperationSchema = z.object({
1039
1678
  scopes: z.array(z.string().trim().min(1).max(120)).max(64),
1040
1679
  draftHint: draftHintSchema
1041
1680
  });
1681
+ var integrationAppDraftFieldsSchema = z.object({
1682
+ name: z.string().trim().min(1).max(120).optional(),
1683
+ description: z.string().trim().max(1e3).optional(),
1684
+ homepageUrl: z.string().trim().max(2e3).optional(),
1685
+ returnUrl: z.string().trim().max(2e3).optional(),
1686
+ agentManifestUrl: z.string().trim().max(2e3).optional()
1687
+ });
1688
+ var integrationRegisterAppOperationSchema = integrationAppDraftFieldsSchema.extend({
1689
+ type: z.literal("integration:register_app"),
1690
+ name: z.string().trim().min(1).max(120),
1691
+ clientKey: z.string().trim().min(1).max(120),
1692
+ returnUrl: z.string().trim().min(1).max(2e3),
1693
+ scopes: z.array(z.string().trim().min(1).max(120)).max(64).default([]),
1694
+ unsafeDemoUrlOverride: z.boolean().optional(),
1695
+ draftHint: draftHintSchema
1696
+ });
1697
+ var integrationUpdateAppRegistrationOperationSchema = integrationAppDraftFieldsSchema.extend({
1698
+ type: z.literal("integration:update_app_registration"),
1699
+ clientKey: z.string().trim().min(1).max(120),
1700
+ scopes: z.array(z.string().trim().min(1).max(120)).max(64).optional(),
1701
+ unsafeDemoUrlOverride: z.boolean().optional(),
1702
+ draftHint: draftHintSchema
1703
+ });
1042
1704
  var actionCardActionSchema = z.discriminatedUnion("type", [
1043
1705
  channelCreateOperationSchema,
1044
1706
  agentCreateOperationSchema,
1045
1707
  channelAddMemberOperationSchema,
1046
- integrationApproveAgentLoginOperationSchema
1708
+ integrationApproveAgentLoginOperationSchema,
1709
+ integrationRegisterAppOperationSchema,
1710
+ integrationUpdateAppRegistrationOperationSchema
1047
1711
  ]);
1048
1712
 
1049
1713
  // ../shared/src/agentInbox.ts
@@ -1288,9 +1952,59 @@ var SERVER_CAPABILITY_MATRIX = {
1288
1952
 
1289
1953
  // ../shared/src/index.ts
1290
1954
  var RUNTIME_CONFIG_VERSION = 1;
1955
+ var EMBEDDED_PI_RUNTIME_ID = "embedded-pi";
1956
+ var PI_RUNTIME_ID = "pi";
1291
1957
  var PI_BUILTIN_PROVIDER_ENV_KEYS = {
1292
- deepseek: "DEEPSEEK_API_KEY"
1958
+ deepseek: "DEEPSEEK_API_KEY",
1959
+ minimax: "MINIMAX_API_KEY",
1960
+ "minimax-cn": "MINIMAX_CN_API_KEY",
1961
+ zai: "ZAI_API_KEY",
1962
+ "zai-coding-cn": "ZAI_CODING_CN_API_KEY",
1963
+ "kimi-coding": "KIMI_API_KEY",
1964
+ "moonshotai-cn": "MOONSHOT_API_KEY",
1965
+ moonshotai: "MOONSHOT_API_KEY",
1966
+ openai: "OPENAI_API_KEY",
1967
+ anthropic: "ANTHROPIC_API_KEY",
1968
+ google: "GEMINI_API_KEY",
1969
+ xai: "XAI_API_KEY",
1970
+ groq: "GROQ_API_KEY",
1971
+ mistral: "MISTRAL_API_KEY",
1972
+ fireworks: "FIREWORKS_API_KEY",
1973
+ together: "TOGETHER_API_KEY",
1974
+ openrouter: "OPENROUTER_API_KEY",
1975
+ "openai-compatible": "OPENAI_COMPATIBLE_API_KEY",
1976
+ "anthropic-compatible": "ANTHROPIC_COMPATIBLE_API_KEY"
1977
+ };
1978
+ var PI_BUILTIN_PROVIDER_API_KEY_REQUIRED = {
1979
+ deepseek: false,
1980
+ minimax: true,
1981
+ "minimax-cn": true,
1982
+ zai: false,
1983
+ "zai-coding-cn": true,
1984
+ "kimi-coding": true,
1985
+ "moonshotai-cn": true,
1986
+ moonshotai: true,
1987
+ openai: true,
1988
+ anthropic: true,
1989
+ google: true,
1990
+ xai: true,
1991
+ groq: true,
1992
+ mistral: true,
1993
+ fireworks: true,
1994
+ together: true,
1995
+ openrouter: true,
1996
+ "openai-compatible": true,
1997
+ "anthropic-compatible": true
1998
+ };
1999
+ var PI_BUILTIN_PROVIDER_API_URL_REQUIRED = {
2000
+ "openai-compatible": true,
2001
+ "anthropic-compatible": true
1293
2002
  };
2003
+ var PI_BUILTIN_PROVIDER_CUSTOM_MODEL_SUPPORTED = {
2004
+ "openai-compatible": true,
2005
+ "anthropic-compatible": true
2006
+ };
2007
+ var PI_BUILTIN_PROVIDER_MODELS = PI_BUILTIN_PROVIDER_MODELS_GENERATED;
1294
2008
  var AGENT_ACTIVITIES = ["online", "thinking", "working", "error", "offline"];
1295
2009
  var isAgentActivity = makeIsMember(AGENT_ACTIVITIES);
1296
2010
  var VALID_ACTIVITIES = new Set(AGENT_ACTIVITIES);
@@ -1298,6 +2012,11 @@ var EXTERNAL_AGENT_RUNTIME_ID = "external";
1298
2012
  var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
1299
2013
  var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
1300
2014
  var RUNTIMES = [
2015
+ // Embedded Pi is an in-process Raft-managed runtime, so it is available
2016
+ // without a user-installed PATH binary and should be the first Create Agent
2017
+ // option. The ordinary `pi` entry below remains the user-installed Pi
2018
+ // runtime and reads the user's configured Pi auth/model setup.
2019
+ { id: EMBEDDED_PI_RUNTIME_ID, displayName: "Embedded Pi", binary: "", supported: true },
1301
2020
  { id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
1302
2021
  { id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
1303
2022
  { id: "antigravity", displayName: "Antigravity CLI", binary: "agy", supported: true },
@@ -1310,7 +2029,7 @@ var RUNTIMES = [
1310
2029
  { id: "cursor", displayName: "Cursor CLI", binary: "cursor-agent", supported: true },
1311
2030
  { id: "gemini", displayName: "Gemini CLI", binary: "gemini", supported: true },
1312
2031
  { id: "opencode", displayName: "OpenCode", binary: "opencode", supported: true },
1313
- { id: "pi", displayName: "Pi", binary: "pi", supported: true }
2032
+ { id: PI_RUNTIME_ID, displayName: "Pi (installed)", binary: "pi", supported: true }
1314
2033
  ];
1315
2034
  var RUNTIME_MODELS = {
1316
2035
  [EXTERNAL_AGENT_RUNTIME_ID]: [
@@ -1362,13 +2081,16 @@ var RUNTIME_MODELS = {
1362
2081
  ],
1363
2082
  opencode: [
1364
2083
  { id: "default", label: "Configured Default / Auto", verified: "suggestion_only" },
1365
- { id: "deepseek/deepseek-v4-pro", label: "DeepSeek V4 Pro (OpenCode)", verified: "suggestion_only" },
1366
- { id: "openrouter/anthropic/claude-opus-4.5", label: "Claude Opus 4.5 via OpenRouter", verified: "suggestion_only" },
1367
- { id: "fusecode/opus[1m]", label: "Opus 1M via FuseCode", verified: "suggestion_only" }
2084
+ { id: "deepseek/deepseek-v4-pro", label: formatRuntimeProviderModelLabel("deepseek/deepseek-v4-pro"), verified: "suggestion_only" },
2085
+ { id: "openrouter/anthropic/claude-opus-4.5", label: formatRuntimeProviderModelLabel("openrouter/anthropic/claude-opus-4.5"), verified: "suggestion_only" },
2086
+ { id: "fusecode/opus[1m]", label: formatRuntimeProviderModelLabel("fusecode/opus[1m]"), verified: "suggestion_only" }
1368
2087
  ],
1369
2088
  pi: [
1370
2089
  { id: "default", label: "Configured Default / Auto", verified: "suggestion_only" }
1371
2090
  ],
2091
+ [EMBEDDED_PI_RUNTIME_ID]: [
2092
+ { id: "deepseek/deepseek-v4-pro", label: "DeepSeek V4 Pro", verified: "launchable" }
2093
+ ],
1372
2094
  // Kimi CLI resolves model keys from each user's local config, so the safest
1373
2095
  // built-in option is to defer to whatever default model the CLI already uses.
1374
2096
  kimi: [
@@ -1400,7 +2122,7 @@ var CONTROLLED_RUNTIME_ENV_KEYS = {
1400
2122
  // RuntimeProviderConfig.pi-builtin → runtimeConfigToLaunchFields, not by
1401
2123
  // user-supplied envVars: reading from PI_BUILTIN_PROVIDER_ENV_KEYS keeps
1402
2124
  // this list in sync as new providers are added.
1403
- pi: Object.values(PI_BUILTIN_PROVIDER_ENV_KEYS)
2125
+ [EMBEDDED_PI_RUNTIME_ID]: Object.values(PI_BUILTIN_PROVIDER_ENV_KEYS)
1404
2126
  };
1405
2127
  function isPlainRecord(value) {
1406
2128
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -1428,6 +2150,11 @@ function stripControlledRuntimeEnvVars(runtime, envVars) {
1428
2150
  return Object.keys(normalized).length > 0 ? normalized : null;
1429
2151
  }
1430
2152
  function isPresetRuntimeModel(runtime, model) {
2153
+ if (runtime === PI_RUNTIME_ID || runtime === EMBEDDED_PI_RUNTIME_ID) {
2154
+ return (RUNTIME_MODELS[runtime] ?? []).some((candidate) => candidate.id === model) || Object.values(PI_BUILTIN_PROVIDER_MODELS).some(
2155
+ (models) => models.some((candidate) => candidate.id === model)
2156
+ );
2157
+ }
1431
2158
  return (RUNTIME_MODELS[runtime] ?? []).some((candidate) => candidate.id === model);
1432
2159
  }
1433
2160
  function modelConfigFromLegacy(runtime, model) {
@@ -1444,10 +2171,20 @@ function parseProviderConfig(runtime, value, legacyApiUrl, legacyApiKey) {
1444
2171
  }
1445
2172
  return { kind: "default" };
1446
2173
  }
1447
- if (runtime === "pi") {
2174
+ if (runtime === EMBEDDED_PI_RUNTIME_ID) {
1448
2175
  if (!isPlainRecord(value)) return { kind: "default" };
1449
- if (value.kind === "pi-builtin" && typeof value.providerId === "string" && value.providerId.trim() && typeof value.apiKey === "string" && value.apiKey.trim() && Object.prototype.hasOwnProperty.call(PI_BUILTIN_PROVIDER_ENV_KEYS, value.providerId.trim())) {
1450
- return { kind: "pi-builtin", providerId: value.providerId.trim(), apiKey: value.apiKey.trim() };
2176
+ if (value.kind === "pi-builtin" && typeof value.providerId === "string" && value.providerId.trim() && typeof value.apiKey === "string" && Object.prototype.hasOwnProperty.call(PI_BUILTIN_PROVIDER_ENV_KEYS, value.providerId.trim())) {
2177
+ const providerId = value.providerId.trim();
2178
+ const apiKey = value.apiKey.trim();
2179
+ const apiUrl = typeof value.apiUrl === "string" ? value.apiUrl.trim() : "";
2180
+ if (PI_BUILTIN_PROVIDER_API_KEY_REQUIRED[providerId] && !apiKey) return { kind: "default" };
2181
+ if (PI_BUILTIN_PROVIDER_API_URL_REQUIRED[providerId] && !apiUrl) return { kind: "default" };
2182
+ return {
2183
+ kind: "pi-builtin",
2184
+ providerId,
2185
+ apiKey,
2186
+ ...apiUrl ? { apiUrl } : {}
2187
+ };
1451
2188
  }
1452
2189
  return { kind: "default" };
1453
2190
  }
@@ -1513,9 +2250,13 @@ function runtimeConfigToLaunchFields(config) {
1513
2250
  generatedEnvVars.ANTHROPIC_CUSTOM_MODEL_OPTION = normalized.model.name;
1514
2251
  }
1515
2252
  }
1516
- if (normalized.runtime === "pi" && normalized.provider?.kind === "pi-builtin") {
2253
+ let modelValue = runtimeConfigModelValue(normalized);
2254
+ if (normalized.runtime === EMBEDDED_PI_RUNTIME_ID && normalized.provider?.kind === "pi-builtin" && normalized.model.kind === "custom" && PI_BUILTIN_PROVIDER_CUSTOM_MODEL_SUPPORTED[normalized.provider.providerId]) {
2255
+ modelValue = `${normalized.provider.providerId}/${normalized.model.name}`;
2256
+ }
2257
+ if (normalized.runtime === EMBEDDED_PI_RUNTIME_ID && normalized.provider?.kind === "pi-builtin") {
1517
2258
  const envKey = PI_BUILTIN_PROVIDER_ENV_KEYS[normalized.provider.providerId];
1518
- if (envKey) generatedEnvVars[envKey] = normalized.provider.apiKey;
2259
+ if (envKey && normalized.provider.apiKey.trim()) generatedEnvVars[envKey] = normalized.provider.apiKey;
1519
2260
  }
1520
2261
  const envVars = {
1521
2262
  ...normalized.envVars ?? {},
@@ -1523,13 +2264,18 @@ function runtimeConfigToLaunchFields(config) {
1523
2264
  };
1524
2265
  return {
1525
2266
  runtime: normalized.runtime,
1526
- model: runtimeConfigModelValue(normalized),
2267
+ model: modelValue,
1527
2268
  mode: normalized.mode,
1528
2269
  reasoningEffort: normalized.reasoningEffort ?? null,
1529
2270
  envVars: Object.keys(envVars).length > 0 ? envVars : null,
1530
2271
  ...normalized.command ? { command: normalized.command } : {}
1531
2272
  };
1532
2273
  }
2274
+ var PRO_SEAT_MONTHLY_USD = 10;
2275
+ var PRO_AGENT_SEAT_BLOCK_SIZE = 10;
2276
+ var PRO_AGENT_SEAT_FRACTION = 1 / PRO_AGENT_SEAT_BLOCK_SIZE;
2277
+ var PRO_SEAT_ANNUAL_MONTHLY_USD = 8.8;
2278
+ var PRO_PACK_AGENT_SEATS = PRO_AGENT_SEAT_BLOCK_SIZE;
1533
2279
  var PLAN_CONFIG = {
1534
2280
  free: {
1535
2281
  displayName: "Free",
@@ -1556,9 +2302,9 @@ var PLAN_CONFIG = {
1556
2302
  },
1557
2303
  pro: {
1558
2304
  displayName: "Pro",
1559
- limits: { maxMachines: -1, maxAgents: 10, maxChannels: -1, messageHistoryDays: -1, includedAgents: 10 },
2305
+ limits: { maxMachines: -1, maxAgents: PRO_PACK_AGENT_SEATS, maxChannels: -1, messageHistoryDays: -1, includedAgents: PRO_PACK_AGENT_SEATS },
1560
2306
  comingSoon: false,
1561
- price: 20,
2307
+ price: PRO_SEAT_MONTHLY_USD,
1562
2308
  extraAgentPrice: 0
1563
2309
  }
1564
2310
  };
@@ -1568,8 +2314,8 @@ var DISPLAY_PLAN_CONFIG = {
1568
2314
  displayName: "Pro",
1569
2315
  limits: { maxMachines: -1, maxAgents: -1, maxChannels: -1, messageHistoryDays: -1, includedAgents: -1 },
1570
2316
  comingSoon: false,
1571
- price: 20,
1572
- priceCadence: "/ seat pack / month",
2317
+ price: PRO_SEAT_MONTHLY_USD,
2318
+ priceCadence: "/ seat / month",
1573
2319
  extraAgentPrice: 0,
1574
2320
  displayFeatures: [
1575
2321
  "Everything in Free",
@@ -1579,7 +2325,7 @@ var DISPLAY_PLAN_CONFIG = {
1579
2325
  "More professional features coming soon"
1580
2326
  ],
1581
2327
  displayDescription: "For builders and teams scaling agent collaboration.",
1582
- displayNote: "$17.60 / seat pack / month when billed yearly"
2328
+ displayNote: `$${PRO_SEAT_ANNUAL_MONTHLY_USD.toFixed(2)} / seat / month when billed yearly. Each human uses 1 seat; each agent uses ${PRO_AGENT_SEAT_FRACTION} seat.`
1583
2329
  },
1584
2330
  enterprise: {
1585
2331
  displayName: "Enterprise",
@@ -2587,6 +3333,19 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
2587
3333
  return candidates.filter((candidate) => existsSync(candidate.path));
2588
3334
  }
2589
3335
 
3336
+ // src/authEnv.ts
3337
+ var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
3338
+ var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
3339
+ function scrubDaemonAuthEnv(env) {
3340
+ delete env[DAEMON_API_KEY_ENV];
3341
+ return env;
3342
+ }
3343
+ function scrubDaemonChildEnv(env) {
3344
+ delete env[DAEMON_API_KEY_ENV];
3345
+ delete env[SLOCK_AGENT_TOKEN_ENV];
3346
+ return env;
3347
+ }
3348
+
2590
3349
  // src/agentCredentialProxy.ts
2591
3350
  import { randomBytes } from "crypto";
2592
3351
  import http from "http";
@@ -3426,6 +4185,7 @@ function latestVisibleMessages(messages, limit) {
3426
4185
  return sorted.slice(Math.max(0, sorted.length - limit));
3427
4186
  }
3428
4187
  function isMessageModelSeen(input, message) {
4188
+ if (messageSenderId(message) === input.agentId) return true;
3429
4189
  const seq = Math.floor(messageSeq(message));
3430
4190
  if (Number.isFinite(seq) && seq > 0 && typeof input.modelSeenSeq === "number" && input.modelSeenSeq >= seq) return true;
3431
4191
  return input.isMessageModelSeen?.({ target: input.target, message }) === true;
@@ -4153,7 +4913,9 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
4153
4913
  var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
4154
4914
  var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
4155
4915
  var RAW_CREDENTIAL_ENV_DENYLIST = [
4156
- "SLOCK_AGENT_CREDENTIAL_KEY"
4916
+ "SLOCK_AGENT_TOKEN",
4917
+ "SLOCK_AGENT_CREDENTIAL_KEY",
4918
+ "SLOCK_AGENT_CREDENTIAL_KEY_FILE"
4157
4919
  ];
4158
4920
  var WORKSPACE_CLI_TRANSPORT_FILENAMES = [
4159
4921
  "agent-token",
@@ -4505,7 +5267,7 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
4505
5267
  SLOCK_SERVER_URL: ctx.config.serverUrl,
4506
5268
  PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
4507
5269
  };
4508
- delete spawnEnv.SLOCK_AGENT_TOKEN;
5270
+ scrubDaemonChildEnv(spawnEnv);
4509
5271
  for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
4510
5272
  delete spawnEnv[key];
4511
5273
  }
@@ -5027,7 +5789,7 @@ function requiresWindowsShell(command, platform = process.platform) {
5027
5789
  }
5028
5790
  function resolveCommandOnPath(command, deps = {}) {
5029
5791
  const platform = deps.platform ?? process.platform;
5030
- const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
5792
+ const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
5031
5793
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
5032
5794
  const existsSyncFn = deps.existsSyncFn ?? existsSync3;
5033
5795
  if (platform === "win32") {
@@ -5053,7 +5815,7 @@ function firstExistingPath(candidates, deps = {}) {
5053
5815
  return null;
5054
5816
  }
5055
5817
  function readCommandVersion(command, args = [], deps = {}) {
5056
- const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
5818
+ const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
5057
5819
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
5058
5820
  try {
5059
5821
  const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
@@ -7133,11 +7895,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
7133
7895
  return parseCursorModelsOutput(String(result.stdout || ""));
7134
7896
  }
7135
7897
  function buildCursorModelProbeEnv(deps = {}) {
7136
- return withWindowsUserEnvironment({
7898
+ return scrubDaemonChildEnv(withWindowsUserEnvironment({
7137
7899
  ...deps.env ?? process.env,
7138
7900
  FORCE_COLOR: "0",
7139
7901
  NO_COLOR: "1"
7140
- }, deps);
7902
+ }, deps));
7141
7903
  }
7142
7904
  function runCursorModelsCommand() {
7143
7905
  return spawnSync("cursor-agent", ["models"], {
@@ -7193,7 +7955,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
7193
7955
  }
7194
7956
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
7195
7957
  const existsSyncFn = deps.existsSyncFn ?? existsSync5;
7196
- const env = deps.env ?? process.env;
7958
+ const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
7197
7959
  const winPath = path8.win32;
7198
7960
  let geminiEntry = null;
7199
7961
  try {
@@ -7330,12 +8092,15 @@ var GeminiDriver = class {
7330
8092
  // src/drivers/kimi.ts
7331
8093
  import { randomUUID as randomUUID2 } from "crypto";
7332
8094
  import { spawn as spawn7 } from "child_process";
7333
- import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
8095
+ import { chmodSync, existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
7334
8096
  import os4 from "os";
7335
8097
  import path9 from "path";
7336
8098
  var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
7337
8099
  var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
7338
8100
  var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
8101
+ var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
8102
+ var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
8103
+ var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
7339
8104
  function parseToolArguments(raw) {
7340
8105
  if (typeof raw !== "string") return raw;
7341
8106
  try {
@@ -7344,6 +8109,73 @@ function parseToolArguments(raw) {
7344
8109
  return raw;
7345
8110
  }
7346
8111
  }
8112
+ function readKimiConfigSource(home = os4.homedir(), env = process.env) {
8113
+ const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
8114
+ if (inlineConfig && inlineConfig.trim()) {
8115
+ return {
8116
+ raw: inlineConfig,
8117
+ explicitPath: null,
8118
+ sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
8119
+ };
8120
+ }
8121
+ const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
8122
+ const configPath = explicitPath && explicitPath.trim() ? explicitPath : path9.join(home, ".kimi", "config.toml");
8123
+ try {
8124
+ return {
8125
+ raw: readFileSync3(configPath, "utf8"),
8126
+ explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
8127
+ sourcePath: configPath
8128
+ };
8129
+ } catch {
8130
+ return {
8131
+ raw: null,
8132
+ explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
8133
+ sourcePath: configPath
8134
+ };
8135
+ }
8136
+ }
8137
+ function buildKimiSpawnEnv(env = process.env) {
8138
+ const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
8139
+ delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
8140
+ delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
8141
+ return scrubDaemonChildEnv(spawnEnv);
8142
+ }
8143
+ function buildKimiEffectiveEnv(ctx, overrideEnv) {
8144
+ return {
8145
+ ...process.env,
8146
+ ...ctx.config.envVars || {},
8147
+ ...overrideEnv || {}
8148
+ };
8149
+ }
8150
+ function buildKimiLaunchOptions(ctx, opts = {}) {
8151
+ const env = buildKimiEffectiveEnv(ctx, opts.env);
8152
+ const source = readKimiConfigSource(opts.home ?? os4.homedir(), env);
8153
+ const args = [];
8154
+ let configFilePath = null;
8155
+ let configContent = null;
8156
+ if (source.explicitPath) {
8157
+ configFilePath = source.explicitPath;
8158
+ } else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
8159
+ configFilePath = path9.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
8160
+ configContent = source.raw;
8161
+ if (opts.writeGeneratedConfig !== false) {
8162
+ writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
8163
+ chmodSync(configFilePath, 384);
8164
+ }
8165
+ }
8166
+ if (configFilePath) {
8167
+ args.push("--config-file", configFilePath);
8168
+ }
8169
+ if (ctx.config.model && ctx.config.model !== "default") {
8170
+ args.push("--model", ctx.config.model);
8171
+ }
8172
+ return {
8173
+ args,
8174
+ env: buildKimiSpawnEnv(env),
8175
+ configFilePath,
8176
+ configContent
8177
+ };
8178
+ }
7347
8179
  function resolveKimiSpawn(commandArgs, deps = {}) {
7348
8180
  return {
7349
8181
  command: resolveCommandOnPath("kimi", deps) ?? "kimi",
@@ -7367,7 +8199,25 @@ var KimiDriver = class {
7367
8199
  };
7368
8200
  model = {
7369
8201
  detectedModelsVerifiedAs: "launchable",
7370
- toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
8202
+ toLaunchSpec: (modelId, ctx, opts) => {
8203
+ if (!ctx) return { args: ["--model", modelId] };
8204
+ const launchCtx = {
8205
+ ...ctx,
8206
+ config: {
8207
+ ...ctx.config,
8208
+ model: modelId
8209
+ }
8210
+ };
8211
+ const launch = buildKimiLaunchOptions(launchCtx, {
8212
+ home: opts?.home,
8213
+ writeGeneratedConfig: false
8214
+ });
8215
+ return {
8216
+ args: launch.args,
8217
+ env: launch.env,
8218
+ configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
8219
+ };
8220
+ }
7371
8221
  };
7372
8222
  supportsStdinNotification = true;
7373
8223
  busyDeliveryMode = "direct";
@@ -7391,21 +8241,23 @@ var KimiDriver = class {
7391
8241
  ` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
7392
8242
  ""
7393
8243
  ].join("\n"), "utf8");
8244
+ const launch = buildKimiLaunchOptions(ctx);
7394
8245
  const args = [
7395
8246
  "--wire",
7396
8247
  "--yolo",
7397
8248
  "--agent-file",
7398
8249
  agentFilePath,
7399
8250
  "--session",
7400
- this.sessionId
8251
+ this.sessionId,
8252
+ ...launch.args
7401
8253
  ];
7402
8254
  const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
7403
8255
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
7404
8256
  args.push("--model", launchRuntimeFields.model);
7405
8257
  }
7406
8258
  const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
7407
- const launch = resolveKimiSpawn(args);
7408
- const proc = spawn7(launch.command, launch.args, {
8259
+ const spawnTarget = resolveKimiSpawn(args);
8260
+ const proc = spawn7(spawnTarget.command, spawnTarget.args, {
7409
8261
  cwd: ctx.workingDirectory,
7410
8262
  stdio: ["pipe", "pipe", "pipe"],
7411
8263
  env: spawnEnv,
@@ -7413,7 +8265,7 @@ var KimiDriver = class {
7413
8265
  // and has an 8191-character command-line limit. Kimi's official
7414
8266
  // installer/uv entrypoint is an executable, so launch it directly and
7415
8267
  // keep prompts on stdin / files instead of routing through cmd.exe.
7416
- shell: launch.shell
8268
+ shell: spawnTarget.shell
7417
8269
  });
7418
8270
  proc.stdin?.write(JSON.stringify({
7419
8271
  jsonrpc: "2.0",
@@ -7526,14 +8378,9 @@ var KimiDriver = class {
7526
8378
  return detectKimiModels();
7527
8379
  }
7528
8380
  };
7529
- function detectKimiModels(home = os4.homedir()) {
7530
- const configPath = path9.join(home, ".kimi", "config.toml");
7531
- let raw;
7532
- try {
7533
- raw = readFileSync3(configPath, "utf8");
7534
- } catch {
7535
- return null;
7536
- }
8381
+ function detectKimiModels(home = os4.homedir(), opts = {}) {
8382
+ const raw = readKimiConfigSource(home, opts.env).raw;
8383
+ if (raw === null) return null;
7537
8384
  const models = [];
7538
8385
  const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
7539
8386
  const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
@@ -8047,14 +8894,6 @@ var SLOCK_AGENT_NAME = "slock";
8047
8894
  var NO_MESSAGE_PROMPT = "No new messages are pending. Stop now.";
8048
8895
  var FIRST_MESSAGE_TASK_PREFIX = "First message task (system-triggered):";
8049
8896
  var MIN_SUPPORTED_OPENCODE_VERSION = "1.14.30";
8050
- var OPENCODE_PROVIDER_LABELS = {
8051
- opencode: "OpenCode",
8052
- "opencode-go": "OpenCode Go",
8053
- openai: "OpenAI",
8054
- openrouter: "OpenRouter",
8055
- deepseek: "DeepSeek",
8056
- fusecode: "FuseCode"
8057
- };
8058
8897
  function parseOpenCodeConfigContent(raw) {
8059
8898
  if (!raw) return {};
8060
8899
  try {
@@ -8192,62 +9031,12 @@ function parseOpenCodeModelsOutput(output) {
8192
9031
  seen.add(line);
8193
9032
  models.push({
8194
9033
  id: line,
8195
- label: formatOpenCodeModelLabel(line),
9034
+ label: formatRuntimeProviderModelLabel(line),
8196
9035
  verified: "launchable"
8197
9036
  });
8198
9037
  }
8199
9038
  return models.length > 0 ? { models } : null;
8200
9039
  }
8201
- function formatOpenCodeModelLabel(modelId) {
8202
- const separatorIndex = modelId.indexOf("/");
8203
- if (separatorIndex <= 0 || separatorIndex === modelId.length - 1) return modelId;
8204
- const providerId = modelId.slice(0, separatorIndex);
8205
- const modelName = modelId.slice(separatorIndex + 1);
8206
- const providerLabel = OPENCODE_PROVIDER_LABELS[providerId] || humanizeOpenCodeSegment(providerId);
8207
- const modelParts = modelName.split("/");
8208
- const modelLabel = humanizeOpenCodeSegment(modelParts[modelParts.length - 1] || modelName);
8209
- if (modelParts.length === 1) return `${modelLabel} \xB7 ${providerLabel}`;
8210
- const upstreamLabel = modelParts.slice(0, -1).map(humanizeOpenCodeSegment).join(" / ");
8211
- return `${modelLabel} \xB7 ${upstreamLabel} via ${providerLabel}`;
8212
- }
8213
- function humanizeOpenCodeSegment(value) {
8214
- return value.replace(/\[(\d+)m\]/gi, "-$1m").split(/[-_]/).filter(Boolean).map(formatOpenCodeLabelToken).join(" ");
8215
- }
8216
- function formatOpenCodeLabelToken(token) {
8217
- const normalized = token.toLowerCase();
8218
- const specialCases = {
8219
- ai: "AI",
8220
- api: "API",
8221
- b: "B",
8222
- chatgpt: "ChatGPT",
8223
- claude: "Claude",
8224
- codestral: "Codestral",
8225
- deepseek: "DeepSeek",
8226
- flash: "Flash",
8227
- free: "Free",
8228
- gemini: "Gemini",
8229
- glm: "GLM",
8230
- gpt: "GPT",
8231
- hy3: "HY3",
8232
- kimi: "Kimi",
8233
- m: "M",
8234
- minimax: "MiniMax",
8235
- nano: "Nano",
8236
- nemotron: "Nemotron",
8237
- omni: "Omni",
8238
- opus: "Opus",
8239
- pro: "Pro",
8240
- sonnet: "Sonnet",
8241
- super: "Super"
8242
- };
8243
- if (specialCases[normalized]) return specialCases[normalized];
8244
- if (/^v\d+(\.\d+)?$/.test(normalized)) return normalized.toUpperCase();
8245
- if (/^\d+m$/i.test(token)) return token.toUpperCase();
8246
- if (/^\d+[bk]$/i.test(token)) return token.toUpperCase();
8247
- if (/^m\d+(\.\d+)?$/i.test(token)) return token.toUpperCase();
8248
- if (/^\d/.test(token)) return token;
8249
- return normalized.charAt(0).toUpperCase() + normalized.slice(1);
8250
- }
8251
9040
  function detectOpenCodeModels(home = os5.homedir(), runCommand = runOpenCodeModelsCommand) {
8252
9041
  const commandResult = runCommand(home);
8253
9042
  if (commandResult.error || commandResult.status !== 0) return null;
@@ -8257,7 +9046,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
8257
9046
  const platform = deps.platform ?? process.platform;
8258
9047
  const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
8259
9048
  const result = spawnSyncFn("opencode", ["models"], {
8260
- env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
9049
+ env: scrubDaemonChildEnv({ ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" }),
8261
9050
  encoding: "utf8",
8262
9051
  timeout: 5e3,
8263
9052
  shell: platform === "win32"
@@ -8528,14 +9317,9 @@ import {
8528
9317
  SettingsManager,
8529
9318
  VERSION as PI_SDK_VERSION
8530
9319
  } from "@earendil-works/pi-coding-agent";
9320
+ import { getModels } from "@earendil-works/pi-ai";
8531
9321
  var PI_SESSION_DIR = ".pi-sessions";
8532
9322
  var PI_SDK_COMPACTION_ENABLED = true;
8533
- var PI_PROVIDER_LABELS = {
8534
- google: "Google",
8535
- openai: "OpenAI",
8536
- openrouter: "OpenRouter",
8537
- deepseek: "DeepSeek"
8538
- };
8539
9323
  function createPiSdkEventMappingState(sessionId = null) {
8540
9324
  return {
8541
9325
  sessionId,
@@ -8577,7 +9361,7 @@ function detectPiModelsFromRegistry(modelRegistry) {
8577
9361
  seen.add(id);
8578
9362
  models.push({
8579
9363
  id,
8580
- label: `${model.name || humanizePiSegment(model.id)} \xB7 ${PI_PROVIDER_LABELS[model.provider] || humanizePiSegment(model.provider)}`,
9364
+ label: `${model.name || humanizeRuntimeProviderSegment(model.id)} \xB7 ${getRuntimeProviderDisplayName(model.provider)}`,
8581
9365
  verified: "launchable"
8582
9366
  });
8583
9367
  }
@@ -8599,6 +9383,77 @@ function logPiServiceDiagnostics(context, services) {
8599
9383
  function formatPiModelLogId(model) {
8600
9384
  return model ? `${model.provider}/${model.id}` : "default";
8601
9385
  }
9386
+ var PI_COMPATIBLE_PROVIDER_CONFIGS = {
9387
+ "openai-compatible": {
9388
+ name: "OpenAI-compatible",
9389
+ sourceProviderId: "openai",
9390
+ api: "openai-completions"
9391
+ },
9392
+ "anthropic-compatible": {
9393
+ name: "Anthropic-compatible",
9394
+ sourceProviderId: "anthropic",
9395
+ api: "anthropic-messages"
9396
+ }
9397
+ };
9398
+ function piSdkModelToProviderModelConfig(model, api) {
9399
+ return {
9400
+ id: model.id,
9401
+ name: model.name ?? humanizeRuntimeProviderSegment(model.id),
9402
+ api,
9403
+ reasoning: model.reasoning,
9404
+ thinkingLevelMap: model.thinkingLevelMap,
9405
+ input: [...model.input],
9406
+ cost: model.cost,
9407
+ contextWindow: model.contextWindow,
9408
+ maxTokens: model.maxTokens,
9409
+ headers: model.headers,
9410
+ compat: model.compat
9411
+ };
9412
+ }
9413
+ function genericCompatibleProviderModelConfig(modelId, api) {
9414
+ return {
9415
+ id: modelId,
9416
+ name: humanizeRuntimeProviderSegment(modelId),
9417
+ api,
9418
+ reasoning: false,
9419
+ input: ["text"],
9420
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
9421
+ contextWindow: 2e5,
9422
+ maxTokens: 16384
9423
+ };
9424
+ }
9425
+ function buildPiCompatibleProviderConfig(providerId, apiUrl, requestedModel) {
9426
+ const config = PI_COMPATIBLE_PROVIDER_CONFIGS[providerId];
9427
+ if (!config) return null;
9428
+ const models = getModels(config.sourceProviderId).map((model) => piSdkModelToProviderModelConfig(model, config.api));
9429
+ const providerPrefix = `${providerId}/`;
9430
+ const requestedProviderModelId = requestedModel?.startsWith(providerPrefix) ? requestedModel.slice(providerPrefix.length) : "";
9431
+ if (requestedProviderModelId && !models.some((model) => model.id === requestedProviderModelId)) {
9432
+ models.push(genericCompatibleProviderModelConfig(requestedProviderModelId, config.api));
9433
+ }
9434
+ return {
9435
+ name: config.name,
9436
+ baseUrl: apiUrl,
9437
+ apiKey: `$${providerId.toUpperCase().replaceAll("-", "_")}_API_KEY`,
9438
+ api: config.api,
9439
+ models
9440
+ };
9441
+ }
9442
+ function applyPiRuntimeProviderOverrides(config, authStorage, modelRegistry, requestedModel) {
9443
+ const runtimeConfig = hydrateRuntimeConfig(config);
9444
+ if (runtimeConfig.runtime !== EMBEDDED_PI_RUNTIME_ID || runtimeConfig.provider?.kind !== "pi-builtin") return;
9445
+ const provider = runtimeConfig.provider;
9446
+ if (provider.apiKey.trim()) {
9447
+ authStorage.setRuntimeApiKey(provider.providerId, provider.apiKey);
9448
+ }
9449
+ if (!modelRegistry) return;
9450
+ if (!PI_BUILTIN_PROVIDER_API_URL_REQUIRED[provider.providerId] || !provider.apiUrl?.trim()) return;
9451
+ if (!PI_BUILTIN_PROVIDER_CUSTOM_MODEL_SUPPORTED[provider.providerId]) return;
9452
+ const providerConfig = buildPiCompatibleProviderConfig(provider.providerId, provider.apiUrl.trim(), requestedModel);
9453
+ if (providerConfig) {
9454
+ modelRegistry.registerProvider(provider.providerId, providerConfig);
9455
+ }
9456
+ }
8602
9457
  function piServiceDiagnosticTraceAttrs(services) {
8603
9458
  let info = 0;
8604
9459
  let warning = 0;
@@ -8648,25 +9503,6 @@ async function detectPiModels(modelRegistry, traceContext = {}) {
8648
9503
  );
8649
9504
  return result;
8650
9505
  }
8651
- function humanizePiSegment(value) {
8652
- return value.split(/[-_/]/).filter(Boolean).map(formatPiLabelToken).join(" ");
8653
- }
8654
- function formatPiLabelToken(token) {
8655
- const normalized = token.toLowerCase();
8656
- const specialCases = {
8657
- ai: "AI",
8658
- api: "API",
8659
- flash: "Flash",
8660
- gpt: "GPT",
8661
- pro: "Pro",
8662
- v4: "V4"
8663
- };
8664
- if (specialCases[normalized]) return specialCases[normalized];
8665
- if (/^v\d+(\.\d+)?$/.test(normalized)) return normalized.toUpperCase();
8666
- if (/^\d+[bk]$/i.test(token)) return token.toUpperCase();
8667
- if (/^\d/.test(token)) return token;
8668
- return normalized.charAt(0).toUpperCase() + normalized.slice(1);
8669
- }
8670
9506
  function piErrorMessage(error) {
8671
9507
  if (typeof error === "string" && error.trim()) return error.trim();
8672
9508
  if (error && typeof error === "object") {
@@ -8782,6 +9618,12 @@ var PI_RUNTIME_SESSION_DESCRIPTOR = {
8782
9618
  };
8783
9619
  var PI_IDLE_PROMPT_RETRY_MS = 25;
8784
9620
  var PI_IDLE_PROMPT_MAX_WAIT_MS = 1e3;
9621
+ function inputSizeTraceAttrs(text) {
9622
+ return {
9623
+ input_chars: text.length,
9624
+ input_bytes: Buffer.byteLength(text, "utf8")
9625
+ };
9626
+ }
8785
9627
  async function createPiAgentSessionForContext(ctx, sessionId) {
8786
9628
  const sessionDir = buildPiSessionDir(ctx.workingDirectory);
8787
9629
  mkdirSync3(sessionDir, { recursive: true });
@@ -8803,6 +9645,7 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8803
9645
  const spawnEnv = await buildPiSpawnEnv(ctx);
8804
9646
  const agentDir = spawnEnv.PI_CODING_AGENT_DIR || getAgentDir();
8805
9647
  const authStorage = AuthStorage.create(path12.join(agentDir, "auth.json"));
9648
+ applyPiRuntimeProviderOverrides(ctx.config, authStorage, null, launchRuntimeFields.model);
8806
9649
  const settingsManager = SettingsManager.create(ctx.workingDirectory, agentDir);
8807
9650
  const services = await createAgentSessionServices({
8808
9651
  cwd: ctx.workingDirectory,
@@ -8813,6 +9656,7 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8813
9656
  systemPromptOverride: () => ctx.standingPrompt
8814
9657
  }
8815
9658
  });
9659
+ applyPiRuntimeProviderOverrides(ctx.config, authStorage, services.modelRegistry, launchRuntimeFields.model);
8816
9660
  applyPiDaemonSettingsOverrides(services.settingsManager);
8817
9661
  logPiServiceDiagnostics("create_session", services);
8818
9662
  addPiServiceTraceEvent(traceSpan, "daemon.pi.session.services_ready", services, {
@@ -8941,46 +9785,129 @@ var PiSdkRuntimeSession = class {
8941
9785
  this.events.on(event, cb);
8942
9786
  }
8943
9787
  async start(input) {
9788
+ const traceSpan = this.startTraceSpan("daemon.pi.session.start", {
9789
+ requested_session_id_present: Boolean(input.sessionId),
9790
+ config_session_id_present: Boolean(this.ctx.config.sessionId),
9791
+ ...inputSizeTraceAttrs(input.text)
9792
+ });
8944
9793
  if (this.started) {
9794
+ traceSpan?.end("error", {
9795
+ attrs: {
9796
+ outcome: "already_started"
9797
+ }
9798
+ });
8945
9799
  return { ok: false, reason: "runtime_error", error: "runtime session already started" };
8946
9800
  }
8947
- if (this.didClose) return { ok: false, reason: "closed" };
9801
+ if (this.didClose) {
9802
+ traceSpan?.end("error", {
9803
+ attrs: {
9804
+ outcome: "closed"
9805
+ }
9806
+ });
9807
+ return { ok: false, reason: "closed" };
9808
+ }
8948
9809
  this.started = true;
8949
9810
  const sessionId = input.sessionId || this.ctx.config.sessionId || randomUUID4();
8950
9811
  this.mappingState.sessionId = sessionId;
8951
9812
  this.setCurrentSessionId(sessionId);
8952
- const session = await this.sessionFactory({
8953
- ...this.ctx,
8954
- config: {
8955
- ...this.ctx.config,
8956
- sessionId
8957
- }
8958
- }, sessionId);
8959
- this.session = session;
8960
- this.mappingState.sessionId = session.sessionId;
8961
- this.setCurrentSessionId(session.sessionId);
8962
- this.unsubscribe = session.subscribe((event) => {
8963
- for (const parsed of mapPiSdkEventToParsedEvents(event, this.mappingState)) {
8964
- this.events.emit("runtime_event", parsed);
8965
- }
8966
- });
8967
- this.emitSessionInit();
8968
- this.launchPrompt(input.text);
8969
- return { ok: true, acceptedAs: "prompt" };
9813
+ try {
9814
+ const session = await this.sessionFactory({
9815
+ ...this.ctx,
9816
+ config: {
9817
+ ...this.ctx.config,
9818
+ sessionId
9819
+ }
9820
+ }, sessionId);
9821
+ this.session = session;
9822
+ this.mappingState.sessionId = session.sessionId;
9823
+ this.setCurrentSessionId(session.sessionId);
9824
+ traceSpan?.addEvent("daemon.pi.session.start.factory_ready", {
9825
+ session_id_present: Boolean(session.sessionId)
9826
+ });
9827
+ this.unsubscribe = session.subscribe((event) => {
9828
+ for (const parsed of mapPiSdkEventToParsedEvents(event, this.mappingState)) {
9829
+ this.events.emit("runtime_event", parsed);
9830
+ }
9831
+ });
9832
+ this.emitSessionInit();
9833
+ traceSpan?.addEvent("daemon.pi.session.start.initial_prompt_dispatch", {
9834
+ sdk_operation: "prompt",
9835
+ dispatch_reason: "initial_prompt"
9836
+ });
9837
+ this.launchPrompt(input.text, "initial_prompt");
9838
+ traceSpan?.end("ok", {
9839
+ attrs: {
9840
+ outcome: "accepted",
9841
+ session_id_present: Boolean(session.sessionId)
9842
+ }
9843
+ });
9844
+ return { ok: true, acceptedAs: "prompt" };
9845
+ } catch (error) {
9846
+ traceSpan?.end("error", {
9847
+ attrs: {
9848
+ outcome: "error",
9849
+ error_class: error instanceof Error ? error.name : typeof error
9850
+ }
9851
+ });
9852
+ throw error;
9853
+ }
8970
9854
  }
8971
9855
  send(input) {
8972
- if (this.didClose) return { ok: false, reason: "closed" };
8973
9856
  const session = this.session;
8974
- if (!session) return { ok: false, reason: "closed" };
9857
+ const traceSpan = this.startTraceSpan("daemon.pi.session.send", {
9858
+ mode: input.mode,
9859
+ streaming: Boolean(session?.isStreaming),
9860
+ ...inputSizeTraceAttrs(input.text)
9861
+ });
9862
+ if (this.didClose) {
9863
+ traceSpan?.end("error", {
9864
+ attrs: {
9865
+ outcome: "closed"
9866
+ }
9867
+ });
9868
+ return { ok: false, reason: "closed" };
9869
+ }
9870
+ if (!session) {
9871
+ traceSpan?.end("error", {
9872
+ attrs: {
9873
+ outcome: "closed"
9874
+ }
9875
+ });
9876
+ return { ok: false, reason: "closed" };
9877
+ }
8975
9878
  if (input.mode === "busy") {
8976
- this.deferSdkCall(() => session.steer(input.text));
9879
+ this.deferSdkCall("steer", "busy_steer", input.text, () => session.steer(input.text));
9880
+ traceSpan?.end("ok", {
9881
+ attrs: {
9882
+ outcome: "accepted",
9883
+ accepted_as: "steer",
9884
+ sdk_operation: "steer",
9885
+ dispatch_reason: "busy_steer"
9886
+ }
9887
+ });
8977
9888
  return { ok: true, acceptedAs: "steer" };
8978
9889
  }
8979
9890
  if (session.isStreaming) {
8980
9891
  this.launchPromptAfterStreaming(input.text);
9892
+ traceSpan?.end("ok", {
9893
+ attrs: {
9894
+ outcome: "accepted",
9895
+ accepted_as: "prompt",
9896
+ sdk_operation: "prompt_or_steer",
9897
+ dispatch_reason: "idle_prompt_after_streaming"
9898
+ }
9899
+ });
8981
9900
  return { ok: true, acceptedAs: "prompt" };
8982
9901
  }
8983
- this.launchPrompt(input.text);
9902
+ this.launchPrompt(input.text, "idle_prompt");
9903
+ traceSpan?.end("ok", {
9904
+ attrs: {
9905
+ outcome: "accepted",
9906
+ accepted_as: "prompt",
9907
+ sdk_operation: "prompt",
9908
+ dispatch_reason: "idle_prompt"
9909
+ }
9910
+ });
8984
9911
  return { ok: true, acceptedAs: "prompt" };
8985
9912
  }
8986
9913
  async stop(opts) {
@@ -9009,7 +9936,7 @@ var PiSdkRuntimeSession = class {
9009
9936
  this.mappingState.sessionAnnounced = true;
9010
9937
  this.events.emit("runtime_event", { kind: "session_init", sessionId });
9011
9938
  }
9012
- launchPrompt(text) {
9939
+ launchPrompt(text, dispatchReason) {
9013
9940
  const session = this.session;
9014
9941
  if (!session) {
9015
9942
  this.events.emit("runtime_event", {
@@ -9018,10 +9945,10 @@ var PiSdkRuntimeSession = class {
9018
9945
  });
9019
9946
  return;
9020
9947
  }
9021
- this.deferSdkCall(() => session.prompt(text));
9948
+ this.deferSdkCall("prompt", dispatchReason, text, () => session.prompt(text));
9022
9949
  }
9023
9950
  launchPromptAfterStreaming(text) {
9024
- this.deferSdkCall(async () => {
9951
+ this.deferSdkCall("prompt_or_steer", "idle_prompt_after_streaming", text, async () => {
9025
9952
  const session = this.session;
9026
9953
  if (!session) return;
9027
9954
  const ready = await this.waitForStreamingToClear(session);
@@ -9041,24 +9968,65 @@ var PiSdkRuntimeSession = class {
9041
9968
  }
9042
9969
  return !this.didClose && this.session === session && !session.isStreaming;
9043
9970
  }
9044
- deferSdkCall(invoke) {
9971
+ deferSdkCall(sdkOperation, dispatchReason, text, invoke) {
9045
9972
  setImmediate(() => {
9046
- if (this.didClose) return;
9047
- try {
9048
- void invoke().catch((error) => {
9049
- if (this.didClose) return;
9050
- this.events.emit("runtime_event", {
9051
- kind: "error",
9052
- message: piErrorMessage(error)
9053
- });
9054
- });
9055
- } catch (error) {
9056
- if (this.didClose) return;
9973
+ void this.invokeDeferredSdkCall(sdkOperation, dispatchReason, text, invoke);
9974
+ });
9975
+ }
9976
+ async invokeDeferredSdkCall(sdkOperation, dispatchReason, text, invoke) {
9977
+ const traceSpan = this.startTraceSpan("daemon.pi.session.sdk_call", {
9978
+ sdk_operation: sdkOperation,
9979
+ dispatch_reason: dispatchReason,
9980
+ ...inputSizeTraceAttrs(text)
9981
+ });
9982
+ if (this.didClose) {
9983
+ traceSpan?.end("cancelled", {
9984
+ attrs: {
9985
+ outcome: "skipped_closed",
9986
+ sdk_operation: sdkOperation,
9987
+ dispatch_reason: dispatchReason
9988
+ }
9989
+ });
9990
+ return;
9991
+ }
9992
+ try {
9993
+ await invoke();
9994
+ traceSpan?.end("ok", {
9995
+ attrs: {
9996
+ outcome: "resolved",
9997
+ sdk_operation: sdkOperation,
9998
+ dispatch_reason: dispatchReason
9999
+ }
10000
+ });
10001
+ } catch (error) {
10002
+ if (!this.didClose) {
9057
10003
  this.events.emit("runtime_event", {
9058
10004
  kind: "error",
9059
10005
  message: piErrorMessage(error)
9060
10006
  });
9061
10007
  }
10008
+ traceSpan?.end("error", {
10009
+ attrs: {
10010
+ outcome: "error",
10011
+ sdk_operation: sdkOperation,
10012
+ dispatch_reason: dispatchReason,
10013
+ error_class: error instanceof Error ? error.name : typeof error
10014
+ }
10015
+ });
10016
+ }
10017
+ }
10018
+ startTraceSpan(name, attrs) {
10019
+ return this.ctx.tracer?.startSpan(name, {
10020
+ surface: "daemon",
10021
+ kind: "internal",
10022
+ attrs: {
10023
+ agentId: this.ctx.agentId,
10024
+ launchId: this.ctx.launchId || void 0,
10025
+ runtime: this.ctx.config.runtime,
10026
+ model: this.ctx.config.model,
10027
+ session_id_present: Boolean(this.mappingState.sessionId),
10028
+ ...attrs
10029
+ }
9062
10030
  });
9063
10031
  }
9064
10032
  async disposeSession() {
@@ -9090,7 +10058,7 @@ var PiSdkRuntimeSession = class {
9090
10058
  }
9091
10059
  };
9092
10060
  var PiDriver = class {
9093
- id = "pi";
10061
+ id;
9094
10062
  supportsNativeStandingPrompt = true;
9095
10063
  lifecycle = {
9096
10064
  kind: "persistent",
@@ -9111,6 +10079,9 @@ var PiDriver = class {
9111
10079
  supportsStdinNotification = true;
9112
10080
  busyDeliveryMode = "direct";
9113
10081
  sessionId = null;
10082
+ constructor(runtimeId = EMBEDDED_PI_RUNTIME_ID) {
10083
+ this.id = runtimeId;
10084
+ }
9114
10085
  get currentSessionId() {
9115
10086
  return this.sessionId;
9116
10087
  }
@@ -9299,6 +10270,11 @@ function createChildProcessRuntimeSession(driver, ctx) {
9299
10270
  }
9300
10271
 
9301
10272
  // src/drivers/index.ts
10273
+ function createInstalledPiDriver() {
10274
+ const driver = new PiDriver(PI_RUNTIME_ID);
10275
+ Object.defineProperty(driver, "probe", { value: void 0 });
10276
+ return driver;
10277
+ }
9302
10278
  var driverFactories = {
9303
10279
  claude: () => new ClaudeDriver(),
9304
10280
  codex: () => new CodexDriver(),
@@ -9314,7 +10290,8 @@ var driverFactories = {
9314
10290
  kimi: () => new KimiDriver(),
9315
10291
  "kimi-sdk": () => new KimiSdkDriver(),
9316
10292
  opencode: () => new OpenCodeDriver(),
9317
- pi: () => new PiDriver()
10293
+ [EMBEDDED_PI_RUNTIME_ID]: () => new PiDriver(EMBEDDED_PI_RUNTIME_ID),
10294
+ [PI_RUNTIME_ID]: () => createInstalledPiDriver()
9318
10295
  };
9319
10296
  function getDriver(runtimeId) {
9320
10297
  const createDriver = driverFactories[runtimeId];
@@ -9895,6 +10872,33 @@ function runnerCredentialErrorDetail(error) {
9895
10872
  async function waitForRunnerCredentialRetry() {
9896
10873
  await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS));
9897
10874
  }
10875
+ function probeSubprocessOsState(pid) {
10876
+ if (typeof pid !== "number") return "unknown";
10877
+ try {
10878
+ const status = readFileSync6(`/proc/${pid}/status`, "utf8");
10879
+ const match = status.match(/^State:\s+(\S)/m);
10880
+ if (match) {
10881
+ const code = match[1];
10882
+ if (code === "R") return "running";
10883
+ if (code === "S") return "sleeping";
10884
+ if (code === "D") return "uninterruptible_sleep";
10885
+ if (code === "Z") return "zombie";
10886
+ if (code === "T" || code === "t") return "stopped";
10887
+ }
10888
+ return "unknown";
10889
+ } catch {
10890
+ return "gone";
10891
+ }
10892
+ }
10893
+ function bucketMs(ms) {
10894
+ if (ms < 1e3) return "<1s";
10895
+ if (ms < 1e4) return "1-10s";
10896
+ if (ms < 6e4) return "10-60s";
10897
+ if (ms < 3e5) return "1-5m";
10898
+ if (ms < 9e5) return "5-15m";
10899
+ if (ms < 36e5) return "15-60m";
10900
+ return ">60m";
10901
+ }
9898
10902
  function stalledRecoverySigtermTimeoutMs() {
9899
10903
  return readNonNegativeIntegerEnv(
9900
10904
  "SLOCK_DAEMON_STALLED_RECOVERY_SIGTERM_TIMEOUT_MS",
@@ -10138,7 +11142,7 @@ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), f
10138
11142
  } else if (runtime === "kimi-sdk" || runtime === "kimi") {
10139
11143
  lookupMethod = "kimi_sdk_index";
10140
11144
  resolvedPath = findKimiSdkSessionDir(sessionId, opts?.agentId, homeDir);
10141
- } else if (runtime === "pi") {
11145
+ } else if (runtime === PI_RUNTIME_ID || runtime === EMBEDDED_PI_RUNTIME_ID) {
10142
11146
  lookupMethod = "pi_jsonl";
10143
11147
  resolvedPath = findPiSessionFile2(sessionId, opts?.workingDirectory, homeDir);
10144
11148
  }
@@ -10300,6 +11304,7 @@ var STDIN_NOTIFICATION_INITIAL_DELAY_MS = 3e3;
10300
11304
  var STDIN_NOTIFICATION_RETRY_DELAY_MS = 15e3;
10301
11305
  var RUNTIME_ERROR_DELIVERY_BACKOFF_BASE_MS = 1e4;
10302
11306
  var RUNTIME_ERROR_DELIVERY_BACKOFF_MAX_MS = 5 * 6e4;
11307
+ var RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD = 3;
10303
11308
  var SPAWN_FAIL_BACKOFF_BASE_MS = 1e3;
10304
11309
  var SPAWN_FAIL_BACKOFF_MAX_MS = 3e4;
10305
11310
  var SPAWN_FAIL_BACKOFF_THRESHOLD = 3;
@@ -10960,7 +11965,7 @@ function resumeSessionRecoveryReason(ap) {
10960
11965
  if (candidates.some(isOpenCodeReplayRejectedByProvider)) return "provider_replay_rejected";
10961
11966
  return null;
10962
11967
  }
10963
- if (ap.driver.id === "pi") {
11968
+ if (ap.driver.id === PI_RUNTIME_ID || ap.driver.id === EMBEDDED_PI_RUNTIME_ID) {
10964
11969
  return candidates.some(isPiReplayRejectedByProvider) ? "provider_replay_rejected" : null;
10965
11970
  }
10966
11971
  if (ap.driver.id === "gemini") {
@@ -11209,6 +12214,7 @@ var AgentProcessManager = class _AgentProcessManager {
11209
12214
  agentStartIntervalMs;
11210
12215
  startingInboxes = /* @__PURE__ */ new Map();
11211
12216
  terminalRuntimeFailures = /* @__PURE__ */ new Map();
12217
+ runtimeErrorFingerprintFences = /* @__PURE__ */ new Map();
11212
12218
  pendingStartRebinds = /* @__PURE__ */ new Map();
11213
12219
  /** Cached configs for agents whose process exited normally — enables auto-restart on next message */
11214
12220
  idleAgentConfigs = /* @__PURE__ */ new Map();
@@ -11236,11 +12242,13 @@ var AgentProcessManager = class _AgentProcessManager {
11236
12242
  // BEFORE ap exists; rate-state must persist across stop/respawn so churn can't bypass).
11237
12243
  // Explicit stop clears (fresh launch resets dedup clock — CC1 lifecycle pattern); silent
11238
12244
  // stop preserves (same-launch respawn must keep counter or churn bypasses the cap).
12245
+ pendingSpawnCause = /* @__PURE__ */ new Map();
11239
12246
  agentSpawnFailBackoff = /* @__PURE__ */ new Map();
11240
12247
  daemonVersion;
11241
12248
  computerVersion;
11242
12249
  workerUrl;
11243
12250
  fetchImpl;
12251
+ serverConnected;
11244
12252
  constructor(sendToServer, daemonApiKey, opts) {
11245
12253
  this.slockCliPath = opts.slockCliPath ?? "";
11246
12254
  this.sendToServer = sendToServer;
@@ -11256,6 +12264,7 @@ var AgentProcessManager = class _AgentProcessManager {
11256
12264
  this.computerVersion = opts.computerVersion?.trim() || null;
11257
12265
  this.workerUrl = opts.workerUrl?.trim() || null;
11258
12266
  this.fetchImpl = opts.fetchImpl ?? daemonFetch;
12267
+ this.serverConnected = opts.serverConnected ?? (() => true);
11259
12268
  this.stdinNotificationRetryMs = Math.max(
11260
12269
  0,
11261
12270
  Math.floor(opts.stdinNotificationRetryMs ?? STDIN_NOTIFICATION_RETRY_DELAY_MS)
@@ -11372,6 +12381,94 @@ var AgentProcessManager = class _AgentProcessManager {
11372
12381
  if (state.timer) clearTimeout(state.timer);
11373
12382
  this.agentSpawnFailBackoff.delete(agentId);
11374
12383
  }
12384
+ // ----- RUNTIME-ERROR FINGERPRINT FENCE (per-agent) ---------------------
12385
+ // The delivery backoff above is scoped to AgentProcess and is cleared when a
12386
+ // runtime process exits. Recoverable terminal errors intentionally keep an
12387
+ // idle restart cache so the next message can wake the agent, but that also
12388
+ // means a deterministic same-fingerprint runtime error can close/restart
12389
+ // forever. Keep this counter outside AgentProcess and reset only on real turn
12390
+ // progress or explicit stop.
12391
+ runtimeErrorFingerprintFenceResetEvent(eventKind) {
12392
+ switch (eventKind) {
12393
+ case "thinking":
12394
+ case "text":
12395
+ case "tool_call":
12396
+ case "tool_output":
12397
+ case "compaction_finished":
12398
+ case "review_finished":
12399
+ case "turn_end":
12400
+ return true;
12401
+ default:
12402
+ return false;
12403
+ }
12404
+ }
12405
+ resetRuntimeErrorFingerprintFence(agentId, resetSource, ap) {
12406
+ const state = this.runtimeErrorFingerprintFences.get(agentId);
12407
+ if (!state) return;
12408
+ this.runtimeErrorFingerprintFences.delete(agentId);
12409
+ this.recordDaemonTrace("daemon.agent.runtime_error_fingerprint_fence.reset", {
12410
+ agentId,
12411
+ runtime: ap?.config.runtime,
12412
+ model: ap?.config.model,
12413
+ launchId: ap?.launchId || state.launchId || void 0,
12414
+ fingerprint: state.fingerprint,
12415
+ attempts: state.attempts,
12416
+ reset_source: resetSource
12417
+ });
12418
+ }
12419
+ formatRuntimeErrorFingerprintFenceDetail(state) {
12420
+ return [
12421
+ `Runtime stopped after ${state.attempts} repeated runtime errors with the same fingerprint (${state.fingerprint}).`,
12422
+ `Last error: ${state.lastRuntimeError}`,
12423
+ "Restart after the runtime/tooling issue is fixed."
12424
+ ].join(" ");
12425
+ }
12426
+ noteRuntimeErrorFingerprintFence(agentId, ap, message, fingerprint, terminalFailure, stickyTerminalFailure) {
12427
+ if (!fingerprint) return null;
12428
+ if (stickyTerminalFailure || terminalFailure?.actionRequired) return null;
12429
+ let state = this.runtimeErrorFingerprintFences.get(agentId);
12430
+ if (!state || state.fingerprint !== fingerprint) {
12431
+ state = {
12432
+ fingerprint,
12433
+ attempts: 0,
12434
+ lastRuntimeError: message,
12435
+ detail: "",
12436
+ launchId: ap.launchId
12437
+ };
12438
+ this.runtimeErrorFingerprintFences.set(agentId, state);
12439
+ }
12440
+ state.attempts += 1;
12441
+ state.lastRuntimeError = message;
12442
+ state.launchId = ap.launchId;
12443
+ state.detail = this.formatRuntimeErrorFingerprintFenceDetail(state);
12444
+ const fenced = state.attempts >= RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD;
12445
+ this.recordDaemonTrace("daemon.agent.runtime_error_fingerprint_fence", {
12446
+ agentId,
12447
+ runtime: ap.config.runtime,
12448
+ model: ap.config.model,
12449
+ launchId: ap.launchId || void 0,
12450
+ fingerprint,
12451
+ attempts: state.attempts,
12452
+ threshold: RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD,
12453
+ fenced,
12454
+ runtime_error_class: buildRuntimeErrorDiagnosticEnvelope(message).spanAttrs.runtime_error_class
12455
+ }, fenced ? "error" : "ok");
12456
+ return fenced ? state : null;
12457
+ }
12458
+ applyRuntimeErrorFingerprintFence(agentId, ap, state) {
12459
+ this.recordDaemonTrace("daemon.agent.runtime_error_fingerprint_fence.tripped", {
12460
+ agentId,
12461
+ runtime: ap.config.runtime,
12462
+ model: ap.config.model,
12463
+ launchId: ap.launchId || void 0,
12464
+ fingerprint: state.fingerprint,
12465
+ attempts: state.attempts,
12466
+ threshold: RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD
12467
+ }, "error");
12468
+ this.idleAgentConfigs.delete(agentId);
12469
+ this.sendAgentStatus(agentId, "inactive", ap.launchId);
12470
+ this.cleanupTerminalRuntimeFailure(agentId, ap, state.detail);
12471
+ }
11375
12472
  scheduleStdinNotification(agentId, ap, delayMs) {
11376
12473
  return ap.notifications.schedule(() => {
11377
12474
  this.sendStdinNotification(agentId);
@@ -11925,6 +13022,18 @@ var AgentProcessManager = class _AgentProcessManager {
11925
13022
  });
11926
13023
  span.end(status);
11927
13024
  }
13025
+ processLifecycleIdentityAttrs(agentId, ap) {
13026
+ const runtimeContext = ap.config.runtimeContext;
13027
+ return {
13028
+ agent_id: agentId,
13029
+ server_id: runtimeContext?.serverId,
13030
+ machine_id: runtimeContext?.machineId,
13031
+ process_instance_id: ap.processInstanceId,
13032
+ runtime: ap.config.runtime,
13033
+ runtime_version: runtimeContext?.daemonVersion,
13034
+ pid: typeof ap.runtime.pid === "number" ? ap.runtime.pid : void 0
13035
+ };
13036
+ }
11928
13037
  startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
11929
13038
  return {
11930
13039
  agentId,
@@ -12343,6 +13452,7 @@ var AgentProcessManager = class _AgentProcessManager {
12343
13452
  let prompt;
12344
13453
  let promptSource;
12345
13454
  let wakeMessageDeliveredAsInboxUpdate = false;
13455
+ let startingInboxDeliveredAsInput = false;
12346
13456
  const startingInboxMessages = this.startingInboxes.get(agentId) || [];
12347
13457
  if (runtimeConfig.runtimeProfileControl && !wakeMessage) {
12348
13458
  prompt = driver.supportsNativeStandingPrompt ? NATIVE_STANDING_PROMPT_STARTUP_INPUT : formatRuntimeProfileControlStartupInput(runtimeConfig.runtimeProfileControl, driver);
@@ -12383,6 +13493,10 @@ You also have unread messages in other channels:`;
12383
13493
  Use the inbox/read commands at a natural breakpoint if you choose to inspect those targets.`;
12384
13494
  }
12385
13495
  }
13496
+ } else if (startingInboxMessages.length > 0) {
13497
+ startingInboxDeliveredAsInput = true;
13498
+ prompt = this.formatInboxUpdateRuntimeInput(startingInboxMessages, driver);
13499
+ promptSource = "starting_inbox_update";
12386
13500
  } else if (isResume && unreadSummary && Object.keys(unreadSummary).length > 0) {
12387
13501
  prompt = `You have unread messages from while you were offline:`;
12388
13502
  for (const [ch, count] of Object.entries(unreadSummary)) {
@@ -12459,6 +13573,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12459
13573
  };
12460
13574
  const initialSessionId = this.initialAgentProcessSessionId(driver, liveProcessConfig);
12461
13575
  const restartSessionId = initialSessionId || (driver.requiresSessionInitForDelivery ? liveProcessConfig.sessionId || null : null);
13576
+ const processInstanceId = randomUUID5();
12462
13577
  agentProcess = {
12463
13578
  runtime,
12464
13579
  driver,
@@ -12488,6 +13603,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12488
13603
  runtimeErrorSinceProgress: false,
12489
13604
  runtimeErrorDeliveryBackoff: createRuntimeErrorDeliveryBackoffState(),
12490
13605
  spawnError: null,
13606
+ processInstanceId,
13607
+ spawnedAtMs: Date.now(),
12491
13608
  exitCode: null,
12492
13609
  exitSignal: null,
12493
13610
  stalledRecoverySigtermTimer: null,
@@ -12512,6 +13629,10 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12512
13629
  }
12513
13630
  if (wakeMessageDeliveredAsInboxUpdate) {
12514
13631
  this.recordInboxUpdateProjection(agentId, agentProcess, agentProcess.inbox, "spawn_wake_inbox_update", "wake", prompt);
13632
+ } else if (startingInboxDeliveredAsInput) {
13633
+ this.recordInboxUpdateProjection(agentId, agentProcess, startingInboxMessages, "spawn_starting_inbox_update", "wake", prompt);
13634
+ this.consumeVisibleMessages(agentId, { messages: startingInboxMessages, source: "spawn_starting_inbox_update" });
13635
+ this.ackInjectedRuntimeProfileMessages(agentId, startingInboxMessages, agentProcess.launchId);
12515
13636
  } else if (wakeMessage && !wakeMessageTransient) {
12516
13637
  this.consumeVisibleMessages(agentId, { messages: [wakeMessage], source: "spawn_wake_message" });
12517
13638
  this.ackInjectedRuntimeProfileMessages(agentId, [wakeMessage], agentProcess.launchId);
@@ -12574,6 +13695,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12574
13695
  current.exitCode = code;
12575
13696
  current.exitSignal = signal;
12576
13697
  }
13698
+ const exitTraceAttrs = this.runtimeExitTraceAttrs.get(runtime);
12577
13699
  this.recordDaemonTrace("daemon.agent.process.exited", {
12578
13700
  agentId,
12579
13701
  launchId: current?.launchId || void 0,
@@ -12585,8 +13707,22 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12585
13707
  runtime_trace_active: Boolean(current?.runtimeTraceSpan),
12586
13708
  inbox_count: current?.inbox.length ?? 0,
12587
13709
  pending_notification_count: current?.notifications.pendingCount ?? 0,
12588
- ...this.runtimeExitTraceAttrs.get(runtime)
13710
+ ...exitTraceAttrs
12589
13711
  });
13712
+ if (agentProcess) {
13713
+ const stopSource = exitTraceAttrs?.stop_source;
13714
+ const exitCause = stopSource?.includes("stall") ? "stall_kill" : stopSource === "disconnect" ? "disconnect_kill" : stopSource === "daemon_exit" ? "parent_exit" : stopSource === "explicit_request" || stopSource === "daemon_internal" || code === 0 ? "expected_terminate" : "crash";
13715
+ const staleForMs = agentProcess.runtimeProgress.ageMs();
13716
+ this.recordDaemonTrace("daemon.runtime.process.exit", {
13717
+ ...this.processLifecycleIdentityAttrs(agentId, agentProcess),
13718
+ exit_code: code,
13719
+ exit_signal: signal,
13720
+ cause: exitCause,
13721
+ last_event_kind: agentProcess.lastActivity || void 0,
13722
+ last_event_age_ms_bucket: bucketMs(staleForMs),
13723
+ uptime_ms_bucket: bucketMs(Date.now() - agentProcess.spawnedAtMs)
13724
+ }, code === 0 ? "ok" : "error");
13725
+ }
12590
13726
  logger.info(`[Agent ${agentId}] Process exited with code ${code}${signal ? ` (signal ${signal})` : ""}`);
12591
13727
  });
12592
13728
  runtime.on("close", ({ code, signal }) => {
@@ -12650,6 +13786,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12650
13786
  text: `Stored ${runtimeLabel} session ${staleSessionId} ${reasonText}. Falling back to a cold start; earlier runtime context may not be restored.`
12651
13787
  }]
12652
13788
  );
13789
+ this.pendingSpawnCause.set(agentId, "restart_crash");
12653
13790
  this.startAgent(
12654
13791
  agentId,
12655
13792
  restartConfig,
@@ -12659,6 +13796,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12659
13796
  ap.launchId || void 0
12660
13797
  ).catch((err) => {
12661
13798
  logger.error(`[Agent ${agentId}] Cold start recovery failed`, err);
13799
+ this.pendingSpawnCause.delete(agentId);
12662
13800
  this.sendAgentStatus(agentId, "inactive", ap.launchId);
12663
13801
  this.broadcastActivity(agentId, "offline", `Crashed (${summary})`, [], ap.launchId);
12664
13802
  });
@@ -12685,6 +13823,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12685
13823
  });
12686
13824
  this.broadcastActivity(agentId, "working", "Message received");
12687
13825
  this.idleAgentConfigs.delete(agentId);
13826
+ if (expectedTerminationReason === "stalled_recovery") {
13827
+ this.pendingSpawnCause.set(agentId, "restart_stall");
13828
+ }
12688
13829
  this.startAgent(agentId, nextConfig, queuedWakeMessage, unreadSummary2, void 0, ap.launchId || void 0).catch((err) => {
12689
13830
  logger.error(`[Agent ${agentId}] Failed to continue with queued message`, err);
12690
13831
  if (this.reportRunnerCredentialMintFailure(agentId, err, ap.launchId, "queued_continuation")) {
@@ -12769,6 +13910,16 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12769
13910
  new_session: false,
12770
13911
  process_pid_present: typeof runtime.pid === "number"
12771
13912
  });
13913
+ const pendingCause = this.pendingSpawnCause.get(agentId);
13914
+ this.pendingSpawnCause.delete(agentId);
13915
+ const startCause = pendingCause ?? (isResume ? "session_resume" : wakeMessage ? "wake_message" : "explicit_start");
13916
+ this.recordDaemonTrace("daemon.runtime.process.spawn", {
13917
+ ...this.processLifecycleIdentityAttrs(agentId, agentProcess),
13918
+ start_cause: startCause,
13919
+ credential_type: effectiveConfig.agentCredentialKey ? "managed_runner" : "legacy_machine",
13920
+ session_id_present: Boolean(agentProcess.sessionId),
13921
+ launch_id_present: Boolean(agentProcess.launchId)
13922
+ });
12772
13923
  this.sendAgentStatus(agentId, "active", agentProcess.launchId);
12773
13924
  if (pendingStartRebind && agentProcess.sessionId) {
12774
13925
  this.sendToServer({ type: "agent:session", agentId, sessionId: agentProcess.sessionId, launchId: agentProcess.launchId || void 0 });
@@ -13123,6 +14274,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13123
14274
  this.agentVisibleBoundaries.delete(agentId);
13124
14275
  this.agentVisibleMessageIds.delete(agentId);
13125
14276
  this.resetSpawnFailBackoff(agentId);
14277
+ this.resetRuntimeErrorFingerprintFence(agentId, "explicit_stop", ap);
13126
14278
  }
13127
14279
  this.runtimeExitTraceAttrs.set(ap.runtime, {
13128
14280
  stop_source: silent ? "daemon_internal" : "explicit_request",
@@ -13307,6 +14459,19 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13307
14459
  return false;
13308
14460
  });
13309
14461
  }
14462
+ if (!transientDelivery && (this.queuedAgentStarts.has(agentId) || this.agentsStarting.has(agentId))) {
14463
+ const pending = this.startingInboxes.get(agentId) || [];
14464
+ pending.push(message);
14465
+ this.startingInboxes.set(agentId, pending);
14466
+ this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
14467
+ outcome: this.agentsStarting.has(agentId) ? "queued_for_starting_process" : "queued_for_queued_start",
14468
+ accepted: true,
14469
+ process_present: false,
14470
+ cached_idle_config_present: false,
14471
+ starting_inbox_count: pending.length
14472
+ }));
14473
+ return true;
14474
+ }
13310
14475
  logger.warn(`[Agent ${agentId}] Delivery received but no running process or cached idle config exists`);
13311
14476
  if (transientDelivery) {
13312
14477
  this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
@@ -14307,26 +15472,18 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14307
15472
  if (!hasToolStart) {
14308
15473
  entries.push({ kind: "status", activity, detail });
14309
15474
  }
15475
+ const launchId = launchIdOverride || ap?.launchId || void 0;
15476
+ const clientSeq = ap ? this.nextActivityClientSeq(agentId) : void 0;
14310
15477
  this.sendToServer({
14311
15478
  type: "agent:activity",
14312
15479
  agentId,
14313
15480
  activity,
14314
15481
  detail,
14315
15482
  entries,
14316
- launchId: launchIdOverride || ap?.launchId || void 0,
14317
- clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0
14318
- });
14319
- this.recordDaemonTrace("daemon.agent.activity.produced", {
14320
- agentId,
14321
- activity,
14322
- detail_present: Boolean(detail),
14323
- entry_kinds: entries.map((e) => e.kind).join(","),
14324
- ap_present: Boolean(ap),
14325
- launch_id_present: Boolean(launchIdOverride || ap?.launchId),
14326
- client_seq_present: ap ? true : false,
14327
- session_id_present: Boolean(ap?.sessionId),
14328
- runtime: ap?.config.runtime
15483
+ launchId,
15484
+ clientSeq
14329
15485
  });
15486
+ this.recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq);
14330
15487
  if (ap) {
14331
15488
  ap.lastActivity = activity;
14332
15489
  ap.lastActivityDetail = detail;
@@ -14337,14 +15494,17 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14337
15494
  this.recordRuntimeTraceEvent(agentId, ap, "activity.heartbeat.sent", {
14338
15495
  activity: ap.lastActivity
14339
15496
  });
15497
+ const heartbeatLaunchId = launchIdOverride || ap.launchId || void 0;
15498
+ const heartbeatClientSeq = this.nextActivityClientSeq(agentId);
14340
15499
  this.sendToServer({
14341
15500
  type: "agent:activity",
14342
15501
  agentId,
14343
15502
  activity: ap.lastActivity,
14344
15503
  detail: ap.lastActivityDetail,
14345
- launchId: launchIdOverride || ap.launchId || void 0,
14346
- clientSeq: this.nextActivityClientSeq(agentId)
15504
+ launchId: heartbeatLaunchId,
15505
+ clientSeq: heartbeatClientSeq
14347
15506
  });
15507
+ this.recordActivityProducedTrace(agentId, ap.lastActivity, ap.lastActivityDetail, [], ap, heartbeatLaunchId, heartbeatClientSeq);
14348
15508
  }, ACTIVITY_HEARTBEAT_MS);
14349
15509
  }
14350
15510
  } else {
@@ -14355,6 +15515,29 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14355
15515
  }
14356
15516
  }
14357
15517
  }
15518
+ recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq) {
15519
+ const runtimeContext = ap?.config.runtimeContext;
15520
+ this.recordDaemonTrace("daemon.agent.activity.produced", {
15521
+ agentId,
15522
+ agent_id: agentId,
15523
+ server_id: runtimeContext?.serverId,
15524
+ machine_id: runtimeContext?.machineId,
15525
+ process_instance_id: ap?.processInstanceId,
15526
+ activity,
15527
+ detail_present: Boolean(detail),
15528
+ entry_kinds: entries.map((e) => e.kind).join(","),
15529
+ ap_present: Boolean(ap),
15530
+ launchId,
15531
+ launch_id: launchId,
15532
+ launch_id_present: Boolean(launchId),
15533
+ clientSeq,
15534
+ client_seq: clientSeq,
15535
+ client_seq_present: typeof clientSeq === "number",
15536
+ correlation_id: `agent:${agentId}:daemonActivity:${launchId ?? "legacy"}:${clientSeq ?? "unsequenced"}`,
15537
+ session_id_present: Boolean(ap?.sessionId),
15538
+ runtime: ap?.config.runtime
15539
+ });
15540
+ }
14358
15541
  /**
14359
15542
  * Respond to a server-issued `agent:activity_probe`. Echoes the
14360
15543
  * agent's current `lastActivity` back through the existing
@@ -14380,15 +15563,18 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14380
15563
  const ap = this.agents.get(agentId);
14381
15564
  const activity = ap?.lastActivity || "offline";
14382
15565
  const detail = ap?.lastActivityDetail || (ap ? "" : "Agent not running");
15566
+ const launchId = ap?.launchId || void 0;
15567
+ const clientSeq = ap ? this.nextActivityClientSeq(agentId) : void 0;
14383
15568
  this.sendToServer({
14384
15569
  type: "agent:activity",
14385
15570
  agentId,
14386
15571
  activity,
14387
15572
  detail,
14388
- launchId: ap?.launchId || void 0,
15573
+ launchId,
14389
15574
  probeId,
14390
- clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0
15575
+ clientSeq
14391
15576
  });
15577
+ this.recordActivityProducedTrace(agentId, activity, detail, [], ap, launchId, clientSeq);
14392
15578
  }
14393
15579
  flushPendingTrajectory(agentId) {
14394
15580
  const ap = this.agents.get(agentId);
@@ -14488,6 +15674,12 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14488
15674
  );
14489
15675
  try {
14490
15676
  void runtimeAtSignal.stop({ signal: "SIGKILL", reason: "stalled_recovery_sigterm_timeout" });
15677
+ this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
15678
+ ...this.processLifecycleIdentityAttrs(agentId, current),
15679
+ action: "sigkill_escalation",
15680
+ outcome: "initiated",
15681
+ delay_ms_bucket: bucketMs(timeoutMs)
15682
+ }, "error");
14491
15683
  } catch (err) {
14492
15684
  const reason = err instanceof Error ? err.message : String(err);
14493
15685
  this.recordDaemonTrace("daemon.agent.stalled_recovery.sigkill_failed", {
@@ -14497,6 +15689,16 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14497
15689
  model: current.config.model,
14498
15690
  reason
14499
15691
  }, "error");
15692
+ this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
15693
+ ...this.processLifecycleIdentityAttrs(agentId, current),
15694
+ action: "sigkill_escalation",
15695
+ outcome: "kill_failed",
15696
+ delay_ms_bucket: bucketMs(timeoutMs),
15697
+ kill_signal_sequence: "SIGTERM,SIGKILL",
15698
+ kill_attempts: 2,
15699
+ subprocess_os_state: probeSubprocessOsState(current.runtime.pid),
15700
+ daemon_child_tracking_present: this.agents.has(agentId)
15701
+ }, "error");
14500
15702
  logger.warn(`[Agent ${agentId}] Failed to force kill stalled ${runtimeLabel} process: ${reason}`);
14501
15703
  }
14502
15704
  }, timeoutMs);
@@ -15036,6 +16238,23 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
15036
16238
  ...runtimeTraceCounterAttrs(ap),
15037
16239
  ...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_stalled")
15038
16240
  });
16241
+ let subprocessPidAlive;
16242
+ if (typeof ap.runtime.pid === "number") {
16243
+ try {
16244
+ process.kill(ap.runtime.pid, 0);
16245
+ subprocessPidAlive = true;
16246
+ } catch {
16247
+ subprocessPidAlive = false;
16248
+ }
16249
+ }
16250
+ this.recordDaemonTrace("daemon.runtime.stall.detected", {
16251
+ ...this.processLifecycleIdentityAttrs(agentId, ap),
16252
+ last_event_kind: ap.lastActivity || void 0,
16253
+ last_event_age_ms_bucket: bucketMs(staleForMs),
16254
+ subprocess_pid_alive: subprocessPidAlive,
16255
+ subprocess_socket_alive: !ap.runtime.closed,
16256
+ daemon_connected_to_server: this.serverConnected()
16257
+ }, "error");
15039
16258
  this.broadcastActivity(agentId, "error", diagnostic.detail);
15040
16259
  return true;
15041
16260
  }
@@ -15087,9 +16306,25 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
15087
16306
  this.runtimeExitTraceAttrs.set(ap.runtime, projection.processExitAttrs);
15088
16307
  this.startStalledRecoverySigtermWatchdog(agentId, ap, runtimeLabel, ap.inbox.length, staleForMs);
15089
16308
  void ap.runtime.stop({ signal: "SIGTERM", reason: projection.runtimeStopReason });
16309
+ this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
16310
+ ...this.processLifecycleIdentityAttrs(agentId, ap),
16311
+ action: "terminate_for_restart",
16312
+ outcome: "initiated",
16313
+ delay_ms_bucket: bucketMs(staleForMs)
16314
+ });
15090
16315
  } catch (err) {
15091
16316
  this.clearStalledRecoverySigtermWatchdog(ap);
15092
16317
  const reason = err instanceof Error ? err.message : String(err);
16318
+ this.recordDaemonTrace("daemon.runtime.stall.recovery_action", {
16319
+ ...this.processLifecycleIdentityAttrs(agentId, ap),
16320
+ action: "terminate_for_restart",
16321
+ outcome: "kill_failed",
16322
+ delay_ms_bucket: bucketMs(staleForMs),
16323
+ kill_signal_sequence: "SIGTERM",
16324
+ kill_attempts: 1,
16325
+ subprocess_os_state: probeSubprocessOsState(ap.runtime.pid),
16326
+ daemon_child_tracking_present: this.agents.has(agentId)
16327
+ }, "error");
15093
16328
  logger.warn(`[Agent ${agentId}] Failed to terminate stalled ${runtimeLabel} process: ${reason}`);
15094
16329
  return false;
15095
16330
  }
@@ -15168,6 +16403,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
15168
16403
  return;
15169
16404
  }
15170
16405
  this.noteRuntimeProgress(ap, event.kind);
16406
+ if (this.runtimeErrorFingerprintFenceResetEvent(event.kind)) {
16407
+ this.resetRuntimeErrorFingerprintFence(agentId, `runtime_progress:${event.kind}`, ap);
16408
+ }
15171
16409
  recordProgressObservedAfterStall();
15172
16410
  } else if (event.kind !== "internal_progress") {
15173
16411
  this.recordDaemonTrace("daemon.agent.event.received_without_process", {
@@ -15360,6 +16598,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
15360
16598
  let visibleErrorMessage = event.message;
15361
16599
  if (ap) {
15362
16600
  const runtimeErrorDiagnostics = buildRuntimeErrorDiagnosticEnvelope(event.message);
16601
+ const runtimeErrorFingerprint = typeof runtimeErrorDiagnostics.spanAttrs.runtime_error_fingerprint === "string" ? runtimeErrorDiagnostics.spanAttrs.runtime_error_fingerprint : null;
15363
16602
  if (runtimeErrorDiagnostics.spanAttrs.runtime_error_action_required === true) {
15364
16603
  visibleErrorMessage = formatRuntimeLoginRequiredMessage(ap.driver.id);
15365
16604
  }
@@ -15376,6 +16615,17 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
15376
16615
  terminalWakeable: Boolean(ap.driver.supportsStdinNotification && terminalFailure && !terminalFailure.actionRequired)
15377
16616
  });
15378
16617
  this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "error" });
16618
+ const fingerprintFence = this.noteRuntimeErrorFingerprintFence(
16619
+ agentId,
16620
+ ap,
16621
+ event.message,
16622
+ runtimeErrorFingerprint,
16623
+ terminalFailure,
16624
+ stickyTerminalFailure
16625
+ );
16626
+ if (fingerprintFence) {
16627
+ visibleErrorMessage = fingerprintFence.detail;
16628
+ }
15379
16629
  this.noteRuntimeErrorDeliveryBackoff(agentId, ap, event.message, terminalFailure, stickyTerminalFailure, backoffReasonOverride);
15380
16630
  if (reduction.shouldDisableToolBoundaryFlush) {
15381
16631
  this.recordGatedSteeringEvent(agentId, ap, "disabled", {
@@ -15396,7 +16646,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
15396
16646
  ...runtimeTraceCounterAttrs(ap),
15397
16647
  ...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_error")
15398
16648
  });
15399
- if (ap.driver.supportsStdinNotification && terminalFailure) {
16649
+ if (fingerprintFence) {
16650
+ this.applyRuntimeErrorFingerprintFence(agentId, ap, fingerprintFence);
16651
+ } else if (ap.driver.supportsStdinNotification && terminalFailure) {
15400
16652
  if (terminalFailure.actionRequired) {
15401
16653
  logger.warn(`[Agent ${agentId}] ${ap.driver.id} auth requires user action; terminating runtime process`);
15402
16654
  try {
@@ -16430,7 +17682,13 @@ var DIAGNOSTIC_ID_ATTRS = /* @__PURE__ */ new Set([
16430
17682
  "bundleId",
16431
17683
  "deliveryId",
16432
17684
  "deliveryCorrelationId",
16433
- "delivery_correlation_id"
17685
+ "delivery_correlation_id",
17686
+ "agent_id",
17687
+ "server_id",
17688
+ "machine_id",
17689
+ "process_instance_id",
17690
+ "launch_id",
17691
+ "correlation_id"
16434
17692
  ]);
16435
17693
  var DIAGNOSTIC_ERROR_ATTRS = /* @__PURE__ */ new Set([
16436
17694
  "runtime_error_class",
@@ -16680,6 +17938,21 @@ var TRACE_UPLOAD_SCOPE = "daemon-trace-bundle:create";
16680
17938
  var DEFAULT_UPLOAD_INTERVAL_MS = 5 * 60 * 1e3;
16681
17939
  var DEFAULT_MIN_FILE_AGE_MS = 60 * 1e3;
16682
17940
  var DEFAULT_MAX_FILES_PER_RUN = 4;
17941
+ var ALLOWED_PRODUCER_DEPLOYMENT_ENVIRONMENTS = /* @__PURE__ */ new Set([
17942
+ "production",
17943
+ "staging",
17944
+ "dev",
17945
+ "test",
17946
+ "slockdev"
17947
+ ]);
17948
+ function readProducerDeploymentEnvironment() {
17949
+ const raw = process.env.SLOCK_DAEMON_DEPLOYMENT_ENV;
17950
+ if (!raw) return void 0;
17951
+ const trimmed = raw.trim();
17952
+ if (!trimmed) return void 0;
17953
+ if (!ALLOWED_PRODUCER_DEPLOYMENT_ENVIRONMENTS.has(trimmed)) return void 0;
17954
+ return trimmed;
17955
+ }
16683
17956
  var DaemonTraceBundleUploader = class {
16684
17957
  options;
16685
17958
  jitter;
@@ -16798,7 +18071,11 @@ var DaemonTraceBundleUploader = class {
16798
18071
  attestationMetadata: {
16799
18072
  bundleId,
16800
18073
  bundleSha256,
16801
- bundleSizeBytes: gzipped.byteLength
18074
+ bundleSizeBytes: gzipped.byteLength,
18075
+ ...(() => {
18076
+ const env = readProducerDeploymentEnvironment();
18077
+ return env ? { deploymentEnvironment: env } : {};
18078
+ })()
16802
18079
  },
16803
18080
  createBody: {
16804
18081
  bundleSha256,
@@ -16891,9 +18168,10 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
16891
18168
  eventAttrs: {
16892
18169
  "daemon.receive": ["seq", "deliveryId"],
16893
18170
  "daemon.deliver_to_agent_manager": ["accepted"],
18171
+ "daemon.delivery.buffered_for_start": ["pending_count"],
16894
18172
  "daemon.ack.sent": ["seq"]
16895
18173
  },
16896
- endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class"]
18174
+ endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class", "pending_count"]
16897
18175
  },
16898
18176
  "daemon.runtime_profile.control.received": {
16899
18177
  spanAttrs: ["agentId", "control_kind", "key_present", "launchId"],
@@ -16926,11 +18204,27 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
16926
18204
  },
16927
18205
  endAttrs: ["outcome", "available_models_count", "diagnostics_count", "diagnostic_info_count", "diagnostic_warning_count", "requested_model", "resolved_model", "resolved_model_present", "error_class"]
16928
18206
  },
18207
+ "daemon.pi.session.start": {
18208
+ spanAttrs: ["agentId", "launchId", "runtime", "model", "session_id_present", "requested_session_id_present", "config_session_id_present", "input_chars", "input_bytes"],
18209
+ eventAttrs: {
18210
+ "daemon.pi.session.start.factory_ready": ["session_id_present"],
18211
+ "daemon.pi.session.start.initial_prompt_dispatch": ["sdk_operation", "dispatch_reason"]
18212
+ },
18213
+ endAttrs: ["outcome", "session_id_present", "error_class"]
18214
+ },
18215
+ "daemon.pi.session.send": {
18216
+ spanAttrs: ["agentId", "launchId", "runtime", "model", "session_id_present", "mode", "streaming", "input_chars", "input_bytes"],
18217
+ endAttrs: ["outcome", "accepted_as", "sdk_operation", "dispatch_reason"]
18218
+ },
18219
+ "daemon.pi.session.sdk_call": {
18220
+ spanAttrs: ["agentId", "launchId", "runtime", "model", "session_id_present", "sdk_operation", "dispatch_reason", "input_chars", "input_bytes"],
18221
+ endAttrs: ["outcome", "sdk_operation", "dispatch_reason", "error_class"]
18222
+ },
16929
18223
  "daemon.connection.local_disconnect_observed": {
16930
18224
  spanAttrs: ["running_agents_count", "idle_agents_count"]
16931
18225
  },
16932
18226
  "daemon.agent.activity.produced": {
16933
- spanAttrs: ["agentId", "activity", "detail_present", "entry_kinds", "ap_present", "launch_id_present", "client_seq_present", "session_id_present", "runtime"]
18227
+ spanAttrs: ["agentId", "agent_id", "server_id", "machine_id", "activity", "detail_present", "entry_kinds", "ap_present", "launchId", "launch_id", "launch_id_present", "clientSeq", "client_seq", "client_seq_present", "correlation_id", "session_id_present", "runtime"]
16934
18228
  },
16935
18229
  "daemon.agent.activity.skipped": {
16936
18230
  spanAttrs: ["agentId", "event_kind", "reason", "text_length"]
@@ -16939,7 +18233,7 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
16939
18233
  spanAttrs: ["agentId", "event_kind", "runtime"]
16940
18234
  }
16941
18235
  };
16942
- var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
18236
+ var DAEMON_CLI_USAGE = `Usage: slock-daemon --server-url <url> (--api-key <key> or ${DAEMON_API_KEY_ENV}=<key>)`;
16943
18237
  var RunnerCredentialMintError2 = class extends Error {
16944
18238
  code;
16945
18239
  retryable;
@@ -16975,9 +18269,9 @@ function runnerCredentialErrorDetail2(error) {
16975
18269
  async function waitForRunnerCredentialRetry2() {
16976
18270
  await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
16977
18271
  }
16978
- function parseDaemonCliArgs(args) {
18272
+ function parseDaemonCliArgs(args, env = {}) {
16979
18273
  let serverUrl = "";
16980
- let apiKey = "";
18274
+ let apiKey = env[DAEMON_API_KEY_ENV] ?? "";
16981
18275
  for (let i = 0; i < args.length; i++) {
16982
18276
  if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
16983
18277
  if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
@@ -17014,7 +18308,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
17014
18308
  }
17015
18309
  async function runBundledSlockCli(argv) {
17016
18310
  process.argv = [process.execPath, "slock", ...argv];
17017
- await import("./dist-KC6QHBPD.js");
18311
+ await import("./dist-53X4DIA6.js");
17018
18312
  }
17019
18313
  function detectRuntimes(tracer = noopTracer) {
17020
18314
  const ids = [];
@@ -17062,6 +18356,20 @@ function detectRuntimes(tracer = noopTracer) {
17062
18356
  } catch {
17063
18357
  probeErrorPresent = true;
17064
18358
  }
18359
+ if (!runtime.binary) {
18360
+ if (runtime.supported) {
18361
+ ids.push(runtime.id);
18362
+ }
18363
+ span.addEvent("daemon.runtime.detect.checked", {
18364
+ runtime: runtime.id,
18365
+ outcome: runtime.supported ? "available" : "unavailable",
18366
+ version_present: false,
18367
+ binary_path_present: false,
18368
+ probe_error_present: probeErrorPresent,
18369
+ builtin_runtime: true
18370
+ });
18371
+ continue;
18372
+ }
17065
18373
  const detectionBinaries = [runtime.binary];
17066
18374
  let detectedByPath = false;
17067
18375
  for (const binary of detectionBinaries) {
@@ -17177,6 +18485,8 @@ var DaemonCore = class {
17177
18485
  observedMachineId = null;
17178
18486
  localTraceSink = null;
17179
18487
  traceBundleUploader = null;
18488
+ coreStartingAgentIds = /* @__PURE__ */ new Set();
18489
+ coreStartPendingDeliveries = /* @__PURE__ */ new Map();
17180
18490
  constructor(options) {
17181
18491
  this.options = options;
17182
18492
  this.daemonVersion = options.daemonVersion ?? readDaemonVersion();
@@ -17202,7 +18512,8 @@ var DaemonCore = class {
17202
18512
  tracer: this.tracer,
17203
18513
  daemonVersion: this.daemonVersion,
17204
18514
  computerVersion: this.computerVersion,
17205
- workerUrl: traceUploadDisabled ? void 0 : process.env.SLOCK_DAEMON_TRACE_UPLOAD_URL || DEFAULT_TRACE_UPLOAD_URL
18515
+ workerUrl: traceUploadDisabled ? void 0 : process.env.SLOCK_DAEMON_TRACE_UPLOAD_URL || DEFAULT_TRACE_UPLOAD_URL,
18516
+ serverConnected: () => connection?.connected ?? false
17206
18517
  };
17207
18518
  this.agentManager = options.agentManagerFactory ? options.agentManagerFactory((msg) => connection.send(msg), options.apiKey, agentManagerOptions) : new AgentProcessManager((msg) => connection.send(msg), options.apiKey, agentManagerOptions);
17208
18519
  const connectionFactory = options.connectionFactory ?? ((connOptions) => new DaemonConnection(connOptions));
@@ -17453,19 +18764,63 @@ var DaemonCore = class {
17453
18764
  }
17454
18765
  );
17455
18766
  }
18767
+ sendDeliveryAck(msg, traceparent) {
18768
+ const ackSeq = msg.seq > 0 ? msg.seq : msg.message.seq ?? 0;
18769
+ const ack = {
18770
+ type: "agent:deliver:ack",
18771
+ agentId: msg.agentId,
18772
+ seq: ackSeq,
18773
+ deliveryId: msg.deliveryId,
18774
+ ...traceparent ? { traceparent } : {}
18775
+ };
18776
+ this.connection.send(ack);
18777
+ }
17456
18778
  async startAgentFromMessage(msg) {
17457
- this.observeRuntimeContext(msg.config);
17458
- const agentCredential = await this.mintRunnerCredential(msg.agentId, msg.config);
17459
- const config = { ...msg.config, agentCredentialKey: agentCredential.apiKey, agentCredentialId: agentCredential.credentialId };
17460
- await this.agentManager.startAgent(
17461
- msg.agentId,
17462
- config,
17463
- msg.wakeMessage,
17464
- msg.unreadSummary,
17465
- msg.resumePrompt,
17466
- msg.launchId,
17467
- msg.wakeMessageTransient ?? false
17468
- );
18779
+ this.coreStartingAgentIds.add(msg.agentId);
18780
+ let wakeDeliveryAck = null;
18781
+ let replayDeliveries = [];
18782
+ try {
18783
+ this.observeRuntimeContext(msg.config);
18784
+ const agentCredential = await this.mintRunnerCredential(msg.agentId, msg.config);
18785
+ const config = { ...msg.config, agentCredentialKey: agentCredential.apiKey, agentCredentialId: agentCredential.credentialId };
18786
+ const pendingDeliveries = this.coreStartPendingDeliveries.get(msg.agentId) || [];
18787
+ this.coreStartPendingDeliveries.delete(msg.agentId);
18788
+ let wakeMessage = msg.wakeMessage;
18789
+ let wakeMessageTransient = msg.wakeMessageTransient ?? false;
18790
+ replayDeliveries = [...pendingDeliveries];
18791
+ if (!wakeMessage) {
18792
+ const wakeIndex = replayDeliveries.findIndex((delivery) => delivery.transient !== true);
18793
+ if (wakeIndex >= 0) {
18794
+ const [wakeDelivery] = replayDeliveries.splice(wakeIndex, 1);
18795
+ if (wakeDelivery) {
18796
+ wakeDeliveryAck = wakeDelivery;
18797
+ wakeMessage = wakeDelivery.message;
18798
+ wakeMessageTransient = wakeDelivery.transient ?? false;
18799
+ }
18800
+ }
18801
+ }
18802
+ await this.agentManager.startAgent(
18803
+ msg.agentId,
18804
+ config,
18805
+ wakeMessage,
18806
+ msg.unreadSummary,
18807
+ msg.resumePrompt,
18808
+ msg.launchId,
18809
+ wakeMessageTransient
18810
+ );
18811
+ this.coreStartingAgentIds.delete(msg.agentId);
18812
+ if (wakeDeliveryAck) {
18813
+ this.sendDeliveryAck(wakeDeliveryAck);
18814
+ }
18815
+ for (const delivery of replayDeliveries) {
18816
+ this.handleMessage(delivery);
18817
+ }
18818
+ } catch (err) {
18819
+ this.coreStartPendingDeliveries.delete(msg.agentId);
18820
+ throw err;
18821
+ } finally {
18822
+ this.coreStartingAgentIds.delete(msg.agentId);
18823
+ }
17469
18824
  }
17470
18825
  handleMessage(msg) {
17471
18826
  const summary = summarizeIncomingMessage(msg);
@@ -17520,6 +18875,14 @@ var DaemonCore = class {
17520
18875
  logger.info(`[Agent ${msg.agentId}] Delivery received (seq=${msg.seq}, from=@${msg.message.sender_name}, target=${formatChannelTarget(msg)})`);
17521
18876
  try {
17522
18877
  span.addEvent("daemon.receive", { seq: msg.seq, deliveryId: msg.deliveryId });
18878
+ if (this.coreStartingAgentIds.has(msg.agentId)) {
18879
+ const pending = this.coreStartPendingDeliveries.get(msg.agentId) || [];
18880
+ pending.push(msg);
18881
+ this.coreStartPendingDeliveries.set(msg.agentId, pending);
18882
+ span.addEvent("daemon.delivery.buffered_for_start", { pending_count: pending.length });
18883
+ span.end("ok", { attrs: { outcome: "buffered-for-start", pending_count: pending.length } });
18884
+ break;
18885
+ }
17523
18886
  const acceptedOrPromise = this.agentManager.deliverMessage(msg.agentId, msg.message, {
17524
18887
  deliveryId: msg.deliveryId,
17525
18888
  transient: msg.transient ?? false
@@ -17532,13 +18895,7 @@ var DaemonCore = class {
17532
18895
  }
17533
18896
  const ackSeq = msg.seq > 0 ? msg.seq : msg.message.seq ?? 0;
17534
18897
  span.addEvent("daemon.ack.sent", { seq: ackSeq });
17535
- this.connection.send({
17536
- type: "agent:deliver:ack",
17537
- agentId: msg.agentId,
17538
- seq: ackSeq,
17539
- traceparent: formatTraceparent(span.context),
17540
- deliveryId: msg.deliveryId
17541
- });
18898
+ this.sendDeliveryAck(msg, formatTraceparent(span.context));
17542
18899
  span.end("ok", { attrs: { outcome: "ack-sent", ackSeq, deliveryId: msg.deliveryId } });
17543
18900
  }, (err) => {
17544
18901
  logger.error(`[Agent ${msg.agentId}] Delivery handling failed`, err);
@@ -17902,6 +19259,8 @@ var DaemonCore = class {
17902
19259
 
17903
19260
  export {
17904
19261
  subscribeDaemonLogs,
19262
+ DAEMON_API_KEY_ENV,
19263
+ scrubDaemonAuthEnv,
17905
19264
  resolveWorkspaceDirectoryPath,
17906
19265
  scanWorkspaceDirectories,
17907
19266
  deleteWorkspaceDirectory,