@botiverse/raft-daemon 0.65.0 → 0.66.0-play.20260702142221

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.
@@ -1,5 +1,5 @@
1
1
  // src/core.ts
2
- import path18 from "path";
2
+ import path19 from "path";
3
3
  import os8 from "os";
4
4
  import { createRequire as createRequire3 } from "module";
5
5
  import { accessSync } from "fs";
@@ -50,427 +50,420 @@ var PI_BUILTIN_PROVIDER_MODELS_GENERATED = {
50
50
  { id: "deepseek/deepseek-v4-flash", label: "DeepSeek V4 Flash" }
51
51
  ],
52
52
  "minimax": [
53
+ { id: "minimax/MiniMax-M3", label: "MiniMax-M3" },
53
54
  { 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" }
55
+ { id: "minimax/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" }
56
56
  ],
57
57
  "minimax-cn": [
58
+ { id: "minimax-cn/MiniMax-M3", label: "MiniMax-M3" },
58
59
  { 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" }
60
+ { id: "minimax-cn/MiniMax-M2.7-highspeed", label: "MiniMax-M2.7-highspeed" }
61
61
  ],
62
62
  "zai": [
63
+ { id: "zai/glm-5.2", label: "GLM-5.2" },
63
64
  { id: "zai/glm-5.1", label: "GLM-5.1" },
64
- { id: "zai/glm-4.5-air", label: "GLM-4.5-Air" },
65
65
  { id: "zai/glm-4.7", label: "GLM-4.7" },
66
+ { id: "zai/glm-4.5-air", label: "GLM-4.5-Air" },
66
67
  { id: "zai/glm-5-turbo", label: "GLM-5-Turbo" },
67
- { id: "zai/glm-5.2", label: "GLM-5.2" },
68
68
  { id: "zai/glm-5v-turbo", label: "GLM-5V-Turbo" }
69
69
  ],
70
70
  "zai-coding-cn": [
71
+ { id: "zai-coding-cn/glm-5.2", label: "GLM-5.2" },
71
72
  { 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
73
  { id: "zai-coding-cn/glm-4.7", label: "GLM-4.7" },
74
+ { id: "zai-coding-cn/glm-4.5-air", label: "GLM-4.5-Air" },
74
75
  { id: "zai-coding-cn/glm-5-turbo", label: "GLM-5-Turbo" },
75
- { id: "zai-coding-cn/glm-5.2", label: "GLM-5.2" },
76
76
  { id: "zai-coding-cn/glm-5v-turbo", label: "GLM-5V-Turbo" }
77
77
  ],
78
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" },
79
+ { id: "moonshotai/kimi-k2.7-code", label: "Kimi K2.7 Code" },
82
80
  { id: "moonshotai/kimi-k2-thinking", label: "Kimi K2 Thinking" },
81
+ { id: "moonshotai/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" },
83
82
  { id: "moonshotai/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
84
- { id: "moonshotai/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
83
+ { id: "moonshotai/kimi-k2-0905-preview", label: "Kimi K2 0905" },
84
+ { id: "moonshotai/kimi-k2-0711-preview", label: "Kimi K2 0711" },
85
+ { id: "moonshotai/kimi-k2.6", label: "Kimi K2.6" },
85
86
  { 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" }
87
+ { id: "moonshotai/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" }
88
88
  ],
89
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" },
90
+ { id: "moonshotai-cn/kimi-k2.7-code", label: "Kimi K2.7 Code" },
93
91
  { id: "moonshotai-cn/kimi-k2-thinking", label: "Kimi K2 Thinking" },
92
+ { id: "moonshotai-cn/kimi-k2.7-code-highspeed", label: "Kimi K2.7 Code HighSpeed" },
94
93
  { id: "moonshotai-cn/kimi-k2-thinking-turbo", label: "Kimi K2 Thinking Turbo" },
95
- { id: "moonshotai-cn/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" },
94
+ { id: "moonshotai-cn/kimi-k2-0905-preview", label: "Kimi K2 0905" },
95
+ { id: "moonshotai-cn/kimi-k2-0711-preview", label: "Kimi K2 0711" },
96
+ { id: "moonshotai-cn/kimi-k2.6", label: "Kimi K2.6" },
96
97
  { 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" }
98
+ { id: "moonshotai-cn/kimi-k2-turbo-preview", label: "Kimi K2 Turbo" }
99
99
  ],
100
100
  "kimi-coding": [
101
- { id: "kimi-coding/kimi-for-coding", label: "Kimi For Coding" },
101
+ { id: "kimi-coding/kimi-k2-thinking", label: "Kimi K2 Thinking" },
102
102
  { id: "kimi-coding/k2p7", label: "Kimi K2.7 Code" },
103
- { id: "kimi-coding/kimi-k2-thinking", label: "Kimi K2 Thinking" }
103
+ { id: "kimi-coding/kimi-for-coding", label: "Kimi For Coding" }
104
104
  ],
105
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
106
  { 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)" },
107
+ { id: "openrouter/~anthropic/claude-fable-latest", label: "Anthropic: Claude Fable Latest" },
124
108
  { id: "openrouter/anthropic/claude-opus-4.8", label: "Anthropic: Claude Opus 4.8" },
109
+ { id: "openrouter/anthropic/claude-opus-4.7", label: "Anthropic: Claude Opus 4.7" },
110
+ { id: "openrouter/anthropic/claude-opus-4.6", label: "Anthropic: Claude Opus 4.6" },
111
+ { id: "openrouter/anthropic/claude-opus-4.5", label: "Anthropic: Claude Opus 4.5" },
112
+ { id: "openrouter/anthropic/claude-opus-4.1", label: "Anthropic: Claude Opus 4.1" },
113
+ { id: "openrouter/anthropic/claude-opus-4", label: "Anthropic: Claude Opus 4" },
114
+ { id: "openrouter/~anthropic/claude-opus-latest", label: "Anthropic: Claude Opus Latest" },
125
115
  { 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" },
116
+ { id: "openrouter/anthropic/claude-opus-4.7-fast", label: "Anthropic: Claude Opus 4.7 (Fast)" },
117
+ { id: "openrouter/anthropic/claude-sonnet-5", label: "Anthropic: Claude Sonnet 5" },
128
118
  { 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" },
119
+ { id: "openrouter/anthropic/claude-sonnet-4.5", label: "Anthropic: Claude Sonnet 4.5" },
120
+ { id: "openrouter/anthropic/claude-sonnet-4", label: "Anthropic: Claude Sonnet 4" },
121
+ { id: "openrouter/~anthropic/claude-sonnet-latest", label: "Anthropic Claude Sonnet Latest" },
122
+ { id: "openrouter/anthropic/claude-haiku-4.5", label: "Anthropic: Claude Haiku 4.5" },
123
+ { id: "openrouter/anthropic/claude-3-haiku", label: "Anthropic: Claude 3 Haiku" },
124
+ { id: "openrouter/~anthropic/claude-haiku-latest", label: "Anthropic Claude Haiku Latest" },
125
+ { id: "openrouter/openai/gpt-5.1-codex-max", label: "OpenAI: GPT-5.1-Codex-Max" },
126
+ { id: "openrouter/kwaipilot/kat-coder-pro-v2", label: "Kwaipilot: KAT-Coder-Pro V2" },
127
+ { id: "openrouter/qwen/qwen3-max-thinking", label: "Qwen: Qwen3 Max Thinking" },
128
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b", label: "NVIDIA: Nemotron 3 Ultra" },
155
129
  { id: "openrouter/google/gemini-2.5-pro-preview", label: "Google: Gemini 2.5 Pro Preview 06-05" },
156
130
  { 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" },
131
+ { id: "openrouter/openai/gpt-5.5-pro", label: "OpenAI: GPT-5.5 Pro" },
132
+ { id: "openrouter/openai/gpt-5.4-pro", label: "OpenAI: GPT-5.4 Pro" },
133
+ { id: "openrouter/openai/gpt-5.2-pro", label: "OpenAI: GPT-5.2 Pro" },
134
+ { id: "openrouter/openai/gpt-5-pro", label: "OpenAI: GPT-5 Pro" },
135
+ { id: "openrouter/deepseek/deepseek-v4-pro", label: "DeepSeek: DeepSeek V4 Pro" },
136
+ { id: "openrouter/qwen/qwen3.7-max", label: "Qwen: Qwen3.7 Max" },
137
+ { id: "openrouter/qwen/qwen3.6-max-preview", label: "Qwen: Qwen3.6 Max Preview" },
161
138
  { id: "openrouter/google/gemini-3.1-pro-preview", label: "Google: Gemini 3.1 Pro Preview" },
162
139
  { 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" },
140
+ { id: "openrouter/openai/o3-pro", label: "OpenAI: o3 Pro" },
141
+ { id: "openrouter/qwen/qwen3-max", label: "Qwen: Qwen3 Max" },
142
+ { id: "openrouter/upstage/solar-pro-3", label: "Upstage: Solar Pro 3" },
143
+ { id: "openrouter/google/gemini-2.5-pro", label: "Google: Gemini 2.5 Pro" },
144
+ { id: "openrouter/xiaomi/mimo-v2.5-pro", label: "Xiaomi: MiMo-V2.5-Pro" },
145
+ { id: "openrouter/amazon/nova-premier-v1", label: "Amazon: Nova Premier 1.0" },
146
+ { id: "openrouter/amazon/nova-pro-v1", label: "Amazon: Nova Pro 1.0" },
147
+ { id: "openrouter/~google/gemini-pro-latest", label: "Google Gemini Pro Latest" },
148
+ { id: "openrouter/sakana/fugu-ultra", label: "Sakana: Fugu Ultra" },
149
+ { id: "openrouter/arcee-ai/trinity-large-thinking", label: "Arcee AI: Trinity Large Thinking" },
150
+ { id: "openrouter/qwen/qwen3-coder", label: "Qwen: Qwen3 Coder 480B A35B" },
151
+ { id: "openrouter/qwen/qwen3-coder-30b-a3b-instruct", label: "Qwen: Qwen3 Coder 30B A3B Instruct" },
152
+ { id: "openrouter/openai/gpt-5.3-codex", label: "OpenAI: GPT-5.3-Codex" },
153
+ { id: "openrouter/openai/gpt-5.2-codex", label: "OpenAI: GPT-5.2-Codex" },
154
+ { id: "openrouter/openai/gpt-5.1-codex", label: "OpenAI: GPT-5.1-Codex" },
155
+ { id: "openrouter/openai/gpt-5-codex", label: "OpenAI: GPT-5 Codex" },
156
+ { id: "openrouter/qwen/qwen3-coder-next", label: "Qwen: Qwen3 Coder Next" },
157
+ { id: "openrouter/qwen/qwen3-coder-plus", label: "Qwen: Qwen3 Coder Plus" },
158
+ { id: "openrouter/moonshotai/kimi-k2.7-code", label: "MoonshotAI: Kimi K2.7 Code" },
159
+ { id: "openrouter/qwen/qwen3-235b-a22b-thinking-2507", label: "Qwen: Qwen3 235B A22B Thinking 2507" },
160
+ { id: "openrouter/qwen/qwen3-30b-a3b-thinking-2507", label: "Qwen: Qwen3 30B A3B Thinking 2507" },
161
+ { id: "openrouter/qwen/qwen-plus-2025-07-28:thinking", label: "Qwen: Qwen Plus 0728 (thinking)" },
162
+ { id: "openrouter/qwen/qwen3-vl-235b-a22b-thinking", label: "Qwen: Qwen3 VL 235B A22B Thinking" },
163
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-thinking", label: "Qwen: Qwen3 Next 80B A3B Thinking" },
164
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-thinking", label: "Qwen: Qwen3 VL 30B A3B Thinking" },
165
+ { id: "openrouter/qwen/qwen3-vl-8b-thinking", label: "Qwen: Qwen3 VL 8B Thinking" },
166
+ { id: "openrouter/google/gemini-3-pro-image", label: "Google: Nano Banana Pro (Gemini 3 Pro Image)" },
167
+ { id: "openrouter/moonshotai/kimi-k2-thinking", label: "MoonshotAI: Kimi K2 Thinking" },
168
+ { id: "openrouter/qwen/qwen3-coder-flash", label: "Qwen: Qwen3 Coder Flash" },
169
+ { id: "openrouter/mistralai/mistral-large-2512", label: "Mistral: Mistral Large 3 2512" },
170
+ { id: "openrouter/mistralai/mistral-large-2407", label: "Mistral Large 2407" },
171
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b", label: "NVIDIA: Nemotron 3 Super" },
172
+ { id: "openrouter/nvidia/llama-3.3-nemotron-super-49b-v1.5", label: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5" },
173
+ { id: "openrouter/ai21/jamba-large-1.7", label: "AI21: Jamba Large 1.7" },
174
+ { id: "openrouter/arcee-ai/virtuoso-large", label: "Arcee AI: Virtuoso Large" },
175
+ { id: "openrouter/mistralai/mistral-large", label: "Mistral Large" },
176
+ { id: "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free", label: "NVIDIA: Nemotron 3 Ultra (free)" },
177
+ { id: "openrouter/openai/gpt-5.1-codex-mini", label: "OpenAI: GPT-5.1-Codex-Mini" },
178
+ { id: "openrouter/qwen/qwen3.5-plus-20260420", label: "Qwen: Qwen3.5 Plus 2026-04-20" },
179
+ { id: "openrouter/mistralai/mistral-small-2603", label: "Mistral: Mistral Small 4" },
190
180
  { id: "openrouter/mistralai/devstral-2512", label: "Mistral: Devstral 2 2512" },
191
181
  { id: "openrouter/mistralai/ministral-14b-2512", label: "Mistral: Ministral 3 14B 2512" },
192
182
  { id: "openrouter/mistralai/ministral-3b-2512", label: "Mistral: Ministral 3 3B 2512" },
193
183
  { 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" },
184
+ { id: "openrouter/mistralai/codestral-2508", label: "Mistral: Codestral 2508" },
205
185
  { 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
186
  { 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
187
  { 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" },
188
+ { id: "openrouter/qwen/qwen3.5-plus-02-15", label: "Qwen: Qwen3.5 Plus 2026-02-15" },
189
+ { id: "openrouter/qwen/qwen-plus-2025-07-28", label: "Qwen: Qwen Plus 0728" },
190
+ { id: "openrouter/openai/gpt-4o-2024-11-20", label: "OpenAI: GPT-4o (2024-11-20)" },
191
+ { id: "openrouter/openai/gpt-4o-2024-08-06", label: "OpenAI: GPT-4o (2024-08-06)" },
192
+ { id: "openrouter/openai/gpt-4o-2024-05-13", label: "OpenAI: GPT-4o (2024-05-13)" },
193
+ { id: "openrouter/moonshotai/kimi-k2-0905", label: "MoonshotAI: Kimi K2 0905" },
194
+ { id: "openrouter/moonshotai/kimi-k2", label: "MoonshotAI: Kimi K2 0711" },
195
+ { id: "openrouter/deepseek/deepseek-r1-0528", label: "DeepSeek: R1 0528" },
304
196
  { 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" },
197
+ { id: "openrouter/qwen/qwen3.5-397b-a17b", label: "Qwen: Qwen3.5 397B A17B" },
198
+ { id: "openrouter/deepseek/deepseek-chat-v3-0324", label: "DeepSeek: DeepSeek V3 0324" },
199
+ { id: "openrouter/qwen/qwen3-235b-a22b", label: "Qwen: Qwen3 235B A22B" },
310
200
  { 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" },
201
+ { id: "openrouter/openai/gpt-oss-120b", label: "OpenAI: gpt-oss-120b" },
202
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct", label: "Qwen: Qwen3 Next 80B A3B Instruct" },
203
+ { id: "openrouter/qwen/qwen-2.5-72b-instruct", label: "Qwen2.5 72B Instruct" },
204
+ { id: "openrouter/meta-llama/llama-3.1-70b-instruct", label: "Meta: Llama 3.1 70B Instruct" },
205
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct", label: "Meta: Llama 3.3 70B Instruct" },
206
+ { id: "openrouter/sao10k/l3.1-euryale-70b", label: "Sao10K: Llama 3.1 Euryale 70B v2.2" },
207
+ { id: "openrouter/qwen/qwen3.6-35b-a3b", label: "Qwen: Qwen3.6 35B A3B" },
208
+ { id: "openrouter/qwen/qwen3-32b", label: "Qwen: Qwen3 32B" },
314
209
  { 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" },
210
+ { id: "openrouter/google/gemma-4-31b-it", label: "Google: Gemma 4 31B" },
211
+ { id: "openrouter/qwen/qwen3-30b-a3b", label: "Qwen: Qwen3 30B A3B" },
212
+ { id: "openrouter/qwen/qwen3-vl-30b-a3b-instruct", label: "Qwen: Qwen3 VL 30B A3B Instruct" },
213
+ { id: "openrouter/cohere/command-r-08-2024", label: "Cohere: Command R (08-2024)" },
214
+ { id: "openrouter/cohere/command-r-plus-08-2024", label: "Cohere: Command R+ (08-2024)" },
215
+ { id: "openrouter/google/gemma-3-27b-it", label: "Google: Gemma 3 27B" },
325
216
  { 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" },
217
+ { id: "openrouter/google/gemma-4-26b-a4b-it", label: "Google: Gemma 4 26B A4B " },
218
+ { id: "openrouter/mistralai/mistral-small-3.2-24b-instruct", label: "Mistral: Mistral Small 3.2 24B" },
219
+ { id: "openrouter/mistralai/mixtral-8x22b-instruct", label: "Mistral: Mixtral 8x22B Instruct" },
220
+ { id: "openrouter/openai/gpt-oss-20b", label: "OpenAI: gpt-oss-20b" },
221
+ { id: "openrouter/openai/gpt-oss-safeguard-20b", label: "OpenAI: gpt-oss-safeguard-20b" },
222
+ { id: "openrouter/qwen/qwen3-14b", label: "Qwen: Qwen3 14B" },
223
+ { id: "openrouter/google/gemma-3-12b-it", label: "Google: Gemma 3 12B" },
339
224
  { id: "openrouter/thedrummer/unslopnemo-12b", label: "TheDrummer: UnslopNemo 12B" },
340
- { id: "openrouter/upstage/solar-pro-3", label: "Upstage: Solar Pro 3" },
225
+ { id: "openrouter/qwen/qwen3.5-122b-a10b", label: "Qwen: Qwen3.5-122B-A10B" },
226
+ { id: "openrouter/ibm-granite/granite-4.1-8b", label: "IBM: Granite 4.1 8B" },
227
+ { id: "openrouter/meta-llama/llama-3.1-8b-instruct", label: "Meta: Llama 3.1 8B Instruct" },
228
+ { id: "openrouter/qwen/qwen3-8b", label: "Qwen: Qwen3 8B" },
229
+ { id: "openrouter/qwen/qwen3-vl-8b-instruct", label: "Qwen: Qwen3 VL 8B Instruct" },
230
+ { id: "openrouter/qwen/qwen-2.5-7b-instruct", label: "Qwen: Qwen2.5 7B Instruct" },
231
+ { id: "openrouter/openai/gpt-5.5", label: "OpenAI: GPT-5.5" },
232
+ { id: "openrouter/openai/gpt-5.4", label: "OpenAI: GPT-5.4" },
233
+ { id: "openrouter/openai/gpt-5.3-chat", label: "OpenAI: GPT-5.3 Chat" },
234
+ { id: "openrouter/openai/gpt-5.2", label: "OpenAI: GPT-5.2" },
235
+ { id: "openrouter/openai/gpt-5.2-chat", label: "OpenAI: GPT-5.2 Chat" },
236
+ { id: "openrouter/z-ai/glm-5.2", label: "Z.ai: GLM 5.2" },
237
+ { id: "openrouter/openai/gpt-5.1", label: "OpenAI: GPT-5.1" },
238
+ { id: "openrouter/openai/gpt-5.1-chat", label: "OpenAI: GPT-5.1 Chat" },
239
+ { id: "openrouter/z-ai/glm-5.1", label: "Z.ai: GLM 5.1" },
240
+ { id: "openrouter/openai/gpt-5", label: "OpenAI: GPT-5" },
241
+ { id: "openrouter/z-ai/glm-5", label: "Z.ai: GLM 5" },
341
242
  { 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" },
243
+ { id: "openrouter/z-ai/glm-4.7", label: "Z.ai: GLM 4.7" },
244
+ { id: "openrouter/z-ai/glm-4.6", label: "Z.ai: GLM 4.6" },
245
+ { id: "openrouter/z-ai/glm-4.6v", label: "Z.ai: GLM 4.6V" },
346
246
  { id: "openrouter/z-ai/glm-4.5", label: "Z.ai: GLM 4.5" },
347
247
  { id: "openrouter/z-ai/glm-4.5-air", label: "Z.ai: GLM 4.5 Air" },
348
248
  { 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" },
249
+ { id: "openrouter/x-ai/grok-4.3", label: "xAI: Grok 4.3" },
250
+ { id: "openrouter/openai/gpt-4.1", label: "OpenAI: GPT-4.1" },
251
+ { id: "openrouter/meta-llama/llama-4-maverick", label: "Meta: Llama 4 Maverick" },
252
+ { id: "openrouter/meta-llama/llama-4-scout", label: "Meta: Llama 4 Scout" },
253
+ { id: "openrouter/openai/gpt-4", label: "OpenAI: GPT-4" },
254
+ { id: "openrouter/openai/gpt-4o", label: "OpenAI: GPT-4o" },
255
+ { id: "openrouter/qwen/qwen3.7-plus", label: "Qwen: Qwen3.7 Plus" },
256
+ { id: "openrouter/qwen/qwen3.6-plus", label: "Qwen: Qwen3.6 Plus" },
257
+ { id: "openrouter/qwen/qwen3.5-35b-a3b", label: "Qwen: Qwen3.5-35B-A3B" },
258
+ { id: "openrouter/qwen/qwen3.5-27b", label: "Qwen: Qwen3.5-27B" },
259
+ { id: "openrouter/qwen/qwen3.5-9b", label: "Qwen: Qwen3.5-9B" },
260
+ { id: "openrouter/mistralai/mistral-medium-3-5", label: "Mistral: Mistral Medium 3.5" },
261
+ { id: "openrouter/deepseek/deepseek-v3.2", label: "DeepSeek: DeepSeek V3.2" },
262
+ { id: "openrouter/deepseek/deepseek-v3.2-exp", label: "DeepSeek: DeepSeek V3.2 Exp" },
263
+ { id: "openrouter/deepseek/deepseek-chat-v3.1", label: "DeepSeek: DeepSeek V3.1" },
264
+ { id: "openrouter/deepseek/deepseek-v3.1-terminus", label: "DeepSeek: DeepSeek V3.1 Terminus" },
265
+ { id: "openrouter/mistralai/mistral-medium-3.1", label: "Mistral: Mistral Medium 3.1" },
266
+ { id: "openrouter/deepseek/deepseek-chat", label: "DeepSeek: DeepSeek V3" },
267
+ { id: "openrouter/minimax/minimax-m3", label: "MiniMax: MiniMax M3" },
268
+ { id: "openrouter/mistralai/mistral-medium-3", label: "Mistral: Mistral Medium 3" },
269
+ { id: "openrouter/openai/o3", label: "OpenAI: o3" },
270
+ { id: "openrouter/openai/o3-deep-research", label: "OpenAI: o3 Deep Research" },
271
+ { id: "openrouter/tencent/hy3-preview", label: "Tencent: Hy3 preview" },
272
+ { id: "openrouter/minimax/minimax-m2.7", label: "MiniMax: MiniMax M2.7" },
273
+ { id: "openrouter/inclusionai/ling-2.6-1t", label: "inclusionAI: Ling-2.6-1T" },
274
+ { id: "openrouter/inclusionai/ring-2.6-1t", label: "inclusionAI: Ring-2.6-1T" },
275
+ { id: "openrouter/moonshotai/kimi-k2.6", label: "MoonshotAI: Kimi K2.6" },
276
+ { id: "openrouter/minimax/minimax-m2.5", label: "MiniMax: MiniMax M2.5" },
277
+ { id: "openrouter/moonshotai/kimi-k2.5", label: "MoonshotAI: Kimi K2.5" },
278
+ { id: "openrouter/xiaomi/mimo-v2.5", label: "Xiaomi: MiMo-V2.5" },
279
+ { id: "openrouter/minimax/minimax-m2.1", label: "MiniMax: MiniMax M2.1" },
280
+ { id: "openrouter/inception/mercury-2", label: "Inception: Mercury 2" },
281
+ { id: "openrouter/minimax/minimax-m2", label: "MiniMax: MiniMax M2" },
282
+ { id: "openrouter/poolside/laguna-xs.2", label: "Poolside: Laguna XS.2" },
283
+ { id: "openrouter/bytedance-seed/seed-1.6", label: "ByteDance Seed: Seed 1.6" },
284
+ { id: "openrouter/deepseek/deepseek-r1", label: "DeepSeek: R1" },
285
+ { id: "openrouter/minimax/minimax-m1", label: "MiniMax: MiniMax M1" },
286
+ { id: "openrouter/openai/o1", label: "OpenAI: o1" },
287
+ { id: "openrouter/poolside/laguna-m.1", label: "Poolside: Laguna M.1" },
288
+ { id: "openrouter/x-ai/grok-build-0.1", label: "xAI: Grok Build 0.1" },
289
+ { id: "openrouter/auto", label: "Auto" },
290
+ { id: "openrouter/openrouter/auto", label: "Auto Router" },
291
+ { id: "openrouter/mistralai/mistral-nemo", label: "Mistral: Mistral Nemo" },
292
+ { id: "openrouter/mistralai/mistral-saba", label: "Mistral: Saba" },
363
293
  { id: "openrouter/~moonshotai/kimi-latest", label: "MoonshotAI Kimi Latest" },
364
294
  { id: "openrouter/~openai/gpt-latest", label: "OpenAI GPT Latest" },
365
- { id: "openrouter/~openai/gpt-mini-latest", label: "OpenAI GPT Mini Latest" }
295
+ { id: "openrouter/openai/gpt-audio", label: "OpenAI: GPT Audio" },
296
+ { id: "openrouter/openai/gpt-chat-latest", label: "OpenAI: GPT Chat Latest" },
297
+ { id: "openrouter/openrouter/fusion", label: "OpenRouter: Fusion" },
298
+ { id: "openrouter/qwen/qwen-plus", label: "Qwen: Qwen-Plus" },
299
+ { id: "openrouter/rekaai/reka-edge", label: "Reka Edge" },
300
+ { id: "openrouter/relace/relace-search", label: "Relace: Relace Search" },
301
+ { id: "openrouter/liquid/lfm-2.5-1.2b-thinking:free", label: "LiquidAI: LFM2.5-1.2B-Thinking (free)" },
302
+ { id: "openrouter/openai/gpt-3.5-turbo-0613", label: "OpenAI: GPT-3.5 Turbo (older v0613)" },
303
+ { id: "openrouter/openai/gpt-3.5-turbo-16k", label: "OpenAI: GPT-3.5 Turbo 16k" },
304
+ { id: "openrouter/z-ai/glm-5-turbo", label: "Z.ai: GLM 5 Turbo" },
305
+ { id: "openrouter/z-ai/glm-5v-turbo", label: "Z.ai: GLM 5V Turbo" },
306
+ { id: "openrouter/z-ai/glm-4.7-flash", label: "Z.ai: GLM 4.7 Flash" },
307
+ { id: "openrouter/deepseek/deepseek-v4-flash", label: "DeepSeek: DeepSeek V4 Flash" },
308
+ { id: "openrouter/openai/gpt-4-turbo", label: "OpenAI: GPT-4 Turbo" },
309
+ { id: "openrouter/openai/gpt-4-turbo-preview", label: "OpenAI: GPT-4 Turbo Preview" },
310
+ { id: "openrouter/stepfun/step-3.7-flash", label: "StepFun: Step 3.7 Flash" },
311
+ { id: "openrouter/qwen/qwen3.6-flash", label: "Qwen: Qwen3.6 Flash" },
312
+ { id: "openrouter/google/gemini-3.5-flash", label: "Google: Gemini 3.5 Flash" },
313
+ { id: "openrouter/openai/gpt-3.5-turbo", label: "OpenAI: GPT-3.5 Turbo" },
314
+ { id: "openrouter/qwen/qwen3.5-flash-02-23", label: "Qwen: Qwen3.5-Flash" },
315
+ { id: "openrouter/stepfun/step-3.5-flash", label: "StepFun: Step 3.5 Flash" },
316
+ { id: "openrouter/google/gemini-3-flash-preview", label: "Google: Gemini 3 Flash Preview" },
317
+ { id: "openrouter/inclusionai/ling-2.6-flash", label: "inclusionAI: Ling-2.6-flash" },
318
+ { id: "openrouter/google/gemini-2.5-flash", label: "Google: Gemini 2.5 Flash" },
319
+ { id: "openrouter/bytedance-seed/seed-1.6-flash", label: "ByteDance Seed: Seed 1.6 Flash" },
320
+ { id: "openrouter/~google/gemini-flash-latest", label: "Google Gemini Flash Latest" },
321
+ { id: "openrouter/nvidia/nemotron-3-super-120b-a12b:free", label: "NVIDIA: Nemotron 3 Super (free)" },
322
+ { id: "openrouter/openai/gpt-4o-mini-2024-07-18", label: "OpenAI: GPT-4o-mini (2024-07-18)" },
323
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b", label: "NVIDIA: Nemotron 3 Nano 30B A3B" },
324
+ { id: "openrouter/openai/gpt-5.4-mini", label: "OpenAI: GPT-5.4 Mini" },
325
+ { id: "openrouter/openai/gpt-5.4-nano", label: "OpenAI: GPT-5.4 Nano" },
326
+ { id: "openrouter/openai/gpt-5-mini", label: "OpenAI: GPT-5 Mini" },
327
+ { id: "openrouter/openai/gpt-5-nano", label: "OpenAI: GPT-5 Nano" },
328
+ { id: "openrouter/openai/gpt-4.1-mini", label: "OpenAI: GPT-4.1 Mini" },
329
+ { id: "openrouter/openai/gpt-4.1-nano", label: "OpenAI: GPT-4.1 Nano" },
330
+ { id: "openrouter/openai/gpt-4o-mini", label: "OpenAI: GPT-4o-mini" },
331
+ { id: "openrouter/openai/o4-mini", label: "OpenAI: o4 Mini" },
332
+ { id: "openrouter/openai/o4-mini-deep-research", label: "OpenAI: o4 Mini Deep Research" },
333
+ { id: "openrouter/openai/o4-mini-high", label: "OpenAI: o4 Mini High" },
334
+ { id: "openrouter/openai/o3-mini", label: "OpenAI: o3 Mini" },
335
+ { id: "openrouter/openai/o3-mini-high", label: "OpenAI: o3 Mini High" },
336
+ { id: "openrouter/amazon/nova-2-lite-v1", label: "Amazon: Nova 2 Lite" },
337
+ { id: "openrouter/bytedance-seed/seed-2.0-lite", label: "ByteDance Seed: Seed-2.0-Lite" },
338
+ { id: "openrouter/bytedance-seed/seed-2.0-mini", label: "ByteDance Seed: Seed-2.0-Mini" },
339
+ { id: "openrouter/amazon/nova-lite-v1", label: "Amazon: Nova Lite 1.0" },
340
+ { id: "openrouter/amazon/nova-micro-v1", label: "Amazon: Nova Micro 1.0" },
341
+ { id: "openrouter/arcee-ai/trinity-mini", label: "Arcee AI: Trinity Mini" },
342
+ { id: "openrouter/cohere/north-mini-code:free", label: "Cohere: North Mini Code (free)" },
343
+ { id: "openrouter/~openai/gpt-mini-latest", label: "OpenAI GPT Mini Latest" },
344
+ { id: "openrouter/openai/gpt-audio-mini", label: "OpenAI: GPT Audio Mini" },
345
+ { id: "openrouter/openai/gpt-oss-120b:free", label: "OpenAI: gpt-oss-120b (free)" },
346
+ { id: "openrouter/qwen/qwen3-next-80b-a3b-instruct:free", label: "Qwen: Qwen3 Next 80B A3B Instruct (free)" },
347
+ { id: "openrouter/meta-llama/llama-3.3-70b-instruct:free", label: "Meta: Llama 3.3 70B Instruct (free)" },
348
+ { id: "openrouter/google/gemma-4-31b-it:free", label: "Google: Gemma 4 31B (free)" },
349
+ { id: "openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", label: "NVIDIA: Nemotron 3 Nano Omni (free)" },
350
+ { id: "openrouter/google/gemma-4-26b-a4b-it:free", label: "Google: Gemma 4 26B A4B (free)" },
351
+ { id: "openrouter/openai/gpt-oss-20b:free", label: "OpenAI: gpt-oss-20b (free)" },
352
+ { id: "openrouter/poolside/laguna-xs.2:free", label: "Poolside: Laguna XS.2 (free)" },
353
+ { id: "openrouter/poolside/laguna-m.1:free", label: "Poolside: Laguna M.1 (free)" },
354
+ { id: "openrouter/openrouter/free", label: "Free Models Router" },
355
+ { id: "openrouter/google/gemini-2.5-flash-lite-preview-09-2025", label: "Google: Gemini 2.5 Flash Lite Preview 09-2025" },
356
+ { id: "openrouter/google/gemini-3.1-flash-lite", label: "Google: Gemini 3.1 Flash Lite" },
357
+ { id: "openrouter/google/gemini-3.1-flash-lite-preview", label: "Google: Gemini 3.1 Flash Lite Preview" },
358
+ { id: "openrouter/google/gemini-2.5-flash-lite", label: "Google: Gemini 2.5 Flash Lite" },
359
+ { id: "openrouter/nvidia/nemotron-3-nano-30b-a3b:free", label: "NVIDIA: Nemotron 3 Nano 30B A3B (free)" },
360
+ { id: "openrouter/nvidia/nemotron-nano-12b-v2-vl:free", label: "NVIDIA: Nemotron Nano 12B 2 VL (free)" },
361
+ { id: "openrouter/nvidia/nemotron-nano-9b-v2:free", label: "NVIDIA: Nemotron Nano 9B V2 (free)" }
366
362
  ],
367
363
  "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
364
  { 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" },
365
+ { id: "openai/gpt-5.5-pro", label: "GPT-5.5 Pro" },
366
+ { id: "openai/gpt-5.4-pro", label: "GPT-5.4 Pro" },
393
367
  { 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)" },
368
+ { id: "openai/gpt-5-pro", label: "GPT-5 Pro" },
369
+ { id: "openai/o3-pro", label: "o3-pro" },
370
+ { id: "openai/o1-pro", label: "o1-pro" },
395
371
  { id: "openai/gpt-5.3-codex", label: "GPT-5.3 Codex" },
396
372
  { 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" },
373
+ { id: "openai/gpt-5.2-codex", label: "GPT-5.2 Codex" },
374
+ { id: "openai/gpt-5.1-codex", label: "GPT-5.1 Codex" },
375
+ { id: "openai/gpt-5-codex", label: "GPT-5-Codex" },
376
+ { id: "openai/gpt-5.1-codex-mini", label: "GPT-5.1 Codex mini" },
377
+ { id: "openai/gpt-4o-2024-11-20", label: "GPT-4o (2024-11-20)" },
378
+ { id: "openai/gpt-4o-2024-08-06", label: "GPT-4o (2024-08-06)" },
379
+ { id: "openai/gpt-4o-2024-05-13", label: "GPT-4o (2024-05-13)" },
400
380
  { 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" },
381
+ { id: "openai/gpt-5.4", label: "GPT-5.4" },
382
+ { id: "openai/gpt-5.3-chat-latest", label: "GPT-5.3 Chat (latest)" },
383
+ { id: "openai/gpt-5.2", label: "GPT-5.2" },
384
+ { id: "openai/gpt-5.2-chat-latest", label: "GPT-5.2 Chat" },
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", label: "GPT-5" },
388
+ { id: "openai/gpt-5-chat-latest", label: "GPT-5 Chat Latest" },
389
+ { id: "openai/gpt-4.1", label: "GPT-4.1" },
390
+ { id: "openai/gpt-4", label: "GPT-4" },
391
+ { id: "openai/gpt-4o", label: "GPT-4o" },
404
392
  { id: "openai/o3", label: "o3" },
405
393
  { 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" },
394
+ { id: "openai/o1", label: "o1" },
395
+ { id: "openai/gpt-4-turbo", label: "GPT-4 Turbo" },
396
+ { id: "openai/gpt-5.4-mini", label: "GPT-5.4 mini" },
397
+ { id: "openai/gpt-5.4-nano", label: "GPT-5.4 nano" },
398
+ { id: "openai/gpt-5-mini", label: "GPT-5 Mini" },
399
+ { id: "openai/gpt-5-nano", label: "GPT-5 Nano" },
400
+ { id: "openai/gpt-4.1-mini", label: "GPT-4.1 mini" },
401
+ { id: "openai/gpt-4.1-nano", label: "GPT-4.1 nano" },
402
+ { id: "openai/gpt-4o-mini", label: "GPT-4o mini" },
408
403
  { id: "openai/o4-mini", label: "o4-mini" },
409
- { id: "openai/o4-mini-deep-research", label: "o4-mini-deep-research" }
404
+ { id: "openai/o4-mini-deep-research", label: "o4-mini-deep-research" },
405
+ { id: "openai/o3-mini", label: "o3-mini" }
410
406
  ],
411
407
  "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
408
  { 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" },
409
+ { id: "anthropic/claude-3-opus-20240229", label: "Claude Opus 3" },
427
410
  { id: "anthropic/claude-opus-4-20250514", label: "Claude Opus 4" },
428
- { id: "anthropic/claude-opus-4-5", label: "Claude Opus 4.5 (latest)" },
429
411
  { id: "anthropic/claude-opus-4-5-20251101", label: "Claude Opus 4.5" },
430
- { id: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" },
412
+ { id: "anthropic/claude-opus-4-1-20250805", label: "Claude Opus 4.1" },
413
+ { id: "anthropic/claude-opus-4-8", label: "Claude Opus 4.8" },
431
414
  { id: "anthropic/claude-opus-4-7", label: "Claude Opus 4.7" },
432
- { id: "anthropic/claude-sonnet-4-0", label: "Claude Sonnet 4 (latest)" },
415
+ { id: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" },
416
+ { id: "anthropic/claude-opus-4-5", label: "Claude Opus 4.5 (latest)" },
417
+ { id: "anthropic/claude-opus-4-1", label: "Claude Opus 4.1 (latest)" },
418
+ { id: "anthropic/claude-opus-4-0", label: "Claude Opus 4 (latest)" },
419
+ { id: "anthropic/claude-3-7-sonnet-20250219", label: "Claude Sonnet 3.7" },
420
+ { id: "anthropic/claude-3-5-sonnet-20241022", label: "Claude Sonnet 3.5 v2" },
421
+ { id: "anthropic/claude-3-5-sonnet-20240620", label: "Claude Sonnet 3.5" },
422
+ { id: "anthropic/claude-3-sonnet-20240229", label: "Claude Sonnet 3" },
433
423
  { id: "anthropic/claude-sonnet-4-20250514", label: "Claude Sonnet 4" },
434
- { id: "anthropic/claude-sonnet-4-5", label: "Claude Sonnet 4.5 (latest)" },
435
424
  { id: "anthropic/claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
436
- { id: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" }
425
+ { id: "anthropic/claude-sonnet-5", label: "Claude Sonnet 5" },
426
+ { id: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
427
+ { id: "anthropic/claude-sonnet-4-5", label: "Claude Sonnet 4.5 (latest)" },
428
+ { id: "anthropic/claude-sonnet-4-0", label: "Claude Sonnet 4 (latest)" },
429
+ { id: "anthropic/claude-3-haiku-20240307", label: "Claude Haiku 3" },
430
+ { id: "anthropic/claude-haiku-4-5-20251001", label: "Claude Haiku 4.5" },
431
+ { id: "anthropic/claude-haiku-4-5", label: "Claude Haiku 4.5 (latest)" }
437
432
  ],
438
433
  "google": [
439
434
  { 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" },
435
+ { id: "google/gemini-3.1-pro-preview-customtools", label: "Gemini 3.1 Pro Preview Custom Tools" },
436
+ { id: "google/gemini-3-pro-preview", label: "Gemini 3 Pro Preview" },
444
437
  { id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro" },
438
+ { id: "google/gemma-4-31b-it", label: "Gemma 4 31B IT" },
439
+ { id: "google/gemma-4-26b-a4b-it", label: "Gemma 4 26B A4B IT" },
440
+ { id: "google/gemini-3.5-flash", label: "Gemini 3.5 Flash" },
445
441
  { id: "google/gemini-3-flash-preview", label: "Gemini 3 Flash Preview" },
446
- { id: "google/gemini-3-pro-preview", label: "Gemini 3 Pro Preview" },
442
+ { id: "google/gemini-2.5-flash", label: "Gemini 2.5 Flash" },
443
+ { id: "google/gemini-2.0-flash", label: "Gemini 2.0 Flash" },
444
+ { id: "google/gemini-flash-latest", label: "Gemini Flash Latest" },
447
445
  { id: "google/gemini-3.1-flash-lite", label: "Gemini 3.1 Flash Lite" },
448
446
  { 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" }
447
+ { id: "google/gemini-2.5-flash-lite", label: "Gemini 2.5 Flash-Lite" },
448
+ { id: "google/gemini-2.0-flash-lite", label: "Gemini 2.0 Flash-Lite" },
449
+ { id: "google/gemini-flash-lite-latest", label: "Gemini Flash-Lite Latest" }
457
450
  ],
458
451
  "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
452
  { id: "xai/grok-4.20-0309-non-reasoning", label: "Grok 4.20 (Non-Reasoning)" },
453
+ { id: "xai/grok-4.20-0309-reasoning", label: "Grok 4.20 (Reasoning)" },
454
+ { id: "xai/grok-code-fast-1", label: "Grok Code Fast 1" },
463
455
  { id: "xai/grok-4.3", label: "Grok 4.3" },
456
+ { id: "xai/grok-3", label: "Grok 3" },
464
457
  { id: "xai/grok-build-0.1", label: "Grok Build 0.1" },
465
- { id: "xai/grok-code-fast-1", label: "Grok Code Fast 1" }
458
+ { id: "xai/grok-3-fast", label: "Grok 3 Fast" }
466
459
  ],
467
460
  "xiaomi": [
468
461
  { 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" },
462
+ { id: "xiaomi/mimo-v2.5-pro-ultraspeed", label: "MiMo-V2.5-Pro-UltraSpeed" },
471
463
  { id: "xiaomi/mimo-v2-pro", label: "MiMo-V2-Pro" },
472
464
  { id: "xiaomi/mimo-v2.5", label: "MiMo-V2.5" },
473
- { id: "xiaomi/mimo-v2.5-pro-ultraspeed", label: "MiMo-V2.5-Pro-UltraSpeed" }
465
+ { id: "xiaomi/mimo-v2-omni", label: "MiMo-V2-Omni" },
466
+ { id: "xiaomi/mimo-v2-flash", label: "MiMo-V2-Flash" }
474
467
  ]
475
468
  };
476
469
 
@@ -820,17 +813,26 @@ function projectApmHeldFreshnessActivity(input) {
820
813
  countLine,
821
814
  ...decisionLines
822
815
  ].filter((line) => Boolean(line)).join("\n");
816
+ const statusEntry = {
817
+ kind: "status",
818
+ activity: "working",
819
+ detail: title,
820
+ producerFactId: input.producerFactId
821
+ };
822
+ const entry = {
823
+ kind: "slock_action",
824
+ producerFactId: input.producerFactId,
825
+ title,
826
+ text
827
+ };
823
828
  return {
824
829
  clauseId: "SMR-006",
825
830
  projector: "held-envelope",
826
831
  surface: "agent:activity",
827
832
  producerFactId: input.producerFactId,
828
- entry: {
829
- kind: "slock_action",
830
- producerFactId: input.producerFactId,
831
- title,
832
- text
833
- }
833
+ statusEntry,
834
+ entry,
835
+ entries: [statusEntry, entry]
834
836
  };
835
837
  }
836
838
  function projectApmFreshnessDecisionTrace(input) {
@@ -1347,6 +1349,7 @@ var TOOL_DISPLAY_METADATA = {
1347
1349
  claim_tasks: { logLabel: "Claiming tasks", activityLabel: "Claiming tasks\u2026", summaryKind: "claim_tasks" },
1348
1350
  unclaim_task: { logLabel: "Unclaiming task", activityLabel: "Unclaiming task\u2026", summaryKind: "task_ref" },
1349
1351
  update_task_status: { logLabel: "Updating task status", activityLabel: "Updating task status\u2026", summaryKind: "task_ref" },
1352
+ add_channel_member: { logLabel: "Adding channel member", activityLabel: "Adding channel member\u2026", summaryKind: "target" },
1350
1353
  join_channel: { logLabel: "Joining channel", activityLabel: "Joining channel\u2026", summaryKind: "target" },
1351
1354
  leave_channel: { logLabel: "Leaving channel", activityLabel: "Leaving channel\u2026", summaryKind: "target" },
1352
1355
  upload_file: { logLabel: "Uploading file", activityLabel: "Uploading file\u2026", summaryKind: "file_path" },
@@ -1378,6 +1381,7 @@ var KNOWN_TOOL_ALIASES = {
1378
1381
  claim_tasks: "claim_tasks",
1379
1382
  unclaim_task: "unclaim_task",
1380
1383
  update_task_status: "update_task_status",
1384
+ add_channel_member: "add_channel_member",
1381
1385
  join_channel: "join_channel",
1382
1386
  leave_channel: "leave_channel",
1383
1387
  upload_file: "upload_file",
@@ -1595,8 +1599,44 @@ function resolveSlockCliInvocation(toolName, input) {
1595
1599
  return { toolName: "search_messages", input: { query: readOptionValue(rest, "--query") } };
1596
1600
  case "server info":
1597
1601
  return { toolName: "list_server", input: {} };
1602
+ case "server update":
1603
+ return {
1604
+ toolName: "update_server",
1605
+ input: {
1606
+ name: readOptionValue(rest, "--name"),
1607
+ avatar_file: readOptionValue(rest, "--avatar-file")
1608
+ }
1609
+ };
1598
1610
  case "channel members":
1599
1611
  return { toolName: "list_channel_members", input: { channel: rest[0] } };
1612
+ case "channel update":
1613
+ return {
1614
+ toolName: "update_channel",
1615
+ input: {
1616
+ target: readOptionValue(rest, "--target"),
1617
+ name: readOptionValue(rest, "--name"),
1618
+ description: readOptionValue(rest, "--description"),
1619
+ visibility: rest.includes("--private") ? "private" : rest.includes("--public") ? "public" : void 0
1620
+ }
1621
+ };
1622
+ case "channel add-member":
1623
+ return {
1624
+ toolName: "add_channel_member",
1625
+ input: {
1626
+ target: readOptionValue(rest, "--target"),
1627
+ user: readOptionValue(rest, "--user"),
1628
+ agent: readOptionValue(rest, "--agent")
1629
+ }
1630
+ };
1631
+ case "channel remove-member":
1632
+ return {
1633
+ toolName: "remove_channel_member",
1634
+ input: {
1635
+ target: readOptionValue(rest, "--target"),
1636
+ user: readOptionValue(rest, "--user"),
1637
+ agent: readOptionValue(rest, "--agent")
1638
+ }
1639
+ };
1600
1640
  case "channel join":
1601
1641
  return { toolName: "join_channel", input: { target: readOptionValue(rest, "--target") } };
1602
1642
  case "channel leave":
@@ -1830,6 +1870,21 @@ var agentApiHistoryQuerySchema = passthroughObject({
1830
1870
  around: optionalStringSchema,
1831
1871
  limit: optionalStringSchema
1832
1872
  });
1873
+ var agentApiKnowledgeGetQuerySchema = passthroughObject({
1874
+ topic: z2.string().trim().min(1),
1875
+ reason: optionalStringSchema,
1876
+ turn_id: optionalStringSchema,
1877
+ trace_id: optionalStringSchema
1878
+ });
1879
+ var agentApiKnowledgeGetResponseSchema = passthroughObject({
1880
+ ok: z2.literal(true),
1881
+ docId: z2.string(),
1882
+ topicOrPath: z2.string(),
1883
+ docVersion: z2.string(),
1884
+ docState: z2.string(),
1885
+ contentType: z2.string(),
1886
+ content: z2.string()
1887
+ });
1833
1888
  var agentApiMessageSearchQuerySchema = passthroughObject({
1834
1889
  q: optionalStringSchema,
1835
1890
  channel: optionalStringSchema,
@@ -1867,6 +1922,58 @@ var agentApiMessageReactionBodySchema = passthroughObject({
1867
1922
  var agentApiChannelMembershipParamsSchema = passthroughObject({
1868
1923
  channelId: z2.string().trim().min(1).transform(asChannelId)
1869
1924
  });
1925
+ var agentApiAttachmentDownloadParamsSchema = passthroughObject({
1926
+ attachmentId: z2.string().trim().min(1)
1927
+ });
1928
+ var agentApiAttachmentCommentsParamsSchema = passthroughObject({
1929
+ attachmentId: z2.string().trim().min(1)
1930
+ });
1931
+ var agentApiAttachmentCommentsQuerySchema = passthroughObject({
1932
+ limit: optionalStringSchema
1933
+ });
1934
+ var agentApiAttachmentCommentAnchorSchema = passthroughObject({
1935
+ type: z2.string().trim().min(1),
1936
+ data: z2.record(z2.string(), z2.unknown())
1937
+ });
1938
+ var agentApiAttachmentCommentReactionSchema = passthroughObject({
1939
+ emoji: z2.string().trim().min(1),
1940
+ reactorType: z2.string().trim().min(1),
1941
+ reactorId: z2.string().trim().min(1),
1942
+ createdAt: z2.string().datetime()
1943
+ });
1944
+ var agentApiAttachmentCommentResolvedBySchema = passthroughObject({
1945
+ reactorId: z2.string().trim().min(1),
1946
+ reactorType: z2.string().trim().min(1)
1947
+ });
1948
+ var agentApiAttachmentCommentSchema = passthroughObject({
1949
+ id: z2.string().trim().min(1),
1950
+ channelId: z2.string().trim().min(1).optional(),
1951
+ senderId: z2.string().trim().min(1),
1952
+ senderType: z2.enum(["user", "agent"]),
1953
+ senderName: z2.string().trim().min(1),
1954
+ senderAvatarUrl: nullableStringSchema.optional(),
1955
+ senderGravatarHash: nullableStringSchema.optional(),
1956
+ content: z2.string(),
1957
+ createdAt: z2.string().datetime(),
1958
+ reactions: z2.array(agentApiAttachmentCommentReactionSchema),
1959
+ anchor: agentApiAttachmentCommentAnchorSchema.nullable(),
1960
+ resolved: z2.boolean().optional(),
1961
+ resolvedBy: agentApiAttachmentCommentResolvedBySchema.nullable().optional(),
1962
+ resolvedAt: z2.string().datetime().nullable().optional()
1963
+ });
1964
+ var agentApiAttachmentCommentsResponseSchema = passthroughObject({
1965
+ comments: z2.array(agentApiAttachmentCommentSchema),
1966
+ threadChannelId: nullableStringSchema.optional(),
1967
+ viewer: passthroughObject({
1968
+ canComment: z2.boolean(),
1969
+ reason: z2.string().optional(),
1970
+ canResolve: z2.boolean(),
1971
+ resolveAction: passthroughObject({
1972
+ type: z2.string().trim().min(1),
1973
+ emoji: z2.string().trim().min(1)
1974
+ }).optional()
1975
+ }).optional()
1976
+ });
1870
1977
  var agentApiChannelMembersQuerySchema = passthroughObject({
1871
1978
  channel: z2.string().trim().min(1)
1872
1979
  });
@@ -2021,6 +2128,9 @@ var agentApiIntegrationAppPrepareBodySchema = passthroughObject({
2021
2128
  unsafeDemoUrlOverride: optionalBooleanSchema,
2022
2129
  draftHint: optionalStringSchema
2023
2130
  });
2131
+ var agentApiIntegrationAppRotateSecretBodySchema = passthroughObject({
2132
+ clientKey: z2.string().trim().min(1)
2133
+ });
2024
2134
  var agentApiActionPrepareBodySchema = passthroughObject({
2025
2135
  target: z2.string().trim().min(1),
2026
2136
  action: actionCardActionSchema
@@ -2028,6 +2138,9 @@ var agentApiActionPrepareBodySchema = passthroughObject({
2028
2138
  var agentApiServerInfoResponseSchema = passthroughObject({
2029
2139
  runtimeContext: passthroughObject({
2030
2140
  agentId: z2.string(),
2141
+ runtime: z2.string().optional(),
2142
+ model: z2.string().optional(),
2143
+ reasoningEffort: reasoningEffortSchema.nullable().optional(),
2031
2144
  serverId: z2.string(),
2032
2145
  machineId: z2.string().nullable().optional(),
2033
2146
  machineName: z2.string().nullable().optional(),
@@ -2044,10 +2157,12 @@ var agentApiServerInfoResponseSchema = passthroughObject({
2044
2157
  joined: z2.boolean()
2045
2158
  })),
2046
2159
  agents: z2.array(passthroughObject({
2047
- name: z2.string()
2160
+ name: z2.string(),
2161
+ role: z2.enum(["owner", "admin", "member"]).nullable().optional()
2048
2162
  })),
2049
2163
  humans: z2.array(passthroughObject({
2050
- name: z2.string()
2164
+ name: z2.string(),
2165
+ role: z2.enum(["owner", "admin", "member"]).nullable().optional()
2051
2166
  }))
2052
2167
  });
2053
2168
  var agentApiMentionActionsPendingQuerySchema = passthroughObject({
@@ -2122,6 +2237,12 @@ var agentApiIntegrationAppPrepareResponseSchema = passthroughObject({
2122
2237
  integrationUpdateAppRegistrationOperationSchema
2123
2238
  ])
2124
2239
  });
2240
+ var agentApiIntegrationAppRotateSecretResponseSchema = passthroughObject({
2241
+ clientId: z2.string(),
2242
+ clientKey: z2.string(),
2243
+ clientName: z2.string(),
2244
+ clientSecret: z2.string()
2245
+ });
2125
2246
  var agentApiAttachmentEnvelopeSchema = passthroughObject({
2126
2247
  id: z2.string(),
2127
2248
  filename: z2.string()
@@ -2257,6 +2378,21 @@ var agentApiChannelMembersResponseSchema = passthroughObject({
2257
2378
  role: optionalStringSchema
2258
2379
  }))
2259
2380
  });
2381
+ var agentApiChannelMuteResponseSchema = passthroughObject({
2382
+ activityMuted: optionalBooleanSchema,
2383
+ muteFromSeq: nullableNumberSchema.optional(),
2384
+ attention: passthroughObject({
2385
+ state: optionalStringSchema,
2386
+ ordinaryActivity: optionalStringSchema,
2387
+ unmuteCommand: optionalStringSchema,
2388
+ unmuteApi: optionalStringSchema,
2389
+ muteCommand: optionalStringSchema,
2390
+ muteApi: optionalStringSchema,
2391
+ stillArrives: optionalStringArraySchema,
2392
+ threadBoundary: optionalStringSchema,
2393
+ catchUp: optionalStringSchema
2394
+ }).optional()
2395
+ });
2260
2396
  var agentApiTaskClaimResultSchema = passthroughObject({
2261
2397
  taskNumber: z2.number().int().positive().optional(),
2262
2398
  messageId: optionalStringSchema,
@@ -2369,6 +2505,16 @@ var agentApiContract = {
2369
2505
  request: { query: agentApiHistoryQuerySchema },
2370
2506
  response: { body: agentApiHistoryResponseSchema }
2371
2507
  }),
2508
+ knowledgeGet: route({
2509
+ key: "knowledgeGet",
2510
+ method: "GET",
2511
+ path: "/knowledge",
2512
+ client: { resource: "knowledge", method: "get" },
2513
+ capability: "knowledge",
2514
+ description: "Fetch a Slock Manual for Agents topic from the current server.",
2515
+ request: { query: agentApiKnowledgeGetQuerySchema },
2516
+ response: { body: agentApiKnowledgeGetResponseSchema }
2517
+ }),
2372
2518
  messageSend: route({
2373
2519
  key: "messageSend",
2374
2520
  method: "POST",
@@ -2429,15 +2575,35 @@ var agentApiContract = {
2429
2575
  request: { params: agentApiChannelMembershipParamsSchema },
2430
2576
  response: { body: agentApiOkResponseSchema }
2431
2577
  }),
2432
- channelLeave: route({
2433
- key: "channelLeave",
2578
+ channelLeave: route({
2579
+ key: "channelLeave",
2580
+ method: "POST",
2581
+ path: "/channels/:channelId/leave",
2582
+ client: { resource: "channels", method: "leave" },
2583
+ capability: "channels",
2584
+ description: "Leave a joined regular channel as the bound agent credential.",
2585
+ request: { params: agentApiChannelMembershipParamsSchema },
2586
+ response: { body: agentApiOkResponseSchema }
2587
+ }),
2588
+ channelMute: route({
2589
+ key: "channelMute",
2590
+ method: "POST",
2591
+ path: "/channels/:channelId/mute",
2592
+ client: { resource: "channels", method: "mute" },
2593
+ capability: "channels",
2594
+ description: "Mute ordinary activity delivery for a visible regular channel as the bound agent credential.",
2595
+ request: { params: agentApiChannelMembershipParamsSchema },
2596
+ response: { body: agentApiChannelMuteResponseSchema }
2597
+ }),
2598
+ channelUnmute: route({
2599
+ key: "channelUnmute",
2434
2600
  method: "POST",
2435
- path: "/channels/:channelId/leave",
2436
- client: { resource: "channels", method: "leave" },
2601
+ path: "/channels/:channelId/unmute",
2602
+ client: { resource: "channels", method: "unmute" },
2437
2603
  capability: "channels",
2438
- description: "Leave a joined regular channel as the bound agent credential.",
2604
+ description: "Unmute ordinary activity delivery for a visible regular channel as the bound agent credential.",
2439
2605
  request: { params: agentApiChannelMembershipParamsSchema },
2440
- response: { body: agentApiOkResponseSchema }
2606
+ response: { body: agentApiChannelMuteResponseSchema }
2441
2607
  }),
2442
2608
  channelMembers: route({
2443
2609
  key: "channelMembers",
@@ -2629,6 +2795,16 @@ var agentApiContract = {
2629
2795
  request: { body: agentApiProfileUpdateBodySchema },
2630
2796
  response: { body: agentApiProfileViewSchema }
2631
2797
  }),
2798
+ profileAvatarUpdate: route({
2799
+ key: "profileAvatarUpdate",
2800
+ method: "POST",
2801
+ path: "/profile/avatar",
2802
+ client: { resource: "profile", method: "updateAvatar" },
2803
+ capability: "server",
2804
+ description: "Update the bound agent profile avatar using multipart form data.",
2805
+ request: {},
2806
+ response: { body: agentApiProfileViewSchema }
2807
+ }),
2632
2808
  integrationList: route({
2633
2809
  key: "integrationList",
2634
2810
  method: "GET",
@@ -2659,6 +2835,22 @@ var agentApiContract = {
2659
2835
  request: { body: agentApiIntegrationAppPrepareBodySchema },
2660
2836
  response: { body: agentApiIntegrationAppPrepareResponseSchema }
2661
2837
  }),
2838
+ integrationAppRotateSecret: route({
2839
+ key: "integrationAppRotateSecret",
2840
+ method: "POST",
2841
+ path: "/integrations/app/rotate-secret",
2842
+ client: { resource: "integrations", method: "rotateAppSecret" },
2843
+ // Mirrors integrationAppPrepare's "read" capability: the AgentApiCapability
2844
+ // enum has no generic "mutation"/"integrations" scope, and the sibling
2845
+ // integration app routes (prepare/login) all gate on "read". Owner-scope is
2846
+ // enforced server-side in rotateClientSecretForAgent's WHERE clause (and the
2847
+ // bound agent credential), so the capability tier is not the security
2848
+ // boundary here. Keep parity with integrationAppPrepare.
2849
+ capability: "read",
2850
+ description: "Regenerate the one-time client secret for a server-local integration app the calling agent owns; invalidates the previous secret.",
2851
+ request: { body: agentApiIntegrationAppRotateSecretBodySchema },
2852
+ response: { body: agentApiIntegrationAppRotateSecretResponseSchema }
2853
+ }),
2662
2854
  actionPrepare: route({
2663
2855
  key: "actionPrepare",
2664
2856
  method: "POST",
@@ -2678,6 +2870,131 @@ var agentApiContract = {
2678
2870
  description: "Upload a multipart attachment as the bound agent credential.",
2679
2871
  request: {},
2680
2872
  response: { body: agentApiAttachmentUploadResponseSchema }
2873
+ }),
2874
+ attachmentDownload: route({
2875
+ key: "attachmentDownload",
2876
+ method: "GET",
2877
+ path: "/attachments/:attachmentId",
2878
+ client: { resource: "attachments", method: "download" },
2879
+ capability: "read",
2880
+ description: "Download attachment bytes visible to the bound agent credential.",
2881
+ request: { params: agentApiAttachmentDownloadParamsSchema },
2882
+ response: { kind: "binary" }
2883
+ }),
2884
+ attachmentCommentsList: route({
2885
+ key: "attachmentCommentsList",
2886
+ method: "GET",
2887
+ path: "/attachments/:attachmentId/comments",
2888
+ client: { resource: "attachments", method: "comments" },
2889
+ capability: "read",
2890
+ description: "List comments scoped to an attachment visible to the bound agent credential.",
2891
+ request: { params: agentApiAttachmentCommentsParamsSchema, query: agentApiAttachmentCommentsQuerySchema },
2892
+ response: { body: agentApiAttachmentCommentsResponseSchema }
2893
+ })
2894
+ };
2895
+
2896
+ // ../shared/src/daemonApiContract.ts
2897
+ import { z as z3 } from "zod";
2898
+ var DAEMON_API_BASE_PATH = "/internal/agent-api";
2899
+ var optionalStringSchema2 = z3.string().trim().optional();
2900
+ var optionalNonNegativeIntSchema = z3.number().int().nonnegative().optional();
2901
+ var optionalQueryIntSchema = z3.union([z3.number().int().nonnegative(), z3.string().trim().min(1)]).optional();
2902
+ var nullableNumberSchema2 = z3.number().finite().nullable();
2903
+ var passthroughObject2 = (shape) => z3.object(shape).passthrough();
2904
+ var daemonApiInboxFlagSchema = z3.enum(["mention", "thread", "dm", "task"]);
2905
+ var daemonApiInboxTargetRowSchema = passthroughObject2({
2906
+ target: z3.string().trim().min(1),
2907
+ channelId: optionalStringSchema2,
2908
+ channelType: optionalStringSchema2,
2909
+ pendingCount: z3.number().int().nonnegative(),
2910
+ firstPendingMsgId: optionalStringSchema2,
2911
+ firstPendingSeq: optionalNonNegativeIntSchema,
2912
+ latestMsgId: optionalStringSchema2,
2913
+ latestSeq: optionalNonNegativeIntSchema,
2914
+ latestSenderName: optionalStringSchema2,
2915
+ latestSenderType: z3.enum(["human", "agent", "system"]).optional(),
2916
+ flags: z3.array(daemonApiInboxFlagSchema)
2917
+ });
2918
+ var daemonApiInboxCheckResponseSchema = passthroughObject2({
2919
+ rows: z3.array(daemonApiInboxTargetRowSchema).optional()
2920
+ });
2921
+ var daemonApiWakeHintsQuerySchema = passthroughObject2({
2922
+ since: z3.union([z3.literal("latest"), z3.number().int().nonnegative(), z3.string().trim().min(1)]).optional(),
2923
+ limit: optionalQueryIntSchema
2924
+ });
2925
+ var daemonApiWakeHintSchema = passthroughObject2({
2926
+ hintId: optionalStringSchema2,
2927
+ hint_id: optionalStringSchema2,
2928
+ eventId: optionalStringSchema2,
2929
+ event_id: optionalStringSchema2,
2930
+ messageId: z3.string().nullable().optional(),
2931
+ message_id: z3.string().nullable().optional(),
2932
+ seq: optionalNonNegativeIntSchema,
2933
+ id: optionalStringSchema2,
2934
+ target: optionalStringSchema2,
2935
+ targetType: optionalStringSchema2,
2936
+ target_type: optionalStringSchema2,
2937
+ reason: optionalStringSchema2,
2938
+ wake_reason: optionalStringSchema2,
2939
+ createdAt: optionalStringSchema2,
2940
+ created_at: optionalStringSchema2
2941
+ });
2942
+ var daemonApiWakeHintsFetchResponseSchema = passthroughObject2({
2943
+ hints: z3.array(daemonApiWakeHintSchema).optional(),
2944
+ wake_hints: z3.array(daemonApiWakeHintSchema).optional(),
2945
+ last_seen_hint_seq: nullableNumberSchema2.optional(),
2946
+ last_hint_seq: nullableNumberSchema2.optional(),
2947
+ has_more: z3.boolean().optional()
2948
+ });
2949
+ var daemonApiActivityEventSchema = passthroughObject2({
2950
+ schema: optionalStringSchema2
2951
+ });
2952
+ var daemonApiActivityForwardBodySchema = passthroughObject2({
2953
+ schema: z3.literal("raft-agent-activity-ingest.v1"),
2954
+ coreSessionId: optionalStringSchema2,
2955
+ adapterInstance: optionalStringSchema2,
2956
+ events: z3.array(daemonApiActivityEventSchema),
2957
+ dropped: optionalNonNegativeIntSchema
2958
+ });
2959
+ var daemonApiActivityForwardResponseSchema = passthroughObject2({
2960
+ ok: z3.literal(true).optional(),
2961
+ acceptedCount: z3.number().int().nonnegative().optional(),
2962
+ rejectedCount: z3.number().int().nonnegative().optional(),
2963
+ droppedCount: z3.number().int().nonnegative().optional()
2964
+ });
2965
+ function route2(input) {
2966
+ return {
2967
+ ...input,
2968
+ fullPath: `${DAEMON_API_BASE_PATH}${input.path}`
2969
+ };
2970
+ }
2971
+ var daemonApiContract = {
2972
+ inboxCheck: route2({
2973
+ key: "inboxCheck",
2974
+ method: "GET",
2975
+ path: "/inbox",
2976
+ client: { resource: "inbox", method: "check" },
2977
+ description: "Read the managed-runner daemon inbox snapshot without draining message content.",
2978
+ request: {},
2979
+ response: { body: daemonApiInboxCheckResponseSchema }
2980
+ }),
2981
+ wakeHintsFetch: route2({
2982
+ key: "wakeHintsFetch",
2983
+ method: "GET",
2984
+ path: "/wake-hints",
2985
+ client: { resource: "wakeHints", method: "fetch" },
2986
+ description: "Peek content-free wake hints without advancing delivery cursors.",
2987
+ request: { query: daemonApiWakeHintsQuerySchema },
2988
+ response: { body: daemonApiWakeHintsFetchResponseSchema }
2989
+ }),
2990
+ activityForward: route2({
2991
+ key: "activityForward",
2992
+ method: "POST",
2993
+ path: "/activity",
2994
+ client: { resource: "activity", method: "forward" },
2995
+ description: "Forward plugin-observed activity from a local bridge to the daemon/server activity ingest path.",
2996
+ request: { body: daemonApiActivityForwardBodySchema },
2997
+ response: { body: daemonApiActivityForwardResponseSchema }
2681
2998
  })
2682
2999
  };
2683
3000
 
@@ -2708,7 +3025,7 @@ function shortMessageId(value) {
2708
3025
  }
2709
3026
 
2710
3027
  // ../shared/src/externalAgentIntegration.ts
2711
- import { z as z3 } from "zod";
3028
+ import { z as z4 } from "zod";
2712
3029
  var EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION = "agent-comms-core.v1";
2713
3030
  var EXTERNAL_AGENT_PROOF_SCHEMA_VERSION = "agent-proof.v1";
2714
3031
  var EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA = "slock-external-runtime-integration.v1";
@@ -2752,35 +3069,35 @@ var externalAgentAdapterFailureValues = [
2752
3069
  "auth_revoked"
2753
3070
  ];
2754
3071
  var externalAgentServerApiModeValues = ["interim-agent-api-events", "agent-inbox-protocol"];
2755
- var nonEmptyStringSchema = z3.string().min(1);
2756
- var isoTimestampSchema = z3.string().refine((value) => !Number.isNaN(Date.parse(value)), {
3072
+ var nonEmptyStringSchema = z4.string().min(1);
3073
+ var isoTimestampSchema = z4.string().refine((value) => !Number.isNaN(Date.parse(value)), {
2757
3074
  message: "must be a parseable timestamp"
2758
3075
  });
2759
- var externalRuntimeIntegrationManifestSchema = z3.object({
2760
- schema: z3.literal(EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA),
3076
+ var externalRuntimeIntegrationManifestSchema = z4.object({
3077
+ schema: z4.literal(EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA),
2761
3078
  runtimeId: nonEmptyStringSchema,
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),
3079
+ integrationPattern: z4.enum(externalAgentIntegrationPatternValues),
3080
+ commsMode: z4.enum(externalAgentCommsModeValues),
3081
+ commsProtocolVersion: z4.literal(EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION),
3082
+ proofSchemaVersion: z4.literal(EXTERNAL_AGENT_PROOF_SCHEMA_VERSION),
2766
3083
  minSlockCliVersion: nonEmptyStringSchema,
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)
3084
+ multiplex: z4.boolean(),
3085
+ agentIsolation: z4.enum(externalAgentIsolationValues),
3086
+ bridgeLifecycle: z4.object({
3087
+ explicitStartOnly: z4.literal(true),
3088
+ oneShotCommandsBridgeIndependent: z4.literal(true),
3089
+ requiresBridgeFailureCodes: z4.array(z4.enum(["BRIDGE_NOT_RUNNING", "NO_CORE_SESSION"])).min(1),
3090
+ autoStartDefault: z4.literal(false)
2774
3091
  }).strict(),
2775
- serverApi: z3.object({
2776
- mode: z3.enum(externalAgentServerApiModeValues),
2777
- deliveryOnly: z3.boolean(),
2778
- cursorAuthority: z3.literal("model_seen_only")
3092
+ serverApi: z4.object({
3093
+ mode: z4.enum(externalAgentServerApiModeValues),
3094
+ deliveryOnly: z4.boolean(),
3095
+ cursorAuthority: z4.literal("model_seen_only")
2779
3096
  }).strict(),
2780
- wakeAdapter: z3.object({
2781
- kind: z3.enum(externalAgentWakeAdapterKindValues),
3097
+ wakeAdapter: z4.object({
3098
+ kind: z4.enum(externalAgentWakeAdapterKindValues),
2782
3099
  protocol: nonEmptyStringSchema,
2783
- requiresInteractiveSession: z3.boolean().optional()
3100
+ requiresInteractiveSession: z4.boolean().optional()
2784
3101
  }).strict()
2785
3102
  }).strict().superRefine((value, ctx) => {
2786
3103
  if (!value.bridgeLifecycle.requiresBridgeFailureCodes.includes("BRIDGE_NOT_RUNNING")) {
@@ -2805,8 +3122,8 @@ var externalRuntimeIntegrationManifestSchema = z3.object({
2805
3122
  });
2806
3123
  }
2807
3124
  });
2808
- var externalAgentWakeEventBaseSchema = z3.object({
2809
- schema: z3.literal(EXTERNAL_AGENT_WAKE_EVENT_SCHEMA),
3125
+ var externalAgentWakeEventBaseSchema = z4.object({
3126
+ schema: z4.literal(EXTERNAL_AGENT_WAKE_EVENT_SCHEMA),
2810
3127
  eventId: nonEmptyStringSchema,
2811
3128
  attemptId: nonEmptyStringSchema,
2812
3129
  messageId: nonEmptyStringSchema,
@@ -2816,30 +3133,30 @@ var externalAgentWakeEventBaseSchema = z3.object({
2816
3133
  adapterInstance: nonEmptyStringSchema,
2817
3134
  runtimeSession: nonEmptyStringSchema.nullable(),
2818
3135
  occurredAt: isoTimestampSchema,
2819
- lifecycleState: z3.enum(externalAgentCommsLifecycleStateValues),
2820
- authority: z3.object({
2821
- source: z3.enum(externalAgentLifecycleSourceValues),
2822
- provenance: z3.enum(externalAgentLifecycleProvenanceValues)
3136
+ lifecycleState: z4.enum(externalAgentCommsLifecycleStateValues),
3137
+ authority: z4.object({
3138
+ source: z4.enum(externalAgentLifecycleSourceValues),
3139
+ provenance: z4.enum(externalAgentLifecycleProvenanceValues)
2823
3140
  }).strict()
2824
3141
  }).strict();
2825
3142
  var externalAgentProofEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
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()
3143
+ kind: z4.literal("proof"),
3144
+ proofLevel: z4.enum(externalAgentWakeProofLevelValues),
3145
+ outcome: z4.literal("ok"),
3146
+ failureMeta: z4.undefined().optional(),
3147
+ reason: z4.string().optional()
2831
3148
  });
2832
3149
  var externalAgentFailedWakeEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
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()
3150
+ kind: z4.literal("wake_attempt"),
3151
+ proofLevel: z4.undefined().optional(),
3152
+ outcome: z4.literal("failed"),
3153
+ failureMeta: z4.object({
3154
+ failureClass: z4.enum(externalAgentAdapterFailureValues),
3155
+ retryAfterMs: z4.number().int().positive().optional()
2839
3156
  }).strict(),
2840
3157
  reason: nonEmptyStringSchema
2841
3158
  });
2842
- var externalAgentWakeEventEnvelopeSchema = z3.discriminatedUnion("kind", [
3159
+ var externalAgentWakeEventEnvelopeSchema = z4.discriminatedUnion("kind", [
2843
3160
  externalAgentProofEventEnvelopeSchema,
2844
3161
  externalAgentFailedWakeEventEnvelopeSchema
2845
3162
  ]);
@@ -2980,13 +3297,15 @@ var RUNTIME_MODELS = {
2980
3297
  builtin: Object.values(PI_BUILTIN_PROVIDER_MODELS).flat().map((model) => ({ id: model.id, label: model.label || formatRuntimeProviderModelLabel(model.id), verified: "launchable" })),
2981
3298
  claude: [
2982
3299
  { id: "opus", label: "Claude Opus" },
3300
+ { id: "fable", label: "Claude Fable" },
3301
+ { id: "sonnet", label: "Claude Sonnet" },
3302
+ { id: "haiku", label: "Claude Haiku" },
2983
3303
  { id: "claude-opus-4-8", label: "Claude Opus 4.8" },
2984
3304
  { id: "claude-opus-4-7", label: "Claude Opus 4.7" },
2985
3305
  { id: "claude-opus-4-6", label: "Claude Opus 4.6" },
2986
- { id: "fable", label: "Claude Fable" },
2987
- { id: "sonnet", label: "Claude Sonnet" },
3306
+ { id: "claude-fable-5", label: "Claude Fable 5" },
3307
+ { id: "claude-sonnet-5", label: "Claude Sonnet 5" },
2988
3308
  { id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
2989
- { id: "haiku", label: "Claude Haiku" },
2990
3309
  { id: "claude-haiku-4-5", label: "Claude Haiku 4.5" }
2991
3310
  ],
2992
3311
  codex: [
@@ -3382,7 +3701,7 @@ var TRIAL_DURATION_DAYS = (TRIAL_END_DATE.getTime() - TRIAL_START_DATE.getTime()
3382
3701
  // src/agentProcessManager.ts
3383
3702
  import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync4, statSync, writeFileSync as writeFileSync4 } from "fs";
3384
3703
  import { mkdir, writeFile, access, readdir as readdir2, stat as stat2, readFile, rm as rm2, lstat, realpath, open } from "fs/promises";
3385
- import { createHash as createHash3, randomUUID as randomUUID5 } from "crypto";
3704
+ import { createHash as createHash3, randomUUID as randomUUID6 } from "crypto";
3386
3705
  import path14 from "path";
3387
3706
  import { gzipSync } from "zlib";
3388
3707
  import os6 from "os";
@@ -3654,8 +3973,8 @@ async function executeResponseRequest(url, init, {
3654
3973
  }
3655
3974
 
3656
3975
  // src/directUploadCapability.ts
3657
- function joinUrl(base, path19) {
3658
- return `${base.replace(/\/+$/, "")}${path19}`;
3976
+ function joinUrl(base, path20) {
3977
+ return `${base.replace(/\/+$/, "")}${path20}`;
3659
3978
  }
3660
3979
  function jsonHeaders(apiKey) {
3661
3980
  return {
@@ -3797,40 +4116,20 @@ function buildCommunicationSection(audience) {
3797
4116
  const installation = describeSlockInstallation(audience);
3798
4117
  return `## Communication \u2014 raft CLI ONLY
3799
4118
 
3800
- Use the \`raft\` CLI for chat / task / attachment operations (\`slock\` remains a legacy alias). ${installation} Use ONLY these commands for communication:
3801
-
3802
- 1. **\`raft message check\`** \u2014 Non-blocking check for new messages. Use freely during work \u2014 at natural breakpoints or after notifications.
3803
- 2. **\`raft message send\`** \u2014 Send a message to a channel or DM.
3804
- 3. **\`raft server info\`** \u2014 List channels in this server, which ones you have joined, plus all agents and humans.
3805
- 4. **\`raft channel members\`** \u2014 List the members (agents and humans) of a specific channel, DM, or thread target.
3806
- 5. **\`raft channel join\`** \u2014 Join a visible public channel. This only affects your own agent membership.
3807
- 6. **\`raft channel leave\`** \u2014 Leave a regular channel you have joined. This only affects your own agent membership.
3808
- 7. **\`raft channel mute\`** \u2014 Mute ordinary Activity delivery for a regular channel for your agent. Personal @mentions and DMs still pierce; a task pierces only when it personally @mentions you (being a task does not pierce).
3809
- 8. **\`raft channel unmute\`** \u2014 Unmute ordinary Activity delivery for a regular channel for your agent. Muted-window messages are not retroactively promoted.
3810
- 9. **\`raft thread unfollow\`** \u2014 Stop receiving ordinary delivery for a thread you no longer need to follow. This only affects your own agent attention state.
3811
- 10. **\`raft message read\`** \u2014 Read past messages from a channel, DM, or thread. Supports \`before\` / \`after\` anchors and \`around\` for centered context.
3812
- 11. **\`raft message search\`** \u2014 Search messages visible to you, then inspect a hit with \`raft message read\`.
3813
- 12. **\`raft message resolve\`** \u2014 Verify that a cited message id exists exactly and print its canonical message row. Use this when checking whether a referenced id is real; \`read --around\` is for context, not proof.
3814
- 13. **\`raft message react\`** \u2014 Add or remove your reaction on a message. Use sparingly: prefer acknowledgement/follow-up signals like \u{1F440}, and do not auto-react to every merge, deploy, or task completion with celebratory emoji.
3815
- 14. **\`raft task list\`** \u2014 View a channel's task board.
3816
- 15. **\`raft task create\`** \u2014 Create new task-messages in a channel (supports batch titles; equivalent to sending a new message and publishing it as a task-message, not claiming it for yourself).
3817
- 16. **\`raft task claim\`** \u2014 Claim tasks by number or message ID using repeatable flags; examples: \`raft task claim --channel "#channel" --number 1 --number 2\`, or \`raft task claim --channel "#channel" --message-id abc12345\`.
3818
- 17. **\`raft task unclaim\`** \u2014 Release your claim on a task.
3819
- 18. **\`raft task update\`** \u2014 Change a task's status (e.g. to in_review or done).
3820
- 19. **\`raft attachment upload\`** \u2014 Upload a file to attach to a message. Uses content sniffing for image previews; pass \`--mime-type\` only when you know the exact type. Returns an attachment ID to pass to \`raft message send\`.
3821
- 20. **\`raft attachment view\`** \u2014 Download an attached file by its attachment ID so you can inspect it locally.
3822
- 21. **\`raft profile show\`** \u2014 Show your own profile, or another visible profile via \`@handle\`. Mirrors the canonical Slock profile view.
3823
- 22. **\`raft profile update\`** \u2014 Update your own profile. Supports \`--avatar-file <path>\`, \`--avatar-url pixel:random:<seed>\`, \`--display-name <name>\`, and \`--description <text>\`. Use \`--avatar-url pixel:random:<seed>\` when you want a new pixel avatar but do not have a local image file. Values must be non-empty. Provide at least one flag per call; multiple flags can be combined.
3824
- 23. **\`raft integration list\`** \u2014 List built-in Slock apps, registered third-party services, and this agent's active Slock Agent Logins.
3825
- 24. **\`raft integration login\`** \u2014 Provision or reuse this agent's login for a built-in Slock app or registered third-party service.
3826
- 25. **\`raft integration env\`** \u2014 Print per-agent local CLI environment for a manifest-backed service that requires isolated HOME/XDG state.
3827
- 26. **\`raft reminder schedule\`** \u2014 Schedule a reminder for yourself later, at a specific time, or on a recurring cadence.
3828
- 27. **\`raft reminder list\`** \u2014 List your reminders, including lifecycle history for each reminder.
3829
- 28. **\`raft reminder snooze\`** \u2014 Push a reminder later without replacing it.
3830
- 29. **\`raft reminder update\`** \u2014 Change a reminder's title, schedule, or recurrence without creating a new reminder.
3831
- 30. **\`raft reminder cancel\`** \u2014 Cancel one of your reminders by ID.
3832
- 31. **\`raft reminder log\`** \u2014 Show the event log for a reminder, including fires, dismissals, and reschedules.
3833
- 32. **\`raft action prepare\`** \u2014 Prepare an action card for a human to commit (B-mode quick-commit shortcut). Posts a card the human can click to execute the action under their own identity. Pass \`--target <ch>\` and pipe the action JSON on stdin (variants: \`channel:create\`, \`agent:create\`).
4119
+ Use the \`raft\` CLI for chat / task / attachment operations (\`slock\` remains a legacy alias). ${installation} Use ONLY these command families for communication and management:
4120
+
4121
+ 1. **Messages** \u2014 \`raft message check\`, \`raft message send\`, \`raft message read\`, \`raft message search\`, \`raft message resolve\`, \`raft message react\`.
4122
+ 2. **Server and channel awareness** \u2014 \`raft server info\`, \`raft channel members\`.
4123
+ 3. **Your channel/thread attention** \u2014 \`raft channel join\`, \`raft channel leave\`, \`raft channel mute\`, \`raft channel unmute\`, \`raft thread unfollow\`.
4124
+ 4. **Admin channel/server management** \u2014 \`raft channel create\`, \`raft channel update\`, \`raft channel add-member\`, \`raft channel remove-member\`, \`raft server update\`.
4125
+ 5. **Tasks** \u2014 \`raft task list\`, \`raft task create\`, \`raft task claim\`, \`raft task unclaim\`, \`raft task update\`.
4126
+ 6. **Attachments** \u2014 \`raft attachment upload\`, \`raft attachment view\`.
4127
+ 7. **Profiles** \u2014 \`raft profile show\`, \`raft profile update\`.
4128
+ 8. **Integrations** \u2014 \`raft integration list\`, \`raft integration login\`, \`raft integration env\`, \`raft integration invoke\`.
4129
+ 9. **Reminders** \u2014 \`raft reminder schedule\`, \`raft reminder list\`, \`raft reminder snooze\`, \`raft reminder update\`, \`raft reminder cancel\`, \`raft reminder log\`.
4130
+ 10. **Action cards** \u2014 \`raft action prepare\`.
4131
+
4132
+ Run any subcommand with \`--help\` for syntax.
3834
4133
 
3835
4134
  The CLI prints human-readable canonical text on success (matching the format you see in received messages and history). On failure it prints canonical labeled text to stderr:
3836
4135
  - \`Error:\` human-readable error summary
@@ -3947,7 +4246,7 @@ Only top-level channel / DM messages can become tasks. Messages inside threads a
3947
4246
 
3948
4247
  **Workflow:**
3949
4248
  1. Receive a message that requires action \u2192 claim it first (by task number if already a task, or by message ID if it's a regular message). Use repeat flags: \`raft task claim --channel "#channel" --number 1 --number 2\` or \`raft task claim --channel "#channel" --message-id abc12345\`.
3950
- 2. If the claim fails, someone else is working on it \u2014 move on to another task
4249
+ 2. If the claim fails, someone else is working on it \u2014 do not work on that task unless an owner/admin explicitly redirects it to you
3951
4250
  3. Post updates in the task's thread: \`raft message send --target "#channel:msgShortId" <<'${D}'\` followed by the message body and \`${D}\`
3952
4251
  4. When done, set status to \`in_review\` so a human can validate via \`raft task update\`
3953
4252
  5. After approval (e.g. "looks good", "merge it"), set status to \`done\`
@@ -4001,7 +4300,7 @@ function buildConversationEtiquetteSection(taskClaimCmd = "`raft task claim`") {
4001
4300
 
4002
4301
  - **Respect ongoing conversations.** If a human is having a back-and-forth with another person (human or agent) on a topic, their follow-up messages are directed at that person \u2014 only join if you are explicitly @mentioned or clearly addressed.
4003
4302
  - **Only the person doing the work should report on it.** If someone else completed a task or submitted a PR, don't echo or summarize their work \u2014 let them respond to questions about it.
4004
- - **Claim before you start.** Always call ${taskClaimCmd} before doing any work on a task. If the claim fails, stop immediately and pick a different task.
4303
+ - **Claim before you start.** Always call ${taskClaimCmd} before doing any work on a task. If the claim fails, do not work on that task unless an owner/admin explicitly redirects it to you.
4005
4304
  - **Before stopping, check for concrete blockers you own.** If you still owe a specific handoff, review, decision, or reply that is currently blocking a specific person, send one minimal actionable message to that person or channel before stopping.
4006
4305
  - **Skip idle narration.** Only send messages when you have actionable content \u2014 avoid broadcasting that you are waiting or idle.`;
4007
4306
  }
@@ -4154,7 +4453,7 @@ function buildPrompt(config, opts) {
4154
4453
  ...opts.extraCriticalRules,
4155
4454
  "- Use only the provided `raft` CLI commands for messaging.",
4156
4455
  "- Do not combine multiple `raft` CLI commands in one shell command. Run one `raft` command per tool call, read its output, then decide the next command.",
4157
- "- Always claim a task via `raft task claim` before starting work on it. If the claim fails, move on to a different task."
4456
+ "- Always claim a task via `raft task claim` before starting work on it. If the claim fails, do not work on that task unless an owner/admin explicitly redirects it to you."
4158
4457
  ];
4159
4458
  const runtimeProfileControl = config.runtimeProfileControl?.kind === "daemon_release_notice" ? config.runtimeProfileControl : null;
4160
4459
  const runtimeProfileControlStartupStep = runtimeProfileControl ? [
@@ -4177,7 +4476,7 @@ function buildPrompt(config, opts) {
4177
4476
  const channelAwarenessSection = cliGuideSections.channelAwareness;
4178
4477
  const thirdPartyIntegrationsSection = `### Third-party integrations
4179
4478
 
4180
- 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.`;
4479
+ 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 manifest-backed HTTP API actions, prefer \`raft integration invoke --service <service> --list-actions\` and then \`raft integration invoke --service <service> --action <name>\`; the CLI performs the stateless Agent Login callback handoff and service-session setup for you. 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; for HTTP API action services, use \`raft integration invoke\` instead. 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 local 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 \`raft integration login\` 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 a stateless Login with Raft API-action session handoff URL; prefer \`raft integration invoke\` over manually opening or curling it. 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 outside the documented CLI flow, 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.`;
4181
4480
  const readingHistorySection = cliGuideSections.readingHistory;
4182
4481
  const historicalReferenceSection = cliGuideSections.historicalReferences;
4183
4482
  const tasksSection = cliGuideSections.tasks;
@@ -4365,6 +4664,19 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
4365
4664
  return candidates.filter((candidate) => existsSync(candidate.path));
4366
4665
  }
4367
4666
 
4667
+ // src/authEnv.ts
4668
+ var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
4669
+ var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
4670
+ function scrubDaemonAuthEnv(env) {
4671
+ delete env[DAEMON_API_KEY_ENV];
4672
+ return env;
4673
+ }
4674
+ function scrubDaemonChildEnv(env) {
4675
+ delete env[DAEMON_API_KEY_ENV];
4676
+ delete env[SLOCK_AGENT_TOKEN_ENV];
4677
+ return env;
4678
+ }
4679
+
4368
4680
  // src/agentCredentialProxy.ts
4369
4681
  import { randomBytes } from "crypto";
4370
4682
  import http from "http";
@@ -5933,7 +6245,9 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
5933
6245
  var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
5934
6246
  var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
5935
6247
  var RAW_CREDENTIAL_ENV_DENYLIST = [
5936
- "SLOCK_AGENT_CREDENTIAL_KEY"
6248
+ "SLOCK_AGENT_TOKEN",
6249
+ "SLOCK_AGENT_CREDENTIAL_KEY",
6250
+ "SLOCK_AGENT_CREDENTIAL_KEY_FILE"
5937
6251
  ];
5938
6252
  var WORKSPACE_CLI_TRANSPORT_FILENAMES = [
5939
6253
  "agent-token",
@@ -6288,7 +6602,7 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
6288
6602
  SLOCK_SERVER_URL: ctx.config.serverUrl,
6289
6603
  PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
6290
6604
  };
6291
- delete spawnEnv.SLOCK_AGENT_TOKEN;
6605
+ scrubDaemonChildEnv(spawnEnv);
6292
6606
  for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
6293
6607
  delete spawnEnv[key];
6294
6608
  }
@@ -6525,14 +6839,15 @@ var ClaudeEventNormalizer = class {
6525
6839
  const stopReason = typeof event.stop_reason === "string" ? event.stop_reason : null;
6526
6840
  const resultSessionId = eventSessionId ?? this.currentSession;
6527
6841
  const usageTelemetry = parseClaudeResultUsageTelemetry(event, resultSessionId);
6842
+ const isMaxTokenError = stopReason === "max_tokens" && (event.is_error === true || subtype !== "success");
6528
6843
  switch (subtype) {
6529
6844
  case "success":
6530
- if (event.is_error && stopReason !== "max_tokens") {
6845
+ if (event.is_error) {
6531
6846
  pushResultError(event, "Execution failed");
6532
6847
  }
6533
6848
  break;
6534
6849
  case "error_during_execution":
6535
- if (stopReason !== "max_tokens") {
6850
+ if (stopReason !== "max_tokens" || isMaxTokenError) {
6536
6851
  pushResultError(event, "Execution failed");
6537
6852
  }
6538
6853
  break;
@@ -6810,7 +7125,7 @@ function requiresWindowsShell(command, platform = process.platform) {
6810
7125
  }
6811
7126
  function resolveCommandOnPath(command, deps = {}) {
6812
7127
  const platform = deps.platform ?? process.platform;
6813
- const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
7128
+ const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
6814
7129
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
6815
7130
  const existsSyncFn = deps.existsSyncFn ?? existsSync3;
6816
7131
  if (platform === "win32") {
@@ -6836,7 +7151,7 @@ function firstExistingPath(candidates, deps = {}) {
6836
7151
  return null;
6837
7152
  }
6838
7153
  function readCommandVersion(command, args = [], deps = {}) {
6839
- const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
7154
+ const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
6840
7155
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
6841
7156
  try {
6842
7157
  const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
@@ -7262,7 +7577,7 @@ function codexNotificationDiagnosticEvent(message) {
7262
7577
  return null;
7263
7578
  }
7264
7579
  const sessionId = codexMessageThreadId(message);
7265
- const path19 = boundedString(params.path);
7580
+ const path20 = boundedString(params.path);
7266
7581
  return {
7267
7582
  kind: "runtime_diagnostic",
7268
7583
  severity: "warning",
@@ -7270,7 +7585,7 @@ function codexNotificationDiagnosticEvent(message) {
7270
7585
  itemType: message.method,
7271
7586
  message: diagnosticMessage,
7272
7587
  ...details ? { details } : {},
7273
- ...path19 ? { path: path19 } : {},
7588
+ ...path20 ? { path: path20 } : {},
7274
7589
  ...params.range !== void 0 ? { range: params.range } : {},
7275
7590
  payloadBytes: payloadBytes(params),
7276
7591
  ...sessionId ? { sessionId } : {}
@@ -8920,11 +9235,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
8920
9235
  return parseCursorModelsOutput(String(result.stdout || ""));
8921
9236
  }
8922
9237
  function buildCursorModelProbeEnv(deps = {}) {
8923
- return withWindowsUserEnvironment({
9238
+ return scrubDaemonChildEnv(withWindowsUserEnvironment({
8924
9239
  ...deps.env ?? process.env,
8925
9240
  FORCE_COLOR: "0",
8926
9241
  NO_COLOR: "1"
8927
- }, deps);
9242
+ }, deps));
8928
9243
  }
8929
9244
  function runCursorModelsCommand() {
8930
9245
  return spawnSync("cursor-agent", ["models"], {
@@ -8980,7 +9295,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
8980
9295
  }
8981
9296
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
8982
9297
  const existsSyncFn = deps.existsSyncFn ?? existsSync5;
8983
- const env = deps.env ?? process.env;
9298
+ const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
8984
9299
  const winPath = path8.win32;
8985
9300
  let geminiEntry = null;
8986
9301
  try {
@@ -9117,12 +9432,15 @@ var GeminiDriver = class {
9117
9432
  // src/drivers/kimi.ts
9118
9433
  import { randomUUID as randomUUID2 } from "crypto";
9119
9434
  import { spawn as spawn7 } from "child_process";
9120
- import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
9435
+ import { chmodSync, existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
9121
9436
  import os4 from "os";
9122
9437
  import path9 from "path";
9123
9438
  var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
9124
9439
  var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
9125
9440
  var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
9441
+ var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
9442
+ var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
9443
+ var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
9126
9444
  function parseToolArguments(raw) {
9127
9445
  if (typeof raw !== "string") return raw;
9128
9446
  try {
@@ -9131,6 +9449,73 @@ function parseToolArguments(raw) {
9131
9449
  return raw;
9132
9450
  }
9133
9451
  }
9452
+ function readKimiConfigSource(home = os4.homedir(), env = process.env) {
9453
+ const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
9454
+ if (inlineConfig && inlineConfig.trim()) {
9455
+ return {
9456
+ raw: inlineConfig,
9457
+ explicitPath: null,
9458
+ sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
9459
+ };
9460
+ }
9461
+ const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
9462
+ const configPath = explicitPath && explicitPath.trim() ? explicitPath : path9.join(home, ".kimi", "config.toml");
9463
+ try {
9464
+ return {
9465
+ raw: readFileSync3(configPath, "utf8"),
9466
+ explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
9467
+ sourcePath: configPath
9468
+ };
9469
+ } catch {
9470
+ return {
9471
+ raw: null,
9472
+ explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
9473
+ sourcePath: configPath
9474
+ };
9475
+ }
9476
+ }
9477
+ function buildKimiSpawnEnv(env = process.env) {
9478
+ const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
9479
+ delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
9480
+ delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
9481
+ return scrubDaemonChildEnv(spawnEnv);
9482
+ }
9483
+ function buildKimiEffectiveEnv(ctx, overrideEnv) {
9484
+ return {
9485
+ ...process.env,
9486
+ ...ctx.config.envVars || {},
9487
+ ...overrideEnv || {}
9488
+ };
9489
+ }
9490
+ function buildKimiLaunchOptions(ctx, opts = {}) {
9491
+ const env = buildKimiEffectiveEnv(ctx, opts.env);
9492
+ const source = readKimiConfigSource(opts.home ?? os4.homedir(), env);
9493
+ const args = [];
9494
+ let configFilePath = null;
9495
+ let configContent = null;
9496
+ if (source.explicitPath) {
9497
+ configFilePath = source.explicitPath;
9498
+ } else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
9499
+ configFilePath = path9.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
9500
+ configContent = source.raw;
9501
+ if (opts.writeGeneratedConfig !== false) {
9502
+ writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
9503
+ chmodSync(configFilePath, 384);
9504
+ }
9505
+ }
9506
+ if (configFilePath) {
9507
+ args.push("--config-file", configFilePath);
9508
+ }
9509
+ if (ctx.config.model && ctx.config.model !== "default") {
9510
+ args.push("--model", ctx.config.model);
9511
+ }
9512
+ return {
9513
+ args,
9514
+ env: buildKimiSpawnEnv(env),
9515
+ configFilePath,
9516
+ configContent
9517
+ };
9518
+ }
9134
9519
  function resolveKimiSpawn(commandArgs, deps = {}) {
9135
9520
  return {
9136
9521
  command: resolveCommandOnPath("kimi", deps) ?? "kimi",
@@ -9154,7 +9539,25 @@ var KimiDriver = class {
9154
9539
  };
9155
9540
  model = {
9156
9541
  detectedModelsVerifiedAs: "launchable",
9157
- toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
9542
+ toLaunchSpec: (modelId, ctx, opts) => {
9543
+ if (!ctx) return { args: ["--model", modelId] };
9544
+ const launchCtx = {
9545
+ ...ctx,
9546
+ config: {
9547
+ ...ctx.config,
9548
+ model: modelId
9549
+ }
9550
+ };
9551
+ const launch = buildKimiLaunchOptions(launchCtx, {
9552
+ home: opts?.home,
9553
+ writeGeneratedConfig: false
9554
+ });
9555
+ return {
9556
+ args: launch.args,
9557
+ env: launch.env,
9558
+ configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
9559
+ };
9560
+ }
9158
9561
  };
9159
9562
  supportsStdinNotification = true;
9160
9563
  busyDeliveryMode = "direct";
@@ -9178,21 +9581,23 @@ var KimiDriver = class {
9178
9581
  ` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
9179
9582
  ""
9180
9583
  ].join("\n"), "utf8");
9584
+ const launch = buildKimiLaunchOptions(ctx);
9181
9585
  const args = [
9182
9586
  "--wire",
9183
9587
  "--yolo",
9184
9588
  "--agent-file",
9185
9589
  agentFilePath,
9186
9590
  "--session",
9187
- this.sessionId
9591
+ this.sessionId,
9592
+ ...launch.args
9188
9593
  ];
9189
9594
  const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
9190
9595
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
9191
9596
  args.push("--model", launchRuntimeFields.model);
9192
9597
  }
9193
9598
  const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
9194
- const launch = resolveKimiSpawn(args);
9195
- const proc = spawn7(launch.command, launch.args, {
9599
+ const spawnTarget = resolveKimiSpawn(args);
9600
+ const proc = spawn7(spawnTarget.command, spawnTarget.args, {
9196
9601
  cwd: ctx.workingDirectory,
9197
9602
  stdio: ["pipe", "pipe", "pipe"],
9198
9603
  env: spawnEnv,
@@ -9200,7 +9605,7 @@ var KimiDriver = class {
9200
9605
  // and has an 8191-character command-line limit. Kimi's official
9201
9606
  // installer/uv entrypoint is an executable, so launch it directly and
9202
9607
  // keep prompts on stdin / files instead of routing through cmd.exe.
9203
- shell: launch.shell
9608
+ shell: spawnTarget.shell
9204
9609
  });
9205
9610
  proc.stdin?.write(JSON.stringify({
9206
9611
  jsonrpc: "2.0",
@@ -9313,14 +9718,9 @@ var KimiDriver = class {
9313
9718
  return detectKimiModels();
9314
9719
  }
9315
9720
  };
9316
- function detectKimiModels(home = os4.homedir()) {
9317
- const configPath = path9.join(home, ".kimi", "config.toml");
9318
- let raw;
9319
- try {
9320
- raw = readFileSync3(configPath, "utf8");
9321
- } catch {
9322
- return null;
9323
- }
9721
+ function detectKimiModels(home = os4.homedir(), opts = {}) {
9722
+ const raw = readKimiConfigSource(home, opts.env).raw;
9723
+ if (raw === null) return null;
9324
9724
  const models = [];
9325
9725
  const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
9326
9726
  const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
@@ -9986,7 +10386,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
9986
10386
  const platform = deps.platform ?? process.platform;
9987
10387
  const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
9988
10388
  const result = spawnSyncFn("opencode", ["models"], {
9989
- env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
10389
+ env: scrubDaemonChildEnv({ ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" }),
9990
10390
  encoding: "utf8",
9991
10391
  timeout: 5e3,
9992
10392
  shell: platform === "win32"
@@ -11520,6 +11920,9 @@ var AgentStartPendingDeliveryBuffer = class {
11520
11920
  get size() {
11521
11921
  return this.pending.size;
11522
11922
  }
11923
+ agentIds() {
11924
+ return [...this.pending.keys()];
11925
+ }
11523
11926
  values(agentId) {
11524
11927
  return [...this.pending.get(agentId) ?? []];
11525
11928
  }
@@ -11606,6 +12009,230 @@ var AgentStartPendingDeliveryBuffer = class {
11606
12009
  }
11607
12010
  };
11608
12011
 
12012
+ // src/agentNoProcessResidency.ts
12013
+ import { randomUUID as randomUUID5 } from "crypto";
12014
+ var AgentNoProcessResidencyTransitions = class {
12015
+ open = /* @__PURE__ */ new Map();
12016
+ transitionSeq = 0;
12017
+ enter(input) {
12018
+ const existing = this.open.get(input.agentId);
12019
+ if (existing && existing.state === input.state && existing.agentLaunchId === input.agentLaunchId) {
12020
+ return [];
12021
+ }
12022
+ const rows = [];
12023
+ if (existing) {
12024
+ rows.push(this.closeRow(existing, { closeResult: "advanced" }));
12025
+ }
12026
+ const current = {
12027
+ agentId: input.agentId,
12028
+ agentLaunchId: input.agentLaunchId,
12029
+ agentLaunchIdPresent: input.agentLaunchIdPresent,
12030
+ serverId: input.serverId,
12031
+ machineId: input.machineId,
12032
+ runtime: input.runtime,
12033
+ driver: input.driver,
12034
+ launchSource: input.launchSource,
12035
+ state: input.state,
12036
+ stateInstanceId: randomUUID5(),
12037
+ isWaitState: input.isWaitState,
12038
+ fenceKind: input.fenceKind,
12039
+ deadlineUnixMs: typeof input.deadlineUnixMs === "number" ? input.deadlineUnixMs : void 0,
12040
+ failureKind: input.failureKind,
12041
+ negativeEvidenceBucket: input.negativeEvidenceBucket
12042
+ };
12043
+ this.open.set(input.agentId, current);
12044
+ rows.push(this.enterRow(current));
12045
+ return rows;
12046
+ }
12047
+ close(agentId, input) {
12048
+ const existing = this.open.get(agentId);
12049
+ if (!existing) return [];
12050
+ this.open.delete(agentId);
12051
+ return [this.closeRow(existing, input)];
12052
+ }
12053
+ enterRow(open2) {
12054
+ return this.baseRow(open2, {
12055
+ transition_kind: "enter",
12056
+ phase_result: "entered",
12057
+ is_wait_state: open2.isWaitState,
12058
+ fence_kind: open2.fenceKind,
12059
+ deadline_unix_ms: open2.deadlineUnixMs,
12060
+ failure_kind: open2.failureKind,
12061
+ negative_evidence_bucket: open2.negativeEvidenceBucket
12062
+ });
12063
+ }
12064
+ closeRow(open2, input) {
12065
+ return this.baseRow(open2, {
12066
+ transition_kind: "close",
12067
+ close_result: input.closeResult,
12068
+ is_wait_state: open2.isWaitState,
12069
+ fence_kind: open2.fenceKind,
12070
+ deadline_unix_ms: open2.deadlineUnixMs,
12071
+ failure_kind: input.failureKind ?? open2.failureKind,
12072
+ negative_evidence_bucket: input.negativeEvidenceBucket ?? open2.negativeEvidenceBucket
12073
+ });
12074
+ }
12075
+ baseRow(open2, attrs) {
12076
+ const transitionSeq = ++this.transitionSeq;
12077
+ const row = {
12078
+ span_name: "launch_residency_transition",
12079
+ phase: "process_residency",
12080
+ agent_launch_id: open2.agentLaunchId,
12081
+ agent_id: open2.agentId,
12082
+ server_id: open2.serverId,
12083
+ machine_id: open2.machineId,
12084
+ runtime: open2.runtime,
12085
+ driver: open2.driver,
12086
+ launch_source: open2.launchSource,
12087
+ state_instance_id: open2.stateInstanceId,
12088
+ residency_state_instance_id: open2.stateInstanceId,
12089
+ transition_seq: transitionSeq,
12090
+ residency_transition_seq: transitionSeq,
12091
+ transition_kind: attrs.transition_kind,
12092
+ state: open2.state,
12093
+ residency: open2.state,
12094
+ agent_launch_id_present: open2.agentLaunchIdPresent
12095
+ };
12096
+ return withoutUndefined({
12097
+ ...row,
12098
+ phase_result: attrs.phase_result,
12099
+ close_result: attrs.close_result,
12100
+ is_wait_state: attrs.is_wait_state,
12101
+ fence_kind: attrs.fence_kind,
12102
+ deadline_unix_ms: attrs.deadline_unix_ms,
12103
+ failure_kind: attrs.failure_kind,
12104
+ negative_evidence_bucket: attrs.negative_evidence_bucket
12105
+ });
12106
+ }
12107
+ };
12108
+ function withoutUndefined(input) {
12109
+ return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
12110
+ }
12111
+ var AgentNoProcessResidency = class {
12112
+ static assertInvariants(context, snapshot) {
12113
+ const running = new Set(snapshot.runningAgentIds);
12114
+ const idle = new Set(snapshot.idleAgentIds);
12115
+ const terminal = new Set(snapshot.terminalFailureAgentIds);
12116
+ const activeCooldown = new Set(snapshot.activeCooldownAgentIds);
12117
+ const queued = new Set(snapshot.queuedAgentIds);
12118
+ const starting = new Set(snapshot.startingAgentIds);
12119
+ for (const agentId of activeCooldown) {
12120
+ if (!idle.has(agentId)) {
12121
+ throw new Error(`Agent no-process residency invariant violation after ${context}: active cooldown without restart config for ${agentId}`);
12122
+ }
12123
+ }
12124
+ for (const agentId of terminal) {
12125
+ if (idle.has(agentId)) {
12126
+ throw new Error(`Agent no-process residency invariant violation after ${context}: terminal failure and idle restart config both present for ${agentId}`);
12127
+ }
12128
+ if (running.has(agentId)) {
12129
+ throw new Error(`Agent no-process residency invariant violation after ${context}: terminal failure while process is still registered for ${agentId}`);
12130
+ }
12131
+ }
12132
+ const allowedPending = this.allowedStartPendingSnapshot(snapshot);
12133
+ const allowed = /* @__PURE__ */ new Set([
12134
+ ...allowedPending.queuedAgentIds,
12135
+ ...allowedPending.startingAgentIds,
12136
+ ...allowedPending.terminalRecoveryAgentIds,
12137
+ ...allowedPending.cooldownAgentIds
12138
+ ]);
12139
+ for (const agentId of snapshot.pendingDeliveryAgentIds) {
12140
+ if (!allowed.has(agentId)) {
12141
+ throw new Error(`Agent no-process residency invariant violation after ${context}: pending delivery without queued/starting/terminal/cooldown residency for ${agentId}`);
12142
+ }
12143
+ }
12144
+ for (const agentId of snapshot.fingerprintFenceAgentIds) {
12145
+ if (!running.has(agentId) && !idle.has(agentId) && !terminal.has(agentId)) {
12146
+ throw new Error(`Agent no-process residency invariant violation after ${context}: fingerprint fence without running process, idle retry config, or terminal failure for ${agentId}`);
12147
+ }
12148
+ }
12149
+ for (const agentId of queued) {
12150
+ if (starting.has(agentId)) {
12151
+ throw new Error(`Agent no-process residency invariant violation after ${context}: queued and starting facts overlap for ${agentId}`);
12152
+ }
12153
+ }
12154
+ }
12155
+ static allowedStartPendingSnapshot(snapshot) {
12156
+ const idle = new Set(snapshot.idleAgentIds);
12157
+ const cooldownAgentIds = snapshot.activeCooldownAgentIds.filter((agentId) => idle.has(agentId));
12158
+ return {
12159
+ queuedAgentIds: [...snapshot.queuedAgentIds],
12160
+ startingAgentIds: [...snapshot.startingAgentIds],
12161
+ terminalRecoveryAgentIds: [...snapshot.terminalFailureAgentIds],
12162
+ cooldownAgentIds
12163
+ };
12164
+ }
12165
+ };
12166
+
12167
+ // src/launchPhaseTransition.ts
12168
+ var LAUNCH_RUNTIME_READINESS_TRANSITION_SPAN = "launch_runtime_readiness_transition";
12169
+ function launchReadinessNegativeEvidence(identity) {
12170
+ return identity.agent_launch_id ? null : "missing_launch_id";
12171
+ }
12172
+ function buildLaunchReadinessEnterAttrs(state) {
12173
+ return {
12174
+ ...state.identity,
12175
+ phase: "runtime_readiness",
12176
+ span_name: LAUNCH_RUNTIME_READINESS_TRANSITION_SPAN,
12177
+ transition_kind: "enter",
12178
+ phase_result: "entered",
12179
+ state: "awaiting_runtime_ready",
12180
+ state_instance_id: state.stateInstanceId,
12181
+ transition_seq: state.enterSeq,
12182
+ is_wait_state: true,
12183
+ fence_kind: state.fenceKind,
12184
+ deadline_unix_ms: state.deadlineUnixMs ?? void 0,
12185
+ negative_evidence_bucket: state.negativeEvidenceBucket ?? void 0
12186
+ };
12187
+ }
12188
+ function buildLaunchReadinessCloseAttrs(state, closeResult, closeSeq) {
12189
+ return {
12190
+ ...state.identity,
12191
+ phase: "runtime_readiness",
12192
+ span_name: LAUNCH_RUNTIME_READINESS_TRANSITION_SPAN,
12193
+ transition_kind: "close",
12194
+ state: "awaiting_runtime_ready",
12195
+ state_instance_id: state.stateInstanceId,
12196
+ transition_seq: closeSeq,
12197
+ close_result: closeResult,
12198
+ negative_evidence_bucket: state.negativeEvidenceBucket ?? void 0
12199
+ };
12200
+ }
12201
+ var LAUNCH_ACTIVATION_DELIVERY_TRANSITION_SPAN = "launch_activation_delivery_transition";
12202
+ function buildLaunchActivationEnterAttrs(state) {
12203
+ return {
12204
+ ...state.identity,
12205
+ phase: "activation_delivery",
12206
+ span_name: LAUNCH_ACTIVATION_DELIVERY_TRANSITION_SPAN,
12207
+ transition_kind: "enter",
12208
+ phase_result: "entered",
12209
+ state: "awaiting_activation_delivery",
12210
+ state_instance_id: state.stateInstanceId,
12211
+ transition_seq: state.enterSeq,
12212
+ // Activation delivery has no independent fence yet — the launch's phase-5
12213
+ // readiness wait (fenced by the startup timeout) is the upstream deadline.
12214
+ // A stuck activation (session never ready-for-delivery) surfaces as an open
12215
+ // row, not a fenced one.
12216
+ is_wait_state: true,
12217
+ fence_kind: "none",
12218
+ negative_evidence_bucket: state.negativeEvidenceBucket ?? void 0
12219
+ };
12220
+ }
12221
+ function buildLaunchActivationCloseAttrs(state, closeResult, closeSeq, deliveredVia) {
12222
+ return {
12223
+ ...state.identity,
12224
+ phase: "activation_delivery",
12225
+ span_name: LAUNCH_ACTIVATION_DELIVERY_TRANSITION_SPAN,
12226
+ transition_kind: "close",
12227
+ state: "awaiting_activation_delivery",
12228
+ state_instance_id: state.stateInstanceId,
12229
+ transition_seq: closeSeq,
12230
+ close_result: closeResult,
12231
+ delivered_via: deliveredVia ?? void 0,
12232
+ negative_evidence_bucket: state.negativeEvidenceBucket ?? void 0
12233
+ };
12234
+ }
12235
+
11609
12236
  // src/agentVisibleDeliveryLedger.ts
11610
12237
  function getMessageShortId(messageId2) {
11611
12238
  return messageId2.startsWith("thread-") ? messageId2.slice(7) : messageId2.slice(0, 8);
@@ -12954,7 +13581,9 @@ Do not copy these answers verbatim.
12954
13581
 
12955
13582
  ## FAQ 15: How do I create agents or channels?
12956
13583
  ### Answer idea
12957
- - When the owner agrees to a new agent or channel, **post an action card** with \`raft action prepare\`. The card lives inline in chat; the owner clicks the action button, the matching create dialog opens prefilled with your values (editable), and the resource is created under their identity when they submit.
13584
+ - If you have \`channel:create\` scope and your server role has channel-management authority, create channels directly with \`raft channel create --name <name>\` (add \`--private\` for private channels). This creates the channel under your agent identity and joins you to it.
13585
+ - If you also have the matching channel-management scopes and authority, edit regular channels with \`raft channel update --target "#channel-name" --name "#new-name"\`, add humans or agents with \`raft channel add-member --target "#channel-name" --user @alice\` or \`--agent @scout\`, and remove them with \`raft channel remove-member --target "#channel-name" --user @alice\` or \`--agent @scout\`. Adding members is the direct follow-up for private channels you create under your agent identity.
13586
+ - When a human should review/commit the action, or when creating a new agent, **post an action card** with \`raft action prepare\`. The card lives inline in chat; the owner clicks the action button, the matching create dialog opens prefilled with your values (editable), and the resource is created under their identity when they submit.
12958
13587
  - v1 supports three action types via \`raft action prepare --target '<channel>' <<'SLOCKACTION' { ... } SLOCKACTION\`:
12959
13588
  - \`{type: "channel:create", name, visibility: "public" | "private", description?, initialHumans?: ["@alice"], initialAgents?: ["@scout"], draftHint?}\`
12960
13589
  - \`{type: "agent:create", name, description?, suggestedComputer?, requiredComputer?, draftHint?}\` \u2014 runtime / model / reasoning effort are the owner's call. Use \`requiredComputer\` only when the owner explicitly says the new agent must run on that computer; use \`suggestedComputer\` for a soft preference.
@@ -12964,12 +13593,12 @@ Do not copy these answers verbatim.
12964
13593
  - Manual fallback (only when the owner explicitly wants to do it themselves or asks how to repeat it): the + buttons in the Agents and Channels sidebar sections. Lead with the action card; mention the + button only on request.
12965
13594
 
12966
13595
  ### Next step
12967
- - Prefill the values you have, post the action card with a short \`draftHint\` explaining why these values, and tell the owner: "click the button on the card to review and commit." Then propose the first task to send once the card flips to Done.
13596
+ - For direct channel creation, name the channel, create it, add needed members if requested/appropriate, then post the first useful update there. For human-committed actions, prefill the values you have, post the action card with a short \`draftHint\` explaining why these values, and tell the owner: "click the button on the card to review and commit." Then propose the first task to send once the card flips to Done.
12968
13597
 
12969
13598
  ### Guardrail
12970
- - Do not imply you already created agents or channels unless the card state is \`executed\`.
13599
+ - Do not imply you created or edited a channel unless the corresponding \`raft channel create\` / \`raft channel update\` command succeeded. Do not imply you added or removed a channel member unless the corresponding member command succeeded. Do not imply you created an agent or a human-committed channel unless the card state is \`executed\`.
12971
13600
  - Do not prefill runtime / model / reasoning effort on \`agent:create\`. Computer placement is only allowed as the structured \`suggestedComputer\` / \`requiredComputer\` field when the owner's request includes that placement; never rely on \`draftHint\` for a computer constraint.
12972
- - If the action type the user wants is not yet supported (e.g. \`channel:add_member\`), say so plainly and offer the manual UI path; do not invent action types the schema does not accept.
13601
+ - If the action type or direct CLI command the user wants is not yet supported, say so plainly and offer the manual UI path; do not invent action types the schema does not accept.
12973
13602
  `;
12974
13603
  }
12975
13604
  function buildOnboardingSeedFiles() {
@@ -13538,7 +14167,10 @@ var AgentProcessManager = class _AgentProcessManager {
13538
14167
  }
13539
14168
  agentStarts;
13540
14169
  startingInboxes = new AgentStartPendingDeliveryBuffer();
14170
+ /** Monotonic ordering counter for launch phase-5/6 exported rows (audit only, not a pairing key). */
14171
+ launchTransitionSeq = 0;
13541
14172
  terminalRuntimeFailures = /* @__PURE__ */ new Map();
14173
+ noProcessResidencyTransitions = new AgentNoProcessResidencyTransitions();
13542
14174
  runtimeErrorFingerprintFences = /* @__PURE__ */ new Map();
13543
14175
  pendingStartRebinds = /* @__PURE__ */ new Map();
13544
14176
  /** Cached configs for agents whose process exited normally — enables auto-restart on next message */
@@ -13618,13 +14250,26 @@ var AgentProcessManager = class _AgentProcessManager {
13618
14250
  this.cliTransportTraceDir = traceDir;
13619
14251
  }
13620
14252
  assertStartPendingDeliveryInvariants(context) {
14253
+ const residencySnapshot = this.noProcessResidencySnapshot();
14254
+ AgentNoProcessResidency.assertInvariants(context, residencySnapshot);
14255
+ this.startingInboxes.assertInvariants(
14256
+ context,
14257
+ AgentNoProcessResidency.allowedStartPendingSnapshot(residencySnapshot)
14258
+ );
14259
+ }
14260
+ noProcessResidencySnapshot() {
13621
14261
  const startSnapshot = this.agentStarts.snapshot();
13622
- this.startingInboxes.assertInvariants(context, {
14262
+ const now = this.clockNow();
14263
+ return {
14264
+ runningAgentIds: [...this.agents.keys()],
13623
14265
  queuedAgentIds: startSnapshot.queuedAgentIds,
13624
14266
  startingAgentIds: startSnapshot.startingAgentIds,
13625
- terminalRecoveryAgentIds: [...this.terminalRuntimeFailures.keys()],
13626
- cooldownAgentIds: [...this.agentSpawnFailBackoff.keys()]
13627
- });
14267
+ idleAgentIds: [...this.idleAgentConfigs.keys()],
14268
+ terminalFailureAgentIds: [...this.terminalRuntimeFailures.keys()],
14269
+ activeCooldownAgentIds: [...this.agentSpawnFailBackoff.entries()].filter(([, state]) => state.untilMs > now).map(([agentId]) => agentId),
14270
+ fingerprintFenceAgentIds: [...this.runtimeErrorFingerprintFences.keys()],
14271
+ pendingDeliveryAgentIds: this.startingInboxes.agentIds()
14272
+ };
13628
14273
  }
13629
14274
  getVisibleBoundary(agentId, target) {
13630
14275
  return this.agentVisibleDelivery.getBoundary(agentId, target);
@@ -13682,15 +14327,17 @@ var AgentProcessManager = class _AgentProcessManager {
13682
14327
  if (s) {
13683
14328
  s.timer = null;
13684
14329
  s.untilMs = 0;
14330
+ this.closeNoProcessResidency(agentId, "timeout", { negativeEvidenceBucket: "spawn_fail_cooldown_expired" });
13685
14331
  }
13686
14332
  }, Math.max(1, state.untilMs - this.clockNow()));
13687
14333
  return { backoffActive: true, attempts: state.attempts, untilMs: state.untilMs };
13688
14334
  }
13689
- resetSpawnFailBackoff(agentId) {
14335
+ resetSpawnFailBackoff(agentId, closeResult = "advanced") {
13690
14336
  const state = this.agentSpawnFailBackoff.get(agentId);
13691
14337
  if (!state) return;
13692
14338
  if (state.timer) clearTimeout(state.timer);
13693
14339
  this.agentSpawnFailBackoff.delete(agentId);
14340
+ this.closeNoProcessResidency(agentId, closeResult, { negativeEvidenceBucket: "spawn_fail_cooldown_reset" });
13694
14341
  }
13695
14342
  // ----- RUNTIME-ERROR FINGERPRINT FENCE (per-agent) ---------------------
13696
14343
  // The delivery backoff above is scoped to AgentProcess and is cleared when a
@@ -14223,19 +14870,19 @@ var AgentProcessManager = class _AgentProcessManager {
14223
14870
  if (input.decision !== "local_hold" && input.decision !== "syncing_hold") return;
14224
14871
  const ap = this.agents.get(agentId);
14225
14872
  const messageCount = input.decision === "syncing_hold" ? input.heldMessageCount ?? input.pendingCount ?? 0 : input.pendingCount ?? input.heldMessageCount ?? 0;
14226
- const entry = projectApmHeldFreshnessActivity({
14873
+ const activity = projectApmHeldFreshnessActivity({
14227
14874
  producerFactId,
14228
14875
  action: input.action,
14229
14876
  decision: input.decision,
14230
14877
  target: input.target,
14231
14878
  messageCount
14232
- }).entry;
14879
+ });
14233
14880
  this.sendToServer({
14234
14881
  type: "agent:activity",
14235
14882
  agentId,
14236
- activity: ap?.lastActivity || "online",
14237
- detail: ap?.lastActivityDetail || "",
14238
- entries: [entry],
14883
+ activity: activity.statusEntry.activity,
14884
+ detail: activity.statusEntry.detail,
14885
+ entries: activity.entries,
14239
14886
  launchId: ap?.launchId || void 0,
14240
14887
  clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0
14241
14888
  });
@@ -14283,6 +14930,64 @@ var AgentProcessManager = class _AgentProcessManager {
14283
14930
  });
14284
14931
  span.end(status);
14285
14932
  }
14933
+ emitNoProcessResidencyRows(rows) {
14934
+ for (const row of rows) {
14935
+ this.recordDaemonTrace("launch_residency_transition", row);
14936
+ }
14937
+ }
14938
+ noProcessResidencyIdentity(agentId, config, launchId, launchSource, driverId) {
14939
+ const runtimeContext = config.runtimeContext;
14940
+ const agentLaunchIdPresent = typeof launchId === "string" && launchId.length > 0;
14941
+ return {
14942
+ agentId,
14943
+ agentLaunchId: agentLaunchIdPresent ? launchId : "missing_launch_id",
14944
+ agentLaunchIdPresent,
14945
+ serverId: runtimeContext?.serverId || "unknown_server",
14946
+ machineId: runtimeContext?.machineId || "unknown_machine",
14947
+ runtime: config.runtime || "unknown_runtime",
14948
+ driver: driverId || this.driverResolver(config.runtime || "claude").id,
14949
+ launchSource
14950
+ };
14951
+ }
14952
+ enterNoProcessResidency(state, identity, opts) {
14953
+ const launchEvidence = identity.agentLaunchIdPresent ? {} : {
14954
+ failureKind: opts.failureKind ?? "missing_launch_id",
14955
+ negativeEvidenceBucket: opts.negativeEvidenceBucket ?? "missing_launch_id"
14956
+ };
14957
+ this.emitNoProcessResidencyRows(this.noProcessResidencyTransitions.enter({
14958
+ ...identity,
14959
+ state,
14960
+ ...opts,
14961
+ ...launchEvidence
14962
+ }));
14963
+ }
14964
+ closeNoProcessResidency(agentId, closeResult, opts = {}) {
14965
+ this.emitNoProcessResidencyRows(this.noProcessResidencyTransitions.close(agentId, {
14966
+ closeResult,
14967
+ failureKind: opts.failureKind,
14968
+ negativeEvidenceBucket: opts.negativeEvidenceBucket
14969
+ }));
14970
+ }
14971
+ startLaunchSource(config, wakeMessage, resumePrompt) {
14972
+ if (config.runtimeProfileControl && !wakeMessage) return "runtime_profile";
14973
+ if (config.sessionId || resumePrompt) return "session_resume";
14974
+ if (wakeMessage) return "wake_message";
14975
+ return "explicit_start";
14976
+ }
14977
+ enterSpawnFailCooldownResidency(agentId, cached, untilMs, source, reason) {
14978
+ if (untilMs <= this.clockNow()) return;
14979
+ this.enterNoProcessResidency(
14980
+ "spawn_fail_cooldown",
14981
+ this.noProcessResidencyIdentity(agentId, cached.config, cached.launchId, source),
14982
+ {
14983
+ isWaitState: true,
14984
+ fenceKind: "spawn_fail_backoff",
14985
+ deadlineUnixMs: untilMs,
14986
+ failureKind: reason,
14987
+ negativeEvidenceBucket: reason
14988
+ }
14989
+ );
14990
+ }
14286
14991
  processLifecycleIdentityAttrs(agentId, ap) {
14287
14992
  const runtimeContext = ap.config.runtimeContext;
14288
14993
  return {
@@ -14510,6 +15215,15 @@ var AgentProcessManager = class _AgentProcessManager {
14510
15215
  this.agentStarts.enqueue(item);
14511
15216
  this.recordDaemonTrace("daemon.agent.start.queued", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
14512
15217
  const startSnapshot = this.agentStarts.snapshot();
15218
+ this.enterNoProcessResidency(
15219
+ "queued_start",
15220
+ this.noProcessResidencyIdentity(agentId, config, launchId, this.startLaunchSource(config, wakeMessage, resumePrompt)),
15221
+ {
15222
+ isWaitState: true,
15223
+ fenceKind: "start_scheduler",
15224
+ deadlineUnixMs: this.clockNow() + Math.max(1, startSnapshot.minStartIntervalMs)
15225
+ }
15226
+ );
14513
15227
  logger.info(
14514
15228
  `[Agent ${agentId}] Start queued (queue=${startSnapshot.queueDepth}, active=${startSnapshot.activeStarts}, max=${startSnapshot.maxConcurrentStarts}, interval=${startSnapshot.minStartIntervalMs}ms)`
14515
15229
  );
@@ -14532,6 +15246,7 @@ var AgentProcessManager = class _AgentProcessManager {
14532
15246
  if (dequeued.kind === "empty") return;
14533
15247
  if (dequeued.kind === "stale") {
14534
15248
  const { item: item2 } = dequeued;
15249
+ this.closeNoProcessResidency(item2.agentId, "suppressed", { negativeEvidenceBucket: "stale_queue_item" });
14535
15250
  this.recordDaemonTrace("daemon.agent.start.skipped", {
14536
15251
  ...this.startQueueTraceAttrs(item2.agentId, item2.config, item2.wakeMessage, item2.unreadSummary, item2.resumePrompt, item2.launchId, item2.wakeMessageTransient),
14537
15252
  reason: "stale_queue_item"
@@ -14541,6 +15256,7 @@ var AgentProcessManager = class _AgentProcessManager {
14541
15256
  }
14542
15257
  const { item } = dequeued;
14543
15258
  if (this.agents.has(item.agentId) || this.agentStarts.hasStarting(item.agentId)) {
15259
+ this.closeNoProcessResidency(item.agentId, "suppressed", { negativeEvidenceBucket: "already_running_or_starting" });
14544
15260
  this.recordDaemonTrace("daemon.agent.start.skipped", {
14545
15261
  ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
14546
15262
  reason: "already_running_or_starting"
@@ -14556,6 +15272,15 @@ var AgentProcessManager = class _AgentProcessManager {
14556
15272
  return;
14557
15273
  }
14558
15274
  this.agentStarts.claimStartSlot(item.agentId);
15275
+ this.enterNoProcessResidency(
15276
+ "starting_process",
15277
+ this.noProcessResidencyIdentity(item.agentId, item.config, item.launchId, this.startLaunchSource(item.config, item.wakeMessage, item.resumePrompt)),
15278
+ {
15279
+ isWaitState: true,
15280
+ fenceKind: "runtime_start_timeout",
15281
+ deadlineUnixMs: this.clockNow() + runtimeStartTimeoutMs()
15282
+ }
15283
+ );
14559
15284
  const startSnapshot = this.agentStarts.snapshot();
14560
15285
  logger.info(
14561
15286
  `[Agent ${item.agentId}] Dequeued start (remaining=${startSnapshot.queueDepth}, active=${startSnapshot.activeStarts})`
@@ -14595,6 +15320,7 @@ var AgentProcessManager = class _AgentProcessManager {
14595
15320
  cancelQueuedAgentStart(agentId, reason) {
14596
15321
  const item = this.agentStarts.cancelQueued(agentId);
14597
15322
  if (!item) return false;
15323
+ this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "start_cancelled" });
14598
15324
  this.startingInboxes.cancelStart(agentId);
14599
15325
  this.assertStartPendingDeliveryInvariants("cancel-queued-start");
14600
15326
  this.recordDaemonTrace("daemon.agent.start.cancelled", {
@@ -14607,6 +15333,7 @@ var AgentProcessManager = class _AgentProcessManager {
14607
15333
  }
14608
15334
  cancelAllQueuedAgentStarts(reason) {
14609
15335
  const cancelled = this.agentStarts.cancelAllQueued((item) => {
15336
+ this.closeNoProcessResidency(item.agentId, "suppressed", { negativeEvidenceBucket: "start_cancelled" });
14610
15337
  this.recordDaemonTrace("daemon.agent.start.cancelled", {
14611
15338
  ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
14612
15339
  reason
@@ -14687,6 +15414,15 @@ var AgentProcessManager = class _AgentProcessManager {
14687
15414
  wakeMessageTransient = pendingStartRebind.wakeMessageTransient === true;
14688
15415
  }
14689
15416
  }
15417
+ this.enterNoProcessResidency(
15418
+ "starting_process",
15419
+ this.noProcessResidencyIdentity(agentId, config, launchId, this.startLaunchSource(config, wakeMessage, resumePrompt)),
15420
+ {
15421
+ isWaitState: true,
15422
+ fenceKind: "runtime_start_timeout",
15423
+ deadlineUnixMs: this.clockNow() + runtimeStartTimeoutMs()
15424
+ }
15425
+ );
14690
15426
  this.recordDaemonTrace("daemon.agent.spawn.started", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
14691
15427
  const driver = this.driverResolver(config.runtime || "claude");
14692
15428
  const legacyWakeRuntimeProfile = wakeMessage ? runtimeProfileNotificationFromMessage(wakeMessage) : null;
@@ -14795,6 +15531,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
14795
15531
  if (canDeferEmptyStart) {
14796
15532
  const pendingMessages = this.startingInboxes.drainOnSpawn(agentId);
14797
15533
  this.agentStarts.clearStarting(agentId);
15534
+ this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "defer_until_concrete_message" });
14798
15535
  this.assertStartPendingDeliveryInvariants("defer-empty-start-drain");
14799
15536
  this.idleAgentConfigs.set(agentId, {
14800
15537
  config: this.buildRestartSafeConfig(runtimeConfig, runtimeConfig.sessionId || null),
@@ -14838,7 +15575,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
14838
15575
  };
14839
15576
  const initialSessionId = this.initialAgentProcessSessionId(driver, liveProcessConfig);
14840
15577
  const restartSessionId = initialSessionId || (driver.requiresSessionInitForDelivery ? liveProcessConfig.sessionId || null : null);
14841
- const processInstanceId = randomUUID5();
15578
+ const processInstanceId = randomUUID6();
14842
15579
  agentProcess = {
14843
15580
  runtime,
14844
15581
  driver,
@@ -14854,6 +15591,9 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
14854
15591
  activityHeartbeat: null,
14855
15592
  startupTimeoutTimer: null,
14856
15593
  startupReadinessSatisfied: false,
15594
+ readinessTransition: null,
15595
+ activationTransition: null,
15596
+ initialActivationDelivered: false,
14857
15597
  compactionWatchdog: null,
14858
15598
  compactionStartedAt: null,
14859
15599
  runtimeProgress: new RuntimeProgressState(Date.now()),
@@ -14879,7 +15619,6 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
14879
15619
  gatedSteering: createGatedSteeringState()
14880
15620
  };
14881
15621
  this.startingInboxes.drainOnSpawn(agentId);
14882
- this.assertStartPendingDeliveryInvariants("spawn-drain");
14883
15622
  this.agents.set(agentId, agentProcess);
14884
15623
  this.idleAgentConfigs.set(agentId, {
14885
15624
  config: this.buildRestartSafeConfig(runtimeConfig, restartSessionId),
@@ -15004,6 +15743,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15004
15743
  if (ap.activityHeartbeat) {
15005
15744
  clearInterval(ap.activityHeartbeat);
15006
15745
  }
15746
+ this.closeRuntimeReadinessTransition(ap, "terminal");
15747
+ this.closeActivationTransition(ap, "terminal");
15007
15748
  this.clearRuntimeStartupTimeout(ap);
15008
15749
  this.clearStalledRecoverySigtermWatchdog(ap);
15009
15750
  const finalCode = ap.exitCode ?? code;
@@ -15096,6 +15837,24 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15096
15837
  this.startAgent(agentId, nextConfig, queuedWakeMessage, unreadSummary2, void 0, ap.launchId || void 0).catch((err) => {
15097
15838
  logger.error(`[Agent ${agentId}] Failed to continue with queued message`, err);
15098
15839
  if (this.reportRunnerCredentialMintFailure(agentId, err, ap.launchId, "queued_continuation")) {
15840
+ this.idleAgentConfigs.set(agentId, {
15841
+ config: nextConfig,
15842
+ sessionId: ap.sessionId,
15843
+ launchId: ap.launchId
15844
+ });
15845
+ const report = this.recordSpawnFailure(agentId, "runner_credential_mint");
15846
+ this.assertStartPendingDeliveryInvariants("queued-continuation-runner-credential-mint-failure");
15847
+ if (report.backoffActive) {
15848
+ this.enterSpawnFailCooldownResidency(agentId, { config: nextConfig, launchId: ap.launchId }, report.untilMs, "queued_continuation", "runner_credential_mint");
15849
+ }
15850
+ this.recordDaemonTrace("daemon.agent.spawn.fail_backoff", {
15851
+ agentId,
15852
+ source: "queued_continuation",
15853
+ reason: "runner_credential_mint",
15854
+ attempts: report.attempts,
15855
+ cooldown_active: report.backoffActive,
15856
+ until_ms: report.untilMs
15857
+ });
15099
15858
  return;
15100
15859
  }
15101
15860
  this.idleAgentConfigs.set(agentId, {
@@ -15170,7 +15929,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15170
15929
  }, "error");
15171
15930
  throw new Error(`Runtime session failed to start: ${startResult.reason}${startResult.error ? ` (${startResult.error})` : ""}`);
15172
15931
  }
15173
- this.terminalRuntimeFailures.delete(agentId);
15932
+ this.closeNoProcessResidency(agentId, "advanced");
15933
+ if (this.terminalRuntimeFailures.delete(agentId)) {
15934
+ this.closeNoProcessResidency(agentId, "advanced", { negativeEvidenceBucket: "terminal_recovery_start_succeeded" });
15935
+ }
15936
+ this.assertStartPendingDeliveryInvariants("spawn-drain");
15174
15937
  this.recordDaemonTrace("daemon.agent.spawn.created", {
15175
15938
  ...this.startQueueTraceAttrs(agentId, effectiveConfig, wakeMessage, unreadSummary, resumePrompt, agentProcess.launchId || void 0, wakeMessageTransient),
15176
15939
  detached: false,
@@ -15192,9 +15955,16 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15192
15955
  this.sendToServer({ type: "agent:session", agentId, sessionId: agentProcess.sessionId, launchId: agentProcess.launchId || void 0 });
15193
15956
  }
15194
15957
  this.broadcastActivity(agentId, "working", "Starting\u2026");
15195
- this.startRuntimeStartupTimeout(agentId, agentProcess);
15958
+ this.startRuntimeStartupTimeout(agentId, agentProcess, startCause);
15959
+ if (wakeMessage || startingInboxMessages.length > 0) {
15960
+ this.openActivationTransition(agentId, agentProcess, startCause);
15961
+ if (wakeMessageDeliveredAsInboxUpdate || startingInboxDeliveredAsInput) {
15962
+ this.closeActivationTransition(agentProcess, "advanced", "spawn_prompt");
15963
+ }
15964
+ }
15196
15965
  } catch (err) {
15197
15966
  this.agentStarts.clearStarting(agentId);
15967
+ this.closeNoProcessResidency(agentId, "terminal", { negativeEvidenceBucket: "runtime_start_failed" });
15198
15968
  this.pendingStartRebinds.delete(agentId);
15199
15969
  this.cleanupFailedRuntimeStart(agentId, agentProcess, err);
15200
15970
  throw err;
@@ -15216,6 +15986,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15216
15986
  clearTimeout(ap.compactionWatchdog);
15217
15987
  ap.compactionWatchdog = null;
15218
15988
  }
15989
+ this.closeRuntimeReadinessTransition(ap, "terminal");
15990
+ this.closeActivationTransition(ap, "terminal");
15219
15991
  this.clearRuntimeStartupTimeout(ap);
15220
15992
  this.clearStalledRecoverySigtermWatchdog(ap);
15221
15993
  this.endRuntimeTrace(ap, "error", {
@@ -15228,7 +16000,9 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15228
16000
  this.revokeManagedRunnerCredential(agentId, ap.config, ap.launchId);
15229
16001
  this.agents.delete(agentId);
15230
16002
  this.idleAgentConfigs.delete(agentId);
15231
- this.terminalRuntimeFailures.delete(agentId);
16003
+ if (this.terminalRuntimeFailures.delete(agentId)) {
16004
+ this.closeNoProcessResidency(agentId, "terminal", { negativeEvidenceBucket: "runtime_start_failed" });
16005
+ }
15232
16006
  }
15233
16007
  cleanupTerminalRuntimeFailure(agentId, ap, detail) {
15234
16008
  if (this.agents.get(agentId) !== ap) return;
@@ -15243,6 +16017,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15243
16017
  ap.activityHeartbeat = null;
15244
16018
  }
15245
16019
  this.clearCompactionWatchdog(ap);
16020
+ this.closeRuntimeReadinessTransition(ap, "terminal");
16021
+ this.closeActivationTransition(ap, "terminal");
15246
16022
  this.clearRuntimeStartupTimeout(ap);
15247
16023
  this.clearStalledRecoverySigtermWatchdog(ap);
15248
16024
  cleanupAgentCredentialProxy(agentId, ap.launchId);
@@ -15251,9 +16027,18 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15251
16027
  if (ap.inbox.length > 0) {
15252
16028
  this.startingInboxes.bufferMessagesDuringStart(agentId, ap.inbox);
15253
16029
  }
16030
+ this.agents.delete(agentId);
15254
16031
  this.terminalRuntimeFailures.set(agentId, { detail, launchId: ap.launchId });
16032
+ this.enterNoProcessResidency(
16033
+ "terminal_runtime_error",
16034
+ this.noProcessResidencyIdentity(agentId, ap.config, ap.launchId, "terminal_runtime_error", ap.driver.id),
16035
+ {
16036
+ isWaitState: false,
16037
+ failureKind: "terminal_runtime_error",
16038
+ negativeEvidenceBucket: "terminal_runtime_error"
16039
+ }
16040
+ );
15255
16041
  this.assertStartPendingDeliveryInvariants("terminal-runtime-failure-cleanup");
15256
- this.agents.delete(agentId);
15257
16042
  const diagnostics = buildRuntimeErrorDiagnosticEnvelope(detail);
15258
16043
  this.recordDaemonTrace("daemon.agent.terminal_runtime_error.cleanup", {
15259
16044
  agentId,
@@ -15517,7 +16302,9 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15517
16302
  this.cancelQueuedAgentStart(agentId, "stop requested");
15518
16303
  this.pendingStartRebinds.delete(agentId);
15519
16304
  this.idleAgentConfigs.delete(agentId);
15520
- this.terminalRuntimeFailures.delete(agentId);
16305
+ if (this.terminalRuntimeFailures.delete(agentId)) {
16306
+ this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "explicit_stop" });
16307
+ }
15521
16308
  const ap = this.agents.get(agentId);
15522
16309
  if (!ap) {
15523
16310
  if (!silent) {
@@ -15538,7 +16325,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15538
16325
  if (!silent) {
15539
16326
  this.activityClientSeqByAgent.delete(agentId);
15540
16327
  this.agentVisibleDelivery.clearAgent(agentId);
15541
- this.resetSpawnFailBackoff(agentId);
16328
+ this.resetSpawnFailBackoff(agentId, "suppressed");
15542
16329
  this.resetRuntimeErrorFingerprintFence(agentId, "explicit_stop", ap);
15543
16330
  }
15544
16331
  this.runtimeExitTraceAttrs.set(ap.runtime, {
@@ -15676,6 +16463,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15676
16463
  const state = this.agentSpawnFailBackoff.get(agentId);
15677
16464
  const startingInboxCount = this.startingInboxes.bufferDuringStart(agentId, message);
15678
16465
  this.assertStartPendingDeliveryInvariants("delivery-spawn-fail-cooldown");
16466
+ this.enterSpawnFailCooldownResidency(agentId, cached, state.untilMs, "idle_auto_restart", "spawn_fail_cooldown_active");
15679
16467
  this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
15680
16468
  outcome: "spawn_fail_cooldown_active",
15681
16469
  accepted: true,
@@ -15702,11 +16490,17 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15702
16490
  }));
15703
16491
  return this.startAgent(agentId, cached.config, message, void 0, void 0, cached.launchId || void 0, transientDelivery).then(() => {
15704
16492
  this.resetSpawnFailBackoff(agentId);
16493
+ this.assertStartPendingDeliveryInvariants("idle-auto-restart-success");
15705
16494
  return true;
15706
16495
  }, (err) => {
15707
16496
  logger.error(`[Agent ${agentId}] Failed to auto-restart`, err);
15708
16497
  if (this.reportRunnerCredentialMintFailure(agentId, err, cached.launchId, "idle_auto_restart")) {
16498
+ this.idleAgentConfigs.set(agentId, cached);
15709
16499
  const report2 = this.recordSpawnFailure(agentId, "runner_credential_mint");
16500
+ this.assertStartPendingDeliveryInvariants("idle-auto-restart-runner-credential-mint-failure");
16501
+ if (report2.backoffActive) {
16502
+ this.enterSpawnFailCooldownResidency(agentId, cached, report2.untilMs, "idle_auto_restart", "runner_credential_mint");
16503
+ }
15710
16504
  this.recordDaemonTrace("daemon.agent.spawn.fail_backoff", {
15711
16505
  agentId,
15712
16506
  source: "idle_auto_restart",
@@ -15719,6 +16513,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
15719
16513
  }
15720
16514
  this.idleAgentConfigs.set(agentId, cached);
15721
16515
  const report = this.recordSpawnFailure(agentId, "spawn_error");
16516
+ this.assertStartPendingDeliveryInvariants("idle-auto-restart-spawn-failure");
16517
+ if (report.backoffActive) {
16518
+ this.enterSpawnFailCooldownResidency(agentId, cached, report.untilMs, "idle_auto_restart", "spawn_error");
16519
+ }
15722
16520
  this.recordDaemonTrace("daemon.agent.spawn.fail_backoff", {
15723
16521
  agentId,
15724
16522
  source: "idle_auto_restart",
@@ -16336,6 +17134,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
16336
17134
  logger.info(`[Agent ${agentId}] Starting from idle state for runtime profile ${kind} ${key}`);
16337
17135
  if (this.isSpawnFailBackoffActive(agentId)) {
16338
17136
  const state = this.agentSpawnFailBackoff.get(agentId);
17137
+ this.enterSpawnFailCooldownResidency(agentId, cached, state.untilMs, "runtime_profile_auto_restart", "spawn_fail_cooldown_active");
16339
17138
  span.end("ok", {
16340
17139
  attrs: {
16341
17140
  outcome: "spawn_fail_cooldown_active",
@@ -16350,11 +17149,17 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
16350
17149
  this.idleAgentConfigs.delete(agentId);
16351
17150
  return this.startAgent(agentId, cached.config, message, void 0, void 0, cached.launchId || void 0).then(() => {
16352
17151
  this.resetSpawnFailBackoff(agentId);
17152
+ this.assertStartPendingDeliveryInvariants("runtime-profile-auto-restart-success");
16353
17153
  return true;
16354
17154
  }, (err) => {
16355
17155
  logger.error(`[Agent ${agentId}] Failed to auto-restart for runtime profile notification`, err);
16356
17156
  if (this.reportRunnerCredentialMintFailure(agentId, err, cached.launchId, "runtime_profile_auto_restart")) {
17157
+ this.idleAgentConfigs.set(agentId, cached);
16357
17158
  const report2 = this.recordSpawnFailure(agentId, "runner_credential_mint");
17159
+ this.assertStartPendingDeliveryInvariants("runtime-profile-auto-restart-runner-credential-mint-failure");
17160
+ if (report2.backoffActive) {
17161
+ this.enterSpawnFailCooldownResidency(agentId, cached, report2.untilMs, "runtime_profile_auto_restart", "runner_credential_mint");
17162
+ }
16358
17163
  this.recordDaemonTrace("daemon.agent.spawn.fail_backoff", {
16359
17164
  agentId,
16360
17165
  source: "runtime_profile_auto_restart",
@@ -16374,6 +17179,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
16374
17179
  }
16375
17180
  this.idleAgentConfigs.set(agentId, cached);
16376
17181
  const report = this.recordSpawnFailure(agentId, "spawn_error");
17182
+ this.assertStartPendingDeliveryInvariants("runtime-profile-auto-restart-spawn-failure");
17183
+ if (report.backoffActive) {
17184
+ this.enterSpawnFailCooldownResidency(agentId, cached, report.untilMs, "runtime_profile_auto_restart", "spawn_error");
17185
+ }
16377
17186
  this.recordDaemonTrace("daemon.agent.spawn.fail_backoff", {
16378
17187
  agentId,
16379
17188
  source: "runtime_profile_auto_restart",
@@ -16677,7 +17486,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
16677
17486
  const gzipped = gzipSync(raw);
16678
17487
  const bundleSha256 = createHash3("sha256").update(gzipped).digest("hex");
16679
17488
  const bundleSizeBytes = gzipped.byteLength;
16680
- const bundleId = randomUUID5();
17489
+ const bundleId = randomUUID6();
16681
17490
  const uploadResult = await uploadWithSignedCapability({
16682
17491
  serverUrl: this.serverUrl,
16683
17492
  apiKey: this.daemonApiKey,
@@ -17458,9 +18267,100 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
17458
18267
  }
17459
18268
  return true;
17460
18269
  }
17461
- startRuntimeStartupTimeout(agentId, ap) {
18270
+ launchIdentityAttrs(agentId, ap, launchSource) {
18271
+ const runtimeContext = ap.config.runtimeContext;
18272
+ return {
18273
+ agent_launch_id: ap.launchId ?? null,
18274
+ agent_id: agentId,
18275
+ server_id: runtimeContext?.serverId ?? null,
18276
+ machine_id: runtimeContext?.machineId ?? null,
18277
+ runtime: ap.config.runtime,
18278
+ driver: ap.driver.id,
18279
+ launch_source: launchSource
18280
+ };
18281
+ }
18282
+ /**
18283
+ * Phase-5 exported-row ENTER: opens the runtime-readiness wait row (task
18284
+ * #149). Idempotent — a second call while a row is open is a no-op so the
18285
+ * (agent_launch_id, state_instance_id) pair keeps exactly-one enter.
18286
+ */
18287
+ openRuntimeReadinessTransition(agentId, ap, launchSource, fenceKind, deadlineUnixMs) {
18288
+ if (ap.readinessTransition) return;
18289
+ const identity = this.launchIdentityAttrs(agentId, ap, launchSource);
18290
+ const state = {
18291
+ stateInstanceId: randomUUID6(),
18292
+ enterSeq: this.launchTransitionSeq++,
18293
+ identity,
18294
+ fenceKind,
18295
+ deadlineUnixMs,
18296
+ negativeEvidenceBucket: launchReadinessNegativeEvidence(identity)
18297
+ };
18298
+ ap.readinessTransition = state;
18299
+ this.recordDaemonTrace(LAUNCH_RUNTIME_READINESS_TRANSITION_SPAN, buildLaunchReadinessEnterAttrs(state));
18300
+ }
18301
+ /**
18302
+ * Phase-5 exported-row CLOSE: closes the open runtime-readiness wait row with
18303
+ * a closed `close_result` (task #149). Idempotent — no-op when no row is open,
18304
+ * so overlapping close paths (ready event, timeout fire, process exit,
18305
+ * cleanup) emit exactly one close.
18306
+ */
18307
+ closeRuntimeReadinessTransition(ap, closeResult) {
18308
+ const state = ap.readinessTransition;
18309
+ if (!state) return;
18310
+ ap.readinessTransition = null;
18311
+ this.recordDaemonTrace(
18312
+ LAUNCH_RUNTIME_READINESS_TRANSITION_SPAN,
18313
+ buildLaunchReadinessCloseAttrs(state, closeResult, this.launchTransitionSeq++),
18314
+ closeResult === "advanced" ? "ok" : "error"
18315
+ );
18316
+ }
18317
+ /**
18318
+ * Phase-6 exported-row ENTER: opens the activation-delivery wait row when a
18319
+ * launch carries an initial activation (wake / buffered inbox) not yet
18320
+ * delivered (task #149). Idempotent + only opens when there is something to
18321
+ * deliver, so explicit starts with no activation produce no phase-6 row.
18322
+ */
18323
+ openActivationTransition(agentId, ap, launchSource) {
18324
+ if (ap.activationTransition || ap.initialActivationDelivered) return;
18325
+ const identity = this.launchIdentityAttrs(agentId, ap, launchSource);
18326
+ const state = {
18327
+ stateInstanceId: randomUUID6(),
18328
+ enterSeq: this.launchTransitionSeq++,
18329
+ identity,
18330
+ negativeEvidenceBucket: launchReadinessNegativeEvidence(identity)
18331
+ };
18332
+ ap.activationTransition = state;
18333
+ this.recordDaemonTrace(LAUNCH_ACTIVATION_DELIVERY_TRANSITION_SPAN, buildLaunchActivationEnterAttrs(state));
18334
+ }
18335
+ /**
18336
+ * Phase-6 exported-row CLOSE: closes the open activation-delivery wait with a
18337
+ * closed `close_result` (+ `delivered_via` on advanced). Idempotent — no-op
18338
+ * when no row is open, so overlapping paths (spawn-prompt, first stdin,
18339
+ * process exit, cleanup) emit exactly one close. Marks the initial activation
18340
+ * delivered on `advanced` so later normal deliveries are not re-counted.
18341
+ */
18342
+ closeActivationTransition(ap, closeResult, deliveredVia) {
18343
+ if (closeResult === "advanced") ap.initialActivationDelivered = true;
18344
+ const state = ap.activationTransition;
18345
+ if (!state) return;
18346
+ ap.activationTransition = null;
18347
+ this.recordDaemonTrace(
18348
+ LAUNCH_ACTIVATION_DELIVERY_TRANSITION_SPAN,
18349
+ buildLaunchActivationCloseAttrs(state, closeResult, this.launchTransitionSeq++, deliveredVia),
18350
+ closeResult === "advanced" ? "ok" : "error"
18351
+ );
18352
+ }
18353
+ startRuntimeStartupTimeout(agentId, ap, launchSource) {
17462
18354
  const timeoutMs = runtimeStartTimeoutMs();
17463
- if (timeoutMs <= 0) return;
18355
+ const fenced = timeoutMs > 0;
18356
+ this.openRuntimeReadinessTransition(
18357
+ agentId,
18358
+ ap,
18359
+ launchSource,
18360
+ fenced ? "runtime_startup_timeout" : "none",
18361
+ fenced ? Date.now() + timeoutMs : null
18362
+ );
18363
+ if (!fenced) return;
17464
18364
  ap.startupTimeoutTimer = setTimeout(() => {
17465
18365
  this.handleRuntimeStartupTimeout(agentId, ap, timeoutMs);
17466
18366
  }, timeoutMs);
@@ -17487,6 +18387,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
17487
18387
  this.clearRuntimeStartupTimeout(ap);
17488
18388
  return;
17489
18389
  }
18390
+ this.closeRuntimeReadinessTransition(ap, "timeout");
17490
18391
  this.clearRuntimeStartupTimeout(ap);
17491
18392
  this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState);
17492
18393
  const terminalFailureDetail = classifyTerminalFailure(ap);
@@ -17524,6 +18425,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
17524
18425
  handleRuntimeStartupRequestError(agentId, ap, event) {
17525
18426
  const current = this.agents.get(agentId);
17526
18427
  if (current !== ap) return;
18428
+ this.closeRuntimeReadinessTransition(ap, "terminal");
18429
+ this.closeActivationTransition(ap, "terminal");
17527
18430
  this.clearRuntimeStartupTimeout(ap);
17528
18431
  this.interruptCompactionIfActive(agentId);
17529
18432
  this.interruptReviewIfActive(agentId);
@@ -17727,6 +18630,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
17727
18630
  const wasStalled = ap.runtimeProgress.isStale;
17728
18631
  if (this.runtimeStartupReadinessSatisfiedByEvent(ap, event)) {
17729
18632
  ap.startupReadinessSatisfied = true;
18633
+ this.closeRuntimeReadinessTransition(ap, "advanced");
17730
18634
  this.clearRuntimeStartupTimeout(ap);
17731
18635
  }
17732
18636
  this.noteRuntimeTraceCounter(ap, event);
@@ -18443,6 +19347,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
18443
19347
  cursors_advanced: "none"
18444
19348
  });
18445
19349
  ap.notifications.recordNoticeWritten(computeInboxNoticeFingerprint(messages), ap.sessionId, messages);
19350
+ this.closeActivationTransition(ap, "advanced", "stdin");
18446
19351
  return true;
18447
19352
  }
18448
19353
  /** Deliver a message to an agent via stdin, formatting it the same way as the MCP bridge */
@@ -18548,6 +19453,7 @@ ${RESPONSE_TARGET_HINT}`);
18548
19453
  outcome: "written",
18549
19454
  stdin_write_attempted: true
18550
19455
  });
19456
+ this.closeActivationTransition(ap, "advanced", "stdin");
18551
19457
  return true;
18552
19458
  }
18553
19459
  /** List ONE level of a directory — directories returned without children (lazy-loaded on demand) */
@@ -18964,7 +19870,7 @@ var ReminderCache = class {
18964
19870
  };
18965
19871
 
18966
19872
  // src/machineLock.ts
18967
- import { createHash as createHash4, randomUUID as randomUUID6 } from "crypto";
19873
+ import { createHash as createHash4, randomUUID as randomUUID7 } from "crypto";
18968
19874
  import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
18969
19875
  import os7 from "os";
18970
19876
  import path15 from "path";
@@ -19021,7 +19927,7 @@ function acquireDaemonMachineLock(options) {
19021
19927
  const lockId = getDaemonMachineLockId(options.apiKey);
19022
19928
  const machineDir = path15.join(rootDir, lockId);
19023
19929
  const lockDir = path15.join(machineDir, "daemon.lock");
19024
- const token = randomUUID6();
19930
+ const token = randomUUID7();
19025
19931
  mkdirSync5(machineDir, { recursive: true });
19026
19932
  for (let attempt = 0; attempt < 2; attempt += 1) {
19027
19933
  try {
@@ -19101,7 +20007,8 @@ var DIAGNOSTIC_ID_ATTRS = /* @__PURE__ */ new Set([
19101
20007
  "machine_id",
19102
20008
  "process_instance_id",
19103
20009
  "launch_id",
19104
- "correlation_id"
20010
+ "correlation_id",
20011
+ "migration_attempt_id"
19105
20012
  ]);
19106
20013
  var DIAGNOSTIC_ERROR_ATTRS = /* @__PURE__ */ new Set([
19107
20014
  "runtime_error_class",
@@ -19343,7 +20250,7 @@ function createTraceClient(options) {
19343
20250
  }
19344
20251
 
19345
20252
  // src/traceBundleUpload.ts
19346
- import { createHash as createHash6, randomUUID as randomUUID7 } from "crypto";
20253
+ import { createHash as createHash6, randomUUID as randomUUID8 } from "crypto";
19347
20254
  import { gzipSync as gzipSync2 } from "zlib";
19348
20255
  import { mkdir as mkdir2, readFile as readFile2, readdir as readdir3, stat as stat3, writeFile as writeFile2 } from "fs/promises";
19349
20256
  import path17 from "path";
@@ -19474,7 +20381,7 @@ var DaemonTraceBundleUploader = class {
19474
20381
  }
19475
20382
  const gzipped = gzipSync2(raw);
19476
20383
  const bundleSha256 = sha256Hex(gzipped);
19477
- const bundleId = randomUUID7();
20384
+ const bundleId = randomUUID8();
19478
20385
  await uploadWithSignedCapability({
19479
20386
  serverUrl: this.options.serverUrl,
19480
20387
  apiKey: this.options.apiKey,
@@ -19552,6 +20459,66 @@ function readPositiveIntegerEnv2(name, fallback) {
19552
20459
  return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
19553
20460
  }
19554
20461
 
20462
+ // src/computerMigrationGuard.ts
20463
+ import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync8 } from "fs";
20464
+ import path18 from "path";
20465
+ var LegacyDaemonKeyAdoptedByComputerError = class extends Error {
20466
+ code = "LEGACY_DAEMON_KEY_ADOPTED_BY_COMPUTER";
20467
+ attachmentPath;
20468
+ serverId;
20469
+ constructor(match) {
20470
+ const serverDisplay = match.serverSlug ? `/${match.serverSlug}` : match.serverId;
20471
+ const startCommand = match.serverSlug ? `raft-computer start /${match.serverSlug}` : "raft-computer start";
20472
+ super(
20473
+ `This legacy daemon key was already adopted by Raft Computer for ${serverDisplay}. Start the Computer supervisor instead: ${startCommand}. Legacy daemon startup is blocked to avoid relaunching a migrated machine key.`
20474
+ );
20475
+ this.name = "LegacyDaemonKeyAdoptedByComputerError";
20476
+ this.attachmentPath = match.attachmentPath;
20477
+ this.serverId = match.serverId;
20478
+ }
20479
+ };
20480
+ function daemonApiKeyFingerprint(apiKey) {
20481
+ return getDaemonMachineLockId(apiKey).slice("machine-".length);
20482
+ }
20483
+ function findAdoptedComputerForLegacyFingerprint(slockHome, legacyApiKeyFingerprint) {
20484
+ const serversDir = path18.join(slockHome, "computer", "servers");
20485
+ if (!existsSync9(serversDir)) return null;
20486
+ let serverDirs;
20487
+ try {
20488
+ serverDirs = readdirSync6(serversDir);
20489
+ } catch {
20490
+ return null;
20491
+ }
20492
+ for (const serverId of serverDirs) {
20493
+ const attachmentPath = path18.join(serversDir, serverId, "runner.state.json");
20494
+ let raw;
20495
+ try {
20496
+ raw = readFileSync8(attachmentPath, "utf8");
20497
+ } catch {
20498
+ continue;
20499
+ }
20500
+ try {
20501
+ const attachment = JSON.parse(raw);
20502
+ if (attachment.kind === "computer-attachment" && attachment.adoptedFromLegacy === true && attachment.legacyApiKeyFingerprint === legacyApiKeyFingerprint) {
20503
+ return {
20504
+ attachmentPath,
20505
+ serverId: typeof attachment.serverId === "string" && attachment.serverId.length > 0 ? attachment.serverId : serverId,
20506
+ serverSlug: typeof attachment.serverSlug === "string" && attachment.serverSlug.length > 0 ? attachment.serverSlug : void 0,
20507
+ serverMachineId: typeof attachment.serverMachineId === "string" && attachment.serverMachineId.length > 0 ? attachment.serverMachineId : void 0
20508
+ };
20509
+ }
20510
+ } catch {
20511
+ continue;
20512
+ }
20513
+ }
20514
+ return null;
20515
+ }
20516
+ function assertLegacyDaemonKeyNotAdoptedByComputer(options) {
20517
+ const legacyApiKeyFingerprint = daemonApiKeyFingerprint(options.apiKey);
20518
+ const match = findAdoptedComputerForLegacyFingerprint(options.slockHome, legacyApiKeyFingerprint);
20519
+ if (match) throw new LegacyDaemonKeyAdoptedByComputerError(match);
20520
+ }
20521
+
19555
20522
  // src/core.ts
19556
20523
  var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
19557
20524
  var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
@@ -19576,6 +20543,34 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
19576
20543
  "daemon.agent.spawn.failed": {
19577
20544
  spanAttrs: ["agentId", "launchId", "runtime", "model", "failure_reason", "failure_detail", "session_id_present"]
19578
20545
  },
20546
+ "launch_residency_transition": {
20547
+ spanAttrs: [
20548
+ "span_name",
20549
+ "phase",
20550
+ "agent_launch_id",
20551
+ "agent_id",
20552
+ "server_id",
20553
+ "machine_id",
20554
+ "runtime",
20555
+ "driver",
20556
+ "launch_source",
20557
+ "state_instance_id",
20558
+ "residency_state_instance_id",
20559
+ "transition_seq",
20560
+ "residency_transition_seq",
20561
+ "transition_kind",
20562
+ "phase_result",
20563
+ "close_result",
20564
+ "state",
20565
+ "residency",
20566
+ "agent_launch_id_present",
20567
+ "is_wait_state",
20568
+ "fence_kind",
20569
+ "deadline_unix_ms",
20570
+ "failure_kind",
20571
+ "negative_evidence_bucket"
20572
+ ]
20573
+ },
19579
20574
  "daemon.agent.delivery": {
19580
20575
  spanAttrs: ["agentId", "deliveryId", "delivery_correlation_id", "messageId", "message_id_present", "seq"],
19581
20576
  eventAttrs: {
@@ -19640,7 +20635,7 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
19640
20635
  spanAttrs: ["agentId", "event_kind", "runtime"]
19641
20636
  }
19642
20637
  };
19643
- var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
20638
+ var DAEMON_CLI_USAGE = `Usage: slock-daemon --server-url <url> (--api-key <key> or ${DAEMON_API_KEY_ENV}=<key>)`;
19644
20639
  var RunnerCredentialMintError2 = class extends Error {
19645
20640
  code;
19646
20641
  retryable;
@@ -19676,9 +20671,9 @@ function runnerCredentialErrorDetail2(error) {
19676
20671
  async function waitForRunnerCredentialRetry2() {
19677
20672
  await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
19678
20673
  }
19679
- function parseDaemonCliArgs(args) {
20674
+ function parseDaemonCliArgs(args, env = {}) {
19680
20675
  let serverUrl = "";
19681
- let apiKey = "";
20676
+ let apiKey = env[DAEMON_API_KEY_ENV] ?? "";
19682
20677
  for (let i = 0; i < args.length; i++) {
19683
20678
  if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
19684
20679
  if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
@@ -19695,13 +20690,13 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
19695
20690
  }
19696
20691
  }
19697
20692
  function resolveSlockCliPath(moduleUrl = import.meta.url) {
19698
- const thisDir = path18.dirname(fileURLToPath(moduleUrl));
19699
- const bundledDistPath = path18.resolve(thisDir, "cli", "index.js");
20693
+ const thisDir = path19.dirname(fileURLToPath(moduleUrl));
20694
+ const bundledDistPath = path19.resolve(thisDir, "cli", "index.js");
19700
20695
  try {
19701
20696
  accessSync(bundledDistPath);
19702
20697
  return bundledDistPath;
19703
20698
  } catch {
19704
- const workspaceDistPath = path18.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
20699
+ const workspaceDistPath = path19.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
19705
20700
  accessSync(workspaceDistPath);
19706
20701
  return workspaceDistPath;
19707
20702
  }
@@ -19715,7 +20710,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
19715
20710
  }
19716
20711
  async function runBundledSlockCli(argv) {
19717
20712
  process.argv = [process.execPath, "slock", ...argv];
19718
- await import("./dist-OGRAMTIO.js");
20713
+ await import("./dist-7Y7CP5NK.js");
19719
20714
  }
19720
20715
  function detectRuntimes(tracer = noopTracer) {
19721
20716
  const ids = [];
@@ -19923,7 +20918,7 @@ var DaemonCore = class {
19923
20918
  }
19924
20919
  resolveMachineStateRoot() {
19925
20920
  if (this.options.machineStateDir) return this.options.machineStateDir;
19926
- if (this.options.dataDir) return path18.join(path18.dirname(this.options.dataDir), "machines");
20921
+ if (this.options.dataDir) return path19.join(path19.dirname(this.options.dataDir), "machines");
19927
20922
  return resolveDefaultMachineStateRoot();
19928
20923
  }
19929
20924
  shouldEnableLocalTrace() {
@@ -19951,7 +20946,7 @@ var DaemonCore = class {
19951
20946
  sinks: [this.localTraceSink]
19952
20947
  }));
19953
20948
  this.agentManager.setTracer(this.tracer);
19954
- this.agentManager.setCliTransportTraceDir(path18.join(machineDir, "traces"));
20949
+ this.agentManager.setCliTransportTraceDir(path19.join(machineDir, "traces"));
19955
20950
  }
19956
20951
  installTraceBundleUploader(machineDir) {
19957
20952
  if (!this.shouldEnableLocalTrace()) return;
@@ -19977,6 +20972,10 @@ var DaemonCore = class {
19977
20972
  `[Slock Daemon] Legacy Slock state exists outside ${SLOCK_HOME_ENV}: ${legacy.path}. This daemon will use ${legacy.destination}; migrate manually if that ${legacy.description} should move with this installation.`
19978
20973
  );
19979
20974
  }
20975
+ assertLegacyDaemonKeyNotAdoptedByComputer({
20976
+ slockHome: this.slockHome,
20977
+ apiKey: this.options.apiKey
20978
+ });
19980
20979
  if (!this.machineLock) {
19981
20980
  this.machineLock = acquireDaemonMachineLock({
19982
20981
  apiKey: this.options.apiKey,
@@ -20652,6 +21651,8 @@ var DaemonCore = class {
20652
21651
 
20653
21652
  export {
20654
21653
  subscribeDaemonLogs,
21654
+ DAEMON_API_KEY_ENV,
21655
+ scrubDaemonAuthEnv,
20655
21656
  resolveWorkspaceDirectoryPath,
20656
21657
  scanWorkspaceDirectories,
20657
21658
  deleteWorkspaceDirectory,