@botiverse/raft-daemon 0.63.7 → 0.64.0

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,16 +11,488 @@ 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_API_KEY_ENV_KEYS_GENERATED = {
16
+ "deepseek": "DEEPSEEK_API_KEY",
17
+ "minimax": "MINIMAX_API_KEY",
18
+ "minimax-cn": "MINIMAX_CN_API_KEY",
19
+ "zai": "ZAI_API_KEY",
20
+ "zai-coding-cn": "ZAI_CODING_CN_API_KEY",
21
+ "moonshotai": "MOONSHOT_API_KEY",
22
+ "moonshotai-cn": "MOONSHOT_API_KEY",
23
+ "kimi-coding": "KIMI_API_KEY",
24
+ "openrouter": "OPENROUTER_API_KEY",
25
+ "openai": "OPENAI_API_KEY",
26
+ "anthropic": "ANTHROPIC_API_KEY",
27
+ "google": "GEMINI_API_KEY",
28
+ "xai": "XAI_API_KEY",
29
+ "xiaomi": "XIAOMI_API_KEY"
30
+ };
31
+ var PI_BUILTIN_PROVIDER_BLOCKED_HOST_ENV_KEYS_GENERATED = {
32
+ "deepseek": ["DEEPSEEK_API_KEY"],
33
+ "minimax": ["MINIMAX_API_KEY"],
34
+ "minimax-cn": ["MINIMAX_CN_API_KEY"],
35
+ "zai": ["ZAI_API_KEY"],
36
+ "zai-coding-cn": ["ZAI_CODING_CN_API_KEY"],
37
+ "moonshotai": ["MOONSHOT_API_KEY"],
38
+ "moonshotai-cn": ["MOONSHOT_API_KEY"],
39
+ "kimi-coding": ["KIMI_API_KEY"],
40
+ "openrouter": ["OPENROUTER_API_KEY"],
41
+ "openai": ["OPENAI_API_KEY"],
42
+ "anthropic": ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
43
+ "google": ["GEMINI_API_KEY"],
44
+ "xai": ["XAI_API_KEY"],
45
+ "xiaomi": ["XIAOMI_API_KEY"]
46
+ };
47
+ var PI_BUILTIN_PROVIDER_MODELS_GENERATED = {
48
+ "deepseek": [
49
+ { id: "deepseek/deepseek-v4-pro", label: "DeepSeek V4 Pro" },
50
+ { id: "deepseek/deepseek-v4-flash", label: "DeepSeek V4 Flash" }
51
+ ],
52
+ "minimax": [
53
+ { id: "minimax/MiniMax-M2.7", label: "MiniMax-M2.7" },
54
+ { id: "minimax/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" },
55
+ { id: "minimax/MiniMax-M3", label: "MiniMax-M3" }
56
+ ],
57
+ "minimax-cn": [
58
+ { id: "minimax-cn/MiniMax-M2.7", label: "MiniMax-M2.7" },
59
+ { id: "minimax-cn/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" },
60
+ { id: "minimax-cn/MiniMax-M3", label: "MiniMax-M3" }
61
+ ],
62
+ "zai": [
63
+ { id: "zai/glm-5.1", label: "GLM-5.1" },
64
+ { id: "zai/glm-4.5-air", label: "GLM-4.5-Air" },
65
+ { id: "zai/glm-4.7", label: "GLM-4.7" },
66
+ { id: "zai/glm-5-turbo", label: "GLM-5-Turbo" },
67
+ { id: "zai/glm-5.2", label: "GLM-5.2" },
68
+ { id: "zai/glm-5v-turbo", label: "GLM-5V-Turbo" }
69
+ ],
70
+ "zai-coding-cn": [
71
+ { id: "zai-coding-cn/glm-5.1", label: "GLM-5.1" },
72
+ { id: "zai-coding-cn/glm-4.5-air", label: "GLM-4.5-Air" },
73
+ { id: "zai-coding-cn/glm-4.7", label: "GLM-4.7" },
74
+ { id: "zai-coding-cn/glm-5-turbo", label: "GLM-5-Turbo" },
75
+ { id: "zai-coding-cn/glm-5.2", label: "GLM-5.2" },
76
+ { id: "zai-coding-cn/glm-5v-turbo", label: "GLM-5V-Turbo" }
77
+ ],
78
+ "moonshotai": [
79
+ { id: "moonshotai/kimi-k2.6", label: "Kimi K2.6" },
80
+ { id: "moonshotai/kimi-k2-0711-preview", label: "Kimi K2 0711" },
81
+ { id: "moonshotai/kimi-k2-0905-preview", label: "Kimi K2 0905" },
82
+ { id: "moonshotai/kimi-k2-thinking", label: "Kimi K2 Thinking" },
83
+ { id: "moonshotai/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
84
+ { id: "moonshotai/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
85
+ { id: "moonshotai/kimi-k2.5", label: "Kimi K2.5" },
86
+ { id: "moonshotai/kimi-k2.7-code", label: "Kimi K2.7 Code" },
87
+ { id: "moonshotai/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" }
88
+ ],
89
+ "moonshotai-cn": [
90
+ { id: "moonshotai-cn/kimi-k2.6", label: "Kimi K2.6" },
91
+ { id: "moonshotai-cn/kimi-k2-0711-preview", label: "Kimi K2 0711" },
92
+ { id: "moonshotai-cn/kimi-k2-0905-preview", label: "Kimi K2 0905" },
93
+ { id: "moonshotai-cn/kimi-k2-thinking", label: "Kimi K2 Thinking" },
94
+ { id: "moonshotai-cn/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
95
+ { id: "moonshotai-cn/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
96
+ { id: "moonshotai-cn/kimi-k2.5", label: "Kimi K2.5" },
97
+ { id: "moonshotai-cn/kimi-k2.7-code", label: "Kimi K2.7 Code" },
98
+ { id: "moonshotai-cn/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" }
99
+ ],
100
+ "kimi-coding": [
101
+ { id: "kimi-coding/kimi-for-coding", label: "Kimi For Coding" },
102
+ { id: "kimi-coding/k2p7", label: "Kimi K2.7 Code" },
103
+ { id: "kimi-coding/kimi-k2-thinking", label: "Kimi K2 Thinking" }
104
+ ],
105
+ "openrouter": [
106
+ { id: "openrouter/moonshotai/kimi-k2.6", label: "MoonshotAI: Kimi K2.6" },
107
+ { id: "openrouter/ai21/jamba-large-1.7", label: "AI21: Jamba Large 1.7" },
108
+ { id: "openrouter/amazon/nova-2-lite-v1", label: "Amazon: Nova 2 Lite" },
109
+ { id: "openrouter/amazon/nova-lite-v1", label: "Amazon: Nova Lite 1.0" },
110
+ { id: "openrouter/amazon/nova-micro-v1", label: "Amazon: Nova Micro 1.0" },
111
+ { id: "openrouter/amazon/nova-premier-v1", label: "Amazon: Nova Premier 1.0" },
112
+ { id: "openrouter/amazon/nova-pro-v1", label: "Amazon: Nova Pro 1.0" },
113
+ { id: "openrouter/anthropic/claude-3-haiku", label: "Anthropic: Claude 3 Haiku" },
114
+ { id: "openrouter/anthropic/claude-3.5-haiku", label: "Anthropic: Claude 3.5 Haiku" },
115
+ { id: "openrouter/anthropic/claude-fable-5", label: "Anthropic: Claude Fable 5" },
116
+ { id: "openrouter/anthropic/claude-haiku-4.5", label: "Anthropic: Claude Haiku 4.5" },
117
+ { id: "openrouter/anthropic/claude-opus-4", label: "Anthropic: Claude Opus 4" },
118
+ { id: "openrouter/anthropic/claude-opus-4.1", label: "Anthropic: Claude Opus 4.1" },
119
+ { id: "openrouter/anthropic/claude-opus-4.5", label: "Anthropic: Claude Opus 4.5" },
120
+ { id: "openrouter/anthropic/claude-opus-4.6", label: "Anthropic: Claude Opus 4.6" },
121
+ { id: "openrouter/anthropic/claude-opus-4.6-fast", label: "Anthropic: Claude Opus 4.6 (Fast)" },
122
+ { id: "openrouter/anthropic/claude-opus-4.7", label: "Anthropic: Claude Opus 4.7" },
123
+ { id: "openrouter/anthropic/claude-opus-4.7-fast", label: "Anthropic: Claude Opus 4.7 (Fast)" },
124
+ { id: "openrouter/anthropic/claude-opus-4.8", label: "Anthropic: Claude Opus 4.8" },
125
+ { id: "openrouter/anthropic/claude-opus-4.8-fast", label: "Anthropic: Claude Opus 4.8 (Fast)" },
126
+ { id: "openrouter/anthropic/claude-sonnet-4", label: "Anthropic: Claude Sonnet 4" },
127
+ { id: "openrouter/anthropic/claude-sonnet-4.5", label: "Anthropic: Claude Sonnet 4.5" },
128
+ { id: "openrouter/anthropic/claude-sonnet-4.6", label: "Anthropic: Claude Sonnet 4.6" },
129
+ { id: "openrouter/arcee-ai/trinity-large-thinking", label: "Arcee AI: Trinity Large Thinking" },
130
+ { id: "openrouter/arcee-ai/trinity-mini", label: "Arcee AI: Trinity Mini" },
131
+ { id: "openrouter/arcee-ai/virtuoso-large", label: "Arcee AI: Virtuoso Large" },
132
+ { id: "openrouter/auto", label: "Auto" },
133
+ { id: "openrouter/bytedance-seed/seed-1.6", label: "ByteDance Seed: Seed 1.6" },
134
+ { id: "openrouter/bytedance-seed/seed-1.6-flash", label: "ByteDance Seed: Seed 1.6 Flash" },
135
+ { id: "openrouter/bytedance-seed/seed-2.0-lite", label: "ByteDance Seed: Seed-2.0-Lite" },
136
+ { id: "openrouter/bytedance-seed/seed-2.0-mini", label: "ByteDance Seed: Seed-2.0-Mini" },
137
+ { id: "openrouter/cohere/command-r-08-2024", label: "Cohere: Command R (08-2024)" },
138
+ { id: "openrouter/cohere/command-r-plus-08-2024", label: "Cohere: Command R+ (08-2024)" },
139
+ { id: "openrouter/cohere/north-mini-code:free", label: "Cohere: North Mini Code (free)" },
140
+ { id: "openrouter/deepseek/deepseek-chat", label: "DeepSeek: DeepSeek V3" },
141
+ { id: "openrouter/deepseek/deepseek-chat-v3-0324", label: "DeepSeek: DeepSeek V3 0324" },
142
+ { id: "openrouter/deepseek/deepseek-chat-v3.1", label: "DeepSeek: DeepSeek V3.1" },
143
+ { id: "openrouter/deepseek/deepseek-r1", label: "DeepSeek: R1" },
144
+ { id: "openrouter/deepseek/deepseek-r1-0528", label: "DeepSeek: R1 0528" },
145
+ { id: "openrouter/deepseek/deepseek-v3.1-terminus", label: "DeepSeek: DeepSeek V3.1 Terminus" },
146
+ { id: "openrouter/deepseek/deepseek-v3.2", label: "DeepSeek: DeepSeek V3.2" },
147
+ { id: "openrouter/deepseek/deepseek-v3.2-exp", label: "DeepSeek: DeepSeek V3.2 Exp" },
148
+ { id: "openrouter/deepseek/deepseek-v4-flash", label: "DeepSeek: DeepSeek V4 Flash" },
149
+ { id: "openrouter/deepseek/deepseek-v4-pro", label: "DeepSeek: DeepSeek V4 Pro" },
150
+ { id: "openrouter/essentialai/rnj-1-instruct", label: "EssentialAI: Rnj 1 Instruct" },
151
+ { id: "openrouter/google/gemini-2.5-flash", label: "Google: Gemini 2.5 Flash" },
152
+ { id: "openrouter/google/gemini-2.5-flash-lite", label: "Google: Gemini 2.5 Flash Lite" },
153
+ { id: "openrouter/google/gemini-2.5-flash-lite-preview-09-2025", label: "Google: Gemini 2.5 Flash Lite Preview 09-2025" },
154
+ { id: "openrouter/google/gemini-2.5-pro", label: "Google: Gemini 2.5 Pro" },
155
+ { id: "openrouter/google/gemini-2.5-pro-preview", label: "Google: Gemini 2.5 Pro Preview 06-05" },
156
+ { id: "openrouter/google/gemini-2.5-pro-preview-05-06", label: "Google: Gemini 2.5 Pro Preview 05-06" },
157
+ { id: "openrouter/google/gemini-3-flash-preview", label: "Google: Gemini 3 Flash Preview" },
158
+ { id: "openrouter/google/gemini-3-pro-image", label: "Google: Nano Banana Pro (Gemini 3 Pro Image)" },
159
+ { id: "openrouter/google/gemini-3.1-flash-lite", label: "Google: Gemini 3.1 Flash Lite" },
160
+ { id: "openrouter/google/gemini-3.1-flash-lite-preview", label: "Google: Gemini 3.1 Flash Lite Preview" },
161
+ { id: "openrouter/google/gemini-3.1-pro-preview", label: "Google: Gemini 3.1 Pro Preview" },
162
+ { id: "openrouter/google/gemini-3.1-pro-preview-customtools", label: "Google: Gemini 3.1 Pro Preview Custom Tools" },
163
+ { id: "openrouter/google/gemini-3.5-flash", label: "Google: Gemini 3.5 Flash" },
164
+ { id: "openrouter/google/gemma-3-12b-it", label: "Google: Gemma 3 12B" },
165
+ { id: "openrouter/google/gemma-3-27b-it", label: "Google: Gemma 3 27B" },
166
+ { id: "openrouter/google/gemma-4-26b-a4b-it", label: "Google: Gemma 4 26B A4B " },
167
+ { id: "openrouter/google/gemma-4-26b-a4b-it:free", label: "Google: Gemma 4 26B A4B (free)" },
168
+ { id: "openrouter/google/gemma-4-31b-it", label: "Google: Gemma 4 31B" },
169
+ { id: "openrouter/google/gemma-4-31b-it:free", label: "Google: Gemma 4 31B (free)" },
170
+ { id: "openrouter/ibm-granite/granite-4.1-8b", label: "IBM: Granite 4.1 8B" },
171
+ { id: "openrouter/inception/mercury-2", label: "Inception: Mercury 2" },
172
+ { id: "openrouter/inclusionai/ling-2.6-1t", label: "inclusionAI: Ling-2.6-1T" },
173
+ { id: "openrouter/inclusionai/ling-2.6-flash", label: "inclusionAI: Ling-2.6-flash" },
174
+ { id: "openrouter/inclusionai/ring-2.6-1t", label: "inclusionAI: Ring-2.6-1T" },
175
+ { id: "openrouter/kwaipilot/kat-coder-pro-v2", label: "Kwaipilot: KAT-Coder-Pro V2" },
176
+ { id: "openrouter/liquid/lfm-2.5-1.2b-thinking:free", label: "LiquidAI: LFM2.5-1.2B-Thinking (free)" },
177
+ { id: "openrouter/meta-llama/llama-3.1-70b-instruct", label: "Meta: Llama 3.1 70B Instruct" },
178
+ { id: "openrouter/meta-llama/llama-3.1-8b-instruct", label: "Meta: Llama 3.1 8B Instruct" },
179
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct", label: "Meta: Llama 3.3 70B Instruct" },
180
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct:free", label: "Meta: Llama 3.3 70B Instruct (free)" },
181
+ { id: "openrouter/meta-llama/llama-4-maverick", label: "Meta: Llama 4 Maverick" },
182
+ { id: "openrouter/meta-llama/llama-4-scout", label: "Meta: Llama 4 Scout" },
183
+ { id: "openrouter/minimax/minimax-m1", label: "MiniMax: MiniMax M1" },
184
+ { id: "openrouter/minimax/minimax-m2", label: "MiniMax: MiniMax M2" },
185
+ { id: "openrouter/minimax/minimax-m2.1", label: "MiniMax: MiniMax M2.1" },
186
+ { id: "openrouter/minimax/minimax-m2.5", label: "MiniMax: MiniMax M2.5" },
187
+ { id: "openrouter/minimax/minimax-m2.7", label: "MiniMax: MiniMax M2.7" },
188
+ { id: "openrouter/minimax/minimax-m3", label: "MiniMax: MiniMax M3" },
189
+ { id: "openrouter/mistralai/codestral-2508", label: "Mistral: Codestral 2508" },
190
+ { id: "openrouter/mistralai/devstral-2512", label: "Mistral: Devstral 2 2512" },
191
+ { id: "openrouter/mistralai/ministral-14b-2512", label: "Mistral: Ministral 3 14B 2512" },
192
+ { id: "openrouter/mistralai/ministral-3b-2512", label: "Mistral: Ministral 3 3B 2512" },
193
+ { id: "openrouter/mistralai/ministral-8b-2512", label: "Mistral: Ministral 3 8B 2512" },
194
+ { id: "openrouter/mistralai/mistral-large", label: "Mistral Large" },
195
+ { id: "openrouter/mistralai/mistral-large-2407", label: "Mistral Large 2407" },
196
+ { id: "openrouter/mistralai/mistral-large-2512", label: "Mistral: Mistral Large 3 2512" },
197
+ { id: "openrouter/mistralai/mistral-medium-3", label: "Mistral: Mistral Medium 3" },
198
+ { id: "openrouter/mistralai/mistral-medium-3-5", label: "Mistral: Mistral Medium 3.5" },
199
+ { id: "openrouter/mistralai/mistral-medium-3.1", label: "Mistral: Mistral Medium 3.1" },
200
+ { id: "openrouter/mistralai/mistral-nemo", label: "Mistral: Mistral Nemo" },
201
+ { id: "openrouter/mistralai/mistral-saba", label: "Mistral: Saba" },
202
+ { id: "openrouter/mistralai/mistral-small-2603", label: "Mistral: Mistral Small 4" },
203
+ { id: "openrouter/mistralai/mistral-small-3.2-24b-instruct", label: "Mistral: Mistral Small 3.2 24B" },
204
+ { id: "openrouter/mistralai/mixtral-8x22b-instruct", label: "Mistral: Mixtral 8x22B Instruct" },
205
+ { id: "openrouter/mistralai/voxtral-small-24b-2507", label: "Mistral: Voxtral Small 24B 2507" },
206
+ { id: "openrouter/moonshotai/kimi-k2", label: "MoonshotAI: Kimi K2 0711" },
207
+ { id: "openrouter/moonshotai/kimi-k2-0905", label: "MoonshotAI: Kimi K2 0905" },
208
+ { id: "openrouter/moonshotai/kimi-k2-thinking", label: "MoonshotAI: Kimi K2 Thinking" },
209
+ { id: "openrouter/moonshotai/kimi-k2.5", label: "MoonshotAI: Kimi K2.5" },
210
+ { id: "openrouter/moonshotai/kimi-k2.7-code", label: "MoonshotAI: Kimi K2.7 Code" },
211
+ { id: "openrouter/nex-agi/nex-n2-pro:free", label: "Nex AGI: Nex-N2-Pro (free)" },
212
+ { id: "openrouter/nvidia/llama-3.3-nemotron-super-49b-v1.5", label: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5" },
213
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b", label: "NVIDIA: Nemotron 3 Nano 30B A3B" },
214
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b:free", label: "NVIDIA: Nemotron 3 Nano 30B A3B (free)" },
215
+ { id: "openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", label: "NVIDIA: Nemotron 3 Nano Omni (free)" },
216
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b", label: "NVIDIA: Nemotron 3 Super" },
217
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b:free", label: "NVIDIA: Nemotron 3 Super (free)" },
218
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b", label: "NVIDIA: Nemotron 3 Ultra" },
219
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free", label: "NVIDIA: Nemotron 3 Ultra (free)" },
220
+ { id: "openrouter/nvidia/nemotron-nano-12b-v2-vl:free", label: "NVIDIA: Nemotron Nano 12B 2 VL (free)" },
221
+ { id: "openrouter/nvidia/nemotron-nano-9b-v2:free", label: "NVIDIA: Nemotron Nano 9B V2 (free)" },
222
+ { id: "openrouter/openai/gpt-3.5-turbo", label: "OpenAI: GPT-3.5 Turbo" },
223
+ { id: "openrouter/openai/gpt-3.5-turbo-0613", label: "OpenAI: GPT-3.5 Turbo (older v0613)" },
224
+ { id: "openrouter/openai/gpt-3.5-turbo-16k", label: "OpenAI: GPT-3.5 Turbo 16k" },
225
+ { id: "openrouter/openai/gpt-4", label: "OpenAI: GPT-4" },
226
+ { id: "openrouter/openai/gpt-4-turbo", label: "OpenAI: GPT-4 Turbo" },
227
+ { id: "openrouter/openai/gpt-4-turbo-preview", label: "OpenAI: GPT-4 Turbo Preview" },
228
+ { id: "openrouter/openai/gpt-4.1", label: "OpenAI: GPT-4.1" },
229
+ { id: "openrouter/openai/gpt-4.1-mini", label: "OpenAI: GPT-4.1 Mini" },
230
+ { id: "openrouter/openai/gpt-4.1-nano", label: "OpenAI: GPT-4.1 Nano" },
231
+ { id: "openrouter/openai/gpt-4o", label: "OpenAI: GPT-4o" },
232
+ { id: "openrouter/openai/gpt-4o-2024-05-13", label: "OpenAI: GPT-4o (2024-05-13)" },
233
+ { id: "openrouter/openai/gpt-4o-2024-08-06", label: "OpenAI: GPT-4o (2024-08-06)" },
234
+ { id: "openrouter/openai/gpt-4o-2024-11-20", label: "OpenAI: GPT-4o (2024-11-20)" },
235
+ { id: "openrouter/openai/gpt-4o-mini", label: "OpenAI: GPT-4o-mini" },
236
+ { id: "openrouter/openai/gpt-4o-mini-2024-07-18", label: "OpenAI: GPT-4o-mini (2024-07-18)" },
237
+ { id: "openrouter/openai/gpt-5", label: "OpenAI: GPT-5" },
238
+ { id: "openrouter/openai/gpt-5-codex", label: "OpenAI: GPT-5 Codex" },
239
+ { id: "openrouter/openai/gpt-5-mini", label: "OpenAI: GPT-5 Mini" },
240
+ { id: "openrouter/openai/gpt-5-nano", label: "OpenAI: GPT-5 Nano" },
241
+ { id: "openrouter/openai/gpt-5-pro", label: "OpenAI: GPT-5 Pro" },
242
+ { id: "openrouter/openai/gpt-5.1", label: "OpenAI: GPT-5.1" },
243
+ { id: "openrouter/openai/gpt-5.1-chat", label: "OpenAI: GPT-5.1 Chat" },
244
+ { id: "openrouter/openai/gpt-5.1-codex", label: "OpenAI: GPT-5.1-Codex" },
245
+ { id: "openrouter/openai/gpt-5.1-codex-max", label: "OpenAI: GPT-5.1-Codex-Max" },
246
+ { id: "openrouter/openai/gpt-5.1-codex-mini", label: "OpenAI: GPT-5.1-Codex-Mini" },
247
+ { id: "openrouter/openai/gpt-5.2", label: "OpenAI: GPT-5.2" },
248
+ { id: "openrouter/openai/gpt-5.2-chat", label: "OpenAI: GPT-5.2 Chat" },
249
+ { id: "openrouter/openai/gpt-5.2-codex", label: "OpenAI: GPT-5.2-Codex" },
250
+ { id: "openrouter/openai/gpt-5.2-pro", label: "OpenAI: GPT-5.2 Pro" },
251
+ { id: "openrouter/openai/gpt-5.3-chat", label: "OpenAI: GPT-5.3 Chat" },
252
+ { id: "openrouter/openai/gpt-5.3-codex", label: "OpenAI: GPT-5.3-Codex" },
253
+ { id: "openrouter/openai/gpt-5.4", label: "OpenAI: GPT-5.4" },
254
+ { id: "openrouter/openai/gpt-5.4-mini", label: "OpenAI: GPT-5.4 Mini" },
255
+ { id: "openrouter/openai/gpt-5.4-nano", label: "OpenAI: GPT-5.4 Nano" },
256
+ { id: "openrouter/openai/gpt-5.4-pro", label: "OpenAI: GPT-5.4 Pro" },
257
+ { id: "openrouter/openai/gpt-5.5", label: "OpenAI: GPT-5.5" },
258
+ { id: "openrouter/openai/gpt-5.5-pro", label: "OpenAI: GPT-5.5 Pro" },
259
+ { id: "openrouter/openai/gpt-audio", label: "OpenAI: GPT Audio" },
260
+ { id: "openrouter/openai/gpt-audio-mini", label: "OpenAI: GPT Audio Mini" },
261
+ { id: "openrouter/openai/gpt-chat-latest", label: "OpenAI: GPT Chat Latest" },
262
+ { id: "openrouter/openai/gpt-oss-120b", label: "OpenAI: gpt-oss-120b" },
263
+ { id: "openrouter/openai/gpt-oss-120b:free", label: "OpenAI: gpt-oss-120b (free)" },
264
+ { id: "openrouter/openai/gpt-oss-20b", label: "OpenAI: gpt-oss-20b" },
265
+ { id: "openrouter/openai/gpt-oss-20b:free", label: "OpenAI: gpt-oss-20b (free)" },
266
+ { id: "openrouter/openai/gpt-oss-safeguard-20b", label: "OpenAI: gpt-oss-safeguard-20b" },
267
+ { id: "openrouter/openai/o1", label: "OpenAI: o1" },
268
+ { id: "openrouter/openai/o3", label: "OpenAI: o3" },
269
+ { id: "openrouter/openai/o3-deep-research", label: "OpenAI: o3 Deep Research" },
270
+ { id: "openrouter/openai/o3-mini", label: "OpenAI: o3 Mini" },
271
+ { id: "openrouter/openai/o3-mini-high", label: "OpenAI: o3 Mini High" },
272
+ { id: "openrouter/openai/o3-pro", label: "OpenAI: o3 Pro" },
273
+ { id: "openrouter/openai/o4-mini", label: "OpenAI: o4 Mini" },
274
+ { id: "openrouter/openai/o4-mini-deep-research", label: "OpenAI: o4 Mini Deep Research" },
275
+ { id: "openrouter/openai/o4-mini-high", label: "OpenAI: o4 Mini High" },
276
+ { id: "openrouter/openrouter/auto", label: "Auto Router" },
277
+ { id: "openrouter/openrouter/free", label: "Free Models Router" },
278
+ { id: "openrouter/openrouter/fusion", label: "OpenRouter: Fusion" },
279
+ { id: "openrouter/openrouter/owl-alpha", label: "Owl Alpha" },
280
+ { id: "openrouter/poolside/laguna-m.1", label: "Poolside: Laguna M.1" },
281
+ { id: "openrouter/poolside/laguna-m.1:free", label: "Poolside: Laguna M.1 (free)" },
282
+ { id: "openrouter/poolside/laguna-xs.2", label: "Poolside: Laguna XS.2" },
283
+ { id: "openrouter/poolside/laguna-xs.2:free", label: "Poolside: Laguna XS.2 (free)" },
284
+ { id: "openrouter/prime-intellect/intellect-3", label: "Prime Intellect: INTELLECT-3" },
285
+ { id: "openrouter/qwen/qwen-2.5-72b-instruct", label: "Qwen2.5 72B Instruct" },
286
+ { id: "openrouter/qwen/qwen-2.5-7b-instruct", label: "Qwen: Qwen2.5 7B Instruct" },
287
+ { id: "openrouter/qwen/qwen-plus", label: "Qwen: Qwen-Plus" },
288
+ { id: "openrouter/qwen/qwen-plus-2025-07-28", label: "Qwen: Qwen Plus 0728" },
289
+ { id: "openrouter/qwen/qwen-plus-2025-07-28:thinking", label: "Qwen: Qwen Plus 0728 (thinking)" },
290
+ { id: "openrouter/qwen/qwen3-14b", label: "Qwen: Qwen3 14B" },
291
+ { id: "openrouter/qwen/qwen3-235b-a22b", label: "Qwen: Qwen3 235B A22B" },
292
+ { id: "openrouter/qwen/qwen3-235b-a22b-2507", label: "Qwen: Qwen3 235B A22B Instruct 2507" },
293
+ { id: "openrouter/qwen/qwen3-235b-a22b-thinking-2507", label: "Qwen: Qwen3 235B A22B Thinking 2507" },
294
+ { id: "openrouter/qwen/qwen3-30b-a3b", label: "Qwen: Qwen3 30B A3B" },
295
+ { id: "openrouter/qwen/qwen3-30b-a3b-instruct-2507", label: "Qwen: Qwen3 30B A3B Instruct 2507" },
296
+ { id: "openrouter/qwen/qwen3-30b-a3b-thinking-2507", label: "Qwen: Qwen3 30B A3B Thinking 2507" },
297
+ { id: "openrouter/qwen/qwen3-32b", label: "Qwen: Qwen3 32B" },
298
+ { id: "openrouter/qwen/qwen3-8b", label: "Qwen: Qwen3 8B" },
299
+ { id: "openrouter/qwen/qwen3-coder", label: "Qwen: Qwen3 Coder 480B A35B" },
300
+ { id: "openrouter/qwen/qwen3-coder-30b-a3b-instruct", label: "Qwen: Qwen3 Coder 30B A3B Instruct" },
301
+ { id: "openrouter/qwen/qwen3-coder-flash", label: "Qwen: Qwen3 Coder Flash" },
302
+ { id: "openrouter/qwen/qwen3-coder-next", label: "Qwen: Qwen3 Coder Next" },
303
+ { id: "openrouter/qwen/qwen3-coder-plus", label: "Qwen: Qwen3 Coder Plus" },
304
+ { id: "openrouter/qwen/qwen3-coder:free", label: "Qwen: Qwen3 Coder 480B A35B (free)" },
305
+ { id: "openrouter/qwen/qwen3-max", label: "Qwen: Qwen3 Max" },
306
+ { id: "openrouter/qwen/qwen3-max-thinking", label: "Qwen: Qwen3 Max Thinking" },
307
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct", label: "Qwen: Qwen3 Next 80B A3B Instruct" },
308
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct:free", label: "Qwen: Qwen3 Next 80B A3B Instruct (free)" },
309
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-thinking", label: "Qwen: Qwen3 Next 80B A3B Thinking" },
310
+ { id: "openrouter/qwen/qwen3-vl-235b-a22b-instruct", label: "Qwen: Qwen3 VL 235B A22B Instruct" },
311
+ { id: "openrouter/qwen/qwen3-vl-235b-a22b-thinking", label: "Qwen: Qwen3 VL 235B A22B Thinking" },
312
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-instruct", label: "Qwen: Qwen3 VL 30B A3B Instruct" },
313
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-thinking", label: "Qwen: Qwen3 VL 30B A3B Thinking" },
314
+ { id: "openrouter/qwen/qwen3-vl-32b-instruct", label: "Qwen: Qwen3 VL 32B Instruct" },
315
+ { id: "openrouter/qwen/qwen3-vl-8b-instruct", label: "Qwen: Qwen3 VL 8B Instruct" },
316
+ { id: "openrouter/qwen/qwen3-vl-8b-thinking", label: "Qwen: Qwen3 VL 8B Thinking" },
317
+ { id: "openrouter/qwen/qwen3.5-122b-a10b", label: "Qwen: Qwen3.5-122B-A10B" },
318
+ { id: "openrouter/qwen/qwen3.5-27b", label: "Qwen: Qwen3.5-27B" },
319
+ { id: "openrouter/qwen/qwen3.5-35b-a3b", label: "Qwen: Qwen3.5-35B-A3B" },
320
+ { id: "openrouter/qwen/qwen3.5-397b-a17b", label: "Qwen: Qwen3.5 397B A17B" },
321
+ { id: "openrouter/qwen/qwen3.5-9b", label: "Qwen: Qwen3.5-9B" },
322
+ { id: "openrouter/qwen/qwen3.5-flash-02-23", label: "Qwen: Qwen3.5-Flash" },
323
+ { id: "openrouter/qwen/qwen3.5-plus-02-15", label: "Qwen: Qwen3.5 Plus 2026-02-15" },
324
+ { id: "openrouter/qwen/qwen3.5-plus-20260420", label: "Qwen: Qwen3.5 Plus 2026-04-20" },
325
+ { id: "openrouter/qwen/qwen3.6-27b", label: "Qwen: Qwen3.6 27B" },
326
+ { id: "openrouter/qwen/qwen3.6-35b-a3b", label: "Qwen: Qwen3.6 35B A3B" },
327
+ { id: "openrouter/qwen/qwen3.6-flash", label: "Qwen: Qwen3.6 Flash" },
328
+ { id: "openrouter/qwen/qwen3.6-max-preview", label: "Qwen: Qwen3.6 Max Preview" },
329
+ { id: "openrouter/qwen/qwen3.6-plus", label: "Qwen: Qwen3.6 Plus" },
330
+ { id: "openrouter/qwen/qwen3.7-max", label: "Qwen: Qwen3.7 Max" },
331
+ { id: "openrouter/qwen/qwen3.7-plus", label: "Qwen: Qwen3.7 Plus" },
332
+ { id: "openrouter/rekaai/reka-edge", label: "Reka Edge" },
333
+ { id: "openrouter/relace/relace-search", label: "Relace: Relace Search" },
334
+ { id: "openrouter/sao10k/l3.1-euryale-70b", label: "Sao10K: Llama 3.1 Euryale 70B v2.2" },
335
+ { id: "openrouter/stepfun/step-3.5-flash", label: "StepFun: Step 3.5 Flash" },
336
+ { id: "openrouter/stepfun/step-3.7-flash", label: "StepFun: Step 3.7 Flash" },
337
+ { id: "openrouter/tencent/hy3-preview", label: "Tencent: Hy3 preview" },
338
+ { id: "openrouter/thedrummer/rocinante-12b", label: "TheDrummer: Rocinante 12B" },
339
+ { id: "openrouter/thedrummer/unslopnemo-12b", label: "TheDrummer: UnslopNemo 12B" },
340
+ { id: "openrouter/upstage/solar-pro-3", label: "Upstage: Solar Pro 3" },
341
+ { id: "openrouter/x-ai/grok-4.20", label: "xAI: Grok 4.20" },
342
+ { id: "openrouter/x-ai/grok-4.3", label: "xAI: Grok 4.3" },
343
+ { id: "openrouter/x-ai/grok-build-0.1", label: "xAI: Grok Build 0.1" },
344
+ { id: "openrouter/xiaomi/mimo-v2.5", label: "Xiaomi: MiMo-V2.5" },
345
+ { id: "openrouter/xiaomi/mimo-v2.5-pro", label: "Xiaomi: MiMo-V2.5-Pro" },
346
+ { id: "openrouter/z-ai/glm-4.5", label: "Z.ai: GLM 4.5" },
347
+ { id: "openrouter/z-ai/glm-4.5-air", label: "Z.ai: GLM 4.5 Air" },
348
+ { id: "openrouter/z-ai/glm-4.5v", label: "Z.ai: GLM 4.5V" },
349
+ { id: "openrouter/z-ai/glm-4.6", label: "Z.ai: GLM 4.6" },
350
+ { id: "openrouter/z-ai/glm-4.6v", label: "Z.ai: GLM 4.6V" },
351
+ { id: "openrouter/z-ai/glm-4.7", label: "Z.ai: GLM 4.7" },
352
+ { id: "openrouter/z-ai/glm-4.7-flash", label: "Z.ai: GLM 4.7 Flash" },
353
+ { id: "openrouter/z-ai/glm-5", label: "Z.ai: GLM 5" },
354
+ { id: "openrouter/z-ai/glm-5-turbo", label: "Z.ai: GLM 5 Turbo" },
355
+ { id: "openrouter/z-ai/glm-5.1", label: "Z.ai: GLM 5.1" },
356
+ { id: "openrouter/z-ai/glm-5.2", label: "Z.ai: GLM 5.2" },
357
+ { id: "openrouter/~anthropic/claude-fable-latest", label: "Anthropic: Claude Fable Latest" },
358
+ { id: "openrouter/~anthropic/claude-haiku-latest", label: "Anthropic Claude Haiku Latest" },
359
+ { id: "openrouter/~anthropic/claude-opus-latest", label: "Anthropic: Claude Opus Latest" },
360
+ { id: "openrouter/~anthropic/claude-sonnet-latest", label: "Anthropic Claude Sonnet Latest" },
361
+ { id: "openrouter/~google/gemini-flash-latest", label: "Google Gemini Flash Latest" },
362
+ { id: "openrouter/~google/gemini-pro-latest", label: "Google Gemini Pro Latest" },
363
+ { id: "openrouter/~moonshotai/kimi-latest", label: "MoonshotAI Kimi Latest" },
364
+ { id: "openrouter/~openai/gpt-latest", label: "OpenAI GPT Latest" },
365
+ { id: "openrouter/~openai/gpt-mini-latest", label: "OpenAI GPT Mini Latest" }
366
+ ],
367
+ "openai": [
368
+ { id: "openai/gpt-5.4", label: "GPT-5.4" },
369
+ { id: "openai/gpt-4", label: "GPT-4" },
370
+ { id: "openai/gpt-4-turbo", label: "GPT-4 Turbo" },
371
+ { id: "openai/gpt-4.1", label: "GPT-4.1" },
372
+ { id: "openai/gpt-4.1-mini", label: "GPT-4.1 mini" },
373
+ { id: "openai/gpt-4.1-nano", label: "GPT-4.1 nano" },
374
+ { id: "openai/gpt-4o", label: "GPT-4o" },
375
+ { id: "openai/gpt-4o-2024-05-13", label: "GPT-4o (2024-05-13)" },
376
+ { id: "openai/gpt-4o-2024-08-06", label: "GPT-4o (2024-08-06)" },
377
+ { id: "openai/gpt-4o-2024-11-20", label: "GPT-4o (2024-11-20)" },
378
+ { id: "openai/gpt-4o-mini", label: "GPT-4o mini" },
379
+ { id: "openai/gpt-5", label: "GPT-5" },
380
+ { id: "openai/gpt-5-chat-latest", label: "GPT-5 Chat Latest" },
381
+ { id: "openai/gpt-5-codex", label: "GPT-5-Codex" },
382
+ { id: "openai/gpt-5-mini", label: "GPT-5 Mini" },
383
+ { id: "openai/gpt-5-nano", label: "GPT-5 Nano" },
384
+ { id: "openai/gpt-5-pro", label: "GPT-5 Pro" },
385
+ { id: "openai/gpt-5.1", label: "GPT-5.1" },
386
+ { id: "openai/gpt-5.1-chat-latest", label: "GPT-5.1 Chat" },
387
+ { id: "openai/gpt-5.1-codex", label: "GPT-5.1 Codex" },
388
+ { id: "openai/gpt-5.1-codex-max", label: "GPT-5.1 Codex Max" },
389
+ { id: "openai/gpt-5.1-codex-mini", label: "GPT-5.1 Codex mini" },
390
+ { id: "openai/gpt-5.2", label: "GPT-5.2" },
391
+ { id: "openai/gpt-5.2-chat-latest", label: "GPT-5.2 Chat" },
392
+ { id: "openai/gpt-5.2-codex", label: "GPT-5.2 Codex" },
393
+ { id: "openai/gpt-5.2-pro", label: "GPT-5.2 Pro" },
394
+ { id: "openai/gpt-5.3-chat-latest", label: "GPT-5.3 Chat (latest)" },
395
+ { id: "openai/gpt-5.3-codex", label: "GPT-5.3 Codex" },
396
+ { id: "openai/gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark" },
397
+ { id: "openai/gpt-5.4-mini", label: "GPT-5.4 mini" },
398
+ { id: "openai/gpt-5.4-nano", label: "GPT-5.4 nano" },
399
+ { id: "openai/gpt-5.4-pro", label: "GPT-5.4 Pro" },
400
+ { id: "openai/gpt-5.5", label: "GPT-5.5" },
401
+ { id: "openai/gpt-5.5-pro", label: "GPT-5.5 Pro" },
402
+ { id: "openai/o1", label: "o1" },
403
+ { id: "openai/o1-pro", label: "o1-pro" },
404
+ { id: "openai/o3", label: "o3" },
405
+ { id: "openai/o3-deep-research", label: "o3-deep-research" },
406
+ { id: "openai/o3-mini", label: "o3-mini" },
407
+ { id: "openai/o3-pro", label: "o3-pro" },
408
+ { id: "openai/o4-mini", label: "o4-mini" },
409
+ { id: "openai/o4-mini-deep-research", label: "o4-mini-deep-research" }
410
+ ],
411
+ "anthropic": [
412
+ { id: "anthropic/claude-opus-4-8", label: "Claude Opus 4.8" },
413
+ { id: "anthropic/claude-3-5-haiku-20241022", label: "Claude Haiku 3.5" },
414
+ { id: "anthropic/claude-3-5-haiku-latest", label: "Claude Haiku 3.5 (latest)" },
415
+ { id: "anthropic/claude-3-5-sonnet-20240620", label: "Claude Sonnet 3.5" },
416
+ { id: "anthropic/claude-3-5-sonnet-20241022", label: "Claude Sonnet 3.5 v2" },
417
+ { id: "anthropic/claude-3-7-sonnet-20250219", label: "Claude Sonnet 3.7" },
418
+ { id: "anthropic/claude-3-haiku-20240307", label: "Claude Haiku 3" },
419
+ { id: "anthropic/claude-3-opus-20240229", label: "Claude Opus 3" },
420
+ { id: "anthropic/claude-3-sonnet-20240229", label: "Claude Sonnet 3" },
421
+ { id: "anthropic/claude-fable-5", label: "Claude Fable 5" },
422
+ { id: "anthropic/claude-haiku-4-5", label: "Claude Haiku 4.5 (latest)" },
423
+ { id: "anthropic/claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" },
424
+ { id: "anthropic/claude-opus-4-0", label: "Claude Opus 4 (latest)" },
425
+ { id: "anthropic/claude-opus-4-1", label: "Claude Opus 4.1 (latest)" },
426
+ { id: "anthropic/claude-opus-4-1-20250805", label: "Claude Opus 4.1" },
427
+ { id: "anthropic/claude-opus-4-20250514", label: "Claude Opus 4" },
428
+ { id: "anthropic/claude-opus-4-5", label: "Claude Opus 4.5 (latest)" },
429
+ { id: "anthropic/claude-opus-4-5-20251101", label: "Claude Opus 4.5" },
430
+ { id: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" },
431
+ { id: "anthropic/claude-opus-4-7", label: "Claude Opus 4.7" },
432
+ { id: "anthropic/claude-sonnet-4-0", label: "Claude Sonnet 4 (latest)" },
433
+ { id: "anthropic/claude-sonnet-4-20250514", label: "Claude Sonnet 4" },
434
+ { id: "anthropic/claude-sonnet-4-5", label: "Claude Sonnet 4.5 (latest)" },
435
+ { id: "anthropic/claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
436
+ { id: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" }
437
+ ],
438
+ "google": [
439
+ { id: "google/gemini-3.1-pro-preview", label: "Gemini 3.1 Pro Preview" },
440
+ { id: "google/gemini-2.0-flash", label: "Gemini 2.0 Flash" },
441
+ { id: "google/gemini-2.0-flash-lite", label: "Gemini 2.0 Flash-Lite" },
442
+ { id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash" },
443
+ { id: "google/gemini-2.5-flash-lite", label: "Gemini 2.5 Flash-Lite" },
444
+ { id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro" },
445
+ { id: "google/gemini-3-flash-preview", label: "Gemini 3 Flash Preview" },
446
+ { id: "google/gemini-3-pro-preview", label: "Gemini 3 Pro Preview" },
447
+ { id: "google/gemini-3.1-flash-lite", label: "Gemini 3.1 Flash Lite" },
448
+ { id: "google/gemini-3.1-flash-lite-preview", label: "Gemini 3.1 Flash Lite Preview" },
449
+ { id: "google/gemini-3.1-pro-preview-customtools", label: "Gemini 3.1 Pro Preview Custom Tools" },
450
+ { id: "google/gemini-3.5-flash", label: "Gemini 3.5 Flash" },
451
+ { id: "google/gemini-flash-latest", label: "Gemini Flash Latest" },
452
+ { id: "google/gemini-flash-lite-latest", label: "Gemini Flash-Lite Latest" },
453
+ { id: "google/gemma-4-26b-a4b-it", label: "Gemma 4 26B A4B IT" },
454
+ { id: "google/gemma-4-31b-it", label: "Gemma 4 31B IT" },
455
+ { id: "google/gemma-4-E2B-it", label: "Gemma 4 E2B IT" },
456
+ { id: "google/gemma-4-E4B-it", label: "Gemma 4 E4B IT" }
457
+ ],
458
+ "xai": [
459
+ { id: "xai/grok-4.20-0309-reasoning", label: "Grok 4.20 (Reasoning)" },
460
+ { id: "xai/grok-3", label: "Grok 3" },
461
+ { id: "xai/grok-3-fast", label: "Grok 3 Fast" },
462
+ { id: "xai/grok-4.20-0309-non-reasoning", label: "Grok 4.20 (Non-Reasoning)" },
463
+ { id: "xai/grok-4.3", label: "Grok 4.3" },
464
+ { id: "xai/grok-build-0.1", label: "Grok Build 0.1" },
465
+ { id: "xai/grok-code-fast-1", label: "Grok Code Fast 1" }
466
+ ],
467
+ "xiaomi": [
468
+ { id: "xiaomi/mimo-v2.5-pro", label: "MiMo-V2.5-Pro" },
469
+ { id: "xiaomi/mimo-v2-flash", label: "MiMo-V2-Flash" },
470
+ { id: "xiaomi/mimo-v2-omni", label: "MiMo-V2-Omni" },
471
+ { id: "xiaomi/mimo-v2-pro", label: "MiMo-V2-Pro" },
472
+ { id: "xiaomi/mimo-v2.5", label: "MiMo-V2.5" },
473
+ { id: "xiaomi/mimo-v2.5-pro-ultraspeed", label: "MiMo-V2.5-Pro-UltraSpeed" }
474
+ ]
475
+ };
476
+
14
477
  // ../shared/src/generated/runtimeProviderDisplayNames.ts
15
478
  var RUNTIME_PROVIDER_DISPLAY_NAMES = {
16
479
  "anthropic": "Anthropic",
17
480
  "deepseek": "DeepSeek",
18
481
  "fusecode": "FuseCode",
19
- "google": "Google",
482
+ "google": "Google Gemini",
483
+ "kimi-coding": "Kimi For Coding",
484
+ "minimax": "MiniMax",
485
+ "minimax-cn": "MiniMax (China)",
486
+ "moonshotai": "Moonshot AI",
487
+ "moonshotai-cn": "Moonshot AI (China)",
20
488
  "openai": "OpenAI",
21
- "opencode": "OpenCode",
489
+ "opencode": "OpenCode Zen",
22
490
  "opencode-go": "OpenCode Go",
23
- "openrouter": "OpenRouter"
491
+ "openrouter": "OpenRouter",
492
+ "xai": "xAI",
493
+ "xiaomi": "Xiaomi MiMo",
494
+ "zai": "ZAI",
495
+ "zai-coding-cn": "ZAI Coding Plan (China)"
24
496
  };
25
497
 
26
498
  // ../shared/src/runtimeProviderDisplay.ts
@@ -63,6 +535,7 @@ function formatRuntimeProviderLabelToken(token) {
63
535
  nemotron: "Nemotron",
64
536
  omni: "Omni",
65
537
  opus: "Opus",
538
+ openai: "OpenAI",
66
539
  pro: "Pro",
67
540
  sonnet: "Sonnet",
68
541
  super: "Super"
@@ -77,6 +550,187 @@ function formatRuntimeProviderLabelToken(token) {
77
550
  return normalized.charAt(0).toUpperCase() + normalized.slice(1);
78
551
  }
79
552
 
553
+ // ../shared/src/runtimeConfigLegacy.ts
554
+ function isPlainRecord(value) {
555
+ return value !== null && typeof value === "object" && !Array.isArray(value);
556
+ }
557
+ function whitelistRecord(record, knownFields) {
558
+ const known = new Set(knownFields);
559
+ const value = {};
560
+ let droppedCount = 0;
561
+ for (const [key, fieldValue] of Object.entries(record)) {
562
+ if (known.has(key)) {
563
+ value[key] = fieldValue;
564
+ } else {
565
+ droppedCount += 1;
566
+ }
567
+ }
568
+ return { value, droppedCount };
569
+ }
570
+ function sanitizeStoredRuntimeConfig(record, deps) {
571
+ const topLevel = whitelistRecord(record, deps.runtimeConfigFields);
572
+ const value = { ...topLevel.value };
573
+ let droppedCount = topLevel.droppedCount;
574
+ const runtime = typeof value.runtime === "string" ? value.runtime : void 0;
575
+ if (isPlainRecord(value.model)) {
576
+ const model = whitelistRecord(value.model, deps.modelConfigFields);
577
+ value.model = model.value;
578
+ droppedCount += model.droppedCount;
579
+ }
580
+ if (isPlainRecord(value.mode)) {
581
+ const mode = whitelistRecord(value.mode, deps.modeConfigFields);
582
+ value.mode = mode.value;
583
+ droppedCount += mode.droppedCount;
584
+ }
585
+ if (isPlainRecord(value.provider)) {
586
+ const provider = whitelistRecord(value.provider, deps.providerKnownFieldsFor(runtime, value.provider));
587
+ value.provider = provider.value;
588
+ droppedCount += provider.droppedCount;
589
+ }
590
+ return { value, droppedCount };
591
+ }
592
+ function normalizeEnvVars(envVars) {
593
+ if (!isPlainRecord(envVars)) return null;
594
+ const normalized = {};
595
+ for (const [key, value] of Object.entries(envVars)) {
596
+ if (typeof key === "string" && typeof value === "string") {
597
+ normalized[key] = value;
598
+ }
599
+ }
600
+ return Object.keys(normalized).length > 0 ? normalized : null;
601
+ }
602
+ function isPresetRuntimeModel(runtimeModels, runtime, model) {
603
+ return (runtimeModels[runtime] ?? []).some((candidate) => candidate.id === model);
604
+ }
605
+ function hasMapKey(map, key) {
606
+ return Object.prototype.hasOwnProperty.call(map, key);
607
+ }
608
+ function modelConfigFromLegacy(runtimeModels, runtime, model) {
609
+ return isPresetRuntimeModel(runtimeModels, runtime, model) ? { kind: "preset", id: model } : { kind: "custom", name: model };
610
+ }
611
+ function parseProviderConfig(runtime, value, builtinProviderEnvKeys, builtinGatewayProviderEnvKeys, piBuiltinProviderEnvKeys, legacyApiUrl, legacyApiKey) {
612
+ if (runtime === "builtin") {
613
+ const providerId = isPlainRecord(value) && typeof value.providerId === "string" ? value.providerId.trim() : "";
614
+ if (value && isPlainRecord(value) && (value.kind === "preset" || value.kind === "managed") && providerId && typeof value.apiKey === "string" && value.apiKey.trim() && hasMapKey(builtinProviderEnvKeys, providerId)) {
615
+ return { kind: "preset", providerId, apiKey: value.apiKey.trim() };
616
+ }
617
+ if (value && isPlainRecord(value) && value.kind === "gateway" && providerId && typeof value.baseUrl === "string" && value.baseUrl.trim() && typeof value.apiKey === "string" && value.apiKey.trim() && hasMapKey(builtinGatewayProviderEnvKeys, providerId)) {
618
+ return { kind: "gateway", providerId, baseUrl: value.baseUrl.trim(), apiKey: value.apiKey.trim() };
619
+ }
620
+ return void 0;
621
+ }
622
+ if (runtime === "claude") {
623
+ if (!isPlainRecord(value)) return { kind: "default" };
624
+ if (value.kind === "custom" && typeof value.apiUrl === "string" && value.apiUrl.trim() && typeof value.apiKey === "string" && value.apiKey.trim()) {
625
+ return { kind: "custom", apiUrl: value.apiUrl.trim(), apiKey: value.apiKey.trim() };
626
+ }
627
+ if (value.kind === "custom" && legacyApiUrl?.trim() && legacyApiKey?.trim()) {
628
+ return { kind: "custom", apiUrl: legacyApiUrl.trim(), apiKey: legacyApiKey.trim() };
629
+ }
630
+ return { kind: "default" };
631
+ }
632
+ if (runtime === "pi") {
633
+ if (!isPlainRecord(value)) return { kind: "default" };
634
+ if (value.kind === "pi-builtin" && typeof value.providerId === "string" && value.providerId.trim() && typeof value.apiKey === "string" && value.apiKey.trim() && Object.prototype.hasOwnProperty.call(piBuiltinProviderEnvKeys, value.providerId.trim())) {
635
+ return { kind: "pi-builtin", providerId: value.providerId.trim(), apiKey: value.apiKey.trim() };
636
+ }
637
+ return { kind: "default" };
638
+ }
639
+ return void 0;
640
+ }
641
+ function parseModelConfig(runtimeModels, runtime, value, fallback, usesLegacyClaudeCustomProvider, legacyCustomModel) {
642
+ if (!isPlainRecord(value)) return modelConfigFromLegacy(runtimeModels, runtime, fallback);
643
+ if (value.kind === "custom" && typeof value.name === "string" && value.name.trim()) {
644
+ return { kind: "custom", name: value.name.trim() };
645
+ }
646
+ if (value.kind === "preset" && typeof value.id === "string" && value.id.trim() && isPresetRuntimeModel(runtimeModels, runtime, value.id.trim())) {
647
+ return { kind: "preset", id: value.id.trim() };
648
+ }
649
+ if (usesLegacyClaudeCustomProvider && runtime === "claude" && legacyCustomModel?.trim()) {
650
+ return { kind: "custom", name: legacyCustomModel.trim() };
651
+ }
652
+ return modelConfigFromLegacy(runtimeModels, runtime, fallback);
653
+ }
654
+ function parseModeConfig(value) {
655
+ if (!isPlainRecord(value)) return { kind: "default" };
656
+ if (value.kind === "fast") return { kind: "fast" };
657
+ return { kind: "default" };
658
+ }
659
+ function parseCommandConfig(runtime, value) {
660
+ if (runtime !== "claude" || typeof value !== "string") return void 0;
661
+ const command = value.trim();
662
+ return command ? command : void 0;
663
+ }
664
+ function providerKind(config) {
665
+ return config.provider?.kind ?? "none";
666
+ }
667
+ function classifyBuiltInGatewayBaseUrlHost(baseUrl) {
668
+ let hostname = "";
669
+ try {
670
+ hostname = new URL(baseUrl).hostname.toLowerCase();
671
+ } catch {
672
+ return "public";
673
+ }
674
+ if (hostname === "localhost" || hostname === "::1" || hostname === "[::1]" || hostname.startsWith("127.")) return "localhost";
675
+ const ipv4 = hostname.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
676
+ if (ipv4) {
677
+ const [a, b] = ipv4.slice(1).map((part) => Number(part));
678
+ if (a === 10 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168 || a === 169 && b === 254) return "private";
679
+ }
680
+ if (hostname === "0.0.0.0" || hostname === "::" || hostname.startsWith("fc") || hostname.startsWith("fd") || hostname.startsWith("fe80:")) return "private";
681
+ return "public";
682
+ }
683
+ function builtInSelectionTraceAttrs(config) {
684
+ if (config.runtime !== "builtin") return {};
685
+ return {
686
+ provider_id: config.provider.providerId,
687
+ model_kind: config.model.kind,
688
+ ...config.model.kind === "preset" ? { model_id: config.model.id } : {},
689
+ ...config.provider.kind === "gateway" ? {
690
+ base_url_present: true,
691
+ base_url_host_class: classifyBuiltInGatewayBaseUrlHost(config.provider.baseUrl)
692
+ } : {}
693
+ };
694
+ }
695
+ function hydrateLegacyRuntimeConfigWithTrace(input, deps) {
696
+ const stored = isPlainRecord(input.runtimeConfig) && input.runtimeConfig.version === deps.runtimeConfigVersion ? input.runtimeConfig : null;
697
+ const sanitized = stored ? sanitizeStoredRuntimeConfig(stored, deps) : null;
698
+ const storedConfig = sanitized?.value ?? null;
699
+ const runtime = typeof stored?.runtime === "string" && stored.runtime.trim() || typeof input.runtime === "string" && input.runtime.trim() || "claude";
700
+ const fallbackModel = typeof input.model === "string" && input.model.trim() || deps.getDefaultModel(runtime);
701
+ const legacyEnvVars = normalizeEnvVars(input.envVars);
702
+ const storedEnvVars = normalizeEnvVars(storedConfig?.envVars);
703
+ const legacyClaudeApiUrl = runtime === "claude" ? legacyEnvVars?.ANTHROPIC_BASE_URL : void 0;
704
+ const legacyClaudeApiKey = runtime === "claude" ? legacyEnvVars?.ANTHROPIC_API_KEY : void 0;
705
+ const legacyClaudeCustomModel = runtime === "claude" ? legacyEnvVars?.ANTHROPIC_CUSTOM_MODEL_OPTION : void 0;
706
+ const provider = stored ? parseProviderConfig(runtime, storedConfig?.provider, deps.builtinProviderEnvKeys, deps.builtinGatewayProviderEnvKeys, deps.piBuiltinProviderEnvKeys, legacyClaudeApiUrl, legacyClaudeApiKey) : runtime === "claude" && legacyClaudeApiUrl && legacyClaudeApiKey ? { kind: "custom", apiUrl: legacyClaudeApiUrl, apiKey: legacyClaudeApiKey } : runtime === "claude" ? { kind: "default" } : void 0;
707
+ const usesLegacyClaudeCustomProvider = runtime === "claude" && provider?.kind === "custom";
708
+ const command = stored ? parseCommandConfig(runtime, storedConfig?.command) : void 0;
709
+ const config = deps.composeRuntimeConfig({
710
+ runtime,
711
+ provider,
712
+ model: stored ? parseModelConfig(deps.runtimeModels, runtime, storedConfig?.model, fallbackModel, usesLegacyClaudeCustomProvider, legacyClaudeCustomModel) : modelConfigFromLegacy(deps.runtimeModels, runtime, fallbackModel),
713
+ mode: stored ? parseModeConfig(storedConfig?.mode) : { kind: "default" },
714
+ reasoningEffort: storedConfig?.reasoningEffort ?? input.reasoningEffort ?? null,
715
+ // Runtime-owned env vars are legacy launch mirrors for provider/model
716
+ // settings. Strip them from user envVars during hydration so the canonical
717
+ // RuntimeConfig provider/model arms remain the only source for generated
718
+ // launch env.
719
+ envVars: deps.stripControlledRuntimeEnvVars(runtime, stored ? storedEnvVars : legacyEnvVars),
720
+ command
721
+ });
722
+ return {
723
+ config,
724
+ trace: {
725
+ outcome: sanitized && sanitized.droppedCount > 0 ? "legacy_sanitized" : "accepted",
726
+ runtime: config.runtime,
727
+ provider_kind: providerKind(config),
728
+ ...builtInSelectionTraceAttrs(config),
729
+ ...sanitized && sanitized.droppedCount > 0 ? { unknown_fields_dropped_count: sanitized.droppedCount } : {}
730
+ }
731
+ };
732
+ }
733
+
80
734
  // ../shared/src/slockRefs.ts
81
735
  var SLOCK_REF_CHANNEL_NAME_PATTERN = String.raw`[\p{L}\p{N}_-]+`;
82
736
  var SLOCK_REF_USER_NAME_PATTERN = SLOCK_REF_CHANNEL_NAME_PATTERN;
@@ -136,6 +790,7 @@ function projectApmHeldFreshnessEnvelope(input) {
136
790
  outcome: "held",
137
791
  subtype: "freshness",
138
792
  reason: "newer_messages_available",
793
+ decision: input.decision ?? "local_hold",
139
794
  producerFactId: input.producerFactId,
140
795
  available_actions: apmHeldFreshnessAvailableActions(input.action),
141
796
  heldMessages: input.heldMessages,
@@ -154,10 +809,16 @@ function projectApmHeldFreshnessEnvelope(input) {
154
809
  }
155
810
  function projectApmHeldFreshnessActivity(input) {
156
811
  const title = input.action === "send" ? "Send held by freshness check" : input.action === "task_claim" ? "Task claim held by freshness check" : "Task update held by freshness check";
812
+ const messageNoun = input.messageCount === 1 ? "message" : "messages";
813
+ const countLine = input.decision === "syncing_hold" ? `unreviewed synced context for this target: ${input.messageCount} ${messageNoun}` : `new messages: ${input.messageCount} newer ${messageNoun}`;
814
+ const decisionLines = input.decision === "syncing_hold" ? [
815
+ "reason: this target's latest synced context was not yet in your reviewed context",
816
+ input.action === "send" ? "action: review the synced context before sending" : "action: review the synced context, then retry this action"
817
+ ] : ["decision: local hold; review the newer context before retrying"];
157
818
  const text = [
158
819
  input.target ? `target: ${input.target}` : null,
159
- `new messages: ${input.messageCount} newer message${input.messageCount === 1 ? "" : "s"}`,
160
- `decision: ${input.decision === "syncing_hold" ? "syncing hold" : "local hold"}; review the newer context before retrying`
820
+ countLine,
821
+ ...decisionLines
161
822
  ].filter((line) => Boolean(line)).join("\n");
162
823
  return {
163
824
  clauseId: "SMR-006",
@@ -1037,6 +1698,10 @@ function summarizeToolInput(toolName, input) {
1037
1698
  // ../shared/src/attachmentPreview.ts
1038
1699
  var CSV_PREVIEW_MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
1039
1700
 
1701
+ // ../shared/src/brandedIds.ts
1702
+ var asMessageId = (id) => id;
1703
+ var asChannelId = (id) => id;
1704
+
1040
1705
  // ../shared/src/actionCards.ts
1041
1706
  import { z } from "zod";
1042
1707
  var uuidSchema = z.uuid();
@@ -1137,6 +1802,885 @@ var actionCardActionSchema = z.discriminatedUnion("type", [
1137
1802
  integrationUpdateAppRegistrationOperationSchema
1138
1803
  ]);
1139
1804
 
1805
+ // ../shared/src/agentApiContract.ts
1806
+ import { z as z2 } from "zod";
1807
+ var AGENT_API_BASE_PATH = "/internal/agent-api";
1808
+ var optionalStringSchema = z2.string().trim().optional();
1809
+ var optionalStringArraySchema = z2.array(z2.string().trim().min(1)).optional();
1810
+ var optionalBooleanSchema = z2.boolean().optional();
1811
+ var optionalNumberSchema = z2.number().finite().optional();
1812
+ var nullableStringSchema = z2.string().nullable();
1813
+ var nullableNumberSchema = z2.number().finite().nullable();
1814
+ var optionalIsoTimestampSchema = z2.string().datetime().optional();
1815
+ var agentStatusSchema = z2.enum(["active", "inactive", "stopped"]);
1816
+ var reminderStatusSchema = z2.enum(["scheduled", "fired", "canceled"]);
1817
+ var reminderEventTypeSchema = z2.enum(["scheduled", "fired", "snoozed", "updated", "canceled"]);
1818
+ var reasoningEffortSchema = z2.enum(["low", "medium", "high", "xhigh"]);
1819
+ var profileVisibilityMembershipStatusSchema = z2.enum(["active", "removed"]);
1820
+ var passthroughObject = (shape) => z2.object(shape).passthrough();
1821
+ var taskStatusSchema = z2.enum(["todo", "in_progress", "in_review", "done", "closed"]);
1822
+ var agentApiEventsQuerySchema = passthroughObject({
1823
+ since: optionalStringSchema,
1824
+ limit: optionalStringSchema
1825
+ });
1826
+ var agentApiHistoryQuerySchema = passthroughObject({
1827
+ channel: z2.string().trim().min(1),
1828
+ before: optionalStringSchema,
1829
+ after: optionalStringSchema,
1830
+ around: optionalStringSchema,
1831
+ limit: optionalStringSchema
1832
+ });
1833
+ var agentApiMessageSearchQuerySchema = passthroughObject({
1834
+ q: optionalStringSchema,
1835
+ channel: optionalStringSchema,
1836
+ sender: optionalStringSchema,
1837
+ senderId: optionalStringSchema,
1838
+ sort: z2.enum(["relevance", "recent"]).optional(),
1839
+ before: optionalStringSchema,
1840
+ after: optionalStringSchema,
1841
+ limit: optionalStringSchema,
1842
+ offset: optionalStringSchema
1843
+ });
1844
+ var agentApiSendBodySchema = passthroughObject({
1845
+ target: z2.string().optional(),
1846
+ content: z2.string().optional(),
1847
+ attachmentIds: optionalStringArraySchema,
1848
+ idempotencyKey: optionalStringSchema,
1849
+ continue: optionalBooleanSchema,
1850
+ sendDraft: optionalBooleanSchema,
1851
+ continueAnyway: optionalBooleanSchema,
1852
+ draftReholdCount: optionalNumberSchema,
1853
+ draftReplacedExisting: optionalBooleanSchema,
1854
+ seenUpToSeq: optionalNumberSchema
1855
+ });
1856
+ var agentApiMessageResolveParamsSchema = passthroughObject({
1857
+ msgId: z2.string().trim().min(1).transform(asMessageId)
1858
+ });
1859
+ var agentApiMessageReactionParamsSchema = passthroughObject({
1860
+ msgId: z2.string().trim().min(1).transform(asMessageId)
1861
+ });
1862
+ var agentApiMessageReactionBodySchema = passthroughObject({
1863
+ emoji: z2.string().trim().min(1).max(16).refine((value) => !/\s/.test(value), {
1864
+ message: "A single reaction emoji is required"
1865
+ })
1866
+ });
1867
+ var agentApiChannelMembershipParamsSchema = passthroughObject({
1868
+ channelId: z2.string().trim().min(1).transform(asChannelId)
1869
+ });
1870
+ var agentApiChannelMembersQuerySchema = passthroughObject({
1871
+ channel: z2.string().trim().min(1)
1872
+ });
1873
+ var agentApiResolveChannelBodySchema = passthroughObject({
1874
+ target: z2.string().trim().min(1)
1875
+ });
1876
+ var agentApiResolveChannelResponseSchema = passthroughObject({
1877
+ channelId: z2.string().trim().min(1)
1878
+ });
1879
+ var agentApiThreadUnfollowBodySchema = passthroughObject({
1880
+ thread: z2.string().trim().min(1)
1881
+ });
1882
+ var agentApiTaskClaimBodySchema = passthroughObject({
1883
+ channel: z2.string().trim().min(1),
1884
+ task_numbers: z2.array(z2.number().int().positive()).optional(),
1885
+ message_ids: optionalStringArraySchema
1886
+ });
1887
+ var agentApiTaskListQuerySchema = passthroughObject({
1888
+ channel: z2.string().trim().min(1),
1889
+ status: z2.union([taskStatusSchema, z2.literal("all")]).optional()
1890
+ });
1891
+ var agentApiTaskCreateBodySchema = passthroughObject({
1892
+ channel: z2.string().trim().min(1),
1893
+ tasks: z2.array(passthroughObject({
1894
+ title: z2.string().trim().min(1)
1895
+ })).min(1)
1896
+ });
1897
+ var agentApiTaskUnclaimBodySchema = passthroughObject({
1898
+ channel: z2.string().trim().min(1),
1899
+ task_number: z2.number().int().positive()
1900
+ });
1901
+ var agentApiTaskUpdateStatusBodySchema = passthroughObject({
1902
+ channel: z2.string().trim().min(1),
1903
+ task_number: z2.number().int().positive(),
1904
+ status: taskStatusSchema
1905
+ });
1906
+ var agentApiReminderListQuerySchema = passthroughObject({
1907
+ status: optionalStringSchema,
1908
+ all: optionalStringSchema
1909
+ });
1910
+ var agentApiReminderParamsSchema = passthroughObject({
1911
+ reminderId: z2.string().trim().min(1)
1912
+ });
1913
+ var agentApiReminderScheduleBodySchema = passthroughObject({
1914
+ title: z2.string(),
1915
+ fireAt: optionalStringSchema,
1916
+ delaySeconds: optionalNumberSchema,
1917
+ msgId: z2.string().nullable().optional(),
1918
+ payload: z2.unknown().optional(),
1919
+ repeat: optionalStringSchema,
1920
+ tz: optionalStringSchema,
1921
+ channel: optionalStringSchema
1922
+ });
1923
+ var agentApiReminderSnoozeBodySchema = passthroughObject({
1924
+ delaySeconds: z2.number().finite()
1925
+ });
1926
+ var agentApiReminderUpdateBodySchema = passthroughObject({
1927
+ fireAt: optionalStringSchema,
1928
+ delaySeconds: optionalNumberSchema,
1929
+ repeat: optionalStringSchema,
1930
+ title: optionalStringSchema,
1931
+ tz: optionalStringSchema
1932
+ });
1933
+ var agentApiProfileShowQuerySchema = passthroughObject({
1934
+ target: optionalStringSchema
1935
+ });
1936
+ var agentApiProfileUpdateBodySchema = passthroughObject({
1937
+ avatarUrl: optionalStringSchema,
1938
+ displayName: optionalStringSchema,
1939
+ description: optionalStringSchema
1940
+ });
1941
+ var agentApiProfileCreatedAgentSchema = passthroughObject({
1942
+ id: z2.string(),
1943
+ name: z2.string(),
1944
+ displayName: nullableStringSchema,
1945
+ avatarUrl: nullableStringSchema,
1946
+ runtime: z2.string(),
1947
+ status: agentStatusSchema
1948
+ });
1949
+ var agentApiProfileCreatorSchema = z2.union([
1950
+ passthroughObject({
1951
+ type: z2.literal("human"),
1952
+ id: z2.string(),
1953
+ name: z2.string(),
1954
+ displayName: nullableStringSchema,
1955
+ avatarUrl: nullableStringSchema,
1956
+ gravatarHash: z2.string()
1957
+ }),
1958
+ passthroughObject({
1959
+ type: z2.literal("agent"),
1960
+ id: z2.string(),
1961
+ name: z2.string(),
1962
+ displayName: nullableStringSchema,
1963
+ avatarUrl: nullableStringSchema,
1964
+ deletedAt: nullableStringSchema
1965
+ })
1966
+ ]);
1967
+ var agentApiProfileViewSchema = z2.discriminatedUnion("kind", [
1968
+ passthroughObject({
1969
+ kind: z2.literal("human"),
1970
+ id: z2.string(),
1971
+ isSelf: z2.boolean(),
1972
+ name: z2.string(),
1973
+ displayName: nullableStringSchema,
1974
+ description: nullableStringSchema,
1975
+ avatarUrl: nullableStringSchema,
1976
+ email: nullableStringSchema,
1977
+ role: z2.enum(["owner", "admin", "member"]).nullable(),
1978
+ joinedAt: nullableStringSchema,
1979
+ membershipStatus: profileVisibilityMembershipStatusSchema,
1980
+ createdAgents: z2.array(agentApiProfileCreatedAgentSchema)
1981
+ }),
1982
+ passthroughObject({
1983
+ kind: z2.literal("agent"),
1984
+ id: z2.string(),
1985
+ isSelf: z2.boolean(),
1986
+ name: z2.string(),
1987
+ displayName: nullableStringSchema,
1988
+ description: nullableStringSchema,
1989
+ avatarUrl: nullableStringSchema,
1990
+ status: agentStatusSchema,
1991
+ serverRole: z2.enum(["owner", "admin", "member"]).nullable(),
1992
+ runtime: z2.string(),
1993
+ model: z2.string(),
1994
+ reasoningEffort: reasoningEffortSchema.nullable(),
1995
+ executionMode: nullableStringSchema,
1996
+ computerId: nullableStringSchema,
1997
+ computerName: nullableStringSchema,
1998
+ computerHostname: nullableStringSchema,
1999
+ daemonVersion: nullableStringSchema,
2000
+ creator: agentApiProfileCreatorSchema.nullable(),
2001
+ createdAgents: z2.array(agentApiProfileCreatedAgentSchema),
2002
+ createdAt: z2.string(),
2003
+ deletedAt: nullableStringSchema
2004
+ })
2005
+ ]);
2006
+ var agentApiIntegrationLoginBodySchema = passthroughObject({
2007
+ service: z2.string().trim().min(1),
2008
+ scopes: optionalStringArraySchema,
2009
+ target: optionalStringSchema
2010
+ });
2011
+ var agentApiIntegrationAppPrepareBodySchema = passthroughObject({
2012
+ mode: z2.enum(["register", "update"]),
2013
+ target: z2.string().trim().min(1),
2014
+ clientKey: z2.string().trim().min(1),
2015
+ name: optionalStringSchema,
2016
+ description: optionalStringSchema,
2017
+ homepageUrl: optionalStringSchema,
2018
+ returnUrl: optionalStringSchema,
2019
+ agentManifestUrl: optionalStringSchema,
2020
+ scopes: optionalStringArraySchema,
2021
+ unsafeDemoUrlOverride: optionalBooleanSchema,
2022
+ draftHint: optionalStringSchema
2023
+ });
2024
+ var agentApiActionPrepareBodySchema = passthroughObject({
2025
+ target: z2.string().trim().min(1),
2026
+ action: actionCardActionSchema
2027
+ });
2028
+ var agentApiServerInfoResponseSchema = passthroughObject({
2029
+ runtimeContext: passthroughObject({
2030
+ agentId: z2.string(),
2031
+ serverId: z2.string(),
2032
+ machineId: z2.string().nullable().optional(),
2033
+ machineName: z2.string().nullable().optional(),
2034
+ machineHostname: z2.string().nullable().optional(),
2035
+ machineOs: z2.string().nullable().optional(),
2036
+ daemonVersion: z2.string().nullable().optional(),
2037
+ workspacePath: z2.string().nullable().optional()
2038
+ }),
2039
+ serverRole: z2.string().nullable().optional(),
2040
+ serverCapabilities: passthroughObject({}).optional(),
2041
+ channels: z2.array(passthroughObject({
2042
+ id: z2.string().transform(asChannelId),
2043
+ name: z2.string(),
2044
+ joined: z2.boolean()
2045
+ })),
2046
+ agents: z2.array(passthroughObject({
2047
+ name: z2.string()
2048
+ })),
2049
+ humans: z2.array(passthroughObject({
2050
+ name: z2.string()
2051
+ }))
2052
+ });
2053
+ var agentApiMentionActionsPendingQuerySchema = passthroughObject({
2054
+ limit: optionalStringSchema
2055
+ });
2056
+ var agentApiMentionActionEnvelopeSchema = passthroughObject({
2057
+ resolutionId: z2.string()
2058
+ });
2059
+ var agentApiMentionActionsPendingResponseSchema = passthroughObject({
2060
+ pendingMentionActions: z2.array(agentApiMentionActionEnvelopeSchema),
2061
+ has_more: z2.boolean().optional()
2062
+ });
2063
+ var agentApiMentionActionsExecuteBodySchema = passthroughObject({
2064
+ action: z2.enum(["notify", "add"]),
2065
+ resolutionIds: optionalStringArraySchema,
2066
+ ids: optionalStringArraySchema
2067
+ });
2068
+ var agentApiMentionActionsExecuteResponseSchema = passthroughObject({
2069
+ ok: z2.literal(true),
2070
+ action: z2.enum(["notify", "add"]),
2071
+ results: z2.array(agentApiMentionActionEnvelopeSchema)
2072
+ });
2073
+ var agentApiIntegrationServiceSchema = passthroughObject({
2074
+ id: z2.string(),
2075
+ clientId: z2.string(),
2076
+ appType: z2.enum(["server_local", "slock_builtin", "third_party_global"]).optional(),
2077
+ name: z2.string(),
2078
+ description: nullableStringSchema,
2079
+ homepageUrl: nullableStringSchema,
2080
+ returnUrl: nullableStringSchema,
2081
+ agentManifestUrl: nullableStringSchema,
2082
+ agentManifestUrlSource: z2.enum(["explicit", "well_known"]).nullable().optional(),
2083
+ createdAt: z2.string(),
2084
+ updatedAt: z2.string()
2085
+ });
2086
+ var agentApiActiveIntegrationLoginSchema = passthroughObject({
2087
+ id: z2.string(),
2088
+ serviceId: z2.string(),
2089
+ clientId: z2.string(),
2090
+ appType: z2.enum(["server_local", "slock_builtin", "third_party_global"]).optional(),
2091
+ name: z2.string(),
2092
+ description: nullableStringSchema,
2093
+ homepageUrl: nullableStringSchema,
2094
+ returnUrl: nullableStringSchema,
2095
+ agentManifestUrl: nullableStringSchema,
2096
+ agentManifestUrlSource: z2.enum(["explicit", "well_known"]).nullable().optional(),
2097
+ scopes: z2.array(z2.string()),
2098
+ createdAt: z2.string()
2099
+ });
2100
+ var agentApiIntegrationListResponseSchema = passthroughObject({
2101
+ services: z2.array(agentApiIntegrationServiceSchema),
2102
+ activeLogins: z2.array(agentApiActiveIntegrationLoginSchema)
2103
+ });
2104
+ var agentApiIntegrationLoginResponseSchema = passthroughObject({
2105
+ status: z2.enum(["logged_in", "already_logged_in", "approval_required"]),
2106
+ service: agentApiIntegrationServiceSchema,
2107
+ scopes: z2.array(z2.string()),
2108
+ requestId: z2.string(),
2109
+ approval: passthroughObject({
2110
+ requestId: z2.string(),
2111
+ target: nullableStringSchema,
2112
+ actionCardMessageId: nullableStringSchema
2113
+ }).optional()
2114
+ });
2115
+ var agentApiIntegrationAppPrepareResponseSchema = passthroughObject({
2116
+ status: z2.literal("prepared"),
2117
+ mode: z2.enum(["register", "update"]),
2118
+ target: z2.string(),
2119
+ actionCardMessageId: z2.string(),
2120
+ action: z2.discriminatedUnion("type", [
2121
+ integrationRegisterAppOperationSchema,
2122
+ integrationUpdateAppRegistrationOperationSchema
2123
+ ])
2124
+ });
2125
+ var agentApiAttachmentEnvelopeSchema = passthroughObject({
2126
+ id: z2.string(),
2127
+ filename: z2.string()
2128
+ });
2129
+ var agentApiAttachmentUploadResponseSchema = passthroughObject({
2130
+ id: z2.string().trim().min(1),
2131
+ filename: z2.string(),
2132
+ mimeType: nullableStringSchema,
2133
+ sizeBytes: z2.number().int().nonnegative(),
2134
+ thumbnailUrl: nullableStringSchema
2135
+ });
2136
+ var agentApiMessageEnvelopeSchema = passthroughObject({
2137
+ seq: optionalNumberSchema,
2138
+ id: optionalStringSchema,
2139
+ message_id: optionalStringSchema,
2140
+ timestamp: optionalIsoTimestampSchema,
2141
+ createdAt: optionalIsoTimestampSchema,
2142
+ senderType: optionalStringSchema,
2143
+ sender_type: optionalStringSchema,
2144
+ senderName: optionalStringSchema,
2145
+ sender_name: optionalStringSchema,
2146
+ senderDescription: z2.string().nullable().optional(),
2147
+ sender_description: z2.string().nullable().optional(),
2148
+ channel_type: optionalStringSchema,
2149
+ channel_name: optionalStringSchema,
2150
+ parent_channel_type: optionalStringSchema,
2151
+ parent_channel_name: optionalStringSchema,
2152
+ content: optionalStringSchema,
2153
+ attachments: z2.array(agentApiAttachmentEnvelopeSchema).optional(),
2154
+ taskStatus: z2.string().nullable().optional(),
2155
+ task_status: z2.string().nullable().optional(),
2156
+ taskNumber: z2.number().int().positive().nullable().optional(),
2157
+ task_number: z2.number().int().positive().nullable().optional(),
2158
+ taskAssigneeId: z2.string().nullable().optional(),
2159
+ task_assignee_id: z2.string().nullable().optional(),
2160
+ taskAssigneeType: z2.string().nullable().optional(),
2161
+ task_assignee_type: z2.string().nullable().optional(),
2162
+ threadId: z2.string().nullable().optional(),
2163
+ replyCount: z2.number().int().nonnegative().nullable().optional()
2164
+ });
2165
+ var agentApiEventsResponseSchema = passthroughObject({
2166
+ events: z2.array(agentApiMessageEnvelopeSchema),
2167
+ last_seen_msgId: nullableStringSchema,
2168
+ last_seen_seq: nullableNumberSchema,
2169
+ reply_target: nullableStringSchema,
2170
+ pending_notice_ids: z2.array(z2.string()),
2171
+ wake_reason: z2.string().nullable(),
2172
+ has_more: z2.boolean()
2173
+ });
2174
+ var agentApiHistoryResponseSchema = passthroughObject({
2175
+ messages: z2.array(agentApiMessageEnvelopeSchema),
2176
+ has_more: z2.boolean(),
2177
+ has_older: z2.boolean(),
2178
+ has_newer: z2.boolean(),
2179
+ last_read_seq: nullableNumberSchema.optional()
2180
+ });
2181
+ var agentApiHeldFreshnessResponseSchema = passthroughObject({
2182
+ ok: z2.literal(true).optional(),
2183
+ state: z2.literal("held"),
2184
+ outcome: z2.literal("held").optional(),
2185
+ subtype: z2.literal("freshness").optional(),
2186
+ reason: z2.string().optional(),
2187
+ decision: z2.enum(["local_hold", "syncing_hold"]).optional(),
2188
+ producerFactId: optionalStringSchema,
2189
+ available_actions: z2.array(z2.string()).optional(),
2190
+ heldMessages: z2.array(agentApiMessageEnvelopeSchema).optional(),
2191
+ recentUnread: z2.array(agentApiMessageEnvelopeSchema).optional(),
2192
+ newMessageCount: optionalNumberSchema,
2193
+ shownMessageCount: optionalNumberSchema,
2194
+ omittedMessageCount: optionalNumberSchema,
2195
+ mentionAnnotation: passthroughObject({
2196
+ formalMentionCount: z2.number().finite()
2197
+ }).optional(),
2198
+ continueAnywaySuggested: optionalBooleanSchema,
2199
+ seenUpToSeq: optionalNumberSchema,
2200
+ seenUpToMessageId: nullableStringSchema.optional()
2201
+ });
2202
+ var agentApiSendSentResponseSchema = passthroughObject({
2203
+ ok: z2.literal(true),
2204
+ state: z2.literal("sent"),
2205
+ messageId: z2.string(),
2206
+ messageSeq: optionalNumberSchema,
2207
+ recentUnread: z2.array(agentApiMessageEnvelopeSchema).optional(),
2208
+ pendingMentionActions: z2.array(agentApiMessageEnvelopeSchema).optional()
2209
+ });
2210
+ var agentApiSendResponseSchema = z2.discriminatedUnion("state", [
2211
+ agentApiSendSentResponseSchema,
2212
+ agentApiHeldFreshnessResponseSchema
2213
+ ]);
2214
+ var agentApiMessageResolveResponseSchema = passthroughObject({
2215
+ message: agentApiMessageEnvelopeSchema
2216
+ });
2217
+ var agentApiOkResponseSchema = passthroughObject({
2218
+ ok: z2.literal(true)
2219
+ });
2220
+ var agentApiSearchResultSchema = passthroughObject({
2221
+ id: z2.string(),
2222
+ seq: z2.number().int().nonnegative(),
2223
+ channelId: z2.string(),
2224
+ threadId: z2.string().nullable(),
2225
+ parentMessageId: z2.string().nullable(),
2226
+ parentMessageContent: z2.string().nullable(),
2227
+ parentChannelId: z2.string(),
2228
+ parentChannelName: z2.string(),
2229
+ parentChannelType: z2.string(),
2230
+ parentChannelArchivedAt: nullableStringSchema,
2231
+ senderId: z2.string(),
2232
+ senderType: z2.string(),
2233
+ senderName: z2.string(),
2234
+ channelName: z2.string(),
2235
+ channelType: z2.string(),
2236
+ channelArchivedAt: nullableStringSchema,
2237
+ content: z2.string(),
2238
+ snippet: z2.string(),
2239
+ createdAt: z2.string().datetime()
2240
+ });
2241
+ var agentApiMessageSearchResponseSchema = passthroughObject({
2242
+ results: z2.array(agentApiSearchResultSchema),
2243
+ hasMore: z2.boolean()
2244
+ });
2245
+ var agentApiChannelMembersResponseSchema = passthroughObject({
2246
+ channel: passthroughObject({
2247
+ ref: z2.string(),
2248
+ type: z2.string()
2249
+ }),
2250
+ agents: z2.array(passthroughObject({
2251
+ name: z2.string(),
2252
+ status: optionalStringSchema
2253
+ })),
2254
+ humans: z2.array(passthroughObject({
2255
+ name: z2.string(),
2256
+ description: z2.string().nullable().optional(),
2257
+ role: optionalStringSchema
2258
+ }))
2259
+ });
2260
+ var agentApiTaskClaimResultSchema = passthroughObject({
2261
+ taskNumber: z2.number().int().positive().optional(),
2262
+ messageId: optionalStringSchema,
2263
+ success: z2.boolean(),
2264
+ reason: optionalStringSchema
2265
+ });
2266
+ var agentApiTaskClaimSuccessResponseSchema = passthroughObject({
2267
+ results: z2.array(agentApiTaskClaimResultSchema)
2268
+ });
2269
+ var agentApiTaskClaimResponseSchema = z2.union([
2270
+ agentApiTaskClaimSuccessResponseSchema,
2271
+ agentApiHeldFreshnessResponseSchema
2272
+ ]);
2273
+ var agentApiTaskEnvelopeSchema = passthroughObject({
2274
+ taskNumber: z2.number().int().positive().optional(),
2275
+ status: z2.string().optional(),
2276
+ title: optionalStringSchema,
2277
+ claimedByName: z2.string().nullable().optional(),
2278
+ createdByName: z2.string().nullable().optional(),
2279
+ messageId: z2.string().nullable().optional(),
2280
+ isLegacy: optionalBooleanSchema
2281
+ });
2282
+ var agentApiTaskListResponseSchema = passthroughObject({
2283
+ tasks: z2.array(agentApiTaskEnvelopeSchema)
2284
+ });
2285
+ var agentApiCreatedTaskEnvelopeSchema = passthroughObject({
2286
+ taskNumber: z2.number().int().positive(),
2287
+ messageId: z2.string(),
2288
+ title: z2.string()
2289
+ });
2290
+ var agentApiTaskCreateResponseSchema = passthroughObject({
2291
+ tasks: z2.array(agentApiCreatedTaskEnvelopeSchema)
2292
+ });
2293
+ var agentApiTaskUnclaimResponseSchema = passthroughObject({
2294
+ ok: z2.literal(true)
2295
+ });
2296
+ var agentApiTaskUpdateStatusSuccessResponseSchema = passthroughObject({
2297
+ ok: z2.literal(true)
2298
+ });
2299
+ var agentApiTaskUpdateStatusResponseSchema = z2.union([
2300
+ agentApiTaskUpdateStatusSuccessResponseSchema,
2301
+ agentApiHeldFreshnessResponseSchema
2302
+ ]);
2303
+ var agentApiActionPrepareResponseSchema = passthroughObject({
2304
+ messageId: z2.string(),
2305
+ metadata: passthroughObject({
2306
+ kind: z2.literal("action-card")
2307
+ })
2308
+ });
2309
+ var agentApiReminderRecurrenceSchema = z2.object({
2310
+ kind: z2.enum(["interval", "daily", "weekly", "unsupported"]),
2311
+ description: z2.string()
2312
+ });
2313
+ var agentApiReminderSummarySchema = z2.object({
2314
+ reminderId: z2.string(),
2315
+ ownerAgentId: z2.string(),
2316
+ title: z2.string(),
2317
+ fireAt: z2.string(),
2318
+ firedAt: nullableStringSchema.optional(),
2319
+ createdAt: z2.string(),
2320
+ status: reminderStatusSchema,
2321
+ msgRef: nullableStringSchema,
2322
+ msgPermalink: nullableStringSchema,
2323
+ recurrence: agentApiReminderRecurrenceSchema.nullable()
2324
+ });
2325
+ var agentApiReminderEventSummarySchema = z2.object({
2326
+ eventId: z2.string(),
2327
+ reminderId: z2.string(),
2328
+ eventType: reminderEventTypeSchema,
2329
+ actorType: z2.enum(["agent", "human", "system"]),
2330
+ actorId: nullableStringSchema,
2331
+ occurredAt: z2.string(),
2332
+ nextFireAt: nullableStringSchema,
2333
+ metadata: z2.record(z2.string(), z2.unknown()).nullable()
2334
+ });
2335
+ var agentApiReminderListResponseSchema = passthroughObject({
2336
+ reminders: z2.array(agentApiReminderSummarySchema)
2337
+ });
2338
+ var agentApiReminderResponseSchema = passthroughObject({
2339
+ reminder: agentApiReminderSummarySchema,
2340
+ warning: optionalStringSchema
2341
+ });
2342
+ var agentApiReminderLogResponseSchema = passthroughObject({
2343
+ events: z2.array(agentApiReminderEventSummarySchema)
2344
+ });
2345
+ function route(input) {
2346
+ return {
2347
+ ...input,
2348
+ fullPath: `${AGENT_API_BASE_PATH}${input.path}`
2349
+ };
2350
+ }
2351
+ var agentApiContract = {
2352
+ events: route({
2353
+ key: "events",
2354
+ method: "GET",
2355
+ path: "/events",
2356
+ client: { resource: "events", method: "get" },
2357
+ capability: "read",
2358
+ description: "Drain pending events for the bound agent credential.",
2359
+ request: { query: agentApiEventsQuerySchema },
2360
+ response: { body: agentApiEventsResponseSchema }
2361
+ }),
2362
+ historyRead: route({
2363
+ key: "historyRead",
2364
+ method: "GET",
2365
+ path: "/history",
2366
+ client: { resource: "history", method: "read" },
2367
+ capability: "read",
2368
+ description: "Read visible history for a channel, DM, or thread target.",
2369
+ request: { query: agentApiHistoryQuerySchema },
2370
+ response: { body: agentApiHistoryResponseSchema }
2371
+ }),
2372
+ messageSend: route({
2373
+ key: "messageSend",
2374
+ method: "POST",
2375
+ path: "/send",
2376
+ client: { resource: "messages", method: "send" },
2377
+ capability: "send",
2378
+ description: "Send a message as the bound agent credential.",
2379
+ request: { body: agentApiSendBodySchema },
2380
+ response: { body: agentApiSendResponseSchema }
2381
+ }),
2382
+ messageResolve: route({
2383
+ key: "messageResolve",
2384
+ method: "GET",
2385
+ path: "/messages/:msgId/resolve",
2386
+ client: { resource: "messages", method: "resolve" },
2387
+ capability: "read",
2388
+ description: "Resolve a message id exactly and return the canonical visible message.",
2389
+ request: { params: agentApiMessageResolveParamsSchema },
2390
+ response: { body: agentApiMessageResolveResponseSchema }
2391
+ }),
2392
+ messageSearch: route({
2393
+ key: "messageSearch",
2394
+ method: "GET",
2395
+ path: "/search",
2396
+ client: { resource: "messages", method: "search" },
2397
+ capability: "read",
2398
+ description: "Search messages visible to the bound agent credential.",
2399
+ request: { query: agentApiMessageSearchQuerySchema },
2400
+ response: { body: agentApiMessageSearchResponseSchema }
2401
+ }),
2402
+ messageReactionAdd: route({
2403
+ key: "messageReactionAdd",
2404
+ method: "POST",
2405
+ path: "/messages/:msgId/reactions",
2406
+ client: { resource: "messages", method: "addReaction" },
2407
+ capability: "reactions",
2408
+ description: "Add a reaction to a visible message as the bound agent credential.",
2409
+ request: { params: agentApiMessageReactionParamsSchema, body: agentApiMessageReactionBodySchema },
2410
+ response: { body: agentApiMessageEnvelopeSchema }
2411
+ }),
2412
+ messageReactionRemove: route({
2413
+ key: "messageReactionRemove",
2414
+ method: "DELETE",
2415
+ path: "/messages/:msgId/reactions",
2416
+ client: { resource: "messages", method: "removeReaction" },
2417
+ capability: "reactions",
2418
+ description: "Remove a reaction from a visible message as the bound agent credential.",
2419
+ request: { params: agentApiMessageReactionParamsSchema, body: agentApiMessageReactionBodySchema },
2420
+ response: { body: agentApiMessageEnvelopeSchema }
2421
+ }),
2422
+ channelJoin: route({
2423
+ key: "channelJoin",
2424
+ method: "POST",
2425
+ path: "/channels/:channelId/join",
2426
+ client: { resource: "channels", method: "join" },
2427
+ capability: "channels",
2428
+ description: "Join a visible public channel as the bound agent credential.",
2429
+ request: { params: agentApiChannelMembershipParamsSchema },
2430
+ response: { body: agentApiOkResponseSchema }
2431
+ }),
2432
+ channelLeave: route({
2433
+ key: "channelLeave",
2434
+ method: "POST",
2435
+ path: "/channels/:channelId/leave",
2436
+ client: { resource: "channels", method: "leave" },
2437
+ capability: "channels",
2438
+ description: "Leave a joined regular channel as the bound agent credential.",
2439
+ request: { params: agentApiChannelMembershipParamsSchema },
2440
+ response: { body: agentApiOkResponseSchema }
2441
+ }),
2442
+ channelMembers: route({
2443
+ key: "channelMembers",
2444
+ method: "GET",
2445
+ path: "/channel-members",
2446
+ client: { resource: "channels", method: "members" },
2447
+ capability: "channels",
2448
+ description: "List agents and humans in a visible channel, DM, or thread.",
2449
+ request: { query: agentApiChannelMembersQuerySchema },
2450
+ response: { body: agentApiChannelMembersResponseSchema }
2451
+ }),
2452
+ resolveChannel: route({
2453
+ key: "resolveChannel",
2454
+ method: "POST",
2455
+ path: "/resolve-channel",
2456
+ client: { resource: "channels", method: "resolve" },
2457
+ capability: "send",
2458
+ description: "Resolve a writable channel, DM, or thread target for the bound agent credential.",
2459
+ request: { body: agentApiResolveChannelBodySchema },
2460
+ response: { body: agentApiResolveChannelResponseSchema }
2461
+ }),
2462
+ threadUnfollow: route({
2463
+ key: "threadUnfollow",
2464
+ method: "POST",
2465
+ path: "/threads/unfollow",
2466
+ client: { resource: "threads", method: "unfollow" },
2467
+ capability: "channels",
2468
+ description: "Stop ordinary delivery for a followed thread as the bound agent credential.",
2469
+ request: { body: agentApiThreadUnfollowBodySchema },
2470
+ response: { body: agentApiOkResponseSchema }
2471
+ }),
2472
+ serverInfo: route({
2473
+ key: "serverInfo",
2474
+ method: "GET",
2475
+ path: "/server",
2476
+ client: { resource: "server", method: "info" },
2477
+ capability: "server",
2478
+ description: "List channels, agents, humans, and runtime context visible to the bound agent.",
2479
+ request: {},
2480
+ response: { body: agentApiServerInfoResponseSchema }
2481
+ }),
2482
+ mentionActionsPending: route({
2483
+ key: "mentionActionsPending",
2484
+ method: "GET",
2485
+ path: "/mention-actions/pending",
2486
+ client: { resource: "mentions", method: "pendingActions" },
2487
+ capability: "mentions",
2488
+ description: "List sender-side pending mention actions for unresolved outsider mentions.",
2489
+ request: { query: agentApiMentionActionsPendingQuerySchema },
2490
+ response: { body: agentApiMentionActionsPendingResponseSchema }
2491
+ }),
2492
+ mentionActionsExecute: route({
2493
+ key: "mentionActionsExecute",
2494
+ method: "POST",
2495
+ path: "/mention-actions/execute",
2496
+ client: { resource: "mentions", method: "executeAction" },
2497
+ capability: "mentions",
2498
+ description: "Execute sender-side mention resolution actions.",
2499
+ request: { body: agentApiMentionActionsExecuteBodySchema },
2500
+ response: { body: agentApiMentionActionsExecuteResponseSchema }
2501
+ }),
2502
+ taskClaim: route({
2503
+ key: "taskClaim",
2504
+ method: "POST",
2505
+ path: "/tasks/claim",
2506
+ client: { resource: "tasks", method: "claim" },
2507
+ capability: "tasks",
2508
+ description: "Claim one or more tasks by task number or message id.",
2509
+ request: { body: agentApiTaskClaimBodySchema },
2510
+ response: { body: agentApiTaskClaimResponseSchema }
2511
+ }),
2512
+ taskList: route({
2513
+ key: "taskList",
2514
+ method: "GET",
2515
+ path: "/tasks",
2516
+ client: { resource: "tasks", method: "list" },
2517
+ capability: "tasks",
2518
+ description: "List tasks in a channel.",
2519
+ request: { query: agentApiTaskListQuerySchema },
2520
+ response: { body: agentApiTaskListResponseSchema }
2521
+ }),
2522
+ taskCreate: route({
2523
+ key: "taskCreate",
2524
+ method: "POST",
2525
+ path: "/tasks",
2526
+ client: { resource: "tasks", method: "create" },
2527
+ capability: "tasks",
2528
+ description: "Create one or more tasks in a channel.",
2529
+ request: { body: agentApiTaskCreateBodySchema },
2530
+ response: { body: agentApiTaskCreateResponseSchema }
2531
+ }),
2532
+ taskUnclaim: route({
2533
+ key: "taskUnclaim",
2534
+ method: "POST",
2535
+ path: "/tasks/unclaim",
2536
+ client: { resource: "tasks", method: "unclaim" },
2537
+ capability: "tasks",
2538
+ description: "Release a previously claimed task.",
2539
+ request: { body: agentApiTaskUnclaimBodySchema },
2540
+ response: { body: agentApiTaskUnclaimResponseSchema }
2541
+ }),
2542
+ taskUpdateStatus: route({
2543
+ key: "taskUpdateStatus",
2544
+ method: "POST",
2545
+ path: "/tasks/update-status",
2546
+ client: { resource: "tasks", method: "updateStatus" },
2547
+ capability: "tasks",
2548
+ description: "Update a task status.",
2549
+ request: { body: agentApiTaskUpdateStatusBodySchema },
2550
+ response: { body: agentApiTaskUpdateStatusResponseSchema }
2551
+ }),
2552
+ reminderList: route({
2553
+ key: "reminderList",
2554
+ method: "GET",
2555
+ path: "/reminders",
2556
+ client: { resource: "reminders", method: "list" },
2557
+ capability: "read",
2558
+ description: "List reminders owned by the bound agent credential.",
2559
+ request: { query: agentApiReminderListQuerySchema },
2560
+ response: { body: agentApiReminderListResponseSchema }
2561
+ }),
2562
+ reminderCreate: route({
2563
+ key: "reminderCreate",
2564
+ method: "POST",
2565
+ path: "/reminders",
2566
+ client: { resource: "reminders", method: "create" },
2567
+ capability: "tasks",
2568
+ description: "Create a reminder owned by the bound agent credential.",
2569
+ request: { body: agentApiReminderScheduleBodySchema },
2570
+ response: { body: agentApiReminderResponseSchema }
2571
+ }),
2572
+ reminderCancel: route({
2573
+ key: "reminderCancel",
2574
+ method: "DELETE",
2575
+ path: "/reminders/:reminderId",
2576
+ client: { resource: "reminders", method: "cancel" },
2577
+ capability: "tasks",
2578
+ description: "Cancel a scheduled or fired reminder owned by the bound agent credential.",
2579
+ request: { params: agentApiReminderParamsSchema },
2580
+ response: { body: agentApiReminderResponseSchema }
2581
+ }),
2582
+ reminderSnooze: route({
2583
+ key: "reminderSnooze",
2584
+ method: "POST",
2585
+ path: "/reminders/:reminderId/snooze",
2586
+ client: { resource: "reminders", method: "snooze" },
2587
+ capability: "tasks",
2588
+ description: "Snooze a scheduled or fired reminder owned by the bound agent credential.",
2589
+ request: { params: agentApiReminderParamsSchema, body: agentApiReminderSnoozeBodySchema },
2590
+ response: { body: agentApiReminderResponseSchema }
2591
+ }),
2592
+ reminderUpdate: route({
2593
+ key: "reminderUpdate",
2594
+ method: "PATCH",
2595
+ path: "/reminders/:reminderId",
2596
+ client: { resource: "reminders", method: "update" },
2597
+ capability: "tasks",
2598
+ description: "Update a scheduled reminder owned by the bound agent credential.",
2599
+ request: { params: agentApiReminderParamsSchema, body: agentApiReminderUpdateBodySchema },
2600
+ response: { body: agentApiReminderResponseSchema }
2601
+ }),
2602
+ reminderLog: route({
2603
+ key: "reminderLog",
2604
+ method: "GET",
2605
+ path: "/reminders/:reminderId/log",
2606
+ client: { resource: "reminders", method: "log" },
2607
+ capability: "read",
2608
+ description: "Read lifecycle events for a reminder owned by the bound agent credential.",
2609
+ request: { params: agentApiReminderParamsSchema },
2610
+ response: { body: agentApiReminderLogResponseSchema }
2611
+ }),
2612
+ profileShow: route({
2613
+ key: "profileShow",
2614
+ method: "GET",
2615
+ path: "/profile",
2616
+ client: { resource: "profile", method: "show" },
2617
+ capability: "read",
2618
+ description: "Show the bound agent profile, or another visible profile when target is provided.",
2619
+ request: { query: agentApiProfileShowQuerySchema },
2620
+ response: { body: agentApiProfileViewSchema }
2621
+ }),
2622
+ profileUpdate: route({
2623
+ key: "profileUpdate",
2624
+ method: "POST",
2625
+ path: "/profile",
2626
+ client: { resource: "profile", method: "update" },
2627
+ capability: "server",
2628
+ description: "Update the bound agent profile metadata.",
2629
+ request: { body: agentApiProfileUpdateBodySchema },
2630
+ response: { body: agentApiProfileViewSchema }
2631
+ }),
2632
+ integrationList: route({
2633
+ key: "integrationList",
2634
+ method: "GET",
2635
+ path: "/integrations",
2636
+ client: { resource: "integrations", method: "list" },
2637
+ capability: "read",
2638
+ description: "List available integration services and active agent logins.",
2639
+ request: {},
2640
+ response: { body: agentApiIntegrationListResponseSchema }
2641
+ }),
2642
+ integrationLogin: route({
2643
+ key: "integrationLogin",
2644
+ method: "POST",
2645
+ path: "/integrations/login",
2646
+ client: { resource: "integrations", method: "login" },
2647
+ capability: "read",
2648
+ description: "Provision or reuse this agent's login for a registered integration service.",
2649
+ request: { body: agentApiIntegrationLoginBodySchema },
2650
+ response: { body: agentApiIntegrationLoginResponseSchema }
2651
+ }),
2652
+ integrationAppPrepare: route({
2653
+ key: "integrationAppPrepare",
2654
+ method: "POST",
2655
+ path: "/integrations/app/prepare",
2656
+ client: { resource: "integrations", method: "prepareApp" },
2657
+ capability: "read",
2658
+ description: "Prepare a third-party integration registration/update action card.",
2659
+ request: { body: agentApiIntegrationAppPrepareBodySchema },
2660
+ response: { body: agentApiIntegrationAppPrepareResponseSchema }
2661
+ }),
2662
+ actionPrepare: route({
2663
+ key: "actionPrepare",
2664
+ method: "POST",
2665
+ path: "/prepare-action",
2666
+ client: { resource: "actions", method: "prepare" },
2667
+ capability: "tasks",
2668
+ description: "Prepare an action card for a human to commit.",
2669
+ request: { body: agentApiActionPrepareBodySchema },
2670
+ response: { body: agentApiActionPrepareResponseSchema }
2671
+ }),
2672
+ attachmentUpload: route({
2673
+ key: "attachmentUpload",
2674
+ method: "POST",
2675
+ path: "/upload",
2676
+ client: { resource: "attachments", method: "upload" },
2677
+ capability: "send",
2678
+ description: "Upload a multipart attachment as the bound agent credential.",
2679
+ request: {},
2680
+ response: { body: agentApiAttachmentUploadResponseSchema }
2681
+ })
2682
+ };
2683
+
1140
2684
  // ../shared/src/agentInbox.ts
1141
2685
  function formatAgentInboxDelta(rows, options = {}) {
1142
2686
  const totalPendingMessages = options.totalPendingMessages;
@@ -1164,7 +2708,7 @@ function shortMessageId(value) {
1164
2708
  }
1165
2709
 
1166
2710
  // ../shared/src/externalAgentIntegration.ts
1167
- import { z as z2 } from "zod";
2711
+ import { z as z3 } from "zod";
1168
2712
  var EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION = "agent-comms-core.v1";
1169
2713
  var EXTERNAL_AGENT_PROOF_SCHEMA_VERSION = "agent-proof.v1";
1170
2714
  var EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA = "slock-external-runtime-integration.v1";
@@ -1208,35 +2752,35 @@ var externalAgentAdapterFailureValues = [
1208
2752
  "auth_revoked"
1209
2753
  ];
1210
2754
  var externalAgentServerApiModeValues = ["interim-agent-api-events", "agent-inbox-protocol"];
1211
- var nonEmptyStringSchema = z2.string().min(1);
1212
- var isoTimestampSchema = z2.string().refine((value) => !Number.isNaN(Date.parse(value)), {
2755
+ var nonEmptyStringSchema = z3.string().min(1);
2756
+ var isoTimestampSchema = z3.string().refine((value) => !Number.isNaN(Date.parse(value)), {
1213
2757
  message: "must be a parseable timestamp"
1214
2758
  });
1215
- var externalRuntimeIntegrationManifestSchema = z2.object({
1216
- schema: z2.literal(EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA),
2759
+ var externalRuntimeIntegrationManifestSchema = z3.object({
2760
+ schema: z3.literal(EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA),
1217
2761
  runtimeId: nonEmptyStringSchema,
1218
- integrationPattern: z2.enum(externalAgentIntegrationPatternValues),
1219
- commsMode: z2.enum(externalAgentCommsModeValues),
1220
- commsProtocolVersion: z2.literal(EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION),
1221
- proofSchemaVersion: z2.literal(EXTERNAL_AGENT_PROOF_SCHEMA_VERSION),
2762
+ integrationPattern: z3.enum(externalAgentIntegrationPatternValues),
2763
+ commsMode: z3.enum(externalAgentCommsModeValues),
2764
+ commsProtocolVersion: z3.literal(EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION),
2765
+ proofSchemaVersion: z3.literal(EXTERNAL_AGENT_PROOF_SCHEMA_VERSION),
1222
2766
  minSlockCliVersion: nonEmptyStringSchema,
1223
- multiplex: z2.boolean(),
1224
- agentIsolation: z2.enum(externalAgentIsolationValues),
1225
- bridgeLifecycle: z2.object({
1226
- explicitStartOnly: z2.literal(true),
1227
- oneShotCommandsBridgeIndependent: z2.literal(true),
1228
- requiresBridgeFailureCodes: z2.array(z2.enum(["BRIDGE_NOT_RUNNING", "NO_CORE_SESSION"])).min(1),
1229
- autoStartDefault: z2.literal(false)
2767
+ multiplex: z3.boolean(),
2768
+ agentIsolation: z3.enum(externalAgentIsolationValues),
2769
+ bridgeLifecycle: z3.object({
2770
+ explicitStartOnly: z3.literal(true),
2771
+ oneShotCommandsBridgeIndependent: z3.literal(true),
2772
+ requiresBridgeFailureCodes: z3.array(z3.enum(["BRIDGE_NOT_RUNNING", "NO_CORE_SESSION"])).min(1),
2773
+ autoStartDefault: z3.literal(false)
1230
2774
  }).strict(),
1231
- serverApi: z2.object({
1232
- mode: z2.enum(externalAgentServerApiModeValues),
1233
- deliveryOnly: z2.boolean(),
1234
- cursorAuthority: z2.literal("model_seen_only")
2775
+ serverApi: z3.object({
2776
+ mode: z3.enum(externalAgentServerApiModeValues),
2777
+ deliveryOnly: z3.boolean(),
2778
+ cursorAuthority: z3.literal("model_seen_only")
1235
2779
  }).strict(),
1236
- wakeAdapter: z2.object({
1237
- kind: z2.enum(externalAgentWakeAdapterKindValues),
2780
+ wakeAdapter: z3.object({
2781
+ kind: z3.enum(externalAgentWakeAdapterKindValues),
1238
2782
  protocol: nonEmptyStringSchema,
1239
- requiresInteractiveSession: z2.boolean().optional()
2783
+ requiresInteractiveSession: z3.boolean().optional()
1240
2784
  }).strict()
1241
2785
  }).strict().superRefine((value, ctx) => {
1242
2786
  if (!value.bridgeLifecycle.requiresBridgeFailureCodes.includes("BRIDGE_NOT_RUNNING")) {
@@ -1261,8 +2805,8 @@ var externalRuntimeIntegrationManifestSchema = z2.object({
1261
2805
  });
1262
2806
  }
1263
2807
  });
1264
- var externalAgentWakeEventBaseSchema = z2.object({
1265
- schema: z2.literal(EXTERNAL_AGENT_WAKE_EVENT_SCHEMA),
2808
+ var externalAgentWakeEventBaseSchema = z3.object({
2809
+ schema: z3.literal(EXTERNAL_AGENT_WAKE_EVENT_SCHEMA),
1266
2810
  eventId: nonEmptyStringSchema,
1267
2811
  attemptId: nonEmptyStringSchema,
1268
2812
  messageId: nonEmptyStringSchema,
@@ -1272,30 +2816,30 @@ var externalAgentWakeEventBaseSchema = z2.object({
1272
2816
  adapterInstance: nonEmptyStringSchema,
1273
2817
  runtimeSession: nonEmptyStringSchema.nullable(),
1274
2818
  occurredAt: isoTimestampSchema,
1275
- lifecycleState: z2.enum(externalAgentCommsLifecycleStateValues),
1276
- authority: z2.object({
1277
- source: z2.enum(externalAgentLifecycleSourceValues),
1278
- provenance: z2.enum(externalAgentLifecycleProvenanceValues)
2819
+ lifecycleState: z3.enum(externalAgentCommsLifecycleStateValues),
2820
+ authority: z3.object({
2821
+ source: z3.enum(externalAgentLifecycleSourceValues),
2822
+ provenance: z3.enum(externalAgentLifecycleProvenanceValues)
1279
2823
  }).strict()
1280
2824
  }).strict();
1281
2825
  var externalAgentProofEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
1282
- kind: z2.literal("proof"),
1283
- proofLevel: z2.enum(externalAgentWakeProofLevelValues),
1284
- outcome: z2.literal("ok"),
1285
- failureMeta: z2.undefined().optional(),
1286
- reason: z2.string().optional()
2826
+ kind: z3.literal("proof"),
2827
+ proofLevel: z3.enum(externalAgentWakeProofLevelValues),
2828
+ outcome: z3.literal("ok"),
2829
+ failureMeta: z3.undefined().optional(),
2830
+ reason: z3.string().optional()
1287
2831
  });
1288
2832
  var externalAgentFailedWakeEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
1289
- kind: z2.literal("wake_attempt"),
1290
- proofLevel: z2.undefined().optional(),
1291
- outcome: z2.literal("failed"),
1292
- failureMeta: z2.object({
1293
- failureClass: z2.enum(externalAgentAdapterFailureValues),
1294
- retryAfterMs: z2.number().int().positive().optional()
2833
+ kind: z3.literal("wake_attempt"),
2834
+ proofLevel: z3.undefined().optional(),
2835
+ outcome: z3.literal("failed"),
2836
+ failureMeta: z3.object({
2837
+ failureClass: z3.enum(externalAgentAdapterFailureValues),
2838
+ retryAfterMs: z3.number().int().positive().optional()
1295
2839
  }).strict(),
1296
2840
  reason: nonEmptyStringSchema
1297
2841
  });
1298
- var externalAgentWakeEventEnvelopeSchema = z2.discriminatedUnion("kind", [
2842
+ var externalAgentWakeEventEnvelopeSchema = z3.discriminatedUnion("kind", [
1299
2843
  externalAgentProofEventEnvelopeSchema,
1300
2844
  externalAgentFailedWakeEventEnvelopeSchema
1301
2845
  ]);
@@ -1383,9 +2927,30 @@ var SERVER_CAPABILITY_MATRIX = {
1383
2927
 
1384
2928
  // ../shared/src/index.ts
1385
2929
  var RUNTIME_CONFIG_VERSION = 1;
2930
+ var BUILTIN_RUNTIME_PROVIDER_ENV_KEYS = PI_BUILTIN_PROVIDER_API_KEY_ENV_KEYS_GENERATED;
2931
+ var BUILTIN_RUNTIME_PROVIDERS = Object.entries(BUILTIN_RUNTIME_PROVIDER_ENV_KEYS).map(([id, envKey]) => ({ id, envKey }));
1386
2932
  var PI_BUILTIN_PROVIDER_ENV_KEYS = {
1387
- deepseek: "DEEPSEEK_API_KEY"
2933
+ deepseek: BUILTIN_RUNTIME_PROVIDER_ENV_KEYS.deepseek
1388
2934
  };
2935
+ var BUILTIN_RUNTIME_PROVIDER_BLOCKED_HOST_ENV_KEYS = Array.from(new Set(
2936
+ Object.values(PI_BUILTIN_PROVIDER_BLOCKED_HOST_ENV_KEYS_GENERATED).flat()
2937
+ ));
2938
+ var BUILTIN_RUNTIME_GATEWAY_PROVIDERS = [
2939
+ { id: "openai-compatible", envKey: "OPENAI_API_KEY", baseUrlEnvKey: "OPENAI_BASE_URL" },
2940
+ { id: "anthropic-compatible", envKey: "ANTHROPIC_API_KEY", baseUrlEnvKey: "ANTHROPIC_BASE_URL" }
2941
+ ];
2942
+ var BUILTIN_RUNTIME_GATEWAY_PROVIDER_ENV_KEYS = Object.fromEntries(BUILTIN_RUNTIME_GATEWAY_PROVIDERS.map((provider) => [provider.id, provider.envKey]));
2943
+ var BUILTIN_RUNTIME_GATEWAY_PROVIDER_BASE_URL_ENV_KEYS = Object.fromEntries(BUILTIN_RUNTIME_GATEWAY_PROVIDERS.map((provider) => [provider.id, provider.baseUrlEnvKey]));
2944
+ var BUILTIN_RUNTIME_CONTROLLED_ENV_KEYS = Array.from(/* @__PURE__ */ new Set([
2945
+ ...Object.values(BUILTIN_RUNTIME_PROVIDER_ENV_KEYS),
2946
+ ...Object.values(BUILTIN_RUNTIME_GATEWAY_PROVIDER_ENV_KEYS),
2947
+ ...Object.values(BUILTIN_RUNTIME_GATEWAY_PROVIDER_BASE_URL_ENV_KEYS)
2948
+ ]));
2949
+ var BUILTIN_RUNTIME_HOST_PROVIDER_ENV_SCRUB_KEYS = Array.from(/* @__PURE__ */ new Set([
2950
+ ...BUILTIN_RUNTIME_CONTROLLED_ENV_KEYS,
2951
+ ...BUILTIN_RUNTIME_PROVIDER_BLOCKED_HOST_ENV_KEYS
2952
+ ]));
2953
+ var PI_BUILTIN_PROVIDER_MODELS = PI_BUILTIN_PROVIDER_MODELS_GENERATED;
1389
2954
  var AGENT_ACTIVITIES = ["online", "thinking", "working", "error", "offline"];
1390
2955
  var isAgentActivity = makeIsMember(AGENT_ACTIVITIES);
1391
2956
  var VALID_ACTIVITIES = new Set(AGENT_ACTIVITIES);
@@ -1393,6 +2958,7 @@ var EXTERNAL_AGENT_RUNTIME_ID = "external";
1393
2958
  var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
1394
2959
  var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
1395
2960
  var RUNTIMES = [
2961
+ { id: "builtin", displayName: "Built-in", binary: "", supported: true },
1396
2962
  { id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
1397
2963
  { id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
1398
2964
  { id: "antigravity", displayName: "Antigravity CLI", binary: "agy", supported: true },
@@ -1411,6 +2977,7 @@ var RUNTIME_MODELS = {
1411
2977
  [EXTERNAL_AGENT_RUNTIME_ID]: [
1412
2978
  { id: EXTERNAL_AGENT_RUNTIME_MODEL, label: EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME }
1413
2979
  ],
2980
+ builtin: Object.values(PI_BUILTIN_PROVIDER_MODELS).flat().map((model) => ({ id: model.id, label: model.label || formatRuntimeProviderModelLabel(model.id), verified: "launchable" })),
1414
2981
  claude: [
1415
2982
  { id: "opus", label: "Claude Opus" },
1416
2983
  { id: "claude-opus-4-8", label: "Claude Opus 4.8" },
@@ -1490,18 +3057,79 @@ function getDefaultModel(runtimeId) {
1490
3057
  return models?.[0]?.id ?? "sonnet";
1491
3058
  }
1492
3059
  var CONTROLLED_RUNTIME_ENV_KEYS = {
3060
+ // Built-in owns all provider credential/base-url env keys for its launch
3061
+ // plan. Scrub both keys we materialize and host provider keys Pi may read
3062
+ // directly, including defensive aliases such as ANTHROPIC_OAUTH_TOKEN.
3063
+ builtin: BUILTIN_RUNTIME_HOST_PROVIDER_ENV_SCRUB_KEYS,
1493
3064
  claude: ["ANTHROPIC_BASE_URL", "ANTHROPIC_API_KEY", "ANTHROPIC_CUSTOM_MODEL_OPTION"],
1494
3065
  // Pi-runtime builtin-provider env vars (e.g. DEEPSEEK_API_KEY). Owned by
1495
- // RuntimeProviderConfig.pi-builtin → runtimeConfigToLaunchFields, not by
3066
+ // PiRuntimeProviderConfig.pi-builtin → buildLaunchPlan, not by
1496
3067
  // user-supplied envVars: reading from PI_BUILTIN_PROVIDER_ENV_KEYS keeps
1497
3068
  // this list in sync as new providers are added.
1498
3069
  pi: Object.values(PI_BUILTIN_PROVIDER_ENV_KEYS)
1499
3070
  };
1500
- function isPlainRecord(value) {
3071
+ var RUNTIME_CONFIG_FIELDS = [
3072
+ "version",
3073
+ "runtime",
3074
+ "provider",
3075
+ "model",
3076
+ "mode",
3077
+ "reasoningEffort",
3078
+ "envVars",
3079
+ "command",
3080
+ "hostUserState"
3081
+ ];
3082
+ var MODEL_CONFIG_FIELDS = ["kind", "id", "name"];
3083
+ var MODE_CONFIG_FIELDS = ["kind"];
3084
+ var CLAUDE_DEFAULT_PROVIDER_FIELDS = ["kind"];
3085
+ var CLAUDE_CUSTOM_PROVIDER_FIELDS = ["kind", "apiUrl", "apiKey"];
3086
+ var PI_DEFAULT_PROVIDER_FIELDS = ["kind"];
3087
+ var PI_BUILTIN_PROVIDER_FIELDS = ["kind", "providerId", "apiKey"];
3088
+ var BUILTIN_PRESET_PROVIDER_FIELDS = ["kind", "providerId", "apiKey"];
3089
+ var BUILTIN_GATEWAY_PROVIDER_FIELDS = ["kind", "providerId", "baseUrl", "apiKey"];
3090
+ var UNKNOWN_PROVIDER_FIELDS = ["kind"];
3091
+ function isPlainRecord2(value) {
1501
3092
  return value !== null && typeof value === "object" && !Array.isArray(value);
1502
3093
  }
1503
- function normalizeEnvVars(envVars) {
1504
- if (!isPlainRecord(envVars)) return null;
3094
+ function providerKnownFieldsFor(runtime, provider) {
3095
+ const kind = typeof provider.kind === "string" ? provider.kind : void 0;
3096
+ if (runtime === "builtin") {
3097
+ if (kind === "preset" || kind === "managed") return BUILTIN_PRESET_PROVIDER_FIELDS;
3098
+ if (kind === "gateway") return BUILTIN_GATEWAY_PROVIDER_FIELDS;
3099
+ }
3100
+ if (runtime === "claude") {
3101
+ if (kind === "default") return CLAUDE_DEFAULT_PROVIDER_FIELDS;
3102
+ if (kind === "custom") return CLAUDE_CUSTOM_PROVIDER_FIELDS;
3103
+ }
3104
+ if (runtime === "pi") {
3105
+ if (kind === "default") return PI_DEFAULT_PROVIDER_FIELDS;
3106
+ if (kind === "pi-builtin") return PI_BUILTIN_PROVIDER_FIELDS;
3107
+ }
3108
+ return UNKNOWN_PROVIDER_FIELDS;
3109
+ }
3110
+ function providerKind2(config) {
3111
+ return config.provider?.kind ?? "none";
3112
+ }
3113
+ function providerKeyPresent(config) {
3114
+ if (config.runtime === "builtin") return config.provider.apiKey.length > 0;
3115
+ if (config.runtime === "claude") return config.provider?.kind === "custom" && config.provider.apiKey.length > 0;
3116
+ if (config.runtime === "pi") return config.provider?.kind === "pi-builtin" && config.provider.apiKey.length > 0;
3117
+ return false;
3118
+ }
3119
+ function builtInSelectionTraceAttrs2(config) {
3120
+ if (config.runtime !== "builtin") return {};
3121
+ return {
3122
+ provider_id: config.provider.providerId,
3123
+ model_kind: config.model.kind,
3124
+ ...config.model.kind === "preset" ? { model_id: config.model.id } : {},
3125
+ ...config.provider.kind === "gateway" ? {
3126
+ base_url_present: true,
3127
+ base_url_host_class: classifyBuiltInGatewayBaseUrlHost2(config.provider.baseUrl)
3128
+ } : {}
3129
+ };
3130
+ }
3131
+ function normalizeEnvVars2(envVars) {
3132
+ if (!isPlainRecord2(envVars)) return null;
1505
3133
  const normalized = {};
1506
3134
  for (const [key, value] of Object.entries(envVars)) {
1507
3135
  if (typeof key === "string" && typeof value === "string") {
@@ -1514,7 +3142,7 @@ function getControlledRuntimeEnvKeys(runtime) {
1514
3142
  return CONTROLLED_RUNTIME_ENV_KEYS[runtime] ?? [];
1515
3143
  }
1516
3144
  function stripControlledRuntimeEnvVars(runtime, envVars) {
1517
- const normalized = normalizeEnvVars(envVars);
3145
+ const normalized = normalizeEnvVars2(envVars);
1518
3146
  if (!normalized) return null;
1519
3147
  const controlled = new Set(getControlledRuntimeEnvKeys(runtime));
1520
3148
  for (const key of controlled) {
@@ -1522,83 +3150,108 @@ function stripControlledRuntimeEnvVars(runtime, envVars) {
1522
3150
  }
1523
3151
  return Object.keys(normalized).length > 0 ? normalized : null;
1524
3152
  }
1525
- function isPresetRuntimeModel(runtime, model) {
1526
- return (RUNTIME_MODELS[runtime] ?? []).some((candidate) => candidate.id === model);
1527
- }
1528
- function modelConfigFromLegacy(runtime, model) {
1529
- return isPresetRuntimeModel(runtime, model) ? { kind: "preset", id: model } : { kind: "custom", name: model };
1530
- }
1531
- function parseProviderConfig(runtime, value, legacyApiUrl, legacyApiKey) {
1532
- if (runtime === "claude") {
1533
- if (!isPlainRecord(value)) return { kind: "default" };
1534
- if (value.kind === "custom" && typeof value.apiUrl === "string" && value.apiUrl.trim() && typeof value.apiKey === "string" && value.apiKey.trim()) {
1535
- return { kind: "custom", apiUrl: value.apiUrl.trim(), apiKey: value.apiKey.trim() };
1536
- }
1537
- if (value.kind === "custom" && legacyApiUrl?.trim() && legacyApiKey?.trim()) {
1538
- return { kind: "custom", apiUrl: legacyApiUrl.trim(), apiKey: legacyApiKey.trim() };
1539
- }
1540
- return { kind: "default" };
3153
+ function classifyBuiltInGatewayBaseUrlHost2(baseUrl) {
3154
+ let hostname = "";
3155
+ try {
3156
+ hostname = new URL(baseUrl).hostname.toLowerCase();
3157
+ } catch {
3158
+ return "public";
1541
3159
  }
1542
- if (runtime === "pi") {
1543
- if (!isPlainRecord(value)) return { kind: "default" };
1544
- 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())) {
1545
- return { kind: "pi-builtin", providerId: value.providerId.trim(), apiKey: value.apiKey.trim() };
1546
- }
1547
- return { kind: "default" };
3160
+ if (hostname === "localhost" || hostname === "::1" || hostname === "[::1]" || hostname.startsWith("127.")) return "localhost";
3161
+ const ipv4 = hostname.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
3162
+ if (ipv4) {
3163
+ const octets = ipv4.slice(1).map((part) => Number(part));
3164
+ const [a, b] = octets;
3165
+ if (a === 10 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168 || a === 169 && b === 254) return "private";
1548
3166
  }
1549
- return void 0;
3167
+ if (hostname === "0.0.0.0" || hostname === "::" || hostname.startsWith("fc") || hostname.startsWith("fd") || hostname.startsWith("fe80:")) {
3168
+ return "private";
3169
+ }
3170
+ return "public";
1550
3171
  }
1551
- function parseModelConfig(runtime, value, fallback, provider, legacyCustomModel) {
1552
- if (!isPlainRecord(value)) return modelConfigFromLegacy(runtime, fallback);
1553
- if (value.kind === "custom" && typeof value.name === "string" && value.name.trim()) {
1554
- return { kind: "custom", name: value.name.trim() };
3172
+ function composeRuntimeConfig(input) {
3173
+ const base = {
3174
+ version: RUNTIME_CONFIG_VERSION,
3175
+ model: input.model,
3176
+ mode: input.mode,
3177
+ reasoningEffort: input.reasoningEffort ?? null,
3178
+ envVars: input.envVars ?? null
3179
+ };
3180
+ if (input.runtime === "builtin") {
3181
+ return {
3182
+ ...base,
3183
+ runtime: "builtin",
3184
+ provider: input.provider,
3185
+ hostUserState: "forbidden"
3186
+ };
1555
3187
  }
1556
- if (value.kind === "preset" && typeof value.id === "string" && value.id.trim() && isPresetRuntimeModel(runtime, value.id.trim())) {
1557
- return { kind: "preset", id: value.id.trim() };
3188
+ if (input.runtime === "claude") {
3189
+ return {
3190
+ ...base,
3191
+ runtime: "claude",
3192
+ provider: input.provider,
3193
+ ...input.command ? { command: input.command } : {}
3194
+ };
1558
3195
  }
1559
- if (provider?.kind === "custom" && runtime === "claude" && legacyCustomModel?.trim()) {
1560
- return { kind: "custom", name: legacyCustomModel.trim() };
3196
+ if (input.runtime === "pi") {
3197
+ return {
3198
+ ...base,
3199
+ runtime: "pi",
3200
+ provider: input.provider
3201
+ };
1561
3202
  }
1562
- return modelConfigFromLegacy(runtime, fallback);
1563
- }
1564
- function parseModeConfig(value) {
1565
- if (!isPlainRecord(value)) return { kind: "default" };
1566
- if (value.kind === "fast") return { kind: "fast" };
1567
- return { kind: "default" };
1568
- }
1569
- function parseCommandConfig(runtime, value) {
1570
- if (runtime !== "claude" || typeof value !== "string") return void 0;
1571
- const command = value.trim();
1572
- return command ? command : void 0;
1573
- }
1574
- function hydrateRuntimeConfig(input) {
1575
- const stored = isPlainRecord(input.runtimeConfig) && input.runtimeConfig.version === RUNTIME_CONFIG_VERSION ? input.runtimeConfig : null;
1576
- const runtime = typeof stored?.runtime === "string" && stored.runtime.trim() || typeof input.runtime === "string" && input.runtime.trim() || "claude";
1577
- const fallbackModel = typeof input.model === "string" && input.model.trim() || getDefaultModel(runtime);
1578
- const legacyEnvVars = normalizeEnvVars(input.envVars);
1579
- const storedEnvVars = normalizeEnvVars(stored?.envVars);
1580
- const legacyClaudeApiUrl = runtime === "claude" ? legacyEnvVars?.ANTHROPIC_BASE_URL : void 0;
1581
- const legacyClaudeApiKey = runtime === "claude" ? legacyEnvVars?.ANTHROPIC_API_KEY : void 0;
1582
- const legacyClaudeCustomModel = runtime === "claude" ? legacyEnvVars?.ANTHROPIC_CUSTOM_MODEL_OPTION : void 0;
1583
- const provider = stored ? parseProviderConfig(runtime, stored.provider, legacyClaudeApiUrl, legacyClaudeApiKey) : runtime === "claude" && legacyClaudeApiUrl && legacyClaudeApiKey ? { kind: "custom", apiUrl: legacyClaudeApiUrl, apiKey: legacyClaudeApiKey } : runtime === "claude" ? { kind: "default" } : void 0;
1584
- const command = stored ? parseCommandConfig(runtime, stored.command) : void 0;
1585
3203
  return {
1586
- version: RUNTIME_CONFIG_VERSION,
1587
- runtime,
1588
- ...provider ? { provider } : {},
1589
- model: stored ? parseModelConfig(runtime, stored.model, fallbackModel, provider, legacyClaudeCustomModel) : modelConfigFromLegacy(runtime, fallbackModel),
1590
- mode: stored ? parseModeConfig(stored.mode) : { kind: "default" },
1591
- reasoningEffort: stored?.reasoningEffort ?? input.reasoningEffort ?? null,
1592
- envVars: stripControlledRuntimeEnvVars(runtime, stored ? storedEnvVars : legacyEnvVars),
1593
- ...command ? { command } : {}
3204
+ ...base,
3205
+ runtime: input.runtime
1594
3206
  };
1595
3207
  }
3208
+ function hydrateRuntimeConfig(input) {
3209
+ return hydrateRuntimeConfigWithTrace(input).config;
3210
+ }
3211
+ function hydrateRuntimeConfigWithTrace(input) {
3212
+ return hydrateLegacyRuntimeConfigWithTrace(input, {
3213
+ runtimeConfigVersion: RUNTIME_CONFIG_VERSION,
3214
+ runtimeModels: RUNTIME_MODELS,
3215
+ runtimeConfigFields: RUNTIME_CONFIG_FIELDS,
3216
+ modelConfigFields: MODEL_CONFIG_FIELDS,
3217
+ modeConfigFields: MODE_CONFIG_FIELDS,
3218
+ getDefaultModel,
3219
+ builtinProviderEnvKeys: BUILTIN_RUNTIME_PROVIDER_ENV_KEYS,
3220
+ builtinGatewayProviderEnvKeys: BUILTIN_RUNTIME_GATEWAY_PROVIDER_ENV_KEYS,
3221
+ piBuiltinProviderEnvKeys: PI_BUILTIN_PROVIDER_ENV_KEYS,
3222
+ providerKnownFieldsFor,
3223
+ stripControlledRuntimeEnvVars,
3224
+ composeRuntimeConfig
3225
+ });
3226
+ }
1596
3227
  function runtimeConfigModelValue(config) {
1597
3228
  return config.model.kind === "custom" ? config.model.name : config.model.id;
1598
3229
  }
1599
- function runtimeConfigToLaunchFields(config) {
1600
- const normalized = isPlainRecord(config) && config.version === RUNTIME_CONFIG_VERSION ? hydrateRuntimeConfig({ runtimeConfig: config }) : hydrateRuntimeConfig(config);
3230
+ function runtimeConfigSource(config) {
3231
+ if (config.runtime === "builtin") return "agent_config";
3232
+ if (config.runtime === "claude") {
3233
+ return config.provider?.kind === "custom" ? "agent_config" : "host_claude_config";
3234
+ }
3235
+ if (config.runtime === "pi") {
3236
+ return config.provider?.kind === "pi-builtin" ? "agent_config" : "local_pi_config";
3237
+ }
3238
+ return config.provider ? "agent_config" : "host_runtime_config";
3239
+ }
3240
+ function buildLaunchPlan(config) {
3241
+ const normalized = config;
1601
3242
  const generatedEnvVars = {};
3243
+ if (normalized.runtime === "builtin") {
3244
+ if (normalized.provider.kind === "preset") {
3245
+ const envKey = BUILTIN_RUNTIME_PROVIDER_ENV_KEYS[normalized.provider.providerId];
3246
+ if (envKey) generatedEnvVars[envKey] = normalized.provider.apiKey;
3247
+ }
3248
+ if (normalized.provider.kind === "gateway") {
3249
+ const apiKeyEnvKey = BUILTIN_RUNTIME_GATEWAY_PROVIDER_ENV_KEYS[normalized.provider.providerId];
3250
+ const baseUrlEnvKey = BUILTIN_RUNTIME_GATEWAY_PROVIDER_BASE_URL_ENV_KEYS[normalized.provider.providerId];
3251
+ if (apiKeyEnvKey) generatedEnvVars[apiKeyEnvKey] = normalized.provider.apiKey;
3252
+ if (baseUrlEnvKey) generatedEnvVars[baseUrlEnvKey] = normalized.provider.baseUrl;
3253
+ }
3254
+ }
1602
3255
  if (normalized.runtime === "claude") {
1603
3256
  if (normalized.provider?.kind === "custom") {
1604
3257
  generatedEnvVars.ANTHROPIC_BASE_URL = normalized.provider.apiUrl;
@@ -1617,14 +3270,30 @@ function runtimeConfigToLaunchFields(config) {
1617
3270
  ...generatedEnvVars
1618
3271
  };
1619
3272
  return {
3273
+ // Compatibility output for launch paths only; persist/re-parse RuntimeConfig for decisions instead of inferring config semantics back from env vars.
1620
3274
  runtime: normalized.runtime,
1621
3275
  model: runtimeConfigModelValue(normalized),
1622
3276
  mode: normalized.mode,
3277
+ configSource: runtimeConfigSource(normalized),
1623
3278
  reasoningEffort: normalized.reasoningEffort ?? null,
1624
3279
  envVars: Object.keys(envVars).length > 0 ? envVars : null,
1625
- ...normalized.command ? { command: normalized.command } : {}
3280
+ ...normalized.command ? { command: normalized.command } : {},
3281
+ trace: {
3282
+ outcome: "materialized",
3283
+ runtime: normalized.runtime,
3284
+ provider_kind: providerKind2(normalized),
3285
+ ...builtInSelectionTraceAttrs2(normalized),
3286
+ config_source: runtimeConfigSource(normalized),
3287
+ provider_key_present: providerKeyPresent(normalized),
3288
+ ...providerKeyPresent(normalized) ? { provider_key_source: "runtime_config_plaintext" } : {},
3289
+ env_key_count: Object.keys(envVars).length
3290
+ }
1626
3291
  };
1627
3292
  }
3293
+ function runtimeConfigToLaunchFields(config) {
3294
+ const { trace: _, configSource: _configSource, ...launchFields } = buildLaunchPlan(config);
3295
+ return launchFields;
3296
+ }
1628
3297
  var PRO_SEAT_MONTHLY_USD = 10;
1629
3298
  var PRO_AGENT_SEAT_BLOCK_SIZE = 10;
1630
3299
  var PRO_AGENT_SEAT_FRACTION = 1 / PRO_AGENT_SEAT_BLOCK_SIZE;
@@ -2506,7 +4175,7 @@ function buildPrompt(config, opts) {
2506
4175
  const channelAwarenessSection = cliGuideSections.channelAwareness;
2507
4176
  const thirdPartyIntegrationsSection = `### Third-party integrations
2508
4177
 
2509
- If a built-in Slock app or registered third-party service requires login, use Slock Agent Login through the CLI instead of asking the human to copy tokens or complete human OAuth for you. If a human asks you to sign into, open, use, or fetch identity from a third-party app or built-in Slock app, first run \`raft integration list\` and match the app to a listed service before browsing the app. Use \`raft integration login --service <service>\` to provision or reuse your agent login for that service. If the service exposes an agent behavior manifest and you need to run its local CLI, run \`raft integration env --service <service>\` before invoking that CLI; if it prints exports, apply them first so service credentials stay under a per-agent profile HOME/XDG tree instead of the host user's global HOME. If it reports that no local env is required, do not invent HOME/XDG overrides. If it fails, do not run that local CLI with the host user's HOME; report that the service manifest is unsupported. Slock does not execute commands from remote manifests automatically. If the CLI reports that the \`integration\` command is unknown, the local daemon/CLI is too old for Slock Agent Login; report that the machine must be upgraded/restarted instead of calling internal HTTP endpoints yourself. When the command returns \`Agent login ready\` or \`Already logged in\`, the agent-side login is ready. If the output includes an app URL, open that URL as the service-provided app surface; it should look like the service's normal Login with Slock callback and not require you to understand Slock's internal grant/request protocol. Do not crawl third-party routes looking for a session before trying the registered-service login path. Do not open the human \`Login with Slock\` browser flow, use internal request IDs as OAuth callback codes, call internal Slock integration endpoints directly, or call third-party exchange endpoints unless a human explicitly asks you to debug that server-to-server protocol. If the service or human asks for your Slock Agent identity card, use \`raft profile show\`. Third-party pages may show \`Login with Slock\`; for agent-facing access, prefer the listed service / Slock Agent Login path.`;
4178
+ If a built-in Slock app or registered third-party service requires login, use Slock Agent Login through the CLI instead of asking the human to copy tokens or complete human OAuth for you. If a human asks you to sign into, open, use, or fetch identity from a third-party app or built-in Slock app, first run \`raft integration list\` and match the app to a listed service before browsing the app. Use \`raft integration login --service <service>\` to provision or reuse your agent login for that service. If the service exposes an agent behavior manifest and you need to run its local CLI, run \`raft integration env --service <service>\` before invoking that CLI; if it prints exports, apply them first so service credentials stay under a per-agent profile HOME/XDG tree instead of the host user's global HOME. If it reports that no local env is required, do not invent HOME/XDG overrides. If it fails, do not run that local CLI with the host user's HOME; report that the service manifest is unsupported. Slock does not execute commands from remote manifests automatically. If the CLI reports that the \`integration\` command is unknown, the local daemon/CLI is too old for Slock Agent Login; report that the machine must be upgraded/restarted instead of calling internal HTTP endpoints yourself. When the command returns \`Agent login ready\` or \`Already logged in\`, the agent-side login is ready. If the output includes a service callback handoff URL, treat it as the registered OAuth callback carrying an Agent Login request code, not as a normal browser app URL; open it only when the service documents a stateless Agent Login callback that accepts that URL directly. Otherwise use the service docs, API, or manifest entry point. Do not crawl third-party routes looking for a session before trying the registered-service login path. Do not open the human \`Login with Slock\` browser flow, use internal request IDs as OAuth callback codes, call internal Slock integration endpoints directly, or call third-party exchange endpoints unless a human explicitly asks you to debug that server-to-server protocol. If the service or human asks for your Slock Agent identity card, use \`raft profile show\`. Third-party pages may show \`Login with Slock\`; for agent-facing access, prefer the listed service / Slock Agent Login path.`;
2510
4179
  const readingHistorySection = cliGuideSections.readingHistory;
2511
4180
  const historicalReferenceSection = cliGuideSections.historicalReferences;
2512
4181
  const tasksSection = cliGuideSections.tasks;
@@ -3486,6 +5155,7 @@ function heldPlan(input, held, trace) {
3486
5155
  localResponse: projectApmHeldFreshnessEnvelope({
3487
5156
  producerFactId,
3488
5157
  action: input.action,
5158
+ decision: held.decision.decision,
3489
5159
  heldMessages: held.context.heldMessages,
3490
5160
  newMessageCount: held.context.newMessageCount,
3491
5161
  omittedMessageCount: held.context.omittedMessageCount,
@@ -4601,7 +6271,7 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
4601
6271
  writeOpencliWrapper(slockDir, opencliBinPath, platform, execIsElectron);
4602
6272
  }
4603
6273
  const wrapperPath = platform === "win32" ? path2.join(slockDir, "slock.cmd") : posixWrapper;
4604
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
6274
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
4605
6275
  const spawnEnv = {
4606
6276
  ...process.env,
4607
6277
  FORCE_COLOR: "0",
@@ -4928,7 +6598,7 @@ var CLAUDE_CUSTOM_PROVIDER_HOST_ENV_KEYS = [
4928
6598
  "CLAUDE_CODE_USE_CCR_V2"
4929
6599
  ];
4930
6600
  function isClaudeCustomProviderConfig(config) {
4931
- const launchRuntimeFields = runtimeConfigToLaunchFields(config);
6601
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(config));
4932
6602
  return launchRuntimeFields.runtime === "claude" && Boolean(launchRuntimeFields.envVars?.ANTHROPIC_BASE_URL) && Boolean(launchRuntimeFields.envVars?.ANTHROPIC_API_KEY);
4933
6603
  }
4934
6604
  function clearInheritedClaudeProviderEnv(explicitEnv) {
@@ -4970,7 +6640,7 @@ function buildClaudeProviderIsolationEnv(ctx) {
4970
6640
  if (!isClaudeCustomProviderConfig(ctx.config)) {
4971
6641
  return {};
4972
6642
  }
4973
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
6643
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
4974
6644
  return {
4975
6645
  ...clearInheritedClaudeProviderEnv(launchRuntimeFields.envVars)
4976
6646
  };
@@ -5204,7 +6874,7 @@ function resolveClaudeCommand(deps = {}) {
5204
6874
  ], deps);
5205
6875
  }
5206
6876
  function resolveClaudeLaunchCommand(config, deps = {}) {
5207
- const launchRuntimeFields = runtimeConfigToLaunchFields(config);
6877
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(config));
5208
6878
  return launchRuntimeFields.command?.trim() || resolveClaudeCommand(deps);
5209
6879
  }
5210
6880
  function probeClaude(deps = {}) {
@@ -5216,7 +6886,7 @@ function probeClaude(deps = {}) {
5216
6886
  };
5217
6887
  }
5218
6888
  function buildClaudeArgs(config, opts) {
5219
- const launchRuntimeFields = runtimeConfigToLaunchFields(config);
6889
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(config));
5220
6890
  const args = [
5221
6891
  "--allow-dangerously-skip-permissions",
5222
6892
  "--dangerously-skip-permissions",
@@ -5387,14 +7057,14 @@ function resolveCodexHomeRootFromEnv(env = process.env, opts = {}) {
5387
7057
  return path6.join(opts.defaultHomeDir ?? os2.homedir(), ".codex");
5388
7058
  }
5389
7059
  function hasConfiguredCodexHome(config, baseEnv = process.env) {
5390
- const launchRuntimeFields = config ? runtimeConfigToLaunchFields(config) : null;
7060
+ const launchRuntimeFields = config ? runtimeConfigToLaunchFields(hydrateRuntimeConfig(config)) : null;
5391
7061
  return Boolean(readConfiguredCodexHome({
5392
7062
  ...baseEnv,
5393
7063
  ...launchRuntimeFields?.envVars || {}
5394
7064
  }));
5395
7065
  }
5396
7066
  function resolveCodexHomeRootFromConfig(config, defaultHomeDir, cwd, baseEnv = process.env, _opts = {}) {
5397
- const launchRuntimeFields = runtimeConfigToLaunchFields(config);
7067
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(config));
5398
7068
  const env = {
5399
7069
  ...baseEnv,
5400
7070
  ...launchRuntimeFields.envVars || {}
@@ -6306,7 +7976,7 @@ var CodexDriver = class {
6306
7976
  // the daemon. They replace the previous transcript-mtime heuristic.
6307
7977
  experimentalRawEvents: true
6308
7978
  };
6309
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
7979
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
6310
7980
  if (launchRuntimeFields.model) {
6311
7981
  threadParams.model = launchRuntimeFields.model;
6312
7982
  }
@@ -6847,7 +8517,7 @@ function buildAntigravityArgs(ctx) {
6847
8517
  const args = [
6848
8518
  "--print",
6849
8519
  "--print-timeout",
6850
- runtimeConfigToLaunchFields(ctx.config).envVars?.ANTIGRAVITY_PRINT_TIMEOUT || DEFAULT_PRINT_TIMEOUT,
8520
+ runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config)).envVars?.ANTIGRAVITY_PRINT_TIMEOUT || DEFAULT_PRINT_TIMEOUT,
6851
8521
  "--dangerously-skip-permissions"
6852
8522
  ];
6853
8523
  if (ctx.config.sessionId) {
@@ -6990,7 +8660,7 @@ var CopilotDriver = class {
6990
8660
  "-p",
6991
8661
  ctx.prompt
6992
8662
  ];
6993
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
8663
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
6994
8664
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
6995
8665
  args.push("--model", launchRuntimeFields.model);
6996
8666
  }
@@ -7128,7 +8798,7 @@ var CursorDriver = class {
7128
8798
  "--approve-mcps",
7129
8799
  "--trust"
7130
8800
  ];
7131
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
8801
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
7132
8802
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
7133
8803
  args.push("--model", launchRuntimeFields.model);
7134
8804
  }
@@ -7268,7 +8938,7 @@ import { existsSync as existsSync5 } from "fs";
7268
8938
  import path8 from "path";
7269
8939
  async function buildGeminiSpawnEnv(ctx, platform = process.platform) {
7270
8940
  const { spawnEnv } = await prepareCliTransport(ctx, { NO_COLOR: "1" }, platform);
7271
- const launchEnvVars = runtimeConfigToLaunchFields(ctx.config).envVars;
8941
+ const launchEnvVars = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config)).envVars;
7272
8942
  if (!Object.prototype.hasOwnProperty.call(launchEnvVars ?? {}, "GEMINI_CLI_TRUST_WORKSPACE")) {
7273
8943
  spawnEnv.GEMINI_CLI_TRUST_WORKSPACE = "true";
7274
8944
  }
@@ -7292,7 +8962,7 @@ function buildGeminiArgs(config) {
7292
8962
  "-p",
7293
8963
  ""
7294
8964
  ];
7295
- const launchRuntimeFields = runtimeConfigToLaunchFields(config);
8965
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(config));
7296
8966
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
7297
8967
  args.push("--model", launchRuntimeFields.model);
7298
8968
  }
@@ -7514,7 +9184,7 @@ var KimiDriver = class {
7514
9184
  "--session",
7515
9185
  this.sessionId
7516
9186
  ];
7517
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
9187
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
7518
9188
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
7519
9189
  args.push("--model", launchRuntimeFields.model);
7520
9190
  }
@@ -7833,7 +9503,7 @@ async function createKimiAgentSessionForContext(ctx, sessionId) {
7833
9503
  userAgentSuffix: `slock-daemon/${getDaemonVersion()}`
7834
9504
  }
7835
9505
  });
7836
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
9506
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
7837
9507
  const sessionFields = {
7838
9508
  workDir: ctx.workingDirectory,
7839
9509
  ...launchRuntimeFields.model && launchRuntimeFields.model !== "default" ? { model: launchRuntimeFields.model } : {}
@@ -8174,7 +9844,7 @@ function parseOpenCodeConfigContent(raw) {
8174
9844
  return {};
8175
9845
  }
8176
9846
  function parseUserOpenCodeConfig(ctx) {
8177
- const raw = runtimeConfigToLaunchFields(ctx.config).envVars?.OPENCODE_CONFIG_CONTENT;
9847
+ const raw = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config)).envVars?.OPENCODE_CONFIG_CONTENT;
8178
9848
  return parseOpenCodeConfigContent(raw);
8179
9849
  }
8180
9850
  function readLocalOpenCodeConfig(home = os5.homedir()) {
@@ -8272,7 +9942,7 @@ async function buildOpenCodeLaunchOptions(ctx, home = os5.homedir(), version = n
8272
9942
  "--dir",
8273
9943
  ctx.workingDirectory
8274
9944
  ];
8275
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
9945
+ const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
8276
9946
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
8277
9947
  args.push("--model", launchRuntimeFields.model);
8278
9948
  }
@@ -8586,7 +10256,25 @@ import {
8586
10256
  VERSION as PI_SDK_VERSION
8587
10257
  } from "@earendil-works/pi-coding-agent";
8588
10258
  var PI_SESSION_DIR = ".pi-sessions";
10259
+ var BUILTIN_SESSION_DIR = ".builtin-sessions";
10260
+ var BUILTIN_AGENT_DIR = ".builtin-runtime";
8589
10261
  var PI_SDK_COMPACTION_ENABLED = true;
10262
+ var BUILTIN_BLOCKED_HOST_AMBIENT_CREDENTIAL_ENV_KEYS = [
10263
+ "AZURE_OPENAI_BASE_URL",
10264
+ "AZURE_OPENAI_RESOURCE_NAME",
10265
+ "AZURE_OPENAI_API_VERSION",
10266
+ "AZURE_OPENAI_DEPLOYMENT_NAME_MAP",
10267
+ "CLOUDFLARE_ACCOUNT_ID",
10268
+ "AWS_PROFILE",
10269
+ "AWS_ACCESS_KEY_ID",
10270
+ "AWS_SECRET_ACCESS_KEY",
10271
+ "AWS_BEARER_TOKEN_BEDROCK",
10272
+ "AWS_REGION"
10273
+ ];
10274
+ var BUILTIN_BLOCKED_HOST_PROVIDER_ENV_KEYS = Array.from(/* @__PURE__ */ new Set([
10275
+ ...BUILTIN_RUNTIME_HOST_PROVIDER_ENV_SCRUB_KEYS,
10276
+ ...BUILTIN_BLOCKED_HOST_AMBIENT_CREDENTIAL_ENV_KEYS
10277
+ ]));
8590
10278
  function createPiSdkEventMappingState(sessionId = null) {
8591
10279
  return {
8592
10280
  sessionId,
@@ -8597,9 +10285,77 @@ function createPiSdkEventMappingState(sessionId = null) {
8597
10285
  function buildPiSessionDir(workingDirectory) {
8598
10286
  return path12.join(workingDirectory, PI_SESSION_DIR);
8599
10287
  }
10288
+ function buildBuiltInSessionDir(workingDirectory) {
10289
+ return path12.join(workingDirectory, BUILTIN_SESSION_DIR);
10290
+ }
10291
+ function buildBuiltInAgentDir(workingDirectory) {
10292
+ return path12.join(workingDirectory, BUILTIN_AGENT_DIR);
10293
+ }
8600
10294
  async function buildPiSpawnEnv(ctx) {
8601
10295
  return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
8602
10296
  }
10297
+ function seedBuiltInAuthStorage(authStorage, runtimeConfig) {
10298
+ if (runtimeConfig.runtime !== "builtin") return;
10299
+ if (runtimeConfig.provider.kind === "preset") {
10300
+ authStorage.setRuntimeApiKey(runtimeConfig.provider.providerId, runtimeConfig.provider.apiKey);
10301
+ return;
10302
+ }
10303
+ if (runtimeConfig.provider.providerId === "openai-compatible") {
10304
+ authStorage.setRuntimeApiKey("openai", runtimeConfig.provider.apiKey);
10305
+ } else if (runtimeConfig.provider.providerId === "anthropic-compatible") {
10306
+ authStorage.setRuntimeApiKey("anthropic", runtimeConfig.provider.apiKey);
10307
+ }
10308
+ }
10309
+ function buildPiSessionCreateEnvPatch(runtimeConfig, envVars) {
10310
+ if (runtimeConfig.runtime !== "builtin" || !envVars) return envVars;
10311
+ const providerApiKeyEnvNames = /* @__PURE__ */ new Set([
10312
+ ...Object.values(BUILTIN_RUNTIME_PROVIDER_ENV_KEYS),
10313
+ ...Object.values(BUILTIN_RUNTIME_GATEWAY_PROVIDER_ENV_KEYS)
10314
+ ]);
10315
+ const filtered = Object.fromEntries(
10316
+ Object.entries(envVars).filter(([key]) => !providerApiKeyEnvNames.has(key))
10317
+ );
10318
+ return Object.keys(filtered).length > 0 ? filtered : null;
10319
+ }
10320
+ var processEnvPatchTail = Promise.resolve();
10321
+ async function runWithProcessEnvPatchLock(fn) {
10322
+ const previous = processEnvPatchTail;
10323
+ let release;
10324
+ processEnvPatchTail = new Promise((resolve) => {
10325
+ release = resolve;
10326
+ });
10327
+ await previous;
10328
+ try {
10329
+ return await fn();
10330
+ } finally {
10331
+ release();
10332
+ }
10333
+ }
10334
+ async function withProcessEnvPatch(patch, fn, opts = {}) {
10335
+ const keys = /* @__PURE__ */ new Set([...opts.removeFirst ?? [], ...Object.keys(patch ?? {})]);
10336
+ if (keys.size === 0) return fn();
10337
+ return runWithProcessEnvPatchLock(async () => {
10338
+ const previous = {};
10339
+ for (const key of keys) {
10340
+ previous[key] = process.env[key];
10341
+ delete process.env[key];
10342
+ }
10343
+ for (const [key, value] of Object.entries(patch ?? {})) {
10344
+ process.env[key] = value;
10345
+ }
10346
+ try {
10347
+ return await fn();
10348
+ } finally {
10349
+ for (const [key, value] of Object.entries(previous)) {
10350
+ if (value === void 0) {
10351
+ delete process.env[key];
10352
+ } else {
10353
+ process.env[key] = value;
10354
+ }
10355
+ }
10356
+ }
10357
+ });
10358
+ }
8603
10359
  function resolvePiModelFromRegistry(modelId, modelRegistry) {
8604
10360
  if (!modelId || modelId === "default") return void 0;
8605
10361
  const [provider, ...modelParts] = modelId.split("/");
@@ -8608,6 +10364,27 @@ function resolvePiModelFromRegistry(modelId, modelRegistry) {
8608
10364
  }
8609
10365
  return modelRegistry.getAll().find((model) => model.id === modelId);
8610
10366
  }
10367
+ function configureBuiltInGatewayCustomModel(modelRegistry, runtimeConfig) {
10368
+ if (runtimeConfig.runtime !== "builtin") return;
10369
+ if (runtimeConfig.provider.kind !== "gateway") return;
10370
+ if (runtimeConfig.model.kind !== "custom") return;
10371
+ const provider = runtimeConfig.provider.providerId === "openai-compatible" ? { id: "openai", api: "openai-completions", apiKeyEnv: "OPENAI_API_KEY" } : { id: "anthropic", api: "anthropic-messages", apiKeyEnv: "ANTHROPIC_API_KEY" };
10372
+ modelRegistry.registerProvider(provider.id, {
10373
+ name: getRuntimeProviderDisplayName(runtimeConfig.provider.providerId),
10374
+ baseUrl: runtimeConfig.provider.baseUrl,
10375
+ apiKey: `$${provider.apiKeyEnv}`,
10376
+ api: provider.api,
10377
+ models: [{
10378
+ id: runtimeConfig.model.name,
10379
+ name: runtimeConfig.model.name,
10380
+ reasoning: true,
10381
+ input: ["text"],
10382
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
10383
+ contextWindow: 2e5,
10384
+ maxTokens: 8192
10385
+ }]
10386
+ });
10387
+ }
8611
10388
  function findPiSessionFile(sessionDir, sessionId) {
8612
10389
  let entries;
8613
10390
  try {
@@ -8814,12 +10591,25 @@ var PI_RUNTIME_SESSION_DESCRIPTOR = {
8814
10591
  };
8815
10592
  var PI_IDLE_PROMPT_RETRY_MS = 25;
8816
10593
  var PI_IDLE_PROMPT_MAX_WAIT_MS = 1e3;
8817
- async function createPiAgentSessionForContext(ctx, sessionId) {
8818
- const sessionDir = buildPiSessionDir(ctx.workingDirectory);
10594
+ async function createPiAgentSessionForContext(ctx, sessionId, opts = {}) {
10595
+ const sessionDir = opts.sessionDir ?? buildPiSessionDir(ctx.workingDirectory);
8819
10596
  mkdirSync3(sessionDir, { recursive: true });
8820
- const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
10597
+ const runtimeConfig = hydrateRuntimeConfig(ctx.config);
10598
+ const launchPlan = buildLaunchPlan(runtimeConfig);
10599
+ const { trace: launchTrace, configSource: _configSource, ...launchRuntimeFields } = launchPlan;
10600
+ const launchTraceEvidenceAttrs = opts.exposeLaunchTraceEvidence ? {
10601
+ config_source: launchTrace.config_source,
10602
+ ...runtimeConfig.runtime === "builtin" ? { host_user_state: runtimeConfig.hostUserState } : {},
10603
+ ...launchTrace.provider_id ? { provider_id: launchTrace.provider_id } : {},
10604
+ ...launchTrace.model_kind ? { model_kind: launchTrace.model_kind } : {},
10605
+ ...launchTrace.model_id ? { model_id: launchTrace.model_id } : {},
10606
+ ...launchTrace.base_url_present !== void 0 ? { base_url_present: launchTrace.base_url_present } : {},
10607
+ ...launchTrace.base_url_host_class ? { base_url_host_class: launchTrace.base_url_host_class } : {},
10608
+ provider_key_present: launchTrace.provider_key_present,
10609
+ ...launchTrace.provider_key_source ? { provider_key_source: launchTrace.provider_key_source } : {}
10610
+ } : {};
8821
10611
  const requestedModel = launchRuntimeFields.model || "default";
8822
- const traceSpan = ctx.tracer?.startSpan("daemon.pi.session.create", {
10612
+ const traceSpan = ctx.tracer?.startSpan(opts.traceName ?? "daemon.pi.session.create", {
8823
10613
  surface: "daemon",
8824
10614
  kind: "internal",
8825
10615
  attrs: {
@@ -8828,15 +10618,22 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8828
10618
  runtime: ctx.config.runtime,
8829
10619
  model: ctx.config.model,
8830
10620
  session_id_present: Boolean(sessionId),
8831
- requested_model: requestedModel
10621
+ requested_model: requestedModel,
10622
+ ...launchTraceEvidenceAttrs
8832
10623
  }
8833
10624
  });
10625
+ const logPrefix = opts.logPrefix ?? "pi-driver";
10626
+ const traceEventPrefix = opts.traceEventPrefix ?? "daemon.pi.session";
8834
10627
  try {
8835
10628
  const spawnEnv = await buildPiSpawnEnv(ctx);
8836
- const agentDir = spawnEnv.PI_CODING_AGENT_DIR || getAgentDir();
10629
+ const agentDir = opts.agentDir ?? spawnEnv.PI_CODING_AGENT_DIR ?? getAgentDir();
10630
+ mkdirSync3(agentDir, { recursive: true });
8837
10631
  const authStorage = AuthStorage.create(path12.join(agentDir, "auth.json"));
10632
+ seedBuiltInAuthStorage(authStorage, runtimeConfig);
8838
10633
  const settingsManager = SettingsManager.create(ctx.workingDirectory, agentDir);
8839
- const services = await createAgentSessionServices({
10634
+ const providerEnvScope = opts.isolateHostProviderEnv ? BUILTIN_BLOCKED_HOST_PROVIDER_ENV_KEYS : void 0;
10635
+ const sessionCreateEnvPatch = buildPiSessionCreateEnvPatch(runtimeConfig, launchRuntimeFields.envVars);
10636
+ const services = await withProcessEnvPatch(sessionCreateEnvPatch, () => createAgentSessionServices({
8840
10637
  cwd: ctx.workingDirectory,
8841
10638
  agentDir,
8842
10639
  authStorage,
@@ -8844,23 +10641,27 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8844
10641
  resourceLoaderOptions: {
8845
10642
  systemPromptOverride: () => ctx.standingPrompt
8846
10643
  }
8847
- });
10644
+ }), { removeFirst: providerEnvScope });
10645
+ configureBuiltInGatewayCustomModel(services.modelRegistry, runtimeConfig);
8848
10646
  applyPiDaemonSettingsOverrides(services.settingsManager);
8849
10647
  logPiServiceDiagnostics("create_session", services);
8850
- addPiServiceTraceEvent(traceSpan, "daemon.pi.session.services_ready", services, {
8851
- agent_dir_source: spawnEnv.PI_CODING_AGENT_DIR ? "spawn_env" : "default"
10648
+ addPiServiceTraceEvent(traceSpan, `${traceEventPrefix}.services_ready`, services, {
10649
+ agent_dir_source: opts.agentDirSource ?? (spawnEnv.PI_CODING_AGENT_DIR ? "spawn_env" : "default"),
10650
+ ...launchTraceEvidenceAttrs
8852
10651
  });
8853
10652
  const model = resolvePiModelFromRegistry(launchRuntimeFields.model, services.modelRegistry);
8854
10653
  const resolvedModel = formatPiModelLogId(model);
8855
- traceSpan?.addEvent("daemon.pi.session.model_resolved", {
10654
+ traceSpan?.addEvent(`${traceEventPrefix}.model_resolved`, {
8856
10655
  available_models_count: services.modelRegistry.getAvailable().length,
8857
10656
  requested_model: requestedModel,
8858
10657
  requested_model_explicit: requestedModel !== "default",
8859
10658
  resolved_model: resolvedModel,
8860
- resolved_model_present: Boolean(model)
10659
+ resolved_model_present: Boolean(model),
10660
+ ...launchTraceEvidenceAttrs
8861
10661
  });
8862
10662
  console.info(
8863
- "[pi-driver] create_session services_ready agentDir=%s available=%d requested=%s resolved=%s",
10663
+ "[%s] create_session services_ready agentDir=%s available=%d requested=%s resolved=%s",
10664
+ logPrefix,
8864
10665
  agentDir,
8865
10666
  services.modelRegistry.getAvailable().length,
8866
10667
  requestedModel,
@@ -8868,13 +10669,15 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8868
10669
  );
8869
10670
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default" && !model) {
8870
10671
  console.warn(
8871
- "[pi-driver] create_session missing_model requested=%s available=%d",
10672
+ "[%s] create_session missing_model requested=%s available=%d",
10673
+ logPrefix,
8872
10674
  requestedModel,
8873
10675
  services.modelRegistry.getAvailable().length
8874
10676
  );
8875
- traceSpan?.addEvent("daemon.pi.session.missing_model", {
10677
+ traceSpan?.addEvent(`${traceEventPrefix}.missing_model`, {
8876
10678
  available_models_count: services.modelRegistry.getAvailable().length,
8877
- requested_model: requestedModel
10679
+ requested_model: requestedModel,
10680
+ ...launchTraceEvidenceAttrs
8878
10681
  });
8879
10682
  traceSpan?.end("error", {
8880
10683
  attrs: {
@@ -8882,14 +10685,21 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8882
10685
  available_models_count: services.modelRegistry.getAvailable().length,
8883
10686
  requested_model: requestedModel,
8884
10687
  resolved_model_present: false,
8885
- ...piServiceDiagnosticTraceAttrs(services)
10688
+ ...piServiceDiagnosticTraceAttrs(services),
10689
+ ...launchTraceEvidenceAttrs
8886
10690
  }
8887
10691
  });
8888
10692
  throw new Error(`Pi model not found: ${launchRuntimeFields.model}`);
8889
10693
  }
8890
10694
  const existingSessionFile = ctx.config.sessionId ? findPiSessionFile(sessionDir, ctx.config.sessionId) : null;
8891
10695
  const sessionManager = existingSessionFile ? SessionManager.open(existingSessionFile, sessionDir, ctx.workingDirectory) : SessionManager.create(ctx.workingDirectory, sessionDir, { id: sessionId });
8892
- const { session } = await createAgentSessionFromServices({
10696
+ const toolSpawnEnv = { ...spawnEnv };
10697
+ if (opts.exposeLaunchEnvToTools === false) {
10698
+ for (const key of Object.keys(launchRuntimeFields.envVars ?? {})) {
10699
+ delete toolSpawnEnv[key];
10700
+ }
10701
+ }
10702
+ const { session } = await withProcessEnvPatch(sessionCreateEnvPatch, () => createAgentSessionFromServices({
8893
10703
  services,
8894
10704
  sessionManager,
8895
10705
  model,
@@ -8900,16 +10710,17 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8900
10710
  ...spawnContext,
8901
10711
  env: {
8902
10712
  ...spawnContext.env,
8903
- ...spawnEnv
10713
+ ...toolSpawnEnv
8904
10714
  }
8905
10715
  })
8906
10716
  })
8907
10717
  ]
8908
- });
8909
- traceSpan?.addEvent("daemon.pi.session.started", {
10718
+ }), { removeFirst: providerEnvScope });
10719
+ traceSpan?.addEvent(`${traceEventPrefix}.started`, {
8910
10720
  requested_model: requestedModel,
8911
10721
  resolved_model: resolvedModel,
8912
- session_id_present: Boolean(session.sessionId)
10722
+ session_id_present: Boolean(session.sessionId),
10723
+ ...launchTraceEvidenceAttrs
8913
10724
  });
8914
10725
  traceSpan?.end("ok", {
8915
10726
  attrs: {
@@ -8918,11 +10729,13 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8918
10729
  requested_model: requestedModel,
8919
10730
  resolved_model: resolvedModel,
8920
10731
  resolved_model_present: Boolean(model),
8921
- ...piServiceDiagnosticTraceAttrs(services)
10732
+ ...piServiceDiagnosticTraceAttrs(services),
10733
+ ...launchTraceEvidenceAttrs
8922
10734
  }
8923
10735
  });
8924
10736
  console.info(
8925
- "[pi-driver] create_session started sessionId=%s requested=%s resolved=%s",
10737
+ "[%s] create_session started sessionId=%s requested=%s resolved=%s",
10738
+ logPrefix,
8926
10739
  sessionId,
8927
10740
  requestedModel,
8928
10741
  resolvedModel
@@ -8932,7 +10745,8 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
8932
10745
  traceSpan?.end("error", {
8933
10746
  attrs: {
8934
10747
  outcome: "error",
8935
- error_class: error instanceof Error ? error.name : typeof error
10748
+ error_class: error instanceof Error ? error.name : typeof error,
10749
+ ...launchTraceEvidenceAttrs
8936
10750
  }
8937
10751
  });
8938
10752
  throw error;
@@ -9181,6 +10995,48 @@ var PiDriver = class {
9181
10995
  });
9182
10996
  }
9183
10997
  };
10998
+ var BuiltInDriver = class extends PiDriver {
10999
+ id = "builtin";
11000
+ model = {
11001
+ detectedModelsVerifiedAs: "launchable",
11002
+ toLaunchSpec: (modelId) => ({ params: { model: modelId } })
11003
+ };
11004
+ probe() {
11005
+ return {
11006
+ available: true,
11007
+ version: PI_SDK_VERSION
11008
+ };
11009
+ }
11010
+ async detectModels(_ctx) {
11011
+ return { models: RUNTIME_MODELS.builtin };
11012
+ }
11013
+ createSession(ctx) {
11014
+ this.sessionId = ctx.config.sessionId || null;
11015
+ return new PiSdkRuntimeSession(ctx, (sessionId) => {
11016
+ this.sessionId = sessionId;
11017
+ }, (sessionCtx, sessionId) => createPiAgentSessionForContext(sessionCtx, sessionId, {
11018
+ agentDir: buildBuiltInAgentDir(sessionCtx.workingDirectory),
11019
+ sessionDir: buildBuiltInSessionDir(sessionCtx.workingDirectory),
11020
+ traceName: "daemon.builtin.session.create",
11021
+ traceEventPrefix: "daemon.builtin.session",
11022
+ logPrefix: "builtin-driver",
11023
+ agentDirSource: "managed_builtin",
11024
+ exposeLaunchTraceEvidence: true,
11025
+ exposeLaunchEnvToTools: false,
11026
+ isolateHostProviderEnv: true
11027
+ }));
11028
+ }
11029
+ buildSystemPrompt(config, _agentId) {
11030
+ return buildCliTransportSystemPrompt(config, {
11031
+ extraCriticalRules: [],
11032
+ postStartupNotes: [
11033
+ "**Built-in runtime note:** Slock keeps this runtime in an isolated SDK session. While you are working, Slock may send inbox-count notifications into the current turn; call `raft message check` at natural breakpoints."
11034
+ ],
11035
+ includeStdinNotificationSection: true,
11036
+ messageNotificationStyle: "direct"
11037
+ });
11038
+ }
11039
+ };
9184
11040
  function delay(ms) {
9185
11041
  return new Promise((resolve) => {
9186
11042
  const timer = setTimeout(resolve, ms);
@@ -9332,6 +11188,7 @@ function createChildProcessRuntimeSession(driver, ctx) {
9332
11188
 
9333
11189
  // src/drivers/index.ts
9334
11190
  var driverFactories = {
11191
+ builtin: () => new BuiltInDriver(),
9335
11192
  claude: () => new ClaudeDriver(),
9336
11193
  codex: () => new CodexDriver(),
9337
11194
  antigravity: () => new AntigravityDriver(),
@@ -9396,75 +11253,528 @@ async function summarizeWorkspaceEntry(entryPath, entry) {
9396
11253
  latestMtime: info.mtime
9397
11254
  };
9398
11255
  }
9399
- return emptyWorkspaceDirectorySummary(info.mtime);
9400
- } catch {
9401
- return emptyWorkspaceDirectorySummary();
11256
+ return emptyWorkspaceDirectorySummary(info.mtime);
11257
+ } catch {
11258
+ return emptyWorkspaceDirectorySummary();
11259
+ }
11260
+ }
11261
+ async function summarizeWorkspaceDirectory(dirPath) {
11262
+ let summary = emptyWorkspaceDirectorySummary();
11263
+ try {
11264
+ const rootInfo = await stat(dirPath);
11265
+ summary = emptyWorkspaceDirectorySummary(rootInfo.mtime);
11266
+ } catch {
11267
+ return summary;
11268
+ }
11269
+ let entries;
11270
+ try {
11271
+ entries = await readdir(dirPath, { withFileTypes: true });
11272
+ } catch {
11273
+ return summary;
11274
+ }
11275
+ const childSummaries = await Promise.all(
11276
+ entries.map((entry) => summarizeWorkspaceEntry(path13.join(dirPath, entry.name), entry))
11277
+ );
11278
+ for (const childSummary of childSummaries) {
11279
+ summary = mergeWorkspaceDirectorySummaries(summary, childSummary);
11280
+ }
11281
+ return summary;
11282
+ }
11283
+ async function scanWorkspaceDirectories(dataDir) {
11284
+ let entries;
11285
+ try {
11286
+ entries = await readdir(dataDir, { withFileTypes: true });
11287
+ } catch {
11288
+ return [];
11289
+ }
11290
+ const results = await Promise.all(
11291
+ entries.map(async (entry) => {
11292
+ if (!entry.isDirectory()) {
11293
+ return null;
11294
+ }
11295
+ const dirPath = path13.join(dataDir, entry.name);
11296
+ try {
11297
+ const summary = await summarizeWorkspaceDirectory(dirPath);
11298
+ return {
11299
+ directoryName: entry.name,
11300
+ totalSizeBytes: summary.totalSizeBytes,
11301
+ lastModified: summary.latestMtime.toISOString(),
11302
+ fileCount: summary.fileCount
11303
+ };
11304
+ } catch {
11305
+ return null;
11306
+ }
11307
+ })
11308
+ );
11309
+ return results.filter((entry) => entry !== null);
11310
+ }
11311
+ async function deleteWorkspaceDirectory(dataDir, directoryName) {
11312
+ const targetDir = resolveWorkspaceDirectoryPath(dataDir, directoryName);
11313
+ if (!targetDir) {
11314
+ return false;
11315
+ }
11316
+ try {
11317
+ await rm(targetDir, { recursive: true, force: true });
11318
+ logger.info(`[Workspace] Deleted directory: ${targetDir}`);
11319
+ return true;
11320
+ } catch (err) {
11321
+ logger.error(`[Workspace] Failed to delete directory ${targetDir}`, err);
11322
+ return false;
11323
+ }
11324
+ }
11325
+
11326
+ // src/agentStartCoordinator.ts
11327
+ var AgentStartCoordinator = class {
11328
+ starting = /* @__PURE__ */ new Set();
11329
+ queuedByAgent = /* @__PURE__ */ new Map();
11330
+ queue = [];
11331
+ activeStarts = 0;
11332
+ pumpTimer = null;
11333
+ lastStartAt = 0;
11334
+ lastStartAgentId = null;
11335
+ maxConcurrentStarts;
11336
+ minStartIntervalMs;
11337
+ constructor(opts) {
11338
+ this.maxConcurrentStarts = Math.max(1, Math.floor(opts.maxConcurrentStarts));
11339
+ this.minStartIntervalMs = Math.max(0, Math.floor(opts.minStartIntervalMs));
11340
+ this.assertInvariants("constructor");
11341
+ }
11342
+ snapshot() {
11343
+ return {
11344
+ activeStarts: this.activeStarts,
11345
+ queueDepth: this.queue.length,
11346
+ maxConcurrentStarts: this.maxConcurrentStarts,
11347
+ minStartIntervalMs: this.minStartIntervalMs,
11348
+ startingAgentIds: [...this.starting],
11349
+ queuedAgentIds: [...this.queuedByAgent.keys()],
11350
+ pumpTimerActive: this.pumpTimer !== null
11351
+ };
11352
+ }
11353
+ hasStarting(agentId) {
11354
+ return this.starting.has(agentId);
11355
+ }
11356
+ hasQueued(agentId) {
11357
+ return this.queuedByAgent.has(agentId);
11358
+ }
11359
+ getQueued(agentId) {
11360
+ return this.queuedByAgent.get(agentId);
11361
+ }
11362
+ enqueue(item) {
11363
+ if (this.starting.has(item.agentId)) {
11364
+ throw new Error(`Agent start invariant violation after enqueue: ${item.agentId} is already starting`);
11365
+ }
11366
+ if (this.queuedByAgent.has(item.agentId)) {
11367
+ throw new Error(`Agent start invariant violation after enqueue: ${item.agentId} is already queued`);
11368
+ }
11369
+ this.queue.push(item);
11370
+ this.queuedByAgent.set(item.agentId, item);
11371
+ this.assertInvariants("enqueue");
11372
+ }
11373
+ markStarting(agentId) {
11374
+ if (this.queuedByAgent.has(agentId)) {
11375
+ throw new Error(`Agent start invariant violation after markStarting: ${agentId} is still queued`);
11376
+ }
11377
+ this.starting.add(agentId);
11378
+ this.assertInvariants("markStarting");
11379
+ }
11380
+ clearStarting(agentId) {
11381
+ this.starting.delete(agentId);
11382
+ this.assertInvariants("clearStarting");
11383
+ }
11384
+ getPumpState(now = Date.now()) {
11385
+ if (this.pumpTimer) return { kind: "blocked", reason: "timer_active" };
11386
+ if (this.queue.length === 0) return { kind: "blocked", reason: "queue_empty" };
11387
+ if (this.activeStarts >= this.maxConcurrentStarts) return { kind: "blocked", reason: "capacity_full" };
11388
+ const item = this.queue[0];
11389
+ if (!item) return { kind: "blocked", reason: "queue_empty" };
11390
+ const shouldRateLimit = item.agentId !== this.lastStartAgentId;
11391
+ const elapsed = now - this.lastStartAt;
11392
+ const waitMs = shouldRateLimit ? Math.max(0, this.minStartIntervalMs - elapsed) : 0;
11393
+ if (waitMs > 0) return { kind: "rate_limited", item, waitMs };
11394
+ return { kind: "ready", item };
11395
+ }
11396
+ schedulePump(waitMs, callback) {
11397
+ if (this.pumpTimer) return;
11398
+ this.pumpTimer = setTimeout(() => {
11399
+ this.pumpTimer = null;
11400
+ callback();
11401
+ }, waitMs);
11402
+ this.assertInvariants("schedulePump");
11403
+ }
11404
+ dequeue() {
11405
+ const item = this.queue.shift();
11406
+ if (!item) {
11407
+ this.assertInvariants("dequeue empty");
11408
+ return { kind: "empty" };
11409
+ }
11410
+ if (this.queuedByAgent.get(item.agentId) !== item) {
11411
+ this.assertInvariants("dequeue stale");
11412
+ return { kind: "stale", item };
11413
+ }
11414
+ this.queuedByAgent.delete(item.agentId);
11415
+ this.assertInvariants("dequeue");
11416
+ return { kind: "item", item };
11417
+ }
11418
+ claimStartSlot(agentId, now = Date.now()) {
11419
+ this.activeStarts++;
11420
+ this.lastStartAt = now;
11421
+ this.lastStartAgentId = agentId;
11422
+ this.assertInvariants("claimStartSlot");
11423
+ }
11424
+ releaseStartSlot() {
11425
+ if (this.activeStarts <= 0) return false;
11426
+ this.activeStarts = Math.max(0, this.activeStarts - 1);
11427
+ this.assertInvariants("releaseStartSlot");
11428
+ return true;
11429
+ }
11430
+ cancelQueued(agentId) {
11431
+ const item = this.queuedByAgent.get(agentId);
11432
+ if (!item) return void 0;
11433
+ this.queuedByAgent.delete(agentId);
11434
+ this.queue = this.queue.filter((candidate) => candidate !== item);
11435
+ this.clearPumpTimerIfIdle();
11436
+ this.assertInvariants("cancelQueued");
11437
+ return item;
11438
+ }
11439
+ cancelAllQueued(onCancel) {
11440
+ const items = [];
11441
+ for (const item of this.queue) {
11442
+ if (this.queuedByAgent.get(item.agentId) === item) {
11443
+ items.push(item);
11444
+ onCancel?.(item);
11445
+ }
11446
+ }
11447
+ this.queue = [];
11448
+ this.queuedByAgent.clear();
11449
+ this.clearPumpTimer();
11450
+ this.assertInvariants("cancelAllQueued");
11451
+ return items;
11452
+ }
11453
+ assertInvariants(context) {
11454
+ if (this.activeStarts < 0) {
11455
+ throw new Error(`Agent start invariant violation after ${context}: activeStarts is negative`);
11456
+ }
11457
+ if (this.activeStarts > this.maxConcurrentStarts) {
11458
+ throw new Error(`Agent start invariant violation after ${context}: activeStarts exceeds maxConcurrentStarts`);
11459
+ }
11460
+ const queuedIds = /* @__PURE__ */ new Set();
11461
+ for (const item of this.queue) {
11462
+ if (queuedIds.has(item.agentId)) {
11463
+ throw new Error(`Agent start invariant violation after ${context}: duplicate queued agent ${item.agentId}`);
11464
+ }
11465
+ queuedIds.add(item.agentId);
11466
+ if (this.queuedByAgent.get(item.agentId) !== item) {
11467
+ throw new Error(`Agent start invariant violation after ${context}: queue/map mismatch for ${item.agentId}`);
11468
+ }
11469
+ if (this.starting.has(item.agentId)) {
11470
+ throw new Error(`Agent start invariant violation after ${context}: ${item.agentId} is queued and starting`);
11471
+ }
11472
+ }
11473
+ if (queuedIds.size !== this.queuedByAgent.size) {
11474
+ throw new Error(`Agent start invariant violation after ${context}: queue/map size mismatch`);
11475
+ }
11476
+ for (const [agentId, item] of this.queuedByAgent) {
11477
+ if (!queuedIds.has(agentId)) {
11478
+ throw new Error(`Agent start invariant violation after ${context}: map-only queued agent ${agentId}`);
11479
+ }
11480
+ if (item.agentId !== agentId) {
11481
+ throw new Error(`Agent start invariant violation after ${context}: map key/item agent mismatch for ${agentId}`);
11482
+ }
11483
+ }
11484
+ }
11485
+ setMaxConcurrentStartsForTesting(value) {
11486
+ this.maxConcurrentStarts = Math.max(1, Math.floor(value));
11487
+ if (this.activeStarts > this.maxConcurrentStarts) {
11488
+ this.activeStarts = this.maxConcurrentStarts;
11489
+ }
11490
+ this.assertInvariants("setMaxConcurrentStartsForTesting");
11491
+ }
11492
+ setActiveStartsForTesting(value) {
11493
+ this.activeStarts = Math.max(0, Math.floor(value));
11494
+ this.assertInvariants("setActiveStartsForTesting");
11495
+ }
11496
+ clearPumpTimerIfIdle() {
11497
+ if (this.queue.length === 0) {
11498
+ this.clearPumpTimer();
11499
+ }
11500
+ }
11501
+ clearPumpTimer() {
11502
+ if (this.pumpTimer) {
11503
+ clearTimeout(this.pumpTimer);
11504
+ this.pumpTimer = null;
11505
+ }
11506
+ }
11507
+ };
11508
+
11509
+ // src/agentStartPendingDeliveryBuffer.ts
11510
+ var AgentStartPendingDeliveryBuffer = class {
11511
+ pending = /* @__PURE__ */ new Map();
11512
+ count(agentId) {
11513
+ return this.pending.get(agentId)?.length ?? 0;
11514
+ }
11515
+ has(agentId) {
11516
+ return this.pending.has(agentId);
11517
+ }
11518
+ get size() {
11519
+ return this.pending.size;
11520
+ }
11521
+ values(agentId) {
11522
+ return [...this.pending.get(agentId) ?? []];
11523
+ }
11524
+ bufferDuringStart(agentId, message) {
11525
+ return this.append(agentId, [message], "bufferDuringStart");
11526
+ }
11527
+ bufferMessagesDuringStart(agentId, messages) {
11528
+ return this.append(agentId, messages, "bufferMessagesDuringStart");
11529
+ }
11530
+ rebindWake(agentId, previousWakeMessage, nextWakeMessage, sameWakeMessage) {
11531
+ if (!previousWakeMessage || !nextWakeMessage || sameWakeMessage(previousWakeMessage, nextWakeMessage)) {
11532
+ return this.count(agentId);
11533
+ }
11534
+ return this.append(agentId, [previousWakeMessage], "rebindWake");
11535
+ }
11536
+ drainOnSpawn(agentId) {
11537
+ const messages = this.pending.get(agentId) ?? [];
11538
+ this.pending.delete(agentId);
11539
+ this.assertInternalInvariants("drainOnSpawn");
11540
+ return messages;
11541
+ }
11542
+ cancelStart(agentId) {
11543
+ this.pending.delete(agentId);
11544
+ this.assertInternalInvariants("cancelStart");
11545
+ }
11546
+ cancelAllStarts() {
11547
+ this.pending.clear();
11548
+ this.assertInternalInvariants("cancelAllStarts");
11549
+ }
11550
+ suppressConsumed(agentId, predicate) {
11551
+ const messages = this.pending.get(agentId);
11552
+ if (!messages || messages.length === 0) return 0;
11553
+ let removed = 0;
11554
+ const retained = messages.filter((message) => {
11555
+ const matched = predicate(message);
11556
+ if (matched) removed += 1;
11557
+ return !matched;
11558
+ });
11559
+ if (retained.length === 0) {
11560
+ this.pending.delete(agentId);
11561
+ } else {
11562
+ this.pending.set(agentId, retained);
11563
+ }
11564
+ this.assertInternalInvariants("suppressConsumed");
11565
+ return removed;
11566
+ }
11567
+ purge(agentId, predicate) {
11568
+ return this.suppressConsumed(agentId, predicate);
11569
+ }
11570
+ assertInvariants(context, snapshot) {
11571
+ this.assertInternalInvariants(context);
11572
+ const allowed = /* @__PURE__ */ new Set([
11573
+ ...snapshot.queuedAgentIds,
11574
+ ...snapshot.startingAgentIds,
11575
+ ...snapshot.terminalRecoveryAgentIds ?? [],
11576
+ ...snapshot.cooldownAgentIds ?? []
11577
+ ]);
11578
+ for (const agentId of this.pending.keys()) {
11579
+ if (!allowed.has(agentId)) {
11580
+ throw new Error(`Agent start pending delivery invariant violation after ${context}: pending messages for non-starting agent ${agentId}`);
11581
+ }
11582
+ }
11583
+ }
11584
+ append(agentId, messages, context) {
11585
+ if (messages.length === 0) return this.count(agentId);
11586
+ const existing = this.pending.get(agentId);
11587
+ if (existing) {
11588
+ existing.push(...messages);
11589
+ } else {
11590
+ this.pending.set(agentId, [...messages]);
11591
+ }
11592
+ this.assertInternalInvariants(context);
11593
+ return this.count(agentId);
11594
+ }
11595
+ assertInternalInvariants(context) {
11596
+ for (const [agentId, messages] of this.pending) {
11597
+ if (!agentId) {
11598
+ throw new Error(`Agent start pending delivery invariant violation after ${context}: empty agent id`);
11599
+ }
11600
+ if (messages.length === 0) {
11601
+ throw new Error(`Agent start pending delivery invariant violation after ${context}: empty pending buffer for ${agentId}`);
11602
+ }
11603
+ }
11604
+ }
11605
+ };
11606
+
11607
+ // src/agentVisibleDeliveryLedger.ts
11608
+ function getMessageShortId(messageId2) {
11609
+ return messageId2.startsWith("thread-") ? messageId2.slice(7) : messageId2.slice(0, 8);
11610
+ }
11611
+ function computeTarget(channelType, channelName, parentChannelName, parentChannelType) {
11612
+ if (channelType === "thread" && parentChannelName) {
11613
+ const shortId = getMessageShortId(String(channelName ?? ""));
11614
+ if (parentChannelType === "dm") {
11615
+ return `dm:@${parentChannelName}:${shortId}`;
11616
+ }
11617
+ return `#${parentChannelName}:${shortId}`;
9402
11618
  }
11619
+ if (channelType === "dm") {
11620
+ return `dm:@${channelName}`;
11621
+ }
11622
+ return `#${channelName}`;
9403
11623
  }
9404
- async function summarizeWorkspaceDirectory(dirPath) {
9405
- let summary = emptyWorkspaceDirectorySummary();
9406
- try {
9407
- const rootInfo = await stat(dirPath);
9408
- summary = emptyWorkspaceDirectorySummary(rootInfo.mtime);
9409
- } catch {
9410
- return summary;
11624
+ function formatAgentMessageVisibleTarget(message) {
11625
+ return computeTarget(message.channel_type, message.channel_name, message.parent_channel_name, message.parent_channel_type);
11626
+ }
11627
+ function formatProxyVisibleMessageTarget(message) {
11628
+ return computeTarget(message.channel_type, message.channel_name, message.parent_channel_name, message.parent_channel_type);
11629
+ }
11630
+ function hasTargetMetadata(message) {
11631
+ if (message.channel_type === "thread") return Boolean(message.parent_channel_name && message.channel_name);
11632
+ return Boolean(message.channel_type && message.channel_name);
11633
+ }
11634
+ function visibleMessageId(message) {
11635
+ if (typeof message.message_id === "string") return String(message.message_id);
11636
+ if (typeof message.id === "string") return String(message.id);
11637
+ return "";
11638
+ }
11639
+ function isTrueDeliveryConsumeSource(source) {
11640
+ return source === "spawn_wake_message" || source === "agent_api_events_local" || source.startsWith("stdin_");
11641
+ }
11642
+ var AgentVisibleDeliveryLedger = class {
11643
+ boundaryByAgent = /* @__PURE__ */ new Map();
11644
+ messageIdsByAgent = /* @__PURE__ */ new Map();
11645
+ clearAgent(agentId) {
11646
+ this.boundaryByAgent.delete(agentId);
11647
+ this.messageIdsByAgent.delete(agentId);
9411
11648
  }
9412
- let entries;
9413
- try {
9414
- entries = await readdir(dirPath, { withFileTypes: true });
9415
- } catch {
9416
- return summary;
11649
+ hasAgentState(agentId) {
11650
+ return this.boundaryByAgent.has(agentId) || this.messageIdsByAgent.has(agentId);
9417
11651
  }
9418
- const childSummaries = await Promise.all(
9419
- entries.map((entry) => summarizeWorkspaceEntry(path13.join(dirPath, entry.name), entry))
9420
- );
9421
- for (const childSummary of childSummaries) {
9422
- summary = mergeWorkspaceDirectorySummaries(summary, childSummary);
11652
+ getBoundary(agentId, target) {
11653
+ return this.boundaryByAgent.get(agentId)?.get(target);
9423
11654
  }
9424
- return summary;
9425
- }
9426
- async function scanWorkspaceDirectories(dataDir) {
9427
- let entries;
9428
- try {
9429
- entries = await readdir(dataDir, { withFileTypes: true });
9430
- } catch {
9431
- return [];
11655
+ getMessageIdSet(agentId, target) {
11656
+ return this.messageIdsByAgent.get(agentId)?.get(target);
9432
11657
  }
9433
- const results = await Promise.all(
9434
- entries.map(async (entry) => {
9435
- if (!entry.isDirectory()) {
9436
- return null;
11658
+ isModelSeen(agentId, target, message) {
11659
+ const seq = Number(message.seq ?? 0);
11660
+ const boundary = this.getBoundary(agentId, target);
11661
+ if (Number.isFinite(seq) && seq > 0 && typeof boundary === "number" && boundary >= Math.floor(seq)) return true;
11662
+ const id = visibleMessageId(message);
11663
+ return id.length > 0 && this.getMessageIdSet(agentId, target)?.has(id) === true;
11664
+ }
11665
+ recordConsumed(agentId, input) {
11666
+ if (input.messages.length === 0 && (!input.target || typeof input.boundarySeq !== "number")) return null;
11667
+ const byTarget = /* @__PURE__ */ new Map();
11668
+ const ensureBucket = (target) => {
11669
+ let bucket = byTarget.get(target);
11670
+ if (!bucket) {
11671
+ bucket = { maxSeq: 0, boundarySeq: 0, seqs: /* @__PURE__ */ new Set(), ids: /* @__PURE__ */ new Set() };
11672
+ byTarget.set(target, bucket);
9437
11673
  }
9438
- const dirPath = path13.join(dataDir, entry.name);
9439
- try {
9440
- const summary = await summarizeWorkspaceDirectory(dirPath);
9441
- return {
9442
- directoryName: entry.name,
9443
- totalSizeBytes: summary.totalSizeBytes,
9444
- lastModified: summary.latestMtime.toISOString(),
9445
- fileCount: summary.fileCount
9446
- };
9447
- } catch {
9448
- return null;
11674
+ return bucket;
11675
+ };
11676
+ for (const message of input.messages) {
11677
+ const messageTarget = formatProxyVisibleMessageTarget(message);
11678
+ if (input.target && hasTargetMetadata(message) && messageTarget !== input.target) {
11679
+ throw new Error(`AgentVisibleDeliveryLedger target mismatch: explicit target ${input.target} does not match visible message target ${messageTarget}`);
9449
11680
  }
9450
- })
9451
- );
9452
- return results.filter((entry) => entry !== null);
9453
- }
9454
- async function deleteWorkspaceDirectory(dataDir, directoryName) {
9455
- const targetDir = resolveWorkspaceDirectoryPath(dataDir, directoryName);
9456
- if (!targetDir) {
9457
- return false;
11681
+ const target = input.target ?? messageTarget;
11682
+ if (!target) continue;
11683
+ const bucket = ensureBucket(target);
11684
+ const seq = Number(message.seq ?? 0);
11685
+ if (Number.isFinite(seq) && seq > 0) {
11686
+ const normalizedSeq = Math.floor(seq);
11687
+ bucket.maxSeq = Math.max(bucket.maxSeq, normalizedSeq);
11688
+ bucket.seqs.add(normalizedSeq);
11689
+ }
11690
+ const id = visibleMessageId(message);
11691
+ if (id.length > 0) bucket.ids.add(id);
11692
+ }
11693
+ if (input.target && typeof input.boundarySeq === "number" && Number.isFinite(input.boundarySeq) && input.boundarySeq > 0) {
11694
+ const bucket = ensureBucket(input.target);
11695
+ bucket.boundarySeq = Math.max(bucket.boundarySeq, Math.floor(input.boundarySeq));
11696
+ }
11697
+ if (byTarget.size === 0) return null;
11698
+ const advancesBoundary = isTrueDeliveryConsumeSource(input.source);
11699
+ for (const [target, bucket] of byTarget) {
11700
+ const previousBoundary = this.getBoundary(agentId, target);
11701
+ if (advancesBoundary) {
11702
+ const highWaterSeq = Math.max(bucket.maxSeq, bucket.boundarySeq);
11703
+ const boundaryMap = this.boundaryMap(agentId);
11704
+ boundaryMap.set(target, Math.max(previousBoundary ?? 0, highWaterSeq));
11705
+ }
11706
+ if (bucket.ids.size > 0) {
11707
+ const targetIds = this.messageIdSet(agentId, target);
11708
+ for (const id of bucket.ids) targetIds.add(id);
11709
+ }
11710
+ this.assertConsumedInvariants("recordConsumed", agentId, target, bucket, {
11711
+ advancesBoundary,
11712
+ previousBoundary
11713
+ });
11714
+ }
11715
+ return {
11716
+ targets: [...byTarget.keys()],
11717
+ messagesCount: input.messages.length,
11718
+ shouldSuppress(message) {
11719
+ const target = formatAgentMessageVisibleTarget(message);
11720
+ const bucket = byTarget.get(target);
11721
+ if (!bucket) return false;
11722
+ const seq = typeof message.seq === "number" ? Math.floor(message.seq) : 0;
11723
+ const id = visibleMessageId(message);
11724
+ return seq > 0 && bucket.boundarySeq > 0 && seq <= bucket.boundarySeq || seq > 0 && bucket.seqs.has(seq) || id.length > 0 && bucket.ids.has(id);
11725
+ }
11726
+ };
9458
11727
  }
9459
- try {
9460
- await rm(targetDir, { recursive: true, force: true });
9461
- logger.info(`[Workspace] Deleted directory: ${targetDir}`);
9462
- return true;
9463
- } catch (err) {
9464
- logger.error(`[Workspace] Failed to delete directory ${targetDir}`, err);
9465
- return false;
11728
+ boundaryMap(agentId) {
11729
+ let map = this.boundaryByAgent.get(agentId);
11730
+ if (!map) {
11731
+ map = /* @__PURE__ */ new Map();
11732
+ this.boundaryByAgent.set(agentId, map);
11733
+ }
11734
+ return map;
9466
11735
  }
9467
- }
11736
+ messageIdMap(agentId) {
11737
+ let map = this.messageIdsByAgent.get(agentId);
11738
+ if (!map) {
11739
+ map = /* @__PURE__ */ new Map();
11740
+ this.messageIdsByAgent.set(agentId, map);
11741
+ }
11742
+ return map;
11743
+ }
11744
+ messageIdSet(agentId, target) {
11745
+ const map = this.messageIdMap(agentId);
11746
+ let ids = map.get(target);
11747
+ if (!ids) {
11748
+ ids = /* @__PURE__ */ new Set();
11749
+ map.set(target, ids);
11750
+ }
11751
+ return ids;
11752
+ }
11753
+ assertConsumedInvariants(context, agentId, target, bucket, options) {
11754
+ const boundary = this.getBoundary(agentId, target);
11755
+ if (!options.advancesBoundary && boundary !== options.previousBoundary) {
11756
+ throw new Error(`Agent visible delivery ledger invariant violation after ${context}: set-only source advanced boundary for ${agentId} ${target}`);
11757
+ }
11758
+ if (options.advancesBoundary) {
11759
+ const highWaterSeq = Math.max(bucket.maxSeq, bucket.boundarySeq);
11760
+ const normalizedBoundary = boundary ?? 0;
11761
+ if (normalizedBoundary < (options.previousBoundary ?? 0)) {
11762
+ throw new Error(`Agent visible delivery ledger invariant violation after ${context}: boundary regressed for ${agentId} ${target}`);
11763
+ }
11764
+ if (highWaterSeq > 0 && normalizedBoundary < highWaterSeq) {
11765
+ throw new Error(`Agent visible delivery ledger invariant violation after ${context}: boundary below consumed high-water for ${agentId} ${target}`);
11766
+ }
11767
+ }
11768
+ if (bucket.ids.size > 0) {
11769
+ const targetIds = this.getMessageIdSet(agentId, target);
11770
+ for (const id of bucket.ids) {
11771
+ if (targetIds?.has(id) !== true) {
11772
+ throw new Error(`Agent visible delivery ledger invariant violation after ${context}: missing consumed message id for ${agentId} ${target}`);
11773
+ }
11774
+ }
11775
+ }
11776
+ }
11777
+ };
9468
11778
 
9469
11779
  // src/runtimeErrorDiagnostics.ts
9470
11780
  import { createHash as createHash2 } from "crypto";
@@ -9975,26 +12285,10 @@ function toLocalTime(iso) {
9975
12285
  function formatChannelLabel(message) {
9976
12286
  return message.channel_type === "dm" ? `DM:@${message.channel_name}` : `#${message.channel_name}`;
9977
12287
  }
9978
- function computeTarget(channelType, channelName, parentChannelName, parentChannelType) {
9979
- if (channelType === "thread" && parentChannelName) {
9980
- const shortId = getMessageShortId(String(channelName ?? ""));
9981
- if (parentChannelType === "dm") {
9982
- return `dm:@${parentChannelName}:${shortId}`;
9983
- }
9984
- return `#${parentChannelName}:${shortId}`;
9985
- }
9986
- if (channelType === "dm") {
9987
- return `dm:@${channelName}`;
9988
- }
9989
- return `#${channelName}`;
9990
- }
9991
12288
  function formatMessageTarget(message) {
9992
- return computeTarget(message.channel_type, message.channel_name, message.parent_channel_name, message.parent_channel_type);
12289
+ return formatAgentMessageVisibleTarget(message);
9993
12290
  }
9994
- function formatVisibleMessageTarget(message) {
9995
- return computeTarget(message.channel_type, message.channel_name, message.parent_channel_name, message.parent_channel_type);
9996
- }
9997
- function getMessageShortId(messageId2) {
12291
+ function getMessageShortId2(messageId2) {
9998
12292
  return messageId2.startsWith("thread-") ? messageId2.slice(7) : messageId2.slice(0, 8);
9999
12293
  }
10000
12294
  var RESPONSE_TARGET_HINT = "Reply in the channel or create/reply in a thread as appropriate; use each message's `target` and `msg` fields to choose the exact target.";
@@ -10261,31 +12555,11 @@ function formatTaskAssigneeType(type) {
10261
12555
  return type ?? null;
10262
12556
  }
10263
12557
  function formatThreadContextMessage(message) {
10264
- const msgId = message.message_id ? getMessageShortId(message.message_id) : "-";
12558
+ const msgId = message.message_id ? getMessageShortId2(message.message_id) : "-";
10265
12559
  const time = message.timestamp ? toLocalTime(message.timestamp) : "-";
10266
12560
  const senderType = formatVisibleActorType(message.sender_type);
10267
12561
  return `- [msg=${msgId} time=${time}${senderType}] ${formatSenderHandle(message)}: ${message.content}`;
10268
12562
  }
10269
- function communicationCommand(name) {
10270
- switch (name) {
10271
- case "send_message":
10272
- return "raft message send";
10273
- case "read_history":
10274
- return "raft message read";
10275
- case "check_messages":
10276
- return "raft message check";
10277
- case "claim_tasks":
10278
- return "raft task claim";
10279
- default:
10280
- return `raft ${name.replace(/_/g, " ")}`;
10281
- }
10282
- }
10283
- function dynamicReplyInstruction() {
10284
- return "reply using `raft message send --target <exact target>`";
10285
- }
10286
- function dynamicClaimInstruction() {
10287
- return "claim the relevant task with `raft task claim`";
10288
- }
10289
12563
  function formatIncomingMessage(message, options = {}) {
10290
12564
  const threadJoinPrefix = message.thread_join_context ? [
10291
12565
  `[Slock thread context: you were added to a new thread via @mention.]`,
@@ -10301,7 +12575,7 @@ function formatIncomingMessage(message, options = {}) {
10301
12575
  ""
10302
12576
  ].join("\n") : "";
10303
12577
  const target = formatMessageTarget(message);
10304
- const msgId = message.message_id ? getMessageShortId(message.message_id) : "-";
12578
+ const msgId = message.message_id ? getMessageShortId2(message.message_id) : "-";
10305
12579
  const time = message.timestamp ? toLocalTime(message.timestamp) : "-";
10306
12580
  const senderType = formatVisibleActorType(message.sender_type);
10307
12581
  const attachSuffix = formatAttachmentSuffix(message.attachments, options.attachmentHint);
@@ -11260,17 +13534,8 @@ var AgentProcessManager = class _AgentProcessManager {
11260
13534
  this.activityClientSeqByAgent.set(agentId, next);
11261
13535
  return next;
11262
13536
  }
11263
- agentsStarting = /* @__PURE__ */ new Set();
11264
- // Prevent concurrent starts of same agent
11265
- queuedAgentStarts = /* @__PURE__ */ new Map();
11266
- agentStartQueue = [];
11267
- activeAgentStartCount = 0;
11268
- agentStartPumpTimer = null;
11269
- lastAgentStartAt = 0;
11270
- lastAgentStartAgentId = null;
11271
- maxConcurrentAgentStarts;
11272
- agentStartIntervalMs;
11273
- startingInboxes = /* @__PURE__ */ new Map();
13537
+ agentStarts;
13538
+ startingInboxes = new AgentStartPendingDeliveryBuffer();
11274
13539
  terminalRuntimeFailures = /* @__PURE__ */ new Map();
11275
13540
  runtimeErrorFingerprintFences = /* @__PURE__ */ new Map();
11276
13541
  pendingStartRebinds = /* @__PURE__ */ new Map();
@@ -11294,8 +13559,7 @@ var AgentProcessManager = class _AgentProcessManager {
11294
13559
  cliTransportTraceDir = null;
11295
13560
  deliveryTraceContexts = /* @__PURE__ */ new WeakMap();
11296
13561
  runtimeExitTraceAttrs = /* @__PURE__ */ new WeakMap();
11297
- agentVisibleBoundaries = /* @__PURE__ */ new Map();
11298
- agentVisibleMessageIds = /* @__PURE__ */ new Map();
13562
+ agentVisibleDelivery = new AgentVisibleDeliveryLedger();
11299
13563
  // Spawn-fail backoff state per-agent (lifted outside AgentProcess because spawn fails
11300
13564
  // BEFORE ap exists; rate-state must persist across stop/respawn so churn can't bypass).
11301
13565
  // Explicit stop clears (fresh launch resets dedup clock — CC1 lifecycle pattern); silent
@@ -11340,18 +13604,10 @@ var AgentProcessManager = class _AgentProcessManager {
11340
13604
  Math.min(1, opts.runtimeErrorDeliveryBackoff?.jitterRatio ?? 0.1)
11341
13605
  );
11342
13606
  this.runtimeErrorDeliveryBackoffFailPointForTesting = opts.runtimeErrorDeliveryBackoff?.failPointForTesting ?? null;
11343
- this.maxConcurrentAgentStarts = Math.max(
11344
- 1,
11345
- Math.floor(
11346
- opts.runtimeStartScheduler?.maxConcurrentStarts ?? readPositiveIntegerEnv("SLOCK_DAEMON_MAX_CONCURRENT_AGENT_STARTS", DEFAULT_MAX_CONCURRENT_AGENT_STARTS)
11347
- )
11348
- );
11349
- this.agentStartIntervalMs = Math.max(
11350
- 0,
11351
- Math.floor(
11352
- opts.runtimeStartScheduler?.minStartIntervalMs ?? readNonNegativeIntegerEnv("SLOCK_DAEMON_AGENT_START_INTERVAL_MS", DEFAULT_AGENT_START_INTERVAL_MS)
11353
- )
11354
- );
13607
+ this.agentStarts = new AgentStartCoordinator({
13608
+ maxConcurrentStarts: opts.runtimeStartScheduler?.maxConcurrentStarts ?? readPositiveIntegerEnv("SLOCK_DAEMON_MAX_CONCURRENT_AGENT_STARTS", DEFAULT_MAX_CONCURRENT_AGENT_STARTS),
13609
+ minStartIntervalMs: opts.runtimeStartScheduler?.minStartIntervalMs ?? readNonNegativeIntegerEnv("SLOCK_DAEMON_AGENT_START_INTERVAL_MS", DEFAULT_AGENT_START_INTERVAL_MS)
13610
+ });
11355
13611
  }
11356
13612
  setTracer(tracer) {
11357
13613
  this.tracer = tracer;
@@ -11359,34 +13615,23 @@ var AgentProcessManager = class _AgentProcessManager {
11359
13615
  setCliTransportTraceDir(traceDir) {
11360
13616
  this.cliTransportTraceDir = traceDir;
11361
13617
  }
11362
- visibleBoundaryMap(agentId) {
11363
- let map = this.agentVisibleBoundaries.get(agentId);
11364
- if (!map) {
11365
- map = /* @__PURE__ */ new Map();
11366
- this.agentVisibleBoundaries.set(agentId, map);
11367
- }
11368
- return map;
13618
+ assertStartPendingDeliveryInvariants(context) {
13619
+ const startSnapshot = this.agentStarts.snapshot();
13620
+ this.startingInboxes.assertInvariants(context, {
13621
+ queuedAgentIds: startSnapshot.queuedAgentIds,
13622
+ startingAgentIds: startSnapshot.startingAgentIds,
13623
+ terminalRecoveryAgentIds: [...this.terminalRuntimeFailures.keys()],
13624
+ cooldownAgentIds: [...this.agentSpawnFailBackoff.keys()]
13625
+ });
11369
13626
  }
11370
13627
  getVisibleBoundary(agentId, target) {
11371
- return this.agentVisibleBoundaries.get(agentId)?.get(target);
11372
- }
11373
- visibleMessageIdMap(agentId) {
11374
- let map = this.agentVisibleMessageIds.get(agentId);
11375
- if (!map) {
11376
- map = /* @__PURE__ */ new Map();
11377
- this.agentVisibleMessageIds.set(agentId, map);
11378
- }
11379
- return map;
13628
+ return this.agentVisibleDelivery.getBoundary(agentId, target);
11380
13629
  }
11381
13630
  getVisibleMessageIdSet(agentId, target) {
11382
- return this.agentVisibleMessageIds.get(agentId)?.get(target);
13631
+ return this.agentVisibleDelivery.getMessageIdSet(agentId, target);
11383
13632
  }
11384
13633
  isVisibleMessageModelSeen(agentId, target, message) {
11385
- const seq = Number(message.seq ?? 0);
11386
- const boundary = this.getVisibleBoundary(agentId, target);
11387
- if (Number.isFinite(seq) && seq > 0 && typeof boundary === "number" && boundary >= Math.floor(seq)) return true;
11388
- const id = typeof message.message_id === "string" ? message.message_id : typeof message.id === "string" ? message.id : "";
11389
- return id.length > 0 && this.getVisibleMessageIdSet(agentId, target)?.has(id) === true;
13634
+ return this.agentVisibleDelivery.isModelSeen(agentId, target, message);
11390
13635
  }
11391
13636
  // ----- SPAWN-FAIL BACKOFF (per-agent) ----------------------------------
11392
13637
  // Anchored at auto_restart_from_idle (apm:3596) + runtime_profile_auto_restart (apm:4137).
@@ -11828,7 +14073,7 @@ var AgentProcessManager = class _AgentProcessManager {
11828
14073
  const collect = (messages) => (messages ?? []).filter((message) => typeof message.seq === "number" && message.seq > 0);
11829
14074
  return [
11830
14075
  ...collect(this.agents.get(agentId)?.inbox),
11831
- ...collect(this.startingInboxes.get(agentId))
14076
+ ...collect(this.startingInboxes.values(agentId))
11832
14077
  ];
11833
14078
  }
11834
14079
  pendingVisibleMessages(agentId, target) {
@@ -11841,61 +14086,13 @@ var AgentProcessManager = class _AgentProcessManager {
11841
14086
  * same seq must not be injected later through the local pending queue.
11842
14087
  */
11843
14088
  consumeVisibleMessages(agentId, input) {
11844
- if (input.messages.length === 0 && (!input.target || typeof input.boundarySeq !== "number")) return;
11845
- const byTarget = /* @__PURE__ */ new Map();
11846
- const ensureBucket = (target) => {
11847
- let bucket = byTarget.get(target);
11848
- if (!bucket) {
11849
- bucket = { maxSeq: 0, boundarySeq: 0, seqs: /* @__PURE__ */ new Set(), ids: /* @__PURE__ */ new Set() };
11850
- byTarget.set(target, bucket);
11851
- }
11852
- return bucket;
11853
- };
11854
- for (const message of input.messages) {
11855
- const seq = Number(message.seq ?? 0);
11856
- const target = input.target ?? formatVisibleMessageTarget(message);
11857
- if (!target) continue;
11858
- const bucket = ensureBucket(target);
11859
- if (Number.isFinite(seq) && seq > 0) {
11860
- bucket.maxSeq = Math.max(bucket.maxSeq, Math.floor(seq));
11861
- bucket.seqs.add(Math.floor(seq));
11862
- }
11863
- const id = typeof message.message_id === "string" ? message.message_id : typeof message.id === "string" ? message.id : null;
11864
- if (id) bucket.ids.add(id);
11865
- }
11866
- if (input.target && typeof input.boundarySeq === "number" && Number.isFinite(input.boundarySeq) && input.boundarySeq > 0) {
11867
- const bucket = ensureBucket(input.target);
11868
- bucket.boundarySeq = Math.max(bucket.boundarySeq, Math.floor(input.boundarySeq));
11869
- }
11870
- if (byTarget.size === 0) return;
11871
- const boundaryMap = this.visibleBoundaryMap(agentId);
11872
- const visibleIds = this.visibleMessageIdMap(agentId);
11873
- const advancesBoundary = input.source === "spawn_wake_message" || input.source === "agent_api_events_local" || input.source.startsWith("stdin_");
11874
- for (const [target, bucket] of byTarget) {
11875
- if (advancesBoundary) {
11876
- const highWaterSeq = Math.max(bucket.maxSeq, bucket.boundarySeq);
11877
- const previous = boundaryMap.get(target) ?? 0;
11878
- boundaryMap.set(target, Math.max(previous, highWaterSeq));
11879
- }
11880
- if (bucket.ids.size > 0) {
11881
- let targetIds = visibleIds.get(target);
11882
- if (!targetIds) {
11883
- targetIds = /* @__PURE__ */ new Set();
11884
- visibleIds.set(target, targetIds);
11885
- }
11886
- for (const id of bucket.ids) targetIds.add(id);
11887
- }
11888
- }
14089
+ const consumed = this.agentVisibleDelivery.recordConsumed(agentId, input);
14090
+ if (!consumed) return;
11889
14091
  const suppress = (messages) => {
11890
14092
  if (!messages || messages.length === 0) return 0;
11891
14093
  let removed = 0;
11892
14094
  const retained = messages.filter((message) => {
11893
- const target = formatMessageTarget(message);
11894
- const bucket = byTarget.get(target);
11895
- if (!bucket) return true;
11896
- const seq = typeof message.seq === "number" ? Math.floor(message.seq) : 0;
11897
- const id = message.message_id ?? "";
11898
- const matched = seq > 0 && bucket.boundarySeq > 0 && seq <= bucket.boundarySeq || seq > 0 && bucket.seqs.has(seq) || id.length > 0 && bucket.ids.has(id);
14095
+ const matched = consumed.shouldSuppress(message);
11899
14096
  if (matched) removed += 1;
11900
14097
  return !matched;
11901
14098
  });
@@ -11904,12 +14101,13 @@ var AgentProcessManager = class _AgentProcessManager {
11904
14101
  };
11905
14102
  const active = this.agents.get(agentId);
11906
14103
  const removedActive = suppress(active?.inbox);
11907
- const removedStarting = suppress(this.startingInboxes.get(agentId));
14104
+ const removedStarting = this.startingInboxes.suppressConsumed(agentId, consumed.shouldSuppress);
14105
+ this.assertStartPendingDeliveryInvariants("visible-consume");
11908
14106
  this.recordDaemonTrace("daemon.agent.inbox.visible_consumed", {
11909
14107
  agentId,
11910
14108
  source: input.source,
11911
- targets: [...byTarget.keys()],
11912
- messages_count: input.messages.length,
14109
+ targets: consumed.targets,
14110
+ messages_count: consumed.messagesCount,
11913
14111
  suppressed_pending_count: removedActive + removedStarting
11914
14112
  });
11915
14113
  }
@@ -11931,11 +14129,8 @@ var AgentProcessManager = class _AgentProcessManager {
11931
14129
  };
11932
14130
  const active = this.agents.get(agentId);
11933
14131
  const removedActive = purge(active?.inbox);
11934
- const startingInbox = this.startingInboxes.get(agentId);
11935
- const removedStarting = purge(startingInbox);
11936
- if (startingInbox && startingInbox.length === 0) {
11937
- this.startingInboxes.delete(agentId);
11938
- }
14132
+ const removedStarting = this.startingInboxes.purge(agentId, (message) => channelIdSet.has(message.channel_id));
14133
+ this.assertStartPendingDeliveryInvariants("purge-starting-inbox");
11939
14134
  if (active && removedActive > 0) {
11940
14135
  active.notifications.remove(removedActive);
11941
14136
  if (active.inbox.length === 0) {
@@ -11952,7 +14147,7 @@ var AgentProcessManager = class _AgentProcessManager {
11952
14147
  removed_starting_count: removedStarting,
11953
14148
  removed_count: removedCount,
11954
14149
  active_inbox_count: active?.inbox.length ?? 0,
11955
- starting_inbox_count: this.startingInboxes.get(agentId)?.length ?? 0
14150
+ starting_inbox_count: this.startingInboxes.count(agentId)
11956
14151
  });
11957
14152
  return { removedCount };
11958
14153
  }
@@ -12025,7 +14220,7 @@ var AgentProcessManager = class _AgentProcessManager {
12025
14220
  recordFreshnessDecisionActivity(agentId, input, producerFactId) {
12026
14221
  if (input.decision !== "local_hold" && input.decision !== "syncing_hold") return;
12027
14222
  const ap = this.agents.get(agentId);
12028
- const messageCount = input.pendingCount ?? input.heldMessageCount ?? 0;
14223
+ const messageCount = input.decision === "syncing_hold" ? input.heldMessageCount ?? input.pendingCount ?? 0 : input.pendingCount ?? input.heldMessageCount ?? 0;
12029
14224
  const entry = projectApmHeldFreshnessActivity({
12030
14225
  producerFactId,
12031
14226
  action: input.action,
@@ -12099,6 +14294,7 @@ var AgentProcessManager = class _AgentProcessManager {
12099
14294
  };
12100
14295
  }
12101
14296
  startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
14297
+ const startSnapshot = this.agentStarts.snapshot();
12102
14298
  return {
12103
14299
  agentId,
12104
14300
  launchId,
@@ -12110,10 +14306,10 @@ var AgentProcessManager = class _AgentProcessManager {
12110
14306
  wake_message_transient: Boolean(wakeMessage && wakeMessageTransient),
12111
14307
  unread_channels_count: unreadSummary ? Object.keys(unreadSummary).length : 0,
12112
14308
  resume_prompt_present: Boolean(resumePrompt),
12113
- queue_depth: this.agentStartQueue.length,
12114
- active_starts: this.activeAgentStartCount,
12115
- max_concurrent_starts: this.maxConcurrentAgentStarts,
12116
- min_start_interval_ms: this.agentStartIntervalMs,
14309
+ queue_depth: startSnapshot.queueDepth,
14310
+ active_starts: startSnapshot.activeStarts,
14311
+ max_concurrent_starts: startSnapshot.maxConcurrentStarts,
14312
+ min_start_interval_ms: startSnapshot.minStartIntervalMs,
12117
14313
  ...this.runtimeLaunchPolicyTraceAttrs(config)
12118
14314
  };
12119
14315
  }
@@ -12199,18 +14395,20 @@ var AgentProcessManager = class _AgentProcessManager {
12199
14395
  return left === right;
12200
14396
  }
12201
14397
  rebindQueuedStart(agentId, start, reason) {
12202
- const item = this.queuedAgentStarts.get(agentId);
14398
+ const item = this.agentStarts.getQueued(agentId);
12203
14399
  if (!item) {
12204
14400
  return false;
12205
14401
  }
12206
14402
  const previousLaunchId = item.launchId || null;
12207
14403
  const nextLaunchId = start.launchId || previousLaunchId;
12208
14404
  const previousWakeMessage = item.wakeMessage;
12209
- if (previousWakeMessage && start.wakeMessage && !this.sameWakeMessage(previousWakeMessage, start.wakeMessage)) {
12210
- const pending = this.startingInboxes.get(agentId) || [];
12211
- pending.push(previousWakeMessage);
12212
- this.startingInboxes.set(agentId, pending);
12213
- }
14405
+ this.startingInboxes.rebindWake(
14406
+ agentId,
14407
+ previousWakeMessage,
14408
+ start.wakeMessage,
14409
+ (left, right) => this.sameWakeMessage(left, right)
14410
+ );
14411
+ this.assertStartPendingDeliveryInvariants("rebind-queued-start");
12214
14412
  item.config = start.config;
12215
14413
  item.unreadSummary = start.unreadSummary;
12216
14414
  item.resumePrompt = start.resumePrompt;
@@ -12277,7 +14475,7 @@ var AgentProcessManager = class _AgentProcessManager {
12277
14475
  logger.info(`[Agent ${agentId}] Start rebound (already running)`);
12278
14476
  return;
12279
14477
  }
12280
- if (this.agentsStarting.has(agentId)) {
14478
+ if (this.agentStarts.hasStarting(agentId)) {
12281
14479
  this.recordDaemonTrace("daemon.agent.start.ignored", {
12282
14480
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
12283
14481
  reason: "already_starting"
@@ -12286,7 +14484,7 @@ var AgentProcessManager = class _AgentProcessManager {
12286
14484
  logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
12287
14485
  return;
12288
14486
  }
12289
- if (this.queuedAgentStarts.has(agentId)) {
14487
+ if (this.agentStarts.hasQueued(agentId)) {
12290
14488
  this.recordDaemonTrace("daemon.agent.start.ignored", {
12291
14489
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
12292
14490
  reason: "already_queued"
@@ -12307,46 +14505,40 @@ var AgentProcessManager = class _AgentProcessManager {
12307
14505
  resolve,
12308
14506
  reject
12309
14507
  };
12310
- this.agentStartQueue.push(item);
12311
- this.queuedAgentStarts.set(agentId, item);
14508
+ this.agentStarts.enqueue(item);
12312
14509
  this.recordDaemonTrace("daemon.agent.start.queued", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
14510
+ const startSnapshot = this.agentStarts.snapshot();
12313
14511
  logger.info(
12314
- `[Agent ${agentId}] Start queued (queue=${this.agentStartQueue.length}, active=${this.activeAgentStartCount}, max=${this.maxConcurrentAgentStarts}, interval=${this.agentStartIntervalMs}ms)`
14512
+ `[Agent ${agentId}] Start queued (queue=${startSnapshot.queueDepth}, active=${startSnapshot.activeStarts}, max=${startSnapshot.maxConcurrentStarts}, interval=${startSnapshot.minStartIntervalMs}ms)`
12315
14513
  );
12316
14514
  this.pumpAgentStartQueue();
12317
14515
  });
12318
14516
  }
12319
14517
  pumpAgentStartQueue() {
12320
- if (this.agentStartPumpTimer) return;
12321
- if (this.agentStartQueue.length === 0) return;
12322
- if (this.activeAgentStartCount >= this.maxConcurrentAgentStarts) return;
12323
- const next = this.agentStartQueue[0];
12324
- const shouldRateLimit = next ? next.agentId !== this.lastAgentStartAgentId : true;
12325
- const elapsed = Date.now() - this.lastAgentStartAt;
12326
- const waitMs = shouldRateLimit ? Math.max(0, this.agentStartIntervalMs - elapsed) : 0;
12327
- if (waitMs > 0) {
14518
+ const pumpState = this.agentStarts.getPumpState();
14519
+ if (pumpState.kind === "blocked") return;
14520
+ if (pumpState.kind === "rate_limited") {
14521
+ const { item: next, waitMs } = pumpState;
12328
14522
  this.recordDaemonTrace("daemon.agent.start.rate_limited", {
12329
14523
  ...this.startQueueTraceAttrs(next.agentId, next.config, next.wakeMessage, next.unreadSummary, next.resumePrompt, next.launchId, next.wakeMessageTransient),
12330
14524
  wait_ms: waitMs
12331
14525
  });
12332
- this.agentStartPumpTimer = setTimeout(() => {
12333
- this.agentStartPumpTimer = null;
12334
- this.pumpAgentStartQueue();
12335
- }, waitMs);
14526
+ this.agentStarts.schedulePump(waitMs, () => this.pumpAgentStartQueue());
12336
14527
  return;
12337
14528
  }
12338
- const item = this.agentStartQueue.shift();
12339
- if (!item) return;
12340
- if (this.queuedAgentStarts.get(item.agentId) !== item) {
14529
+ const dequeued = this.agentStarts.dequeue();
14530
+ if (dequeued.kind === "empty") return;
14531
+ if (dequeued.kind === "stale") {
14532
+ const { item: item2 } = dequeued;
12341
14533
  this.recordDaemonTrace("daemon.agent.start.skipped", {
12342
- ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
14534
+ ...this.startQueueTraceAttrs(item2.agentId, item2.config, item2.wakeMessage, item2.unreadSummary, item2.resumePrompt, item2.launchId, item2.wakeMessageTransient),
12343
14535
  reason: "stale_queue_item"
12344
14536
  });
12345
14537
  this.pumpAgentStartQueue();
12346
14538
  return;
12347
14539
  }
12348
- this.queuedAgentStarts.delete(item.agentId);
12349
- if (this.agents.has(item.agentId) || this.agentsStarting.has(item.agentId)) {
14540
+ const { item } = dequeued;
14541
+ if (this.agents.has(item.agentId) || this.agentStarts.hasStarting(item.agentId)) {
12350
14542
  this.recordDaemonTrace("daemon.agent.start.skipped", {
12351
14543
  ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
12352
14544
  reason: "already_running_or_starting"
@@ -12361,11 +14553,10 @@ var AgentProcessManager = class _AgentProcessManager {
12361
14553
  this.pumpAgentStartQueue();
12362
14554
  return;
12363
14555
  }
12364
- this.activeAgentStartCount++;
12365
- this.lastAgentStartAt = Date.now();
12366
- this.lastAgentStartAgentId = item.agentId;
14556
+ this.agentStarts.claimStartSlot(item.agentId);
14557
+ const startSnapshot = this.agentStarts.snapshot();
12367
14558
  logger.info(
12368
- `[Agent ${item.agentId}] Dequeued start (remaining=${this.agentStartQueue.length}, active=${this.activeAgentStartCount})`
14559
+ `[Agent ${item.agentId}] Dequeued start (remaining=${startSnapshot.queueDepth}, active=${startSnapshot.activeStarts})`
12369
14560
  );
12370
14561
  this.recordDaemonTrace("daemon.agent.start.dequeued", this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient));
12371
14562
  this.startAgentNow(
@@ -12385,30 +14576,25 @@ var AgentProcessManager = class _AgentProcessManager {
12385
14576
  });
12386
14577
  }
12387
14578
  releaseAgentStartSlot(agentId, reason) {
12388
- if (this.activeAgentStartCount <= 0) return;
12389
- this.activeAgentStartCount = Math.max(0, this.activeAgentStartCount - 1);
14579
+ if (!this.agentStarts.releaseStartSlot()) return;
14580
+ const startSnapshot = this.agentStarts.snapshot();
12390
14581
  this.recordDaemonTrace("daemon.agent.start.slot_released", {
12391
14582
  agentId,
12392
14583
  reason,
12393
- active_starts: this.activeAgentStartCount,
12394
- queue_depth: this.agentStartQueue.length,
12395
- max_concurrent_starts: this.maxConcurrentAgentStarts
14584
+ active_starts: startSnapshot.activeStarts,
14585
+ queue_depth: startSnapshot.queueDepth,
14586
+ max_concurrent_starts: startSnapshot.maxConcurrentStarts
12396
14587
  });
12397
14588
  logger.info(
12398
- `[Agent ${agentId}] Start slot released (${reason}) (active=${this.activeAgentStartCount}, queue=${this.agentStartQueue.length})`
14589
+ `[Agent ${agentId}] Start slot released (${reason}) (active=${startSnapshot.activeStarts}, queue=${startSnapshot.queueDepth})`
12399
14590
  );
12400
14591
  this.pumpAgentStartQueue();
12401
14592
  }
12402
14593
  cancelQueuedAgentStart(agentId, reason) {
12403
- const item = this.queuedAgentStarts.get(agentId);
14594
+ const item = this.agentStarts.cancelQueued(agentId);
12404
14595
  if (!item) return false;
12405
- this.queuedAgentStarts.delete(agentId);
12406
- this.agentStartQueue = this.agentStartQueue.filter((candidate) => candidate !== item);
12407
- this.startingInboxes.delete(agentId);
12408
- if (this.agentStartQueue.length === 0 && this.agentStartPumpTimer) {
12409
- clearTimeout(this.agentStartPumpTimer);
12410
- this.agentStartPumpTimer = null;
12411
- }
14596
+ this.startingInboxes.cancelStart(agentId);
14597
+ this.assertStartPendingDeliveryInvariants("cancel-queued-start");
12412
14598
  this.recordDaemonTrace("daemon.agent.start.cancelled", {
12413
14599
  ...this.startQueueTraceAttrs(agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
12414
14600
  reason
@@ -12418,23 +14604,18 @@ var AgentProcessManager = class _AgentProcessManager {
12418
14604
  return true;
12419
14605
  }
12420
14606
  cancelAllQueuedAgentStarts(reason) {
12421
- for (const item of this.agentStartQueue) {
12422
- if (this.queuedAgentStarts.get(item.agentId) === item) {
12423
- this.recordDaemonTrace("daemon.agent.start.cancelled", {
12424
- ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
12425
- reason
12426
- }, "cancelled");
12427
- logger.info(`[Agent ${item.agentId}] Queued start cancelled (${reason})`);
12428
- item.resolve();
12429
- }
12430
- }
12431
- this.agentStartQueue = [];
12432
- this.queuedAgentStarts.clear();
12433
- this.startingInboxes.clear();
12434
- if (this.agentStartPumpTimer) {
12435
- clearTimeout(this.agentStartPumpTimer);
12436
- this.agentStartPumpTimer = null;
14607
+ const cancelled = this.agentStarts.cancelAllQueued((item) => {
14608
+ this.recordDaemonTrace("daemon.agent.start.cancelled", {
14609
+ ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
14610
+ reason
14611
+ }, "cancelled");
14612
+ logger.info(`[Agent ${item.agentId}] Queued start cancelled (${reason})`);
14613
+ });
14614
+ for (const item of cancelled) {
14615
+ item.resolve();
12437
14616
  }
14617
+ this.startingInboxes.cancelAllStarts();
14618
+ this.assertStartPendingDeliveryInvariants("cancel-all-queued-starts");
12438
14619
  }
12439
14620
  async startAgentNow(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
12440
14621
  if (this.agents.has(agentId)) {
@@ -12446,7 +14627,7 @@ var AgentProcessManager = class _AgentProcessManager {
12446
14627
  logger.info(`[Agent ${agentId}] Start rebound (already running)`);
12447
14628
  return;
12448
14629
  }
12449
- if (this.agentsStarting.has(agentId)) {
14630
+ if (this.agentStarts.hasStarting(agentId)) {
12450
14631
  this.recordDaemonTrace("daemon.agent.spawn.skipped", {
12451
14632
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
12452
14633
  reason: "already_starting"
@@ -12455,7 +14636,7 @@ var AgentProcessManager = class _AgentProcessManager {
12455
14636
  logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
12456
14637
  return;
12457
14638
  }
12458
- this.agentsStarting.add(agentId);
14639
+ this.agentStarts.markStarting(agentId);
12459
14640
  let agentProcess = null;
12460
14641
  let pendingStartRebind;
12461
14642
  const originalLaunchId = launchId || null;
@@ -12488,11 +14669,13 @@ var AgentProcessManager = class _AgentProcessManager {
12488
14669
  if (pendingStartRebind) {
12489
14670
  this.pendingStartRebinds.delete(agentId);
12490
14671
  const previousWakeMessage = wakeMessage;
12491
- if (previousWakeMessage && pendingStartRebind.wakeMessage && !this.sameWakeMessage(previousWakeMessage, pendingStartRebind.wakeMessage)) {
12492
- const pending = this.startingInboxes.get(agentId) || [];
12493
- pending.push(previousWakeMessage);
12494
- this.startingInboxes.set(agentId, pending);
12495
- }
14672
+ this.startingInboxes.rebindWake(
14673
+ agentId,
14674
+ previousWakeMessage,
14675
+ pendingStartRebind.wakeMessage,
14676
+ (left, right) => this.sameWakeMessage(left, right)
14677
+ );
14678
+ this.assertStartPendingDeliveryInvariants("rebind-starting-start");
12496
14679
  config = pendingStartRebind.config;
12497
14680
  unreadSummary = pendingStartRebind.unreadSummary;
12498
14681
  resumePrompt = pendingStartRebind.resumePrompt;
@@ -12533,7 +14716,7 @@ var AgentProcessManager = class _AgentProcessManager {
12533
14716
  let promptSource;
12534
14717
  let wakeMessageDeliveredAsInboxUpdate = false;
12535
14718
  let startingInboxDeliveredAsInput = false;
12536
- const startingInboxMessages = this.startingInboxes.get(agentId) || [];
14719
+ const startingInboxMessages = this.startingInboxes.values(agentId);
12537
14720
  if (runtimeConfig.runtimeProfileControl && !wakeMessage) {
12538
14721
  prompt = driver.supportsNativeStandingPrompt ? NATIVE_STANDING_PROMPT_STARTUP_INPUT : formatRuntimeProfileControlStartupInput(runtimeConfig.runtimeProfileControl, driver);
12539
14722
  promptSource = "runtime_profile_control";
@@ -12585,7 +14768,7 @@ Use the inbox/read commands at a natural breakpoint if you choose to inspect tho
12585
14768
  }
12586
14769
  prompt += `
12587
14770
 
12588
- Use ${communicationCommand("read_history")} to catch up on the channels listed above, then stop. Read each listed channel at most once unless a read fails. Do NOT call ${communicationCommand("check_messages")} in this mode. If the history reveals a direct request, assignment, @mention, review request, or task clearly addressed to you, switch into active handling instead of stopping: ${dynamicReplyInstruction()} and ${dynamicClaimInstruction()} before starting work. Otherwise, do NOT send any message in this mode. ${getMessageDeliveryText(driver)}`;
14771
+ Use \`raft message read\` to catch up on the channels listed above, then stop. Read each listed channel at most once unless a read fails. Do NOT call \`raft message check\` in this mode. If the history reveals a direct request, assignment, @mention, review request, or task clearly addressed to you, switch into active handling instead of stopping: reply using \`raft message send --target <exact target>\` and claim the relevant task with \`raft task claim\` before starting work. Otherwise, do NOT send any message in this mode. ${getMessageDeliveryText(driver)}`;
12589
14772
  promptSource = "resume_unread_summary";
12590
14773
  } else if (isResume) {
12591
14774
  prompt = `No new messages while you were away. Nothing to do \u2014 just stop. ${getMessageDeliveryText(driver)}`;
@@ -12608,9 +14791,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12608
14791
  const effectiveLaunchId = launchId || null;
12609
14792
  const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !runtimeConfig.runtimeProfileControl && (!unreadSummary || Object.keys(unreadSummary).length === 0);
12610
14793
  if (canDeferEmptyStart) {
12611
- const pendingMessages = this.startingInboxes.get(agentId) || [];
12612
- this.startingInboxes.delete(agentId);
12613
- this.agentsStarting.delete(agentId);
14794
+ const pendingMessages = this.startingInboxes.drainOnSpawn(agentId);
14795
+ this.agentStarts.clearStarting(agentId);
14796
+ this.assertStartPendingDeliveryInvariants("defer-empty-start-drain");
12614
14797
  this.idleAgentConfigs.set(agentId, {
12615
14798
  config: this.buildRestartSafeConfig(runtimeConfig, runtimeConfig.sessionId || null),
12616
14799
  sessionId: runtimeConfig.sessionId || null,
@@ -12693,7 +14876,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12693
14876
  pendingTrajectory: null,
12694
14877
  gatedSteering: createGatedSteeringState()
12695
14878
  };
12696
- this.startingInboxes.delete(agentId);
14879
+ this.startingInboxes.drainOnSpawn(agentId);
14880
+ this.assertStartPendingDeliveryInvariants("spawn-drain");
12697
14881
  this.agents.set(agentId, agentProcess);
12698
14882
  this.idleAgentConfigs.set(agentId, {
12699
14883
  config: this.buildRestartSafeConfig(runtimeConfig, restartSessionId),
@@ -12704,7 +14888,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
12704
14888
  this.recordStartRebind(agentId, pendingStartRebind, "startup_registered", originalLaunchId, effectiveLaunchId, agentProcess.sessionId);
12705
14889
  }
12706
14890
  this.startRuntimeTrace(agentId, agentProcess, "spawn", wakeMessage ? [wakeMessage] : void 0, runtimeInputTraceAttrs);
12707
- this.agentsStarting.delete(agentId);
14891
+ this.agentStarts.clearStarting(agentId);
12708
14892
  if (runtimeConfig.runtimeProfileControl) {
12709
14893
  this.ackInjectedRuntimeProfileControl(agentId, runtimeConfig.runtimeProfileControl, agentProcess.launchId);
12710
14894
  }
@@ -13008,7 +15192,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13008
15192
  this.broadcastActivity(agentId, "working", "Starting\u2026");
13009
15193
  this.startRuntimeStartupTimeout(agentId, agentProcess);
13010
15194
  } catch (err) {
13011
- this.agentsStarting.delete(agentId);
15195
+ this.agentStarts.clearStarting(agentId);
13012
15196
  this.pendingStartRebinds.delete(agentId);
13013
15197
  this.cleanupFailedRuntimeStart(agentId, agentProcess, err);
13014
15198
  throw err;
@@ -13062,11 +15246,11 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13062
15246
  cleanupAgentCredentialProxy(agentId, ap.launchId);
13063
15247
  this.revokeManagedRunnerCredential(agentId, ap.config, ap.launchId);
13064
15248
  this.idleAgentConfigs.delete(agentId);
13065
- const pending = this.startingInboxes.get(agentId) || [];
13066
15249
  if (ap.inbox.length > 0) {
13067
- this.startingInboxes.set(agentId, [...pending, ...ap.inbox]);
15250
+ this.startingInboxes.bufferMessagesDuringStart(agentId, ap.inbox);
13068
15251
  }
13069
15252
  this.terminalRuntimeFailures.set(agentId, { detail, launchId: ap.launchId });
15253
+ this.assertStartPendingDeliveryInvariants("terminal-runtime-failure-cleanup");
13070
15254
  this.agents.delete(agentId);
13071
15255
  const diagnostics = buildRuntimeErrorDiagnosticEnvelope(detail);
13072
15256
  this.recordDaemonTrace("daemon.agent.terminal_runtime_error.cleanup", {
@@ -13309,10 +15493,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13309
15493
  );
13310
15494
  }
13311
15495
  queueRuntimeProfileNotificationDuringStart(agentId, message, kind, key) {
13312
- const pending = this.startingInboxes.get(agentId) || [];
13313
- pending.push(message);
13314
- this.startingInboxes.set(agentId, pending);
13315
- const queuedStart = this.queuedAgentStarts.get(agentId);
15496
+ const startingInboxCount = this.startingInboxes.bufferDuringStart(agentId, message);
15497
+ this.assertStartPendingDeliveryInvariants("runtime-profile-during-start");
15498
+ const queuedStart = this.agentStarts.getQueued(agentId);
13316
15499
  this.recordDaemonTrace("daemon.agent.runtime_profile.routed", {
13317
15500
  agentId,
13318
15501
  kind,
@@ -13320,7 +15503,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13320
15503
  key_hash: hashRuntimeProfileKey(key),
13321
15504
  outcome: "queued_during_start",
13322
15505
  startup_pending: true,
13323
- starting_inbox_count: pending.length,
15506
+ starting_inbox_count: startingInboxCount,
13324
15507
  launchId: queuedStart?.launchId
13325
15508
  });
13326
15509
  logger.info(`[Agent ${agentId}] Queued runtime profile ${kind} ${key} during startup`);
@@ -13352,8 +15535,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13352
15535
  this.agents.delete(agentId);
13353
15536
  if (!silent) {
13354
15537
  this.activityClientSeqByAgent.delete(agentId);
13355
- this.agentVisibleBoundaries.delete(agentId);
13356
- this.agentVisibleMessageIds.delete(agentId);
15538
+ this.agentVisibleDelivery.clearAgent(agentId);
13357
15539
  this.resetSpawnFailBackoff(agentId);
13358
15540
  this.resetRuntimeErrorFingerprintFence(agentId, "explicit_stop", ap);
13359
15541
  }
@@ -13379,6 +15561,15 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13379
15561
  if (!silent) {
13380
15562
  logger.warn(`[Agent ${agentId}] Stop timed out; force killing`);
13381
15563
  }
15564
+ this.recordDaemonTrace("daemon.agent.stop.timeout_sigkill", {
15565
+ agent_id: agentId,
15566
+ pid: typeof ap.runtime.pid === "number" ? ap.runtime.pid : void 0,
15567
+ timeout_ms: 5e3,
15568
+ reason: "wait_timeout",
15569
+ signal: "SIGKILL"
15570
+ });
15571
+ void ap.runtime.stop({ signal: "SIGKILL" }).catch(() => {
15572
+ });
13382
15573
  resolve();
13383
15574
  }, 5e3);
13384
15575
  ap.runtime.on("exit", () => {
@@ -13410,9 +15601,9 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13410
15601
  }
13411
15602
  const ap = this.agents.get(agentId);
13412
15603
  if (!ap) {
13413
- if (this.agentsStarting.has(agentId) || this.queuedAgentStarts.has(agentId)) {
15604
+ if (this.agentStarts.hasStarting(agentId) || this.agentStarts.hasQueued(agentId)) {
13414
15605
  if (transientDelivery) {
13415
- const queuedStart2 = this.queuedAgentStarts.get(agentId);
15606
+ const queuedStart2 = this.agentStarts.getQueued(agentId);
13416
15607
  this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
13417
15608
  outcome: "transient_dropped_during_start",
13418
15609
  accepted: true,
@@ -13422,16 +15613,15 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13422
15613
  }));
13423
15614
  return true;
13424
15615
  }
13425
- const queuedStart = this.queuedAgentStarts.get(agentId);
13426
- const pending = this.startingInboxes.get(agentId) || [];
13427
- pending.push(message);
13428
- this.startingInboxes.set(agentId, pending);
15616
+ const queuedStart = this.agentStarts.getQueued(agentId);
15617
+ const startingInboxCount = this.startingInboxes.bufferDuringStart(agentId, message);
15618
+ this.assertStartPendingDeliveryInvariants("delivery-during-start");
13429
15619
  this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
13430
15620
  outcome: "queued_during_start",
13431
15621
  accepted: true,
13432
15622
  process_present: false,
13433
15623
  startup_pending: true,
13434
- starting_inbox_count: pending.length,
15624
+ starting_inbox_count: startingInboxCount,
13435
15625
  launchId: queuedStart?.launchId
13436
15626
  }));
13437
15627
  return true;
@@ -13449,16 +15639,15 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13449
15639
  }));
13450
15640
  return true;
13451
15641
  }
13452
- const pending = this.startingInboxes.get(agentId) || [];
13453
- pending.push(message);
13454
- this.startingInboxes.set(agentId, pending);
15642
+ const startingInboxCount = this.startingInboxes.bufferDuringStart(agentId, message);
15643
+ this.assertStartPendingDeliveryInvariants("delivery-terminal-runtime-error");
13455
15644
  this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
13456
15645
  outcome: "queued_terminal_runtime_error_no_process",
13457
15646
  accepted: true,
13458
15647
  process_present: false,
13459
15648
  cached_idle_config_present: false,
13460
15649
  terminal_runtime_failure: true,
13461
- starting_inbox_count: pending.length,
15650
+ starting_inbox_count: startingInboxCount,
13462
15651
  launchId: terminalRuntimeFailure.launchId || void 0
13463
15652
  }));
13464
15653
  this.sendAgentStatus(agentId, "inactive", terminalRuntimeFailure.launchId);
@@ -13483,9 +15672,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13483
15672
  logger.info(`[Agent ${agentId}] Starting from idle state for new message`);
13484
15673
  if (this.isSpawnFailBackoffActive(agentId)) {
13485
15674
  const state = this.agentSpawnFailBackoff.get(agentId);
13486
- const pending = this.startingInboxes.get(agentId) || [];
13487
- pending.push(message);
13488
- this.startingInboxes.set(agentId, pending);
15675
+ const startingInboxCount = this.startingInboxes.bufferDuringStart(agentId, message);
15676
+ this.assertStartPendingDeliveryInvariants("delivery-spawn-fail-cooldown");
13489
15677
  this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
13490
15678
  outcome: "spawn_fail_cooldown_active",
13491
15679
  accepted: true,
@@ -13496,7 +15684,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13496
15684
  launchId: cached.launchId || void 0,
13497
15685
  spawn_fail_attempts: state.attempts,
13498
15686
  spawn_fail_until_ms: state.untilMs,
13499
- starting_inbox_count: pending.length
15687
+ starting_inbox_count: startingInboxCount
13500
15688
  }));
13501
15689
  return true;
13502
15690
  }
@@ -13540,16 +15728,15 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13540
15728
  return false;
13541
15729
  });
13542
15730
  }
13543
- if (!transientDelivery && (this.queuedAgentStarts.has(agentId) || this.agentsStarting.has(agentId))) {
13544
- const pending = this.startingInboxes.get(agentId) || [];
13545
- pending.push(message);
13546
- this.startingInboxes.set(agentId, pending);
15731
+ if (!transientDelivery && (this.agentStarts.hasQueued(agentId) || this.agentStarts.hasStarting(agentId))) {
15732
+ const startingInboxCount = this.startingInboxes.bufferDuringStart(agentId, message);
15733
+ this.assertStartPendingDeliveryInvariants("delivery-queued-or-starting");
13547
15734
  this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
13548
- outcome: this.agentsStarting.has(agentId) ? "queued_for_starting_process" : "queued_for_queued_start",
15735
+ outcome: this.agentStarts.hasStarting(agentId) ? "queued_for_starting_process" : "queued_for_queued_start",
13549
15736
  accepted: true,
13550
15737
  process_present: false,
13551
15738
  cached_idle_config_present: false,
13552
- starting_inbox_count: pending.length
15739
+ starting_inbox_count: startingInboxCount
13553
15740
  }));
13554
15741
  return true;
13555
15742
  }
@@ -13877,8 +16064,74 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
13877
16064
  async stopAll() {
13878
16065
  this.cancelAllQueuedAgentStarts("daemon shutdown");
13879
16066
  this.idleAgentConfigs.clear();
16067
+ const pids = [];
16068
+ for (const ap of this.agents.values()) {
16069
+ if (typeof ap.runtime.pid === "number") pids.push(ap.runtime.pid);
16070
+ }
13880
16071
  const ids = [...this.agents.keys()];
16072
+ this.recordDaemonTrace("daemon.agent.stop_all.started", {
16073
+ agent_count: ids.length,
16074
+ pid_count: pids.length,
16075
+ pids: pids.join(",")
16076
+ });
13881
16077
  await Promise.all(ids.map((id) => this.stopAgent(id, { wait: true, silent: true })));
16078
+ const survivors = pids.filter((pid) => {
16079
+ try {
16080
+ process.kill(pid, 0);
16081
+ return true;
16082
+ } catch {
16083
+ return false;
16084
+ }
16085
+ });
16086
+ if (survivors.length > 0) {
16087
+ for (const pid of survivors) {
16088
+ logger.warn(`[Daemon] Agent subprocess ${pid} survived stopAll; sending SIGKILL`);
16089
+ try {
16090
+ process.kill(pid, "SIGKILL");
16091
+ } catch {
16092
+ }
16093
+ }
16094
+ this.recordDaemonTrace("daemon.agent.stop_all.survivor_reaped", {
16095
+ survivor_count: survivors.length,
16096
+ survivor_pids: survivors.join(","),
16097
+ reason: "shutdown_survivor",
16098
+ signal: "SIGKILL"
16099
+ });
16100
+ const deadline = Date.now() + 2e3;
16101
+ while (Date.now() < deadline) {
16102
+ const alive = survivors.filter((pid) => {
16103
+ try {
16104
+ process.kill(pid, 0);
16105
+ return true;
16106
+ } catch {
16107
+ return false;
16108
+ }
16109
+ });
16110
+ if (alive.length === 0) break;
16111
+ await new Promise((r) => setTimeout(r, 50));
16112
+ }
16113
+ const stillAlive = survivors.filter((pid) => {
16114
+ try {
16115
+ process.kill(pid, 0);
16116
+ return true;
16117
+ } catch {
16118
+ return false;
16119
+ }
16120
+ });
16121
+ const outcome = stillAlive.length > 0 ? "survivors_still_alive" : "survivors_killed";
16122
+ this.recordDaemonTrace("daemon.agent.stop_all.completed", {
16123
+ survivor_count: survivors.length,
16124
+ reaped_count: survivors.length - stillAlive.length,
16125
+ still_alive_count: stillAlive.length,
16126
+ outcome
16127
+ }, stillAlive.length > 0 ? "error" : "ok");
16128
+ } else {
16129
+ this.recordDaemonTrace("daemon.agent.stop_all.completed", {
16130
+ agent_count: ids.length,
16131
+ survivor_count: 0,
16132
+ outcome: "all_dead"
16133
+ });
16134
+ }
13882
16135
  }
13883
16136
  getRunningAgentIds() {
13884
16137
  return [...this.agents.keys()];
@@ -14064,8 +16317,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14064
16317
  });
14065
16318
  return written;
14066
16319
  }
14067
- if (this.agentsStarting.has(agentId) || this.queuedAgentStarts.has(agentId)) {
14068
- const queuedStart = this.queuedAgentStarts.get(agentId);
16320
+ if (this.agentStarts.hasStarting(agentId) || this.agentStarts.hasQueued(agentId)) {
16321
+ const queuedStart = this.agentStarts.getQueued(agentId);
14069
16322
  this.queueRuntimeProfileNotificationDuringStart(agentId, message, kind, key);
14070
16323
  span.end("ok", {
14071
16324
  attrs: {
@@ -14572,7 +16825,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14572
16825
  entries.push({ kind: "status", activity, detail });
14573
16826
  }
14574
16827
  const launchId = launchIdOverride || ap?.launchId || void 0;
14575
- const clientSeq = ap ? this.nextActivityClientSeq(agentId) : void 0;
16828
+ const clientSeq = this.nextActivityClientSeq(agentId);
16829
+ const producerFactId = this.buildActivityProducerFactId(agentId, launchId, clientSeq);
14576
16830
  this.sendToServer({
14577
16831
  type: "agent:activity",
14578
16832
  agentId,
@@ -14580,9 +16834,10 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14580
16834
  detail,
14581
16835
  entries,
14582
16836
  launchId,
14583
- clientSeq
16837
+ clientSeq,
16838
+ producerFactId
14584
16839
  });
14585
- this.recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq);
16840
+ this.recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq, producerFactId);
14586
16841
  if (ap) {
14587
16842
  ap.lastActivity = activity;
14588
16843
  ap.lastActivityDetail = detail;
@@ -14595,15 +16850,17 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14595
16850
  });
14596
16851
  const heartbeatLaunchId = launchIdOverride || ap.launchId || void 0;
14597
16852
  const heartbeatClientSeq = this.nextActivityClientSeq(agentId);
16853
+ const heartbeatProducerFactId = this.buildActivityProducerFactId(agentId, heartbeatLaunchId, heartbeatClientSeq);
14598
16854
  this.sendToServer({
14599
16855
  type: "agent:activity",
14600
16856
  agentId,
14601
16857
  activity: ap.lastActivity,
14602
16858
  detail: ap.lastActivityDetail,
14603
16859
  launchId: heartbeatLaunchId,
14604
- clientSeq: heartbeatClientSeq
16860
+ clientSeq: heartbeatClientSeq,
16861
+ producerFactId: heartbeatProducerFactId
14605
16862
  });
14606
- this.recordActivityProducedTrace(agentId, ap.lastActivity, ap.lastActivityDetail, [], ap, heartbeatLaunchId, heartbeatClientSeq);
16863
+ this.recordActivityProducedTrace(agentId, ap.lastActivity, ap.lastActivityDetail, [], ap, heartbeatLaunchId, heartbeatClientSeq, heartbeatProducerFactId);
14607
16864
  }, ACTIVITY_HEARTBEAT_MS);
14608
16865
  }
14609
16866
  } else {
@@ -14614,7 +16871,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14614
16871
  }
14615
16872
  }
14616
16873
  }
14617
- recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq) {
16874
+ recordActivityProducedTrace(agentId, activity, detail, entries, ap, launchId, clientSeq, producerFactId) {
14618
16875
  const runtimeContext = ap?.config.runtimeContext;
14619
16876
  this.recordDaemonTrace("daemon.agent.activity.produced", {
14620
16877
  agentId,
@@ -14632,11 +16889,16 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14632
16889
  clientSeq,
14633
16890
  client_seq: clientSeq,
14634
16891
  client_seq_present: typeof clientSeq === "number",
16892
+ producerFactId,
16893
+ producer_fact_id: producerFactId,
14635
16894
  correlation_id: `agent:${agentId}:daemonActivity:${launchId ?? "legacy"}:${clientSeq ?? "unsequenced"}`,
14636
16895
  session_id_present: Boolean(ap?.sessionId),
14637
16896
  runtime: ap?.config.runtime
14638
16897
  });
14639
16898
  }
16899
+ buildActivityProducerFactId(agentId, launchId, clientSeq) {
16900
+ return `daemon_activity:${agentId}:${launchId ?? "legacy"}:${clientSeq}`;
16901
+ }
14640
16902
  /**
14641
16903
  * Respond to a server-issued `agent:activity_probe`. Echoes the
14642
16904
  * agent's current `lastActivity` back through the existing
@@ -14663,7 +16925,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14663
16925
  const activity = ap?.lastActivity || "offline";
14664
16926
  const detail = ap?.lastActivityDetail || (ap ? "" : "Agent not running");
14665
16927
  const launchId = ap?.launchId || void 0;
14666
- const clientSeq = ap ? this.nextActivityClientSeq(agentId) : void 0;
16928
+ const clientSeq = this.nextActivityClientSeq(agentId);
16929
+ const producerFactId = this.buildActivityProducerFactId(agentId, launchId, clientSeq);
14667
16930
  this.sendToServer({
14668
16931
  type: "agent:activity",
14669
16932
  agentId,
@@ -14671,9 +16934,10 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
14671
16934
  detail,
14672
16935
  launchId,
14673
16936
  probeId,
14674
- clientSeq
16937
+ clientSeq,
16938
+ producerFactId
14675
16939
  });
14676
- this.recordActivityProducedTrace(agentId, activity, detail, [], ap, launchId, clientSeq);
16940
+ this.recordActivityProducedTrace(agentId, activity, detail, [], ap, launchId, clientSeq, producerFactId);
14677
16941
  }
14678
16942
  flushPendingTrajectory(agentId) {
14679
16943
  const ap = this.agents.get(agentId);
@@ -16383,6 +18647,7 @@ var DaemonConnection = class {
16383
18647
  this.pendingActivityByAgent.delete(msg.agentId);
16384
18648
  }
16385
18649
  this.ws.send(JSON.stringify(msg));
18650
+ this.traceActivitySent(msg, "websocket_open");
16386
18651
  return;
16387
18652
  }
16388
18653
  this.observeLaunchIdentity(msg);
@@ -16580,12 +18845,35 @@ var DaemonConnection = class {
16580
18845
  this.pendingActivityByAgent.clear();
16581
18846
  for (const msg of pending) {
16582
18847
  ws.send(JSON.stringify(msg));
18848
+ this.traceActivitySent(msg, "replay");
16583
18849
  }
16584
18850
  this.trace("daemon.connection.outbound_replayed", {
16585
18851
  outbound_message_kind: "agent:activity",
16586
18852
  message_count: pending.length
16587
18853
  });
16588
18854
  }
18855
+ traceActivitySent(msg, sendPath) {
18856
+ if (msg.type !== "agent:activity") return;
18857
+ this.trace("daemon.agent.activity.sent", {
18858
+ agentId: msg.agentId,
18859
+ agent_id: msg.agentId,
18860
+ activity: msg.activity,
18861
+ detail_present: Boolean(msg.detail),
18862
+ entry_kinds: (msg.entries ?? []).map((entry) => entry.kind).join(","),
18863
+ launchId: msg.launchId,
18864
+ launch_id: msg.launchId,
18865
+ launch_id_present: Boolean(msg.launchId),
18866
+ clientSeq: msg.clientSeq,
18867
+ client_seq: msg.clientSeq,
18868
+ client_seq_present: typeof msg.clientSeq === "number",
18869
+ producerFactId: msg.producerFactId,
18870
+ producer_fact_id: msg.producerFactId,
18871
+ producer_fact_id_present: Boolean(msg.producerFactId),
18872
+ correlation_id: msg.producerFactId ?? `agent:${msg.agentId}:daemonActivity:${msg.launchId ?? "legacy"}:${msg.clientSeq ?? "unsequenced"}`,
18873
+ probe_id_present: Boolean(msg.probeId),
18874
+ send_path: sendPath
18875
+ });
18876
+ }
16589
18877
  lastInboundAgeBucket() {
16590
18878
  return durationMsBucket(this.lastInboundAt == null ? null : this.clock.now() - this.lastInboundAt);
16591
18879
  }
@@ -17327,6 +19615,16 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
17327
19615
  },
17328
19616
  endAttrs: ["outcome", "available_models_count", "diagnostics_count", "diagnostic_info_count", "diagnostic_warning_count", "requested_model", "resolved_model", "resolved_model_present", "error_class"]
17329
19617
  },
19618
+ "daemon.builtin.session.create": {
19619
+ spanAttrs: ["agentId", "launchId", "runtime", "model", "session_id_present", "requested_model", "config_source", "host_user_state", "provider_id", "model_kind", "model_id", "base_url_present", "base_url_host_class", "provider_key_present", "provider_key_source"],
19620
+ eventAttrs: {
19621
+ "daemon.builtin.session.services_ready": ["available_models_count", "diagnostics_count", "diagnostic_info_count", "diagnostic_warning_count", "agent_dir_source", "config_source", "host_user_state", "provider_id", "model_kind", "model_id", "base_url_present", "base_url_host_class", "provider_key_present", "provider_key_source"],
19622
+ "daemon.builtin.session.model_resolved": ["available_models_count", "requested_model", "requested_model_explicit", "resolved_model", "resolved_model_present", "config_source", "host_user_state", "provider_id", "model_kind", "model_id", "base_url_present", "base_url_host_class", "provider_key_present", "provider_key_source"],
19623
+ "daemon.builtin.session.missing_model": ["available_models_count", "requested_model", "config_source", "host_user_state", "provider_id", "model_kind", "model_id", "base_url_present", "base_url_host_class", "provider_key_present", "provider_key_source"],
19624
+ "daemon.builtin.session.started": ["requested_model", "resolved_model", "session_id_present", "config_source", "host_user_state", "provider_id", "model_kind", "model_id", "base_url_present", "base_url_host_class", "provider_key_present", "provider_key_source"]
19625
+ },
19626
+ endAttrs: ["outcome", "available_models_count", "diagnostics_count", "diagnostic_info_count", "diagnostic_warning_count", "requested_model", "resolved_model", "resolved_model_present", "error_class", "config_source", "host_user_state", "provider_id", "model_kind", "model_id", "base_url_present", "base_url_host_class", "provider_key_present", "provider_key_source"]
19627
+ },
17330
19628
  "daemon.connection.local_disconnect_observed": {
17331
19629
  spanAttrs: ["running_agents_count", "idle_agents_count"]
17332
19630
  },
@@ -17415,7 +19713,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
17415
19713
  }
17416
19714
  async function runBundledSlockCli(argv) {
17417
19715
  process.argv = [process.execPath, "slock", ...argv];
17418
- await import("./dist-7ZEXJWIW.js");
19716
+ await import("./dist-TPCGG5OS.js");
17419
19717
  }
17420
19718
  function detectRuntimes(tracer = noopTracer) {
17421
19719
  const ids = [];
@@ -18355,6 +20653,7 @@ export {
18355
20653
  resolveWorkspaceDirectoryPath,
18356
20654
  scanWorkspaceDirectories,
18357
20655
  deleteWorkspaceDirectory,
20656
+ DAEMON_CORE_TRACE_ATTR_CONTRACTS,
18358
20657
  DAEMON_CLI_USAGE,
18359
20658
  parseDaemonCliArgs,
18360
20659
  readDaemonVersion,