@botiverse/raft-daemon 0.66.0 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-EX73HXGE.js → chunk-RXK2KSYW.js} +1616 -757
- package/dist/cli/index.js +456 -359
- package/dist/core.js +1 -1
- package/dist/{dist-PCKZII47.js → dist-Y3VRAU5E.js} +456 -359
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/core.ts
|
|
2
|
-
import
|
|
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.
|
|
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-
|
|
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
|
|
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.
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
127
|
-
{ id: "openrouter/anthropic/claude-sonnet-
|
|
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/
|
|
130
|
-
{ id: "openrouter/
|
|
131
|
-
{ id: "openrouter/
|
|
132
|
-
{ id: "openrouter/
|
|
133
|
-
{ id: "openrouter/
|
|
134
|
-
{ id: "openrouter/
|
|
135
|
-
{ id: "openrouter/
|
|
136
|
-
{ id: "openrouter/
|
|
137
|
-
{ id: "openrouter/
|
|
138
|
-
{ id: "openrouter/
|
|
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/
|
|
158
|
-
{ id: "openrouter/
|
|
159
|
-
{ id: "openrouter/
|
|
160
|
-
{ id: "openrouter/
|
|
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/
|
|
164
|
-
{ id: "openrouter/
|
|
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" },
|
|
180
|
+
{ id: "openrouter/mistralai/devstral-2512", label: "Mistral: Devstral 2 2512" },
|
|
181
|
+
{ id: "openrouter/mistralai/ministral-14b-2512", label: "Mistral: Ministral 3 14B 2512" },
|
|
182
|
+
{ id: "openrouter/mistralai/ministral-3b-2512", label: "Mistral: Ministral 3 3B 2512" },
|
|
183
|
+
{ id: "openrouter/mistralai/ministral-8b-2512", label: "Mistral: Ministral 3 8B 2512" },
|
|
184
|
+
{ id: "openrouter/mistralai/codestral-2508", label: "Mistral: Codestral 2508" },
|
|
185
|
+
{ id: "openrouter/mistralai/voxtral-small-24b-2507", label: "Mistral: Voxtral Small 24B 2507" },
|
|
186
|
+
{ id: "openrouter/qwen/qwen3-235b-a22b-2507", label: "Qwen: Qwen3 235B A22B Instruct 2507" },
|
|
187
|
+
{ id: "openrouter/qwen/qwen3-30b-a3b-instruct-2507", label: "Qwen: Qwen3 30B A3B Instruct 2507" },
|
|
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" },
|
|
196
|
+
{ id: "openrouter/qwen/qwen3-coder:free", label: "Qwen: Qwen3 Coder 480B A35B (free)" },
|
|
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" },
|
|
200
|
+
{ id: "openrouter/qwen/qwen3-vl-235b-a22b-instruct", label: "Qwen: Qwen3 VL 235B A22B Instruct" },
|
|
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" },
|
|
209
|
+
{ id: "openrouter/qwen/qwen3-vl-32b-instruct", label: "Qwen: Qwen3 VL 32B Instruct" },
|
|
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)" },
|
|
165
215
|
{ id: "openrouter/google/gemma-3-27b-it", label: "Google: Gemma 3 27B" },
|
|
216
|
+
{ id: "openrouter/qwen/qwen3.6-27b", label: "Qwen: Qwen3.6 27B" },
|
|
166
217
|
{ id: "openrouter/google/gemma-4-26b-a4b-it", label: "Google: Gemma 4 26B A4B " },
|
|
167
|
-
{ id: "openrouter/
|
|
168
|
-
{ id: "openrouter/
|
|
169
|
-
{ id: "openrouter/
|
|
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" },
|
|
224
|
+
{ id: "openrouter/thedrummer/unslopnemo-12b", label: "TheDrummer: UnslopNemo 12B" },
|
|
225
|
+
{ id: "openrouter/qwen/qwen3.5-122b-a10b", label: "Qwen: Qwen3.5-122B-A10B" },
|
|
170
226
|
{ 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
227
|
{ id: "openrouter/meta-llama/llama-3.1-8b-instruct", label: "Meta: Llama 3.1 8B Instruct" },
|
|
179
|
-
{ id: "openrouter/
|
|
180
|
-
{ id: "openrouter/
|
|
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" },
|
|
242
|
+
{ id: "openrouter/x-ai/grok-4.20", label: "xAI: Grok 4.20" },
|
|
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" },
|
|
246
|
+
{ id: "openrouter/z-ai/glm-4.5", label: "Z.ai: GLM 4.5" },
|
|
247
|
+
{ id: "openrouter/z-ai/glm-4.5-air", label: "Z.ai: GLM 4.5 Air" },
|
|
248
|
+
{ id: "openrouter/z-ai/glm-4.5v", label: "Z.ai: GLM 4.5V" },
|
|
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" },
|
|
181
251
|
{ id: "openrouter/meta-llama/llama-4-maverick", label: "Meta: Llama 4 Maverick" },
|
|
182
252
|
{ id: "openrouter/meta-llama/llama-4-scout", label: "Meta: Llama 4 Scout" },
|
|
183
|
-
{ id: "openrouter/
|
|
184
|
-
{ id: "openrouter/
|
|
185
|
-
{ id: "openrouter/
|
|
186
|
-
{ id: "openrouter/
|
|
187
|
-
{ id: "openrouter/
|
|
188
|
-
{ id: "openrouter/
|
|
189
|
-
{ id: "openrouter/
|
|
190
|
-
{ id: "openrouter/mistralai/devstral-2512", label: "Mistral: Devstral 2 2512" },
|
|
191
|
-
{ id: "openrouter/mistralai/ministral-14b-2512", label: "Mistral: Ministral 3 14B 2512" },
|
|
192
|
-
{ id: "openrouter/mistralai/ministral-3b-2512", label: "Mistral: Ministral 3 3B 2512" },
|
|
193
|
-
{ id: "openrouter/mistralai/ministral-8b-2512", label: "Mistral: Ministral 3 8B 2512" },
|
|
194
|
-
{ id: "openrouter/mistralai/mistral-large", label: "Mistral Large" },
|
|
195
|
-
{ id: "openrouter/mistralai/mistral-large-2407", label: "Mistral Large 2407" },
|
|
196
|
-
{ id: "openrouter/mistralai/mistral-large-2512", label: "Mistral: Mistral Large 3 2512" },
|
|
197
|
-
{ id: "openrouter/mistralai/mistral-medium-3", label: "Mistral: Mistral Medium 3" },
|
|
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" },
|
|
198
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" },
|
|
199
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" },
|
|
200
291
|
{ id: "openrouter/mistralai/mistral-nemo", label: "Mistral: Mistral Nemo" },
|
|
201
292
|
{ id: "openrouter/mistralai/mistral-saba", label: "Mistral: Saba" },
|
|
202
|
-
{ id: "openrouter/
|
|
203
|
-
{ id: "openrouter/
|
|
204
|
-
{ id: "openrouter/
|
|
205
|
-
{ id: "openrouter/
|
|
206
|
-
{ id: "openrouter/
|
|
207
|
-
{ id: "openrouter/
|
|
208
|
-
{ id: "openrouter/
|
|
209
|
-
{ id: "openrouter/
|
|
210
|
-
{ id: "openrouter/
|
|
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" },
|
|
293
|
+
{ id: "openrouter/~moonshotai/kimi-latest", label: "MoonshotAI Kimi Latest" },
|
|
294
|
+
{ id: "openrouter/~openai/gpt-latest", label: "OpenAI GPT 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)" },
|
|
223
302
|
{ id: "openrouter/openai/gpt-3.5-turbo-0613", label: "OpenAI: GPT-3.5 Turbo (older v0613)" },
|
|
224
303
|
{ id: "openrouter/openai/gpt-3.5-turbo-16k", label: "OpenAI: GPT-3.5 Turbo 16k" },
|
|
225
|
-
{ id: "openrouter/
|
|
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" },
|
|
226
308
|
{ id: "openrouter/openai/gpt-4-turbo", label: "OpenAI: GPT-4 Turbo" },
|
|
227
309
|
{ id: "openrouter/openai/gpt-4-turbo-preview", label: "OpenAI: GPT-4 Turbo Preview" },
|
|
228
|
-
{ id: "openrouter/
|
|
229
|
-
{ id: "openrouter/
|
|
230
|
-
{ id: "openrouter/
|
|
231
|
-
{ id: "openrouter/openai/gpt-
|
|
232
|
-
{ id: "openrouter/
|
|
233
|
-
{ id: "openrouter/
|
|
234
|
-
{ id: "openrouter/
|
|
235
|
-
{ id: "openrouter/
|
|
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)" },
|
|
236
322
|
{ id: "openrouter/openai/gpt-4o-mini-2024-07-18", label: "OpenAI: GPT-4o-mini (2024-07-18)" },
|
|
237
|
-
{ id: "openrouter/
|
|
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" },
|
|
323
|
+
{ id: "openrouter/nvidia/nemotron-3-nano-30b-a3b", label: "NVIDIA: Nemotron 3 Nano 30B A3B" },
|
|
254
324
|
{ id: "openrouter/openai/gpt-5.4-mini", label: "OpenAI: GPT-5.4 Mini" },
|
|
255
325
|
{ id: "openrouter/openai/gpt-5.4-nano", label: "OpenAI: GPT-5.4 Nano" },
|
|
256
|
-
{ id: "openrouter/openai/gpt-5
|
|
257
|
-
{ id: "openrouter/openai/gpt-5
|
|
258
|
-
{ id: "openrouter/openai/gpt-
|
|
259
|
-
{ id: "openrouter/openai/gpt-
|
|
260
|
-
{ id: "openrouter/openai/gpt-
|
|
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" },
|
|
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" },
|
|
273
331
|
{ id: "openrouter/openai/o4-mini", label: "OpenAI: o4 Mini" },
|
|
274
332
|
{ id: "openrouter/openai/o4-mini-deep-research", label: "OpenAI: o4 Mini Deep Research" },
|
|
275
333
|
{ id: "openrouter/openai/o4-mini-high", label: "OpenAI: o4 Mini High" },
|
|
276
|
-
{ id: "openrouter/
|
|
277
|
-
{ id: "openrouter/
|
|
278
|
-
{ id: "openrouter/
|
|
279
|
-
{ id: "openrouter/
|
|
280
|
-
{ id: "openrouter/
|
|
281
|
-
{ id: "openrouter/
|
|
282
|
-
{ id: "openrouter/
|
|
283
|
-
{ id: "openrouter/
|
|
284
|
-
{ id: "openrouter/
|
|
285
|
-
{ id: "openrouter/
|
|
286
|
-
{ id: "openrouter/
|
|
287
|
-
{ id: "openrouter/
|
|
288
|
-
{ id: "openrouter/qwen/qwen-plus-2025-07-28", label: "Qwen: Qwen Plus 0728" },
|
|
289
|
-
{ id: "openrouter/qwen/qwen-plus-2025-07-28:thinking", label: "Qwen: Qwen Plus 0728 (thinking)" },
|
|
290
|
-
{ id: "openrouter/qwen/qwen3-14b", label: "Qwen: Qwen3 14B" },
|
|
291
|
-
{ id: "openrouter/qwen/qwen3-235b-a22b", label: "Qwen: Qwen3 235B A22B" },
|
|
292
|
-
{ id: "openrouter/qwen/qwen3-235b-a22b-2507", label: "Qwen: Qwen3 235B A22B Instruct 2507" },
|
|
293
|
-
{ id: "openrouter/qwen/qwen3-235b-a22b-thinking-2507", label: "Qwen: Qwen3 235B A22B Thinking 2507" },
|
|
294
|
-
{ id: "openrouter/qwen/qwen3-30b-a3b", label: "Qwen: Qwen3 30B A3B" },
|
|
295
|
-
{ id: "openrouter/qwen/qwen3-30b-a3b-instruct-2507", label: "Qwen: Qwen3 30B A3B Instruct 2507" },
|
|
296
|
-
{ id: "openrouter/qwen/qwen3-30b-a3b-thinking-2507", label: "Qwen: Qwen3 30B A3B Thinking 2507" },
|
|
297
|
-
{ id: "openrouter/qwen/qwen3-32b", label: "Qwen: Qwen3 32B" },
|
|
298
|
-
{ id: "openrouter/qwen/qwen3-8b", label: "Qwen: Qwen3 8B" },
|
|
299
|
-
{ id: "openrouter/qwen/qwen3-coder", label: "Qwen: Qwen3 Coder 480B A35B" },
|
|
300
|
-
{ id: "openrouter/qwen/qwen3-coder-30b-a3b-instruct", label: "Qwen: Qwen3 Coder 30B A3B Instruct" },
|
|
301
|
-
{ id: "openrouter/qwen/qwen3-coder-flash", label: "Qwen: Qwen3 Coder Flash" },
|
|
302
|
-
{ id: "openrouter/qwen/qwen3-coder-next", label: "Qwen: Qwen3 Coder Next" },
|
|
303
|
-
{ id: "openrouter/qwen/qwen3-coder-plus", label: "Qwen: Qwen3 Coder Plus" },
|
|
304
|
-
{ id: "openrouter/qwen/qwen3-coder:free", label: "Qwen: Qwen3 Coder 480B A35B (free)" },
|
|
305
|
-
{ id: "openrouter/qwen/qwen3-max", label: "Qwen: Qwen3 Max" },
|
|
306
|
-
{ id: "openrouter/qwen/qwen3-max-thinking", label: "Qwen: Qwen3 Max Thinking" },
|
|
307
|
-
{ id: "openrouter/qwen/qwen3-next-80b-a3b-instruct", label: "Qwen: Qwen3 Next 80B A3B Instruct" },
|
|
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)" },
|
|
308
346
|
{ id: "openrouter/qwen/qwen3-next-80b-a3b-instruct:free", label: "Qwen: Qwen3 Next 80B A3B Instruct (free)" },
|
|
309
|
-
{ id: "openrouter/
|
|
310
|
-
{ id: "openrouter/
|
|
311
|
-
{ id: "openrouter/
|
|
312
|
-
{ id: "openrouter/
|
|
313
|
-
{ id: "openrouter/
|
|
314
|
-
{ id: "openrouter/
|
|
315
|
-
{ id: "openrouter/
|
|
316
|
-
{ id: "openrouter/
|
|
317
|
-
{ id: "openrouter/
|
|
318
|
-
{ id: "openrouter/
|
|
319
|
-
{ id: "openrouter/
|
|
320
|
-
{ id: "openrouter/
|
|
321
|
-
{ id: "openrouter/
|
|
322
|
-
{ id: "openrouter/
|
|
323
|
-
{ id: "openrouter/
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
{ id: "openrouter/qwen/qwen3.6-35b-a3b", label: "Qwen: Qwen3.6 35B A3B" },
|
|
327
|
-
{ id: "openrouter/qwen/qwen3.6-flash", label: "Qwen: Qwen3.6 Flash" },
|
|
328
|
-
{ id: "openrouter/qwen/qwen3.6-max-preview", label: "Qwen: Qwen3.6 Max Preview" },
|
|
329
|
-
{ id: "openrouter/qwen/qwen3.6-plus", label: "Qwen: Qwen3.6 Plus" },
|
|
330
|
-
{ id: "openrouter/qwen/qwen3.7-max", label: "Qwen: Qwen3.7 Max" },
|
|
331
|
-
{ id: "openrouter/qwen/qwen3.7-plus", label: "Qwen: Qwen3.7 Plus" },
|
|
332
|
-
{ id: "openrouter/rekaai/reka-edge", label: "Reka Edge" },
|
|
333
|
-
{ id: "openrouter/relace/relace-search", label: "Relace: Relace Search" },
|
|
334
|
-
{ id: "openrouter/sao10k/l3.1-euryale-70b", label: "Sao10K: Llama 3.1 Euryale 70B v2.2" },
|
|
335
|
-
{ id: "openrouter/stepfun/step-3.5-flash", label: "StepFun: Step 3.5 Flash" },
|
|
336
|
-
{ id: "openrouter/stepfun/step-3.7-flash", label: "StepFun: Step 3.7 Flash" },
|
|
337
|
-
{ id: "openrouter/tencent/hy3-preview", label: "Tencent: Hy3 preview" },
|
|
338
|
-
{ id: "openrouter/thedrummer/rocinante-12b", label: "TheDrummer: Rocinante 12B" },
|
|
339
|
-
{ id: "openrouter/thedrummer/unslopnemo-12b", label: "TheDrummer: UnslopNemo 12B" },
|
|
340
|
-
{ id: "openrouter/upstage/solar-pro-3", label: "Upstage: Solar Pro 3" },
|
|
341
|
-
{ id: "openrouter/x-ai/grok-4.20", label: "xAI: Grok 4.20" },
|
|
342
|
-
{ id: "openrouter/x-ai/grok-4.3", label: "xAI: Grok 4.3" },
|
|
343
|
-
{ id: "openrouter/x-ai/grok-build-0.1", label: "xAI: Grok Build 0.1" },
|
|
344
|
-
{ id: "openrouter/xiaomi/mimo-v2.5", label: "Xiaomi: MiMo-V2.5" },
|
|
345
|
-
{ id: "openrouter/xiaomi/mimo-v2.5-pro", label: "Xiaomi: MiMo-V2.5-Pro" },
|
|
346
|
-
{ id: "openrouter/z-ai/glm-4.5", label: "Z.ai: GLM 4.5" },
|
|
347
|
-
{ id: "openrouter/z-ai/glm-4.5-air", label: "Z.ai: GLM 4.5 Air" },
|
|
348
|
-
{ id: "openrouter/z-ai/glm-4.5v", label: "Z.ai: GLM 4.5V" },
|
|
349
|
-
{ id: "openrouter/z-ai/glm-4.6", label: "Z.ai: GLM 4.6" },
|
|
350
|
-
{ id: "openrouter/z-ai/glm-4.6v", label: "Z.ai: GLM 4.6V" },
|
|
351
|
-
{ id: "openrouter/z-ai/glm-4.7", label: "Z.ai: GLM 4.7" },
|
|
352
|
-
{ id: "openrouter/z-ai/glm-4.7-flash", label: "Z.ai: GLM 4.7 Flash" },
|
|
353
|
-
{ id: "openrouter/z-ai/glm-5", label: "Z.ai: GLM 5" },
|
|
354
|
-
{ id: "openrouter/z-ai/glm-5-turbo", label: "Z.ai: GLM 5 Turbo" },
|
|
355
|
-
{ id: "openrouter/z-ai/glm-5.1", label: "Z.ai: GLM 5.1" },
|
|
356
|
-
{ id: "openrouter/z-ai/glm-5.2", label: "Z.ai: GLM 5.2" },
|
|
357
|
-
{ id: "openrouter/~anthropic/claude-fable-latest", label: "Anthropic: Claude Fable Latest" },
|
|
358
|
-
{ id: "openrouter/~anthropic/claude-haiku-latest", label: "Anthropic Claude Haiku Latest" },
|
|
359
|
-
{ id: "openrouter/~anthropic/claude-opus-latest", label: "Anthropic: Claude Opus Latest" },
|
|
360
|
-
{ id: "openrouter/~anthropic/claude-sonnet-latest", label: "Anthropic Claude Sonnet Latest" },
|
|
361
|
-
{ id: "openrouter/~google/gemini-flash-latest", label: "Google Gemini Flash Latest" },
|
|
362
|
-
{ id: "openrouter/~google/gemini-pro-latest", label: "Google Gemini Pro Latest" },
|
|
363
|
-
{ id: "openrouter/~moonshotai/kimi-latest", label: "MoonshotAI Kimi Latest" },
|
|
364
|
-
{ id: "openrouter/~openai/gpt-latest", label: "OpenAI GPT Latest" },
|
|
365
|
-
{ id: "openrouter/~openai/gpt-mini-latest", label: "OpenAI GPT Mini Latest" }
|
|
366
|
-
],
|
|
367
|
-
"openai": [
|
|
368
|
-
{ id: "openai/gpt-5.4", label: "GPT-5.4" },
|
|
369
|
-
{ id: "openai/gpt-4", label: "GPT-4" },
|
|
370
|
-
{ id: "openai/gpt-4-turbo", label: "GPT-4 Turbo" },
|
|
371
|
-
{ id: "openai/gpt-4.1", label: "GPT-4.1" },
|
|
372
|
-
{ id: "openai/gpt-4.1-mini", label: "GPT-4.1 mini" },
|
|
373
|
-
{ id: "openai/gpt-4.1-nano", label: "GPT-4.1 nano" },
|
|
374
|
-
{ id: "openai/gpt-4o", label: "GPT-4o" },
|
|
375
|
-
{ id: "openai/gpt-4o-2024-05-13", label: "GPT-4o (2024-05-13)" },
|
|
376
|
-
{ id: "openai/gpt-4o-2024-08-06", label: "GPT-4o (2024-08-06)" },
|
|
377
|
-
{ id: "openai/gpt-4o-2024-11-20", label: "GPT-4o (2024-11-20)" },
|
|
378
|
-
{ id: "openai/gpt-4o-mini", label: "GPT-4o mini" },
|
|
379
|
-
{ id: "openai/gpt-5", label: "GPT-5" },
|
|
380
|
-
{ id: "openai/gpt-5-chat-latest", label: "GPT-5 Chat Latest" },
|
|
381
|
-
{ id: "openai/gpt-5-codex", label: "GPT-5-Codex" },
|
|
382
|
-
{ id: "openai/gpt-5-mini", label: "GPT-5 Mini" },
|
|
383
|
-
{ id: "openai/gpt-5-nano", label: "GPT-5 Nano" },
|
|
384
|
-
{ id: "openai/gpt-5-pro", label: "GPT-5 Pro" },
|
|
385
|
-
{ id: "openai/gpt-5.1", label: "GPT-5.1" },
|
|
386
|
-
{ id: "openai/gpt-5.1-chat-latest", label: "GPT-5.1 Chat" },
|
|
387
|
-
{ id: "openai/gpt-5.1-codex", label: "GPT-5.1 Codex" },
|
|
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)" }
|
|
362
|
+
],
|
|
363
|
+
"openai": [
|
|
388
364
|
{ id: "openai/gpt-5.1-codex-max", label: "GPT-5.1 Codex Max" },
|
|
389
|
-
{ id: "openai/gpt-5.
|
|
390
|
-
{ id: "openai/gpt-5.
|
|
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
|
|
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.
|
|
398
|
-
{ id: "openai/gpt-5.
|
|
399
|
-
{ id: "openai/gpt-5
|
|
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.
|
|
402
|
-
{ id: "openai/
|
|
403
|
-
{ id: "openai/
|
|
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/
|
|
407
|
-
{ id: "openai/
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
441
|
-
{ id: "google/gemini-
|
|
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-
|
|
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-
|
|
450
|
-
{ id: "google/gemini-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
|
@@ -823,7 +816,9 @@ function projectApmHeldFreshnessActivity(input) {
|
|
|
823
816
|
const statusEntry = {
|
|
824
817
|
kind: "status",
|
|
825
818
|
activity: "working",
|
|
819
|
+
activityKind: "working",
|
|
826
820
|
detail: title,
|
|
821
|
+
detailKind: "slock_action",
|
|
827
822
|
producerFactId: input.producerFactId
|
|
828
823
|
};
|
|
829
824
|
const entry = {
|
|
@@ -2165,6 +2160,9 @@ var agentApiServerInfoResponseSchema = passthroughObject({
|
|
|
2165
2160
|
})),
|
|
2166
2161
|
agents: z2.array(passthroughObject({
|
|
2167
2162
|
name: z2.string(),
|
|
2163
|
+
status: z2.string().optional(),
|
|
2164
|
+
activity: z2.string().nullable().optional(),
|
|
2165
|
+
activityDetail: z2.string().nullable().optional(),
|
|
2168
2166
|
role: z2.enum(["owner", "admin", "member"]).nullable().optional()
|
|
2169
2167
|
})),
|
|
2170
2168
|
humans: z2.array(passthroughObject({
|
|
@@ -3277,6 +3275,45 @@ var BUILTIN_RUNTIME_HOST_PROVIDER_ENV_SCRUB_KEYS = Array.from(/* @__PURE__ */ ne
|
|
|
3277
3275
|
var PI_BUILTIN_PROVIDER_MODELS = PI_BUILTIN_PROVIDER_MODELS_GENERATED;
|
|
3278
3276
|
var AGENT_ACTIVITIES = ["online", "thinking", "working", "error", "offline"];
|
|
3279
3277
|
var isAgentActivity = makeIsMember(AGENT_ACTIVITIES);
|
|
3278
|
+
var AGENT_ACTIVITY_DETAIL_KINDS = [
|
|
3279
|
+
"none",
|
|
3280
|
+
"message_received",
|
|
3281
|
+
"starting",
|
|
3282
|
+
"runtime_starting",
|
|
3283
|
+
"idle",
|
|
3284
|
+
"running_command",
|
|
3285
|
+
"checking_messages",
|
|
3286
|
+
"compacting_context",
|
|
3287
|
+
"compaction_finished",
|
|
3288
|
+
"compaction_stale",
|
|
3289
|
+
"reviewing_changes",
|
|
3290
|
+
"review_finished",
|
|
3291
|
+
"runtime_reconnecting",
|
|
3292
|
+
"runtime_error",
|
|
3293
|
+
"runtime_crashed",
|
|
3294
|
+
"runtime_unavailable",
|
|
3295
|
+
"runtime_stalled",
|
|
3296
|
+
"stalled_recovery",
|
|
3297
|
+
"stopped",
|
|
3298
|
+
"ready",
|
|
3299
|
+
"runtime_interrupted",
|
|
3300
|
+
"machine_disconnected",
|
|
3301
|
+
"daemon_activity",
|
|
3302
|
+
"external_activity",
|
|
3303
|
+
"synthetic_repair",
|
|
3304
|
+
"slock_action",
|
|
3305
|
+
"system_message",
|
|
3306
|
+
// Generic structured runtime-progress heartbeat (Claude --include-partial-messages
|
|
3307
|
+
// stream events / system status) — a "working" liveness signal with no rendered
|
|
3308
|
+
// content. NOT a subagent. (APM 1.6 6a)
|
|
3309
|
+
"runtime_progress",
|
|
3310
|
+
// A subagent (Claude `Agent` tool) lifecycle/activity row, marked from explicit
|
|
3311
|
+
// parent_tool_use_id / task-lifecycle lineage — never inferred from display text.
|
|
3312
|
+
// (APM 1.6 6b)
|
|
3313
|
+
"subagent_activity",
|
|
3314
|
+
"other"
|
|
3315
|
+
];
|
|
3316
|
+
var isAgentActivityDetailKind = makeIsMember(AGENT_ACTIVITY_DETAIL_KINDS);
|
|
3280
3317
|
var VALID_ACTIVITIES = new Set(AGENT_ACTIVITIES);
|
|
3281
3318
|
var EXTERNAL_AGENT_RUNTIME_ID = "external";
|
|
3282
3319
|
var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
|
|
@@ -3304,13 +3341,15 @@ var RUNTIME_MODELS = {
|
|
|
3304
3341
|
builtin: Object.values(PI_BUILTIN_PROVIDER_MODELS).flat().map((model) => ({ id: model.id, label: model.label || formatRuntimeProviderModelLabel(model.id), verified: "launchable" })),
|
|
3305
3342
|
claude: [
|
|
3306
3343
|
{ id: "opus", label: "Claude Opus" },
|
|
3344
|
+
{ id: "fable", label: "Claude Fable" },
|
|
3345
|
+
{ id: "sonnet", label: "Claude Sonnet" },
|
|
3346
|
+
{ id: "haiku", label: "Claude Haiku" },
|
|
3307
3347
|
{ id: "claude-opus-4-8", label: "Claude Opus 4.8" },
|
|
3308
3348
|
{ id: "claude-opus-4-7", label: "Claude Opus 4.7" },
|
|
3309
3349
|
{ id: "claude-opus-4-6", label: "Claude Opus 4.6" },
|
|
3310
|
-
{ id: "fable", label: "Claude Fable" },
|
|
3311
|
-
{ id: "sonnet", label: "Claude Sonnet" },
|
|
3350
|
+
{ id: "claude-fable-5", label: "Claude Fable 5" },
|
|
3351
|
+
{ id: "claude-sonnet-5", label: "Claude Sonnet 5" },
|
|
3312
3352
|
{ id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
|
|
3313
|
-
{ id: "haiku", label: "Claude Haiku" },
|
|
3314
3353
|
{ id: "claude-haiku-4-5", label: "Claude Haiku 4.5" }
|
|
3315
3354
|
],
|
|
3316
3355
|
codex: [
|
|
@@ -3978,8 +4017,8 @@ async function executeResponseRequest(url, init, {
|
|
|
3978
4017
|
}
|
|
3979
4018
|
|
|
3980
4019
|
// src/directUploadCapability.ts
|
|
3981
|
-
function joinUrl(base,
|
|
3982
|
-
return `${base.replace(/\/+$/, "")}${
|
|
4020
|
+
function joinUrl(base, path20) {
|
|
4021
|
+
return `${base.replace(/\/+$/, "")}${path20}`;
|
|
3983
4022
|
}
|
|
3984
4023
|
function jsonHeaders(apiKey) {
|
|
3985
4024
|
return {
|
|
@@ -5062,7 +5101,7 @@ function projectApmRuntimeProgressStalledTrace(input) {
|
|
|
5062
5101
|
}
|
|
5063
5102
|
function projectApmRuntimeStallDiagnostic(input) {
|
|
5064
5103
|
const context = [];
|
|
5065
|
-
const lastActivityDetailKind =
|
|
5104
|
+
const lastActivityDetailKind = input.lastActivityDetail ? input.lastActivityDetailKind : void 0;
|
|
5066
5105
|
if (input.lastActivityDetail) {
|
|
5067
5106
|
context.push(`after ${input.lastActivityDetail}`);
|
|
5068
5107
|
}
|
|
@@ -5094,7 +5133,7 @@ function projectApmRuntimeStallDiagnostic(input) {
|
|
|
5094
5133
|
traceAttrs: {
|
|
5095
5134
|
ageMs: input.staleForMs,
|
|
5096
5135
|
staleForMinutes: input.staleForMinutes,
|
|
5097
|
-
lastActivity: input.
|
|
5136
|
+
lastActivity: input.lastActivityKind,
|
|
5098
5137
|
lastActivityDetailPresent: Boolean(input.lastActivityDetail),
|
|
5099
5138
|
lastActivityDetailKind,
|
|
5100
5139
|
runtime: input.runtime,
|
|
@@ -5118,20 +5157,6 @@ function projectApmRuntimeStallDiagnostic(input) {
|
|
|
5118
5157
|
}
|
|
5119
5158
|
};
|
|
5120
5159
|
}
|
|
5121
|
-
function classifyApmRuntimeStallActivityDetail(detail) {
|
|
5122
|
-
if (!detail) return void 0;
|
|
5123
|
-
if (detail === "Message received") return "message_received";
|
|
5124
|
-
if (detail === "Starting\u2026") return "starting";
|
|
5125
|
-
if (detail === "Running command\u2026") return "running_command";
|
|
5126
|
-
if (detail === "Checking messages\u2026") return "checking_messages";
|
|
5127
|
-
if (detail === "Compacting context") return "compacting_context";
|
|
5128
|
-
if (detail === "Context compaction finished") return "compaction_finished";
|
|
5129
|
-
if (detail === "Context compaction still running; no finish event observed") return "compaction_stale";
|
|
5130
|
-
if (detail === "Idle" || detail === "Process idle") return "idle";
|
|
5131
|
-
if (detail.startsWith("Restarting stalled ") && detail.endsWith(" runtime for queued message")) return "stalled_recovery";
|
|
5132
|
-
if (detail.startsWith("Runtime stalled: no runtime events for ")) return "runtime_stalled";
|
|
5133
|
-
return "other";
|
|
5134
|
-
}
|
|
5135
5160
|
function reduceApmGatedFlushReadiness(state, input) {
|
|
5136
5161
|
if (!input.isGated) return { shouldNotify: false, blockedReason: "non_gated", effects: [] };
|
|
5137
5162
|
if (!input.hasSession) return { shouldNotify: false, blockedReason: "missing_session", effects: [] };
|
|
@@ -5858,27 +5883,44 @@ function writeProxyFailureResponse(res, failure) {
|
|
|
5858
5883
|
res.destroy();
|
|
5859
5884
|
return;
|
|
5860
5885
|
}
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
code: "agent_proxy_failed",
|
|
5886
|
+
const body = {
|
|
5887
|
+
error: failure.responseError ?? "failed to proxy local agent request",
|
|
5888
|
+
code: failure.responseCode ?? "agent_proxy_failed",
|
|
5865
5889
|
detail: failure.errorMessage
|
|
5866
|
-
}
|
|
5890
|
+
};
|
|
5891
|
+
if (failure.lifecycleInvalidAgentId) body.agent_id = failure.lifecycleInvalidAgentId;
|
|
5892
|
+
if (failure.lifecycleInvalidContext) body.invariant_context = failure.lifecycleInvalidContext;
|
|
5893
|
+
res.writeHead(failure.responseStatusCode ?? 502, { "content-type": "application/json" });
|
|
5894
|
+
res.end(JSON.stringify(body));
|
|
5867
5895
|
}
|
|
5868
5896
|
function proxyFailureForError(method, target, err) {
|
|
5869
5897
|
const queryKeys = target ? [.../* @__PURE__ */ new Set([...target.searchParams.keys()])].sort() : [];
|
|
5870
5898
|
const cause = err instanceof Error ? err.cause : void 0;
|
|
5899
|
+
const errorMessage = truncateProxyErrorMessage(err instanceof Error ? err.message : String(err));
|
|
5900
|
+
const lifecycleInvalid = parseAgentNoProcessResidencyInvariant(errorMessage);
|
|
5871
5901
|
const failure = {
|
|
5872
5902
|
method,
|
|
5873
5903
|
pathname: target?.pathname ?? "unknown",
|
|
5874
5904
|
queryKeys,
|
|
5875
5905
|
errorName: err instanceof Error ? err.name : typeof err,
|
|
5876
|
-
errorMessage
|
|
5906
|
+
errorMessage
|
|
5877
5907
|
};
|
|
5908
|
+
if (lifecycleInvalid) {
|
|
5909
|
+
failure.responseStatusCode = 409;
|
|
5910
|
+
failure.responseCode = "agent_lifecycle_state_invalid";
|
|
5911
|
+
failure.responseError = "local daemon agent lifecycle state invalid";
|
|
5912
|
+
failure.lifecycleInvalidAgentId = lifecycleInvalid.agentId;
|
|
5913
|
+
failure.lifecycleInvalidContext = lifecycleInvalid.context;
|
|
5914
|
+
}
|
|
5878
5915
|
const errorCause = describeProxyErrorCause(cause);
|
|
5879
5916
|
if (errorCause) failure.errorCause = errorCause;
|
|
5880
5917
|
return failure;
|
|
5881
5918
|
}
|
|
5919
|
+
function parseAgentNoProcessResidencyInvariant(message) {
|
|
5920
|
+
const match = /^Agent no-process residency invariant violation after ([^:]+): .+ for ([0-9a-f-]{36})\b/i.exec(message);
|
|
5921
|
+
if (!match) return void 0;
|
|
5922
|
+
return { context: match[1], agentId: match[2] };
|
|
5923
|
+
}
|
|
5882
5924
|
function describeProxyErrorCause(cause) {
|
|
5883
5925
|
if (!cause) return void 0;
|
|
5884
5926
|
if (cause instanceof Error) {
|
|
@@ -5915,18 +5957,21 @@ function transportNormalizedErrorForHttpStatus(target, status, launchId) {
|
|
|
5915
5957
|
};
|
|
5916
5958
|
}
|
|
5917
5959
|
function transportNormalizedErrorForError(target, err, launchId) {
|
|
5960
|
+
const localDaemonStateInvalid = parseAgentNoProcessResidencyInvariant(
|
|
5961
|
+
sanitizeTransportOriginalMessage(err instanceof Error ? err.message : String(err))
|
|
5962
|
+
);
|
|
5918
5963
|
return {
|
|
5919
|
-
normalizedCode: "transport_failure",
|
|
5964
|
+
normalizedCode: localDaemonStateInvalid ? "local_daemon_state_invalid" : "transport_failure",
|
|
5920
5965
|
routeFamily: routeFamilyForPath(target?.pathname ?? "unknown"),
|
|
5921
5966
|
responseStarted: false,
|
|
5922
|
-
upstreamLayer: target ? upstreamLayerForProxyError(err) : "unknown",
|
|
5967
|
+
upstreamLayer: localDaemonStateInvalid ? "unknown" : target ? upstreamLayerForProxyError(err) : "unknown",
|
|
5923
5968
|
originalMessage: sanitizeTransportOriginalMessage(err instanceof Error ? err.message : String(err)),
|
|
5924
5969
|
launchId,
|
|
5925
|
-
targetHostClass: target ? daemonUpstreamTargetHostClass(target) : "custom_server",
|
|
5970
|
+
targetHostClass: localDaemonStateInvalid ? "local_daemon" : target ? daemonUpstreamTargetHostClass(target) : "custom_server",
|
|
5926
5971
|
// Today the local credential proxy is only used by CLI wrappers. If runtime
|
|
5927
5972
|
// or daemon-internal callers use it later, plumb the caller identity here.
|
|
5928
5973
|
downstreamCaller: "cli",
|
|
5929
|
-
upstream: "server"
|
|
5974
|
+
upstream: localDaemonStateInvalid ? "local_daemon" : "server"
|
|
5930
5975
|
};
|
|
5931
5976
|
}
|
|
5932
5977
|
function routeFamilyForPath(pathname) {
|
|
@@ -6423,10 +6468,10 @@ function runtimeContextEnv(config) {
|
|
|
6423
6468
|
return {
|
|
6424
6469
|
...ctx.agentId ? { SLOCK_CURRENT_AGENT_ID: ctx.agentId } : {},
|
|
6425
6470
|
...ctx.serverId ? { SLOCK_CURRENT_SERVER_ID: ctx.serverId } : {},
|
|
6426
|
-
...ctx.machineId ? {
|
|
6427
|
-
...ctx.machineName ? {
|
|
6428
|
-
...ctx.machineHostname ? {
|
|
6429
|
-
...ctx.machineOs ? {
|
|
6471
|
+
...ctx.machineId ? { RAFT_CURRENT_COMPUTER_ID: ctx.machineId } : {},
|
|
6472
|
+
...ctx.machineName ? { RAFT_CURRENT_COMPUTER_NAME: ctx.machineName } : {},
|
|
6473
|
+
...ctx.machineHostname ? { RAFT_CURRENT_COMPUTER_HOSTNAME: ctx.machineHostname } : {},
|
|
6474
|
+
...ctx.machineOs ? { RAFT_CURRENT_COMPUTER_OS: ctx.machineOs } : {},
|
|
6430
6475
|
...ctx.daemonVersion ? { SLOCK_CURRENT_DAEMON_VERSION: ctx.daemonVersion } : {},
|
|
6431
6476
|
...ctx.workspacePath ? { SLOCK_CURRENT_WORKSPACE_PATH: ctx.workspacePath } : {}
|
|
6432
6477
|
};
|
|
@@ -6611,6 +6656,28 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
|
|
|
6611
6656
|
}
|
|
6612
6657
|
|
|
6613
6658
|
// src/drivers/claudeEventNormalizer.ts
|
|
6659
|
+
function extractSubagentLineage(event) {
|
|
6660
|
+
const parentToolUseId = finiteString(event.parent_tool_use_id);
|
|
6661
|
+
const subagentType = finiteString(event.subagent_type);
|
|
6662
|
+
if (!parentToolUseId && !subagentType) return void 0;
|
|
6663
|
+
return {
|
|
6664
|
+
...parentToolUseId ? { parentToolUseId } : {},
|
|
6665
|
+
...subagentType ? { subagentType } : {},
|
|
6666
|
+
phase: "active"
|
|
6667
|
+
};
|
|
6668
|
+
}
|
|
6669
|
+
function taskLifecyclePhase(subtype) {
|
|
6670
|
+
switch (subtype) {
|
|
6671
|
+
case "task_started":
|
|
6672
|
+
return "started";
|
|
6673
|
+
case "task_progress":
|
|
6674
|
+
return "progress";
|
|
6675
|
+
case "task_notification":
|
|
6676
|
+
return "notification";
|
|
6677
|
+
default:
|
|
6678
|
+
return null;
|
|
6679
|
+
}
|
|
6680
|
+
}
|
|
6614
6681
|
function collectResultErrorDetail(message, fallback) {
|
|
6615
6682
|
const parts = [];
|
|
6616
6683
|
if (Array.isArray(message.errors)) {
|
|
@@ -6784,6 +6851,25 @@ var ClaudeEventNormalizer = class {
|
|
|
6784
6851
|
if (event.subtype === "compact_boundary") {
|
|
6785
6852
|
events.push({ kind: "compaction_finished" });
|
|
6786
6853
|
}
|
|
6854
|
+
{
|
|
6855
|
+
const phase = typeof event.subtype === "string" ? taskLifecyclePhase(event.subtype) : null;
|
|
6856
|
+
if (phase) {
|
|
6857
|
+
events.push({
|
|
6858
|
+
kind: "subagent_progress",
|
|
6859
|
+
source: "claude_task_lifecycle",
|
|
6860
|
+
phase,
|
|
6861
|
+
...finiteString(event.task_id) ? { taskId: finiteString(event.task_id) } : {},
|
|
6862
|
+
// `system` task-lifecycle envelopes carry the outer Agent tool id
|
|
6863
|
+
// as `tool_use_id`; belt-and-suspenders fall back to
|
|
6864
|
+
// `parent_tool_use_id` in case a Claude version names it that way
|
|
6865
|
+
// on the envelope (confirmed field name = tool_use_id, @Huarong).
|
|
6866
|
+
...finiteString(event.tool_use_id) ?? finiteString(event.parent_tool_use_id) ? { parentToolUseId: finiteString(event.tool_use_id) ?? finiteString(event.parent_tool_use_id) } : {},
|
|
6867
|
+
...finiteString(event.subagent_type) ? { subagentType: finiteString(event.subagent_type) } : {},
|
|
6868
|
+
...finiteString(event.last_tool_name) ? { lastToolName: finiteString(event.last_tool_name) } : {},
|
|
6869
|
+
payloadBytes: Buffer.byteLength(line, "utf8")
|
|
6870
|
+
});
|
|
6871
|
+
}
|
|
6872
|
+
}
|
|
6787
6873
|
break;
|
|
6788
6874
|
case "stream_event":
|
|
6789
6875
|
events.push({
|
|
@@ -6795,19 +6881,21 @@ var ClaudeEventNormalizer = class {
|
|
|
6795
6881
|
break;
|
|
6796
6882
|
case "assistant": {
|
|
6797
6883
|
const content = event.message?.content;
|
|
6884
|
+
const subagent = extractSubagentLineage(event);
|
|
6885
|
+
const withLineage = subagent ? { subagent } : {};
|
|
6798
6886
|
if (Array.isArray(content)) {
|
|
6799
6887
|
const hasToolUse = content.some((block) => block?.type === "tool_use");
|
|
6800
6888
|
for (const block of content) {
|
|
6801
6889
|
if (block.type === "thinking" && block.thinking) {
|
|
6802
|
-
events.push({ kind: "thinking", text: block.thinking });
|
|
6890
|
+
events.push({ kind: "thinking", text: block.thinking, ...withLineage });
|
|
6803
6891
|
} else if (block.type === "text" && block.text) {
|
|
6804
6892
|
if (isProviderApiFailureText(block.text, hasToolUse)) {
|
|
6805
6893
|
events.push({ kind: "error", message: block.text });
|
|
6806
6894
|
} else {
|
|
6807
|
-
events.push({ kind: "text", text: block.text });
|
|
6895
|
+
events.push({ kind: "text", text: block.text, ...withLineage });
|
|
6808
6896
|
}
|
|
6809
6897
|
} else if (block.type === "tool_use") {
|
|
6810
|
-
events.push({ kind: "tool_call", name: block.name || "unknown_tool", input: block.input });
|
|
6898
|
+
events.push({ kind: "tool_call", name: block.name || "unknown_tool", input: block.input, ...withLineage });
|
|
6811
6899
|
}
|
|
6812
6900
|
}
|
|
6813
6901
|
}
|
|
@@ -6815,10 +6903,12 @@ var ClaudeEventNormalizer = class {
|
|
|
6815
6903
|
}
|
|
6816
6904
|
case "user": {
|
|
6817
6905
|
const content = event.message?.content;
|
|
6906
|
+
const subagent = extractSubagentLineage(event);
|
|
6907
|
+
const withLineage = subagent ? { subagent } : {};
|
|
6818
6908
|
if (Array.isArray(content)) {
|
|
6819
6909
|
for (const block of content) {
|
|
6820
6910
|
if (block.type === "tool_result") {
|
|
6821
|
-
events.push({ kind: "tool_output", name: block.name || block.tool_use_id || "tool_result" });
|
|
6911
|
+
events.push({ kind: "tool_output", name: block.name || block.tool_use_id || "tool_result", ...withLineage });
|
|
6822
6912
|
}
|
|
6823
6913
|
}
|
|
6824
6914
|
}
|
|
@@ -7567,7 +7657,7 @@ function codexNotificationDiagnosticEvent(message) {
|
|
|
7567
7657
|
return null;
|
|
7568
7658
|
}
|
|
7569
7659
|
const sessionId = codexMessageThreadId(message);
|
|
7570
|
-
const
|
|
7660
|
+
const path20 = boundedString(params.path);
|
|
7571
7661
|
return {
|
|
7572
7662
|
kind: "runtime_diagnostic",
|
|
7573
7663
|
severity: "warning",
|
|
@@ -7575,7 +7665,7 @@ function codexNotificationDiagnosticEvent(message) {
|
|
|
7575
7665
|
itemType: message.method,
|
|
7576
7666
|
message: diagnosticMessage,
|
|
7577
7667
|
...details ? { details } : {},
|
|
7578
|
-
...
|
|
7668
|
+
...path20 ? { path: path20 } : {},
|
|
7579
7669
|
...params.range !== void 0 ? { range: params.range } : {},
|
|
7580
7670
|
payloadBytes: payloadBytes(params),
|
|
7581
7671
|
...sessionId ? { sessionId } : {}
|
|
@@ -10448,6 +10538,7 @@ var OpenCodeDriver = class {
|
|
|
10448
10538
|
};
|
|
10449
10539
|
supportsStdinNotification = false;
|
|
10450
10540
|
busyDeliveryMode = "none";
|
|
10541
|
+
supportsNativeStandingPrompt = true;
|
|
10451
10542
|
terminateProcessOnTurnEnd = true;
|
|
10452
10543
|
deferSpawnUntilMessage = true;
|
|
10453
10544
|
shouldDeferWakeMessage(message) {
|
|
@@ -10830,6 +10921,16 @@ function mapPiAssistantMessageEvent(assistantEvent, state) {
|
|
|
10830
10921
|
}
|
|
10831
10922
|
}
|
|
10832
10923
|
}
|
|
10924
|
+
function mapPiMessageEndEvent(event) {
|
|
10925
|
+
const message = event.message;
|
|
10926
|
+
if (message?.role !== "assistant" || message.stopReason !== "error") {
|
|
10927
|
+
return [];
|
|
10928
|
+
}
|
|
10929
|
+
return [{
|
|
10930
|
+
kind: "error",
|
|
10931
|
+
message: typeof message.errorMessage === "string" && message.errorMessage.trim() ? message.errorMessage.trim() : "Pi SDK assistant turn ended with an unknown provider error"
|
|
10932
|
+
}];
|
|
10933
|
+
}
|
|
10833
10934
|
function mapPiSdkEventToParsedEvents(event, state) {
|
|
10834
10935
|
const events = [];
|
|
10835
10936
|
pushSessionInitIfNeeded2(state, events);
|
|
@@ -10837,7 +10938,6 @@ function mapPiSdkEventToParsedEvents(event, state) {
|
|
|
10837
10938
|
case "agent_start":
|
|
10838
10939
|
case "turn_start":
|
|
10839
10940
|
case "turn_end":
|
|
10840
|
-
case "message_end":
|
|
10841
10941
|
case "tool_execution_update":
|
|
10842
10942
|
case "queue_update":
|
|
10843
10943
|
case "session_info_changed":
|
|
@@ -10845,6 +10945,9 @@ function mapPiSdkEventToParsedEvents(event, state) {
|
|
|
10845
10945
|
case "auto_retry_start":
|
|
10846
10946
|
case "auto_retry_end":
|
|
10847
10947
|
return events;
|
|
10948
|
+
case "message_end":
|
|
10949
|
+
events.push(...mapPiMessageEndEvent(event));
|
|
10950
|
+
return events;
|
|
10848
10951
|
case "message_start":
|
|
10849
10952
|
if (event.message.role === "assistant") {
|
|
10850
10953
|
state.sawTextDelta = false;
|
|
@@ -12069,6 +12172,270 @@ var AgentNoProcessResidency = class {
|
|
|
12069
12172
|
}
|
|
12070
12173
|
};
|
|
12071
12174
|
|
|
12175
|
+
// src/agentLifecycleRecord.ts
|
|
12176
|
+
var AgentLifecycleRecords = class {
|
|
12177
|
+
idleRestartSnapshots = /* @__PURE__ */ new Map();
|
|
12178
|
+
terminalFailures = /* @__PURE__ */ new Map();
|
|
12179
|
+
activeSpawnFailBackoffs = /* @__PURE__ */ new Map();
|
|
12180
|
+
pendingStartRebinds = /* @__PURE__ */ new Map();
|
|
12181
|
+
pendingSpawnCauses = /* @__PURE__ */ new Map();
|
|
12182
|
+
runtimeErrorFingerprintFences = /* @__PURE__ */ new Map();
|
|
12183
|
+
activityClientSeqs = /* @__PURE__ */ new Map();
|
|
12184
|
+
stopEpochs = /* @__PURE__ */ new Map();
|
|
12185
|
+
recordStop(agentId) {
|
|
12186
|
+
const next = (this.stopEpochs.get(agentId) ?? 0) + 1;
|
|
12187
|
+
this.stopEpochs.set(agentId, next);
|
|
12188
|
+
return next;
|
|
12189
|
+
}
|
|
12190
|
+
stopEpoch(agentId) {
|
|
12191
|
+
return this.stopEpochs.get(agentId) ?? 0;
|
|
12192
|
+
}
|
|
12193
|
+
stopEpochChanged(agentId, epoch) {
|
|
12194
|
+
return this.stopEpoch(agentId) !== epoch;
|
|
12195
|
+
}
|
|
12196
|
+
nextActivityClientSeq(agentId) {
|
|
12197
|
+
const next = (this.activityClientSeqs.get(agentId) ?? 0) + 1;
|
|
12198
|
+
this.activityClientSeqs.set(agentId, next);
|
|
12199
|
+
return next;
|
|
12200
|
+
}
|
|
12201
|
+
deleteActivityClientSeq(agentId) {
|
|
12202
|
+
return this.activityClientSeqs.delete(agentId);
|
|
12203
|
+
}
|
|
12204
|
+
getRestartSnapshot(agentId) {
|
|
12205
|
+
return this.idleRestartSnapshots.get(agentId);
|
|
12206
|
+
}
|
|
12207
|
+
setRestartSnapshot(agentId, snapshot) {
|
|
12208
|
+
this.idleRestartSnapshots.set(agentId, snapshot);
|
|
12209
|
+
}
|
|
12210
|
+
deleteRestartSnapshot(agentId) {
|
|
12211
|
+
return this.idleRestartSnapshots.delete(agentId);
|
|
12212
|
+
}
|
|
12213
|
+
clearRestartSnapshots() {
|
|
12214
|
+
this.idleRestartSnapshots.clear();
|
|
12215
|
+
}
|
|
12216
|
+
restartSnapshotEntries() {
|
|
12217
|
+
return this.idleRestartSnapshots.entries();
|
|
12218
|
+
}
|
|
12219
|
+
restartSnapshotAgentIds() {
|
|
12220
|
+
return this.idleRestartSnapshots.keys();
|
|
12221
|
+
}
|
|
12222
|
+
getTerminalFailure(agentId) {
|
|
12223
|
+
return this.terminalFailures.get(agentId);
|
|
12224
|
+
}
|
|
12225
|
+
setTerminalFailure(agentId, failure) {
|
|
12226
|
+
this.terminalFailures.set(agentId, failure);
|
|
12227
|
+
}
|
|
12228
|
+
deleteTerminalFailure(agentId) {
|
|
12229
|
+
return this.terminalFailures.delete(agentId);
|
|
12230
|
+
}
|
|
12231
|
+
terminalFailureAgentIds() {
|
|
12232
|
+
return this.terminalFailures.keys();
|
|
12233
|
+
}
|
|
12234
|
+
getSpawnFailBackoff(agentId) {
|
|
12235
|
+
return this.activeSpawnFailBackoffs.get(agentId);
|
|
12236
|
+
}
|
|
12237
|
+
getOrCreateSpawnFailBackoff(agentId, create) {
|
|
12238
|
+
let state = this.activeSpawnFailBackoffs.get(agentId);
|
|
12239
|
+
if (!state) {
|
|
12240
|
+
state = create();
|
|
12241
|
+
this.activeSpawnFailBackoffs.set(agentId, state);
|
|
12242
|
+
}
|
|
12243
|
+
return state;
|
|
12244
|
+
}
|
|
12245
|
+
deleteSpawnFailBackoff(agentId) {
|
|
12246
|
+
return this.activeSpawnFailBackoffs.delete(agentId);
|
|
12247
|
+
}
|
|
12248
|
+
activeSpawnFailBackoffAgentIds(now, isActive) {
|
|
12249
|
+
return [...this.activeSpawnFailBackoffs.entries()].filter(([, state]) => isActive(state, now)).map(([agentId]) => agentId);
|
|
12250
|
+
}
|
|
12251
|
+
getPendingStartRebind(agentId) {
|
|
12252
|
+
return this.pendingStartRebinds.get(agentId);
|
|
12253
|
+
}
|
|
12254
|
+
setPendingStartRebind(agentId, start) {
|
|
12255
|
+
this.pendingStartRebinds.set(agentId, start);
|
|
12256
|
+
}
|
|
12257
|
+
deletePendingStartRebind(agentId) {
|
|
12258
|
+
return this.pendingStartRebinds.delete(agentId);
|
|
12259
|
+
}
|
|
12260
|
+
getPendingSpawnCause(agentId) {
|
|
12261
|
+
return this.pendingSpawnCauses.get(agentId);
|
|
12262
|
+
}
|
|
12263
|
+
setPendingSpawnCause(agentId, cause) {
|
|
12264
|
+
this.pendingSpawnCauses.set(agentId, cause);
|
|
12265
|
+
}
|
|
12266
|
+
deletePendingSpawnCause(agentId) {
|
|
12267
|
+
return this.pendingSpawnCauses.delete(agentId);
|
|
12268
|
+
}
|
|
12269
|
+
getRuntimeErrorFingerprintFence(agentId) {
|
|
12270
|
+
return this.runtimeErrorFingerprintFences.get(agentId);
|
|
12271
|
+
}
|
|
12272
|
+
setRuntimeErrorFingerprintFence(agentId, fence) {
|
|
12273
|
+
this.runtimeErrorFingerprintFences.set(agentId, fence);
|
|
12274
|
+
}
|
|
12275
|
+
deleteRuntimeErrorFingerprintFence(agentId) {
|
|
12276
|
+
return this.runtimeErrorFingerprintFences.delete(agentId);
|
|
12277
|
+
}
|
|
12278
|
+
runtimeErrorFingerprintFenceAgentIds() {
|
|
12279
|
+
return this.runtimeErrorFingerprintFences.keys();
|
|
12280
|
+
}
|
|
12281
|
+
snapshot(args) {
|
|
12282
|
+
return {
|
|
12283
|
+
runningAgentIds: args.runningAgentIds,
|
|
12284
|
+
queuedAgentIds: args.queuedAgentIds,
|
|
12285
|
+
startingAgentIds: args.startingAgentIds,
|
|
12286
|
+
idleRestartSnapshots: [...this.idleRestartSnapshots.entries()],
|
|
12287
|
+
terminalFailures: [...this.terminalFailures.entries()],
|
|
12288
|
+
activeSpawnFailBackoffs: [...this.activeSpawnFailBackoffs.entries()].filter(([, state]) => args.isSpawnFailBackoffActive(state, args.now)),
|
|
12289
|
+
pendingStartRebinds: [...this.pendingStartRebinds.entries()],
|
|
12290
|
+
pendingSpawnCauses: [...this.pendingSpawnCauses.entries()],
|
|
12291
|
+
runtimeErrorFingerprintFences: [...this.runtimeErrorFingerprintFences.entries()],
|
|
12292
|
+
activityClientSeqs: [...this.activityClientSeqs.entries()]
|
|
12293
|
+
};
|
|
12294
|
+
}
|
|
12295
|
+
assertInvariants(context, snapshot) {
|
|
12296
|
+
assertAgentLifecycleRecordInvariants(context, snapshot);
|
|
12297
|
+
}
|
|
12298
|
+
};
|
|
12299
|
+
function buildAgentLifecycleRecords(snapshot) {
|
|
12300
|
+
const running = new Set(snapshot.runningAgentIds);
|
|
12301
|
+
const queued = new Set(snapshot.queuedAgentIds);
|
|
12302
|
+
const starting = new Set(snapshot.startingAgentIds);
|
|
12303
|
+
const facts = /* @__PURE__ */ new Map();
|
|
12304
|
+
for (const agentId of snapshot.runningAgentIds) {
|
|
12305
|
+
factsFor(facts, agentId);
|
|
12306
|
+
}
|
|
12307
|
+
for (const agentId of snapshot.queuedAgentIds) {
|
|
12308
|
+
factsFor(facts, agentId);
|
|
12309
|
+
}
|
|
12310
|
+
for (const agentId of snapshot.startingAgentIds) {
|
|
12311
|
+
factsFor(facts, agentId);
|
|
12312
|
+
}
|
|
12313
|
+
for (const [agentId, restartSnapshot] of snapshot.idleRestartSnapshots) {
|
|
12314
|
+
factsFor(facts, agentId).restartSnapshot = restartSnapshot;
|
|
12315
|
+
}
|
|
12316
|
+
for (const [agentId, failure] of snapshot.terminalFailures) {
|
|
12317
|
+
factsFor(facts, agentId).terminalFailure = failure;
|
|
12318
|
+
}
|
|
12319
|
+
for (const [agentId, backoff] of snapshot.activeSpawnFailBackoffs) {
|
|
12320
|
+
factsFor(facts, agentId).activeSpawnFailBackoff = backoff;
|
|
12321
|
+
}
|
|
12322
|
+
for (const [agentId, pendingStartRebind] of snapshot.pendingStartRebinds) {
|
|
12323
|
+
factsFor(facts, agentId).pendingStartRebind = pendingStartRebind;
|
|
12324
|
+
}
|
|
12325
|
+
for (const [agentId, cause] of snapshot.pendingSpawnCauses) {
|
|
12326
|
+
factsFor(facts, agentId).pendingSpawnCause = cause;
|
|
12327
|
+
}
|
|
12328
|
+
for (const [agentId, fence] of snapshot.runtimeErrorFingerprintFences) {
|
|
12329
|
+
factsFor(facts, agentId).runtimeErrorFingerprintFence = fence;
|
|
12330
|
+
}
|
|
12331
|
+
for (const [agentId, seq] of snapshot.activityClientSeqs) {
|
|
12332
|
+
factsFor(facts, agentId).activityClientSeq = seq;
|
|
12333
|
+
}
|
|
12334
|
+
const records = /* @__PURE__ */ new Map();
|
|
12335
|
+
for (const [agentId, agentFacts] of facts) {
|
|
12336
|
+
if (queued.has(agentId) && starting.has(agentId)) {
|
|
12337
|
+
throw new Error(`queued and starting facts overlap for ${agentId}`);
|
|
12338
|
+
}
|
|
12339
|
+
if (agentFacts.terminalFailure) {
|
|
12340
|
+
assertTerminalRecordFacts(agentId, agentFacts, running.has(agentId));
|
|
12341
|
+
records.set(agentId, {
|
|
12342
|
+
kind: "terminal",
|
|
12343
|
+
agentId,
|
|
12344
|
+
terminalFailure: agentFacts.terminalFailure,
|
|
12345
|
+
fingerprintFence: agentFacts.runtimeErrorFingerprintFence,
|
|
12346
|
+
activityClientSeq: agentFacts.activityClientSeq
|
|
12347
|
+
});
|
|
12348
|
+
continue;
|
|
12349
|
+
}
|
|
12350
|
+
if (agentFacts.activeSpawnFailBackoff !== void 0) {
|
|
12351
|
+
if (running.has(agentId)) {
|
|
12352
|
+
throw new Error(`running process and active cooldown both present for ${agentId}`);
|
|
12353
|
+
}
|
|
12354
|
+
if (!agentFacts.restartSnapshot) {
|
|
12355
|
+
throw new Error(`active cooldown without restart config for ${agentId}`);
|
|
12356
|
+
}
|
|
12357
|
+
records.set(agentId, {
|
|
12358
|
+
kind: "cooldown",
|
|
12359
|
+
agentId,
|
|
12360
|
+
restartSnapshot: agentFacts.restartSnapshot,
|
|
12361
|
+
spawnFailBackoff: agentFacts.activeSpawnFailBackoff,
|
|
12362
|
+
fingerprintFence: agentFacts.runtimeErrorFingerprintFence,
|
|
12363
|
+
activityClientSeq: agentFacts.activityClientSeq
|
|
12364
|
+
});
|
|
12365
|
+
continue;
|
|
12366
|
+
}
|
|
12367
|
+
if (running.has(agentId)) {
|
|
12368
|
+
records.set(agentId, {
|
|
12369
|
+
kind: "running",
|
|
12370
|
+
agentId,
|
|
12371
|
+
restartSnapshot: agentFacts.restartSnapshot,
|
|
12372
|
+
pendingStartRebind: agentFacts.pendingStartRebind,
|
|
12373
|
+
pendingSpawnCause: agentFacts.pendingSpawnCause,
|
|
12374
|
+
fingerprintFence: agentFacts.runtimeErrorFingerprintFence,
|
|
12375
|
+
activityClientSeq: agentFacts.activityClientSeq
|
|
12376
|
+
});
|
|
12377
|
+
continue;
|
|
12378
|
+
}
|
|
12379
|
+
if (starting.has(agentId)) {
|
|
12380
|
+
records.set(agentId, {
|
|
12381
|
+
kind: "starting",
|
|
12382
|
+
agentId,
|
|
12383
|
+
restartSnapshot: agentFacts.restartSnapshot,
|
|
12384
|
+
pendingStartRebind: agentFacts.pendingStartRebind,
|
|
12385
|
+
activityClientSeq: agentFacts.activityClientSeq
|
|
12386
|
+
});
|
|
12387
|
+
continue;
|
|
12388
|
+
}
|
|
12389
|
+
if (queued.has(agentId)) {
|
|
12390
|
+
records.set(agentId, {
|
|
12391
|
+
kind: "queued",
|
|
12392
|
+
agentId,
|
|
12393
|
+
restartSnapshot: agentFacts.restartSnapshot,
|
|
12394
|
+
pendingStartRebind: agentFacts.pendingStartRebind,
|
|
12395
|
+
activityClientSeq: agentFacts.activityClientSeq
|
|
12396
|
+
});
|
|
12397
|
+
continue;
|
|
12398
|
+
}
|
|
12399
|
+
if (agentFacts.restartSnapshot) {
|
|
12400
|
+
records.set(agentId, {
|
|
12401
|
+
kind: "idle",
|
|
12402
|
+
agentId,
|
|
12403
|
+
restartSnapshot: agentFacts.restartSnapshot,
|
|
12404
|
+
fingerprintFence: agentFacts.runtimeErrorFingerprintFence,
|
|
12405
|
+
activityClientSeq: agentFacts.activityClientSeq
|
|
12406
|
+
});
|
|
12407
|
+
}
|
|
12408
|
+
}
|
|
12409
|
+
return records;
|
|
12410
|
+
}
|
|
12411
|
+
function assertAgentLifecycleRecordInvariants(context, snapshot) {
|
|
12412
|
+
try {
|
|
12413
|
+
buildAgentLifecycleRecords(snapshot);
|
|
12414
|
+
} catch (err) {
|
|
12415
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
12416
|
+
throw new Error(`Agent lifecycle record invariant violation after ${context}: ${detail}`);
|
|
12417
|
+
}
|
|
12418
|
+
}
|
|
12419
|
+
function factsFor(facts, agentId) {
|
|
12420
|
+
let value = facts.get(agentId);
|
|
12421
|
+
if (!value) {
|
|
12422
|
+
value = {};
|
|
12423
|
+
facts.set(agentId, value);
|
|
12424
|
+
}
|
|
12425
|
+
return value;
|
|
12426
|
+
}
|
|
12427
|
+
function assertTerminalRecordFacts(agentId, facts, isRunning) {
|
|
12428
|
+
if (isRunning) {
|
|
12429
|
+
throw new Error(`terminal failure while process is still registered for ${agentId}`);
|
|
12430
|
+
}
|
|
12431
|
+
if (facts.restartSnapshot) {
|
|
12432
|
+
throw new Error(`terminal failure and idle restart config both present for ${agentId}`);
|
|
12433
|
+
}
|
|
12434
|
+
if (facts.pendingStartRebind) {
|
|
12435
|
+
throw new Error(`terminal failure and pending start rebind both present for ${agentId}`);
|
|
12436
|
+
}
|
|
12437
|
+
}
|
|
12438
|
+
|
|
12072
12439
|
// src/launchPhaseTransition.ts
|
|
12073
12440
|
var LAUNCH_RUNTIME_READINESS_TRANSITION_SPAN = "launch_runtime_readiness_transition";
|
|
12074
12441
|
function launchReadinessNegativeEvidence(identity) {
|
|
@@ -12342,7 +12709,7 @@ function buildRuntimeErrorDiagnosticEnvelope(message) {
|
|
|
12342
12709
|
const httpStatus = extractHttpStatus(rawMessage);
|
|
12343
12710
|
const runtimeErrorClass = classifyRuntimeError(rawMessage, httpStatus);
|
|
12344
12711
|
const runtimeErrorReason = classifyRuntimeErrorReason(runtimeErrorClass);
|
|
12345
|
-
const runtimeErrorAction = classifyRuntimeErrorAction(
|
|
12712
|
+
const runtimeErrorAction = classifyRuntimeErrorAction(runtimeErrorClass);
|
|
12346
12713
|
const fingerprint = fingerprintRuntimeError(scrubbed);
|
|
12347
12714
|
const spanAttrs = {
|
|
12348
12715
|
turn_outcome: "failed",
|
|
@@ -12368,6 +12735,9 @@ function buildRuntimeErrorDiagnosticEnvelope(message) {
|
|
|
12368
12735
|
};
|
|
12369
12736
|
}
|
|
12370
12737
|
function formatRuntimeLoginRequiredMessage(runtimeId) {
|
|
12738
|
+
if (runtimeId === "builtin") {
|
|
12739
|
+
return "Built-in provider authentication failed. Check this agent's provider API key and region/provider selection, then retry starting this agent.";
|
|
12740
|
+
}
|
|
12371
12741
|
const runtimeLabel = runtimeDisplayName(runtimeId);
|
|
12372
12742
|
return `${runtimeLabel} is not logged in on this machine. Please log in to ${runtimeLabel} locally, then retry starting this agent.`;
|
|
12373
12743
|
}
|
|
@@ -12411,8 +12781,8 @@ function classifyRuntimeError(message, httpStatus) {
|
|
|
12411
12781
|
if (/\bnot found\b/i.test(message)) return "NotFoundError";
|
|
12412
12782
|
return "RuntimeError";
|
|
12413
12783
|
}
|
|
12414
|
-
function classifyRuntimeErrorAction(
|
|
12415
|
-
if (runtimeErrorClass === "AuthError"
|
|
12784
|
+
function classifyRuntimeErrorAction(runtimeErrorClass) {
|
|
12785
|
+
if (runtimeErrorClass === "AuthError") {
|
|
12416
12786
|
return "user_reauth";
|
|
12417
12787
|
}
|
|
12418
12788
|
return "none";
|
|
@@ -12464,6 +12834,8 @@ function runtimeDisplayName(runtimeId) {
|
|
|
12464
12834
|
return "OpenCode";
|
|
12465
12835
|
case "pi":
|
|
12466
12836
|
return "Pi";
|
|
12837
|
+
case "builtin":
|
|
12838
|
+
return "Built-in";
|
|
12467
12839
|
default:
|
|
12468
12840
|
return runtimeId || "This runtime";
|
|
12469
12841
|
}
|
|
@@ -12722,6 +13094,36 @@ var WORKSPACE_IMAGE_MIME_BY_EXTENSION = {
|
|
|
12722
13094
|
".png": "image/png",
|
|
12723
13095
|
".webp": "image/webp"
|
|
12724
13096
|
};
|
|
13097
|
+
var WORKSPACE_NEVER_VISIBLE_HIDDEN_NAMES = /* @__PURE__ */ new Set([
|
|
13098
|
+
".aws",
|
|
13099
|
+
".gnupg",
|
|
13100
|
+
".ssh",
|
|
13101
|
+
".slock",
|
|
13102
|
+
".slock-runtime"
|
|
13103
|
+
]);
|
|
13104
|
+
var WORKSPACE_SECRET_FILE_PATTERNS = [
|
|
13105
|
+
/^\.env(?:\.|$)/i,
|
|
13106
|
+
/(?:^|[._-])secret(?:s)?(?:[._-]|$)/i,
|
|
13107
|
+
/(?:^|[._-])credential(?:s)?(?:[._-]|$)/i,
|
|
13108
|
+
/(?:^|[._-])token(?:s)?(?:[._-]|$)/i
|
|
13109
|
+
];
|
|
13110
|
+
function isWorkspaceNeverVisibleHiddenEntry(name) {
|
|
13111
|
+
return WORKSPACE_NEVER_VISIBLE_HIDDEN_NAMES.has(name) || name.startsWith(".slock-");
|
|
13112
|
+
}
|
|
13113
|
+
function workspacePathParts(relativePath) {
|
|
13114
|
+
return relativePath.split(path14.sep).filter(Boolean);
|
|
13115
|
+
}
|
|
13116
|
+
function isWorkspaceHiddenPath(relativePath) {
|
|
13117
|
+
return workspacePathParts(relativePath).some((part) => part.startsWith("."));
|
|
13118
|
+
}
|
|
13119
|
+
function isWorkspaceNeverVisibleHiddenPath(relativePath) {
|
|
13120
|
+
return workspacePathParts(relativePath).some(isWorkspaceNeverVisibleHiddenEntry);
|
|
13121
|
+
}
|
|
13122
|
+
function isWorkspaceSecretFilePath(filePath) {
|
|
13123
|
+
return workspacePathParts(filePath).some(
|
|
13124
|
+
(part) => WORKSPACE_SECRET_FILE_PATTERNS.some((pattern) => pattern.test(part))
|
|
13125
|
+
);
|
|
13126
|
+
}
|
|
12725
13127
|
function readPositiveIntegerEnv(name, fallback) {
|
|
12726
13128
|
const raw = process.env[name];
|
|
12727
13129
|
if (!raw) return fallback;
|
|
@@ -12816,9 +13218,6 @@ function toLocalTime(iso) {
|
|
|
12816
13218
|
const pad = (n) => String(n).padStart(2, "0");
|
|
12817
13219
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
12818
13220
|
}
|
|
12819
|
-
function formatChannelLabel(message) {
|
|
12820
|
-
return message.channel_type === "dm" ? `DM:@${message.channel_name}` : `#${message.channel_name}`;
|
|
12821
|
-
}
|
|
12822
13221
|
function formatMessageTarget(message) {
|
|
12823
13222
|
return formatAgentMessageVisibleTarget(message);
|
|
12824
13223
|
}
|
|
@@ -13148,17 +13547,8 @@ function formatRuntimeProfileControlStartupInput(control, driver) {
|
|
|
13148
13547
|
"Read the Runtime Profile daemon release notice from your system prompt before normal work.",
|
|
13149
13548
|
"No chat reply or runtime control action is required for this notice. Stop after reading it; queued inbox messages will be delivered separately.",
|
|
13150
13549
|
"",
|
|
13151
|
-
control.message
|
|
13152
|
-
].join("\n");
|
|
13153
|
-
}
|
|
13154
|
-
function buildUnreadSummary(messages, excludeChannel) {
|
|
13155
|
-
const summary = /* @__PURE__ */ new Map();
|
|
13156
|
-
for (const message of messages) {
|
|
13157
|
-
const label = formatChannelLabel(message);
|
|
13158
|
-
if (excludeChannel && label === excludeChannel) continue;
|
|
13159
|
-
summary.set(label, (summary.get(label) || 0) + 1);
|
|
13160
|
-
}
|
|
13161
|
-
return summary.size > 0 ? Object.fromEntries(summary) : void 0;
|
|
13550
|
+
control.message
|
|
13551
|
+
].join("\n");
|
|
13162
13552
|
}
|
|
13163
13553
|
var MAX_TRAJECTORY_TEXT = 2e3;
|
|
13164
13554
|
var TRAJECTORY_COALESCE_MS = 350;
|
|
@@ -13578,6 +13968,49 @@ Success = user starts useful collaboration and setup progresses,
|
|
|
13578
13968
|
not finishing a long onboarding conversation in one channel.
|
|
13579
13969
|
`;
|
|
13580
13970
|
}
|
|
13971
|
+
function createAgentProcessStartupState(context) {
|
|
13972
|
+
return { kind: "waiting", timer: null, ...context };
|
|
13973
|
+
}
|
|
13974
|
+
function agentProcessStartupContext(startup) {
|
|
13975
|
+
return {
|
|
13976
|
+
wakeMessage: startup.wakeMessage,
|
|
13977
|
+
unreadSummary: startup.unreadSummary,
|
|
13978
|
+
resumePrompt: startup.resumePrompt
|
|
13979
|
+
};
|
|
13980
|
+
}
|
|
13981
|
+
function agentProcessStartupReady(startup) {
|
|
13982
|
+
return { kind: "ready", ...agentProcessStartupContext(startup) };
|
|
13983
|
+
}
|
|
13984
|
+
var DecisionErrorWindow = class {
|
|
13985
|
+
progressEpoch = 0;
|
|
13986
|
+
stderrEpoch = 0;
|
|
13987
|
+
stderrLines = [];
|
|
13988
|
+
runtimeError = null;
|
|
13989
|
+
noteRuntimeProgress() {
|
|
13990
|
+
this.progressEpoch += 1;
|
|
13991
|
+
}
|
|
13992
|
+
recordStderr(text) {
|
|
13993
|
+
const base = this.stderrEpoch === this.progressEpoch ? this.stderrLines : [];
|
|
13994
|
+
this.stderrLines = pushRecentStderr(base, text);
|
|
13995
|
+
this.stderrEpoch = this.progressEpoch;
|
|
13996
|
+
}
|
|
13997
|
+
recordRuntimeError(message) {
|
|
13998
|
+
this.runtimeError = { epoch: this.progressEpoch, message };
|
|
13999
|
+
}
|
|
14000
|
+
currentStderrLines() {
|
|
14001
|
+
return this.stderrEpoch === this.progressEpoch ? this.stderrLines : [];
|
|
14002
|
+
}
|
|
14003
|
+
currentRuntimeError() {
|
|
14004
|
+
if (!this.runtimeError || this.runtimeError.epoch !== this.progressEpoch) return null;
|
|
14005
|
+
return this.runtimeError.message;
|
|
14006
|
+
}
|
|
14007
|
+
currentErrorCandidates() {
|
|
14008
|
+
return [
|
|
14009
|
+
this.currentRuntimeError(),
|
|
14010
|
+
...this.currentStderrLines()
|
|
14011
|
+
].filter((value) => !!value);
|
|
14012
|
+
}
|
|
14013
|
+
};
|
|
13581
14014
|
function createRuntimeTraceCounters() {
|
|
13582
14015
|
return {
|
|
13583
14016
|
events: 0,
|
|
@@ -13591,6 +14024,7 @@ function createRuntimeTraceCounters() {
|
|
|
13591
14024
|
}
|
|
13592
14025
|
function createRuntimeErrorDeliveryBackoffState() {
|
|
13593
14026
|
return {
|
|
14027
|
+
kind: "idle",
|
|
13594
14028
|
attempts: 0,
|
|
13595
14029
|
untilMs: 0,
|
|
13596
14030
|
timer: null,
|
|
@@ -13766,11 +14200,41 @@ function runtimeRecoveryTraceAttrs(event) {
|
|
|
13766
14200
|
details_present: Boolean(event.details)
|
|
13767
14201
|
};
|
|
13768
14202
|
}
|
|
14203
|
+
function subagentProgressDetail(event) {
|
|
14204
|
+
const role = event.subagentType ? ` (${event.subagentType})` : "";
|
|
14205
|
+
switch (event.phase) {
|
|
14206
|
+
case "started":
|
|
14207
|
+
return `Subagent started${role}`;
|
|
14208
|
+
case "progress":
|
|
14209
|
+
return `Subagent working${role}`;
|
|
14210
|
+
case "notification":
|
|
14211
|
+
return `Subagent update${role}`;
|
|
14212
|
+
default:
|
|
14213
|
+
return `Subagent working${role}`;
|
|
14214
|
+
}
|
|
14215
|
+
}
|
|
14216
|
+
function subagentLineageFromEvent(event) {
|
|
14217
|
+
return {
|
|
14218
|
+
...event.parentToolUseId ? { parentToolUseId: event.parentToolUseId } : {},
|
|
14219
|
+
...event.subagentType ? { subagentType: event.subagentType } : {},
|
|
14220
|
+
...event.taskId ? { taskId: event.taskId } : {},
|
|
14221
|
+
phase: event.phase
|
|
14222
|
+
};
|
|
14223
|
+
}
|
|
14224
|
+
function subagentProgressTraceAttrs(event) {
|
|
14225
|
+
return {
|
|
14226
|
+
kind: event.kind,
|
|
14227
|
+
source: event.source,
|
|
14228
|
+
phase: event.phase,
|
|
14229
|
+
parent_tool_use_id_present: Boolean(event.parentToolUseId),
|
|
14230
|
+
subagent_type_present: Boolean(event.subagentType),
|
|
14231
|
+
task_id_present: Boolean(event.taskId),
|
|
14232
|
+
last_tool_name_present: Boolean(event.lastToolName),
|
|
14233
|
+
payloadBytes: event.payloadBytes
|
|
14234
|
+
};
|
|
14235
|
+
}
|
|
13769
14236
|
function currentErrorCandidates(ap) {
|
|
13770
|
-
return
|
|
13771
|
-
ap.runtimeErrorSinceProgress ? ap.lastRuntimeError : null,
|
|
13772
|
-
...ap.recentDecisionStderr
|
|
13773
|
-
].filter((value) => !!value);
|
|
14237
|
+
return ap.decisionErrorWindow.currentErrorCandidates();
|
|
13774
14238
|
}
|
|
13775
14239
|
function classifyTerminalFailure(ap) {
|
|
13776
14240
|
const candidates = [
|
|
@@ -13860,8 +14324,10 @@ function buildRuntimeStallDiagnostic(ap, staleForMs, staleForMinutes) {
|
|
|
13860
14324
|
return projectApmRuntimeStallDiagnostic({
|
|
13861
14325
|
staleForMs,
|
|
13862
14326
|
staleForMinutes,
|
|
14327
|
+
lastActivityKind: ap.lastActivityKind,
|
|
13863
14328
|
lastActivity: ap.lastActivity,
|
|
13864
14329
|
lastActivityDetail: ap.lastActivityDetail,
|
|
14330
|
+
lastActivityDetailKind: ap.lastActivityDetailKind,
|
|
13865
14331
|
runtimeDescriptorBusyDelivery: ap.runtime.descriptor.busyDelivery,
|
|
13866
14332
|
runtimeProgressLastEventKind: ap.runtimeProgress.lastEventKind,
|
|
13867
14333
|
runtime: ap.config.runtime,
|
|
@@ -14047,39 +14513,16 @@ var NATIVE_STANDING_PROMPT_STARTUP_INPUT = (
|
|
|
14047
14513
|
);
|
|
14048
14514
|
var AgentProcessManager = class _AgentProcessManager {
|
|
14049
14515
|
agents = /* @__PURE__ */ new Map();
|
|
14050
|
-
|
|
14051
|
-
* Per-agent monotonic clientSeq for `agent:activity` upstream dedup.
|
|
14052
|
-
* Server dedupes ingest by `(launchId, clientSeq)` (#engineering:72283cf7
|
|
14053
|
-
* task #340 PR B). This counter is keyed by agentId at the MANAGER level —
|
|
14054
|
-
* NOT on the per-process `AgentProcess` — so it SURVIVES process recreation
|
|
14055
|
-
* (cold-start-resume / idle-auto-restart / queued-continuation /
|
|
14056
|
-
* runtime-profile restart). Those daemon-internal restarts reuse the
|
|
14057
|
-
* server-issued launchId but spawn a fresh process; if the counter reset to
|
|
14058
|
-
* 0 (as the old per-`ap` field did) the reused launchId's `(launchId,
|
|
14059
|
-
* clientSeq)` window would collide and the server would drop the
|
|
14060
|
-
* post-restart activity as stale — the "activity log stops updating after
|
|
14061
|
-
* error→restart" bug. Keeping it monotonic-per-agent and never resetting on
|
|
14062
|
-
* respawn guarantees a fresh dedup key under the same launchId. launchId is
|
|
14063
|
-
* decoupled: it stays the identity/gate token, this is the clock.
|
|
14064
|
-
* (#proj-o11y:a1e54b59 — RS dedup-epoch ⊥ launchId-identity separation.)
|
|
14065
|
-
*/
|
|
14066
|
-
activityClientSeqByAgent = /* @__PURE__ */ new Map();
|
|
14516
|
+
lifecycleRecords = new AgentLifecycleRecords();
|
|
14067
14517
|
/** Next monotonic `agent:activity` clientSeq for this agent (never resets on respawn). */
|
|
14068
14518
|
nextActivityClientSeq(agentId) {
|
|
14069
|
-
|
|
14070
|
-
this.activityClientSeqByAgent.set(agentId, next);
|
|
14071
|
-
return next;
|
|
14519
|
+
return this.lifecycleRecords.nextActivityClientSeq(agentId);
|
|
14072
14520
|
}
|
|
14073
14521
|
agentStarts;
|
|
14074
14522
|
startingInboxes = new AgentStartPendingDeliveryBuffer();
|
|
14075
14523
|
/** Monotonic ordering counter for launch phase-5/6 exported rows (audit only, not a pairing key). */
|
|
14076
14524
|
launchTransitionSeq = 0;
|
|
14077
|
-
terminalRuntimeFailures = /* @__PURE__ */ new Map();
|
|
14078
14525
|
noProcessResidencyTransitions = new AgentNoProcessResidencyTransitions();
|
|
14079
|
-
runtimeErrorFingerprintFences = /* @__PURE__ */ new Map();
|
|
14080
|
-
pendingStartRebinds = /* @__PURE__ */ new Map();
|
|
14081
|
-
/** Cached configs for agents whose process exited normally — enables auto-restart on next message */
|
|
14082
|
-
idleAgentConfigs = /* @__PURE__ */ new Map();
|
|
14083
14526
|
slockCliPath;
|
|
14084
14527
|
sendToServer;
|
|
14085
14528
|
daemonApiKey;
|
|
@@ -14099,12 +14542,16 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14099
14542
|
deliveryTraceContexts = /* @__PURE__ */ new WeakMap();
|
|
14100
14543
|
runtimeExitTraceAttrs = /* @__PURE__ */ new WeakMap();
|
|
14101
14544
|
agentVisibleDelivery = new AgentVisibleDeliveryLedger();
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14105
|
-
|
|
14106
|
-
|
|
14107
|
-
|
|
14545
|
+
/**
|
|
14546
|
+
* Per-agent lifecycle facts that outlive a single `AgentProcess`.
|
|
14547
|
+
*
|
|
14548
|
+
* The old implementation stored these as separate manager-level maps:
|
|
14549
|
+
* idle restart snapshots, terminal runtime failures, spawn-fail cooldown,
|
|
14550
|
+
* pending start rebinds, pending spawn causes, runtime-error fences, and the
|
|
14551
|
+
* activity client sequence. Keeping their storage under one owner makes the
|
|
14552
|
+
* lifecycle projection/invariants read the actual mutation boundary instead
|
|
14553
|
+
* of reconstructing it from unrelated fields.
|
|
14554
|
+
*/
|
|
14108
14555
|
daemonVersion;
|
|
14109
14556
|
computerVersion;
|
|
14110
14557
|
workerUrl;
|
|
@@ -14155,8 +14602,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14155
14602
|
this.cliTransportTraceDir = traceDir;
|
|
14156
14603
|
}
|
|
14157
14604
|
assertStartPendingDeliveryInvariants(context) {
|
|
14605
|
+
this.repairNonresidentRuntimeErrorFingerprintFences(context);
|
|
14158
14606
|
const residencySnapshot = this.noProcessResidencySnapshot();
|
|
14159
14607
|
AgentNoProcessResidency.assertInvariants(context, residencySnapshot);
|
|
14608
|
+
this.lifecycleRecords.assertInvariants(context, this.agentLifecycleRecordSnapshot());
|
|
14160
14609
|
this.startingInboxes.assertInvariants(
|
|
14161
14610
|
context,
|
|
14162
14611
|
AgentNoProcessResidency.allowedStartPendingSnapshot(residencySnapshot)
|
|
@@ -14169,13 +14618,30 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14169
14618
|
runningAgentIds: [...this.agents.keys()],
|
|
14170
14619
|
queuedAgentIds: startSnapshot.queuedAgentIds,
|
|
14171
14620
|
startingAgentIds: startSnapshot.startingAgentIds,
|
|
14172
|
-
idleAgentIds: [...this.
|
|
14173
|
-
terminalFailureAgentIds: [...this.
|
|
14174
|
-
activeCooldownAgentIds:
|
|
14175
|
-
|
|
14621
|
+
idleAgentIds: [...this.lifecycleRecords.restartSnapshotAgentIds()],
|
|
14622
|
+
terminalFailureAgentIds: [...this.lifecycleRecords.terminalFailureAgentIds()],
|
|
14623
|
+
activeCooldownAgentIds: this.lifecycleRecords.activeSpawnFailBackoffAgentIds(
|
|
14624
|
+
now,
|
|
14625
|
+
(state, currentTime) => state.untilMs > currentTime
|
|
14626
|
+
),
|
|
14627
|
+
fingerprintFenceAgentIds: [...this.lifecycleRecords.runtimeErrorFingerprintFenceAgentIds()],
|
|
14176
14628
|
pendingDeliveryAgentIds: this.startingInboxes.agentIds()
|
|
14177
14629
|
};
|
|
14178
14630
|
}
|
|
14631
|
+
agentLifecycleRecordSnapshot() {
|
|
14632
|
+
const startSnapshot = this.agentStarts.snapshot();
|
|
14633
|
+
const now = this.clockNow();
|
|
14634
|
+
return this.lifecycleRecords.snapshot({
|
|
14635
|
+
runningAgentIds: [...this.agents.keys()],
|
|
14636
|
+
queuedAgentIds: startSnapshot.queuedAgentIds,
|
|
14637
|
+
startingAgentIds: startSnapshot.startingAgentIds,
|
|
14638
|
+
now,
|
|
14639
|
+
isSpawnFailBackoffActive: (state, currentTime) => state.untilMs > currentTime
|
|
14640
|
+
});
|
|
14641
|
+
}
|
|
14642
|
+
agentLifecycleRecord(agentId) {
|
|
14643
|
+
return buildAgentLifecycleRecords(this.agentLifecycleRecordSnapshot()).get(agentId);
|
|
14644
|
+
}
|
|
14179
14645
|
getVisibleBoundary(agentId, target) {
|
|
14180
14646
|
return this.agentVisibleDelivery.getBoundary(agentId, target);
|
|
14181
14647
|
}
|
|
@@ -14196,15 +14662,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14196
14662
|
// bypasses the cap — CC1 lifecycle pattern). Never advances any consume cursor or model-seen
|
|
14197
14663
|
// state (3-cursor orthogonality with CC1/CC2).
|
|
14198
14664
|
getOrCreateSpawnFailBackoff(agentId) {
|
|
14199
|
-
|
|
14200
|
-
if (!state) {
|
|
14201
|
-
state = createRuntimeErrorDeliveryBackoffState();
|
|
14202
|
-
this.agentSpawnFailBackoff.set(agentId, state);
|
|
14203
|
-
}
|
|
14204
|
-
return state;
|
|
14665
|
+
return this.lifecycleRecords.getOrCreateSpawnFailBackoff(agentId, createRuntimeErrorDeliveryBackoffState);
|
|
14205
14666
|
}
|
|
14206
14667
|
isSpawnFailBackoffActive(agentId) {
|
|
14207
|
-
const state = this.
|
|
14668
|
+
const state = this.lifecycleRecords.getSpawnFailBackoff(agentId);
|
|
14208
14669
|
if (!state) return false;
|
|
14209
14670
|
return state.untilMs > 0 && this.clockNow() < state.untilMs;
|
|
14210
14671
|
}
|
|
@@ -14228,7 +14689,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14228
14689
|
state.untilMs = this.clockNow() + Math.floor(baseDelay);
|
|
14229
14690
|
if (state.timer) clearTimeout(state.timer);
|
|
14230
14691
|
state.timer = setTimeout(() => {
|
|
14231
|
-
const s = this.
|
|
14692
|
+
const s = this.lifecycleRecords.getSpawnFailBackoff(agentId);
|
|
14232
14693
|
if (s) {
|
|
14233
14694
|
s.timer = null;
|
|
14234
14695
|
s.untilMs = 0;
|
|
@@ -14238,10 +14699,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14238
14699
|
return { backoffActive: true, attempts: state.attempts, untilMs: state.untilMs };
|
|
14239
14700
|
}
|
|
14240
14701
|
resetSpawnFailBackoff(agentId, closeResult = "advanced") {
|
|
14241
|
-
const state = this.
|
|
14702
|
+
const state = this.lifecycleRecords.getSpawnFailBackoff(agentId);
|
|
14242
14703
|
if (!state) return;
|
|
14243
14704
|
if (state.timer) clearTimeout(state.timer);
|
|
14244
|
-
this.
|
|
14705
|
+
this.lifecycleRecords.deleteSpawnFailBackoff(agentId);
|
|
14245
14706
|
this.closeNoProcessResidency(agentId, closeResult, { negativeEvidenceBucket: "spawn_fail_cooldown_reset" });
|
|
14246
14707
|
}
|
|
14247
14708
|
// ----- RUNTIME-ERROR FINGERPRINT FENCE (per-agent) ---------------------
|
|
@@ -14266,9 +14727,9 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14266
14727
|
}
|
|
14267
14728
|
}
|
|
14268
14729
|
resetRuntimeErrorFingerprintFence(agentId, resetSource, ap) {
|
|
14269
|
-
const state = this.
|
|
14730
|
+
const state = this.lifecycleRecords.getRuntimeErrorFingerprintFence(agentId);
|
|
14270
14731
|
if (!state) return;
|
|
14271
|
-
this.
|
|
14732
|
+
this.lifecycleRecords.deleteRuntimeErrorFingerprintFence(agentId);
|
|
14272
14733
|
this.recordDaemonTrace("daemon.agent.runtime_error_fingerprint_fence.reset", {
|
|
14273
14734
|
agentId,
|
|
14274
14735
|
runtime: ap?.config.runtime,
|
|
@@ -14279,6 +14740,17 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14279
14740
|
reset_source: resetSource
|
|
14280
14741
|
});
|
|
14281
14742
|
}
|
|
14743
|
+
resetRuntimeErrorFingerprintFenceIfNonresident(agentId, resetSource, ap) {
|
|
14744
|
+
if (this.agents.has(agentId)) return;
|
|
14745
|
+
if (this.lifecycleRecords.getRestartSnapshot(agentId)) return;
|
|
14746
|
+
if (this.lifecycleRecords.getTerminalFailure(agentId)) return;
|
|
14747
|
+
this.resetRuntimeErrorFingerprintFence(agentId, resetSource, ap);
|
|
14748
|
+
}
|
|
14749
|
+
repairNonresidentRuntimeErrorFingerprintFences(context) {
|
|
14750
|
+
for (const agentId of [...this.lifecycleRecords.runtimeErrorFingerprintFenceAgentIds()]) {
|
|
14751
|
+
this.resetRuntimeErrorFingerprintFenceIfNonresident(agentId, `invariant_repair:${context}`);
|
|
14752
|
+
}
|
|
14753
|
+
}
|
|
14282
14754
|
formatRuntimeErrorFingerprintFenceDetail(state) {
|
|
14283
14755
|
return [
|
|
14284
14756
|
`Runtime stopped after ${state.attempts} repeated runtime errors with the same fingerprint (${state.fingerprint}).`,
|
|
@@ -14289,7 +14761,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14289
14761
|
noteRuntimeErrorFingerprintFence(agentId, ap, message, fingerprint, terminalFailure, stickyTerminalFailure) {
|
|
14290
14762
|
if (!fingerprint) return null;
|
|
14291
14763
|
if (stickyTerminalFailure || terminalFailure?.actionRequired) return null;
|
|
14292
|
-
let state = this.
|
|
14764
|
+
let state = this.lifecycleRecords.getRuntimeErrorFingerprintFence(agentId);
|
|
14293
14765
|
if (!state || state.fingerprint !== fingerprint) {
|
|
14294
14766
|
state = {
|
|
14295
14767
|
fingerprint,
|
|
@@ -14298,7 +14770,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14298
14770
|
detail: "",
|
|
14299
14771
|
launchId: ap.launchId
|
|
14300
14772
|
};
|
|
14301
|
-
this.
|
|
14773
|
+
this.lifecycleRecords.setRuntimeErrorFingerprintFence(agentId, state);
|
|
14302
14774
|
}
|
|
14303
14775
|
state.attempts += 1;
|
|
14304
14776
|
state.lastRuntimeError = message;
|
|
@@ -14328,7 +14800,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14328
14800
|
attempts: state.attempts,
|
|
14329
14801
|
threshold: RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD
|
|
14330
14802
|
}, "error");
|
|
14331
|
-
this.
|
|
14803
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
14332
14804
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
14333
14805
|
this.cleanupTerminalRuntimeFailure(agentId, ap, state.detail);
|
|
14334
14806
|
}
|
|
@@ -14380,7 +14852,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14380
14852
|
}
|
|
14381
14853
|
this.commitApmIdleState(agentId, ap, false);
|
|
14382
14854
|
this.startRuntimeTrace(agentId, ap, "async-rejected-idle-delivery-retry", messages);
|
|
14383
|
-
this.
|
|
14855
|
+
this.broadcastMessageReceivedActivity(agentId);
|
|
14384
14856
|
const accepted = this.deliverInboxUpdateViaStdin(
|
|
14385
14857
|
agentId,
|
|
14386
14858
|
ap,
|
|
@@ -14426,11 +14898,46 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14426
14898
|
return this.sendStdinNotification(agentId, { forceUnsupportedRetry: true });
|
|
14427
14899
|
}
|
|
14428
14900
|
clearRuntimeErrorDeliveryBackoff(ap) {
|
|
14429
|
-
if (ap.runtimeErrorDeliveryBackoff.timer) {
|
|
14901
|
+
if (ap.runtimeErrorDeliveryBackoff.kind === "backing_off" && ap.runtimeErrorDeliveryBackoff.timer) {
|
|
14430
14902
|
clearTimeout(ap.runtimeErrorDeliveryBackoff.timer);
|
|
14431
14903
|
}
|
|
14432
14904
|
ap.runtimeErrorDeliveryBackoff = createRuntimeErrorDeliveryBackoffState();
|
|
14433
14905
|
}
|
|
14906
|
+
clearPendingTrajectoryTimer(ap) {
|
|
14907
|
+
if (ap.pendingTrajectory?.timer) {
|
|
14908
|
+
clearTimeout(ap.pendingTrajectory.timer);
|
|
14909
|
+
}
|
|
14910
|
+
ap.pendingTrajectory = null;
|
|
14911
|
+
}
|
|
14912
|
+
clearActivityHeartbeat(ap) {
|
|
14913
|
+
if (ap.activityHeartbeat.kind === "inactive") return;
|
|
14914
|
+
clearInterval(ap.activityHeartbeat.timer);
|
|
14915
|
+
ap.activityHeartbeat = { kind: "inactive" };
|
|
14916
|
+
}
|
|
14917
|
+
broadcastMessageReceivedActivity(agentId) {
|
|
14918
|
+
this.broadcastActivity(agentId, "working", "Message received", [], void 0, "message_received");
|
|
14919
|
+
}
|
|
14920
|
+
toolActivityDetailKind(toolName) {
|
|
14921
|
+
switch (resolveToolSemantic(toolName) ?? toolName) {
|
|
14922
|
+
case "bash":
|
|
14923
|
+
return "running_command";
|
|
14924
|
+
case "check_messages":
|
|
14925
|
+
case "receive_message":
|
|
14926
|
+
return "checking_messages";
|
|
14927
|
+
default:
|
|
14928
|
+
return "other";
|
|
14929
|
+
}
|
|
14930
|
+
}
|
|
14931
|
+
disposeAgentProcessTimers(ap, options = {}) {
|
|
14932
|
+
this.clearRuntimeErrorDeliveryBackoff(ap);
|
|
14933
|
+
this.clearPendingTrajectoryTimer(ap);
|
|
14934
|
+
this.clearActivityHeartbeat(ap);
|
|
14935
|
+
this.clearRuntimeStartupTimeout(ap);
|
|
14936
|
+
if (options.includeCompactionWatchdog ?? true) {
|
|
14937
|
+
this.clearCompactionWatchdog(ap);
|
|
14938
|
+
}
|
|
14939
|
+
this.clearStalledRecoverySigtermWatchdog(ap);
|
|
14940
|
+
}
|
|
14434
14941
|
clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, resetSource) {
|
|
14435
14942
|
if (ap.runtimeErrorDeliveryBackoff.attempts === 0 && ap.runtimeErrorDeliveryBackoff.untilMs === 0) return;
|
|
14436
14943
|
const attempts = ap.runtimeErrorDeliveryBackoff.attempts;
|
|
@@ -14450,16 +14957,22 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14450
14957
|
this.clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, eventKind);
|
|
14451
14958
|
}
|
|
14452
14959
|
runtimeErrorDeliveryBackoffRemainingMs(ap) {
|
|
14960
|
+
if (ap.runtimeErrorDeliveryBackoff.kind === "idle") return 0;
|
|
14453
14961
|
return Math.max(0, ap.runtimeErrorDeliveryBackoff.untilMs - Date.now());
|
|
14454
14962
|
}
|
|
14963
|
+
runtimeErrorDeliveryBackoffTimerScheduled(ap) {
|
|
14964
|
+
return ap.runtimeErrorDeliveryBackoff.kind === "backing_off" && ap.runtimeErrorDeliveryBackoff.timer !== null;
|
|
14965
|
+
}
|
|
14455
14966
|
scheduleRuntimeErrorDeliveryBackoffFlush(agentId, ap) {
|
|
14967
|
+
const state = ap.runtimeErrorDeliveryBackoff;
|
|
14968
|
+
if (state.kind === "idle") return false;
|
|
14456
14969
|
const delayMs = this.runtimeErrorDeliveryBackoffRemainingMs(ap);
|
|
14457
|
-
if (delayMs <= 0 ||
|
|
14458
|
-
|
|
14459
|
-
ap.runtimeErrorDeliveryBackoff.timer = null;
|
|
14970
|
+
if (delayMs <= 0 || state.timer) return false;
|
|
14971
|
+
state.timer = setTimeout(() => {
|
|
14972
|
+
if (ap.runtimeErrorDeliveryBackoff === state) state.timer = null;
|
|
14460
14973
|
this.flushRuntimeErrorDeliveryBackoff(agentId);
|
|
14461
14974
|
}, delayMs);
|
|
14462
|
-
|
|
14975
|
+
state.timer.unref?.();
|
|
14463
14976
|
return true;
|
|
14464
14977
|
}
|
|
14465
14978
|
recoverableRuntimeDeliveryBackoffReason(message, terminalFailure, stickyTerminalFailure, reasonOverride) {
|
|
@@ -14490,13 +15003,16 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14490
15003
|
const cappedDelayMs = Math.min(this.runtimeErrorDeliveryBackoffMaxMs, exponentialDelayMs);
|
|
14491
15004
|
const jitterMs = Math.floor(cappedDelayMs * this.runtimeErrorDeliveryBackoffJitterRatio * Math.random());
|
|
14492
15005
|
const delayMs = Math.min(this.runtimeErrorDeliveryBackoffMaxMs, cappedDelayMs + jitterMs);
|
|
14493
|
-
if (ap.runtimeErrorDeliveryBackoff.timer) {
|
|
15006
|
+
if (ap.runtimeErrorDeliveryBackoff.kind === "backing_off" && ap.runtimeErrorDeliveryBackoff.timer) {
|
|
14494
15007
|
clearTimeout(ap.runtimeErrorDeliveryBackoff.timer);
|
|
14495
|
-
ap.runtimeErrorDeliveryBackoff.timer = null;
|
|
14496
15008
|
}
|
|
14497
|
-
ap.runtimeErrorDeliveryBackoff
|
|
14498
|
-
|
|
14499
|
-
|
|
15009
|
+
ap.runtimeErrorDeliveryBackoff = {
|
|
15010
|
+
kind: "backing_off",
|
|
15011
|
+
attempts,
|
|
15012
|
+
reason,
|
|
15013
|
+
untilMs: Date.now() + delayMs,
|
|
15014
|
+
timer: null
|
|
15015
|
+
};
|
|
14500
15016
|
if (ap.inbox.length > 0) {
|
|
14501
15017
|
this.scheduleRuntimeErrorDeliveryBackoffFlush(agentId, ap);
|
|
14502
15018
|
}
|
|
@@ -14536,7 +15052,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14536
15052
|
runtime_error_backoff_remaining_ms: remainingMs,
|
|
14537
15053
|
runtime_error_backoff_attempts: ap.runtimeErrorDeliveryBackoff.attempts,
|
|
14538
15054
|
runtime_error_backoff_reason: ap.runtimeErrorDeliveryBackoff.reason || void 0,
|
|
14539
|
-
runtime_error_backoff_timer_scheduled: scheduled || ap
|
|
15055
|
+
runtime_error_backoff_timer_scheduled: scheduled || this.runtimeErrorDeliveryBackoffTimerScheduled(ap)
|
|
14540
15056
|
}));
|
|
14541
15057
|
return true;
|
|
14542
15058
|
}
|
|
@@ -14571,7 +15087,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14571
15087
|
}
|
|
14572
15088
|
this.commitApmIdleState(agentId, ap, false);
|
|
14573
15089
|
this.startRuntimeTrace(agentId, ap, "runtime-error-backoff-idle-delivery", messages);
|
|
14574
|
-
this.
|
|
15090
|
+
this.broadcastMessageReceivedActivity(agentId);
|
|
14575
15091
|
const accepted2 = this.deliverInboxUpdateViaStdin(
|
|
14576
15092
|
agentId,
|
|
14577
15093
|
ap,
|
|
@@ -14752,7 +15268,11 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14752
15268
|
path: input.pathname,
|
|
14753
15269
|
query_keys: input.queryKeys,
|
|
14754
15270
|
error_name: input.errorName,
|
|
14755
|
-
error_message: input.errorMessage
|
|
15271
|
+
error_message: input.errorMessage,
|
|
15272
|
+
response_status_code: input.responseStatusCode,
|
|
15273
|
+
response_code: input.responseCode,
|
|
15274
|
+
lifecycle_invalid_agent_id: input.lifecycleInvalidAgentId,
|
|
15275
|
+
lifecycle_invalid_context: input.lifecycleInvalidContext
|
|
14756
15276
|
}, "error");
|
|
14757
15277
|
}
|
|
14758
15278
|
recordAgentProxyTransportNormalizedError(agentId, input) {
|
|
@@ -14786,7 +15306,9 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14786
15306
|
type: "agent:activity",
|
|
14787
15307
|
agentId,
|
|
14788
15308
|
activity: activity.statusEntry.activity,
|
|
15309
|
+
activityKind: activity.statusEntry.activityKind ?? activity.statusEntry.activity,
|
|
14789
15310
|
detail: activity.statusEntry.detail,
|
|
15311
|
+
detailKind: activity.statusEntry.detailKind ?? "daemon_activity",
|
|
14790
15312
|
entries: activity.entries,
|
|
14791
15313
|
launchId: ap?.launchId || void 0,
|
|
14792
15314
|
clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0
|
|
@@ -14796,8 +15318,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14796
15318
|
this.sendToServer({
|
|
14797
15319
|
type: "agent:activity",
|
|
14798
15320
|
agentId,
|
|
14799
|
-
activity: ap.lastActivity || "online",
|
|
15321
|
+
activity: ap.lastActivity || ap.lastActivityKind || "online",
|
|
15322
|
+
activityKind: ap.lastActivityKind || "online",
|
|
14800
15323
|
detail: ap.lastActivityDetail || "",
|
|
15324
|
+
detailKind: ap.lastActivityDetailKind || "none",
|
|
14801
15325
|
entries: [runtimeDiagnosticTrajectoryEntry(event)],
|
|
14802
15326
|
launchId: ap.launchId || void 0,
|
|
14803
15327
|
clientSeq: this.nextActivityClientSeq(agentId)
|
|
@@ -14809,12 +15333,46 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14809
15333
|
...runtimeDiagnosticTraceAttrs(event)
|
|
14810
15334
|
});
|
|
14811
15335
|
}
|
|
15336
|
+
/**
|
|
15337
|
+
* APM 1.6 6a — surface a generic structured "working" signal from an
|
|
15338
|
+
* internal_progress liveness tick during a long turn. Only transitions INTO
|
|
15339
|
+
* the runtime-progress state once (idempotent while already in it) so the
|
|
15340
|
+
* high-frequency Claude partial-message stream does not spam a rendered status
|
|
15341
|
+
* line every tick; the activity heartbeat then keeps the signal live. Carries
|
|
15342
|
+
* no raw content — a bounded "Working" detail only. Never marks a subagent.
|
|
15343
|
+
*/
|
|
15344
|
+
maybeBroadcastRuntimeProgressActivity(agentId, ap) {
|
|
15345
|
+
const alreadyLive = ap.lastActivityKind === "working" || ap.lastActivityKind === "thinking";
|
|
15346
|
+
if (alreadyLive) return;
|
|
15347
|
+
this.broadcastActivity(agentId, "working", "Working", [], void 0, "runtime_progress");
|
|
15348
|
+
}
|
|
15349
|
+
recordSubagentProgressActivity(agentId, ap, event) {
|
|
15350
|
+
this.flushPendingTrajectory(agentId);
|
|
15351
|
+
this.broadcastActivity(
|
|
15352
|
+
agentId,
|
|
15353
|
+
"working",
|
|
15354
|
+
subagentProgressDetail(event),
|
|
15355
|
+
[],
|
|
15356
|
+
void 0,
|
|
15357
|
+
"subagent_activity",
|
|
15358
|
+
"working",
|
|
15359
|
+
subagentLineageFromEvent(event)
|
|
15360
|
+
);
|
|
15361
|
+
this.recordDaemonTrace("daemon.runtime.subagent.progress", {
|
|
15362
|
+
agentId,
|
|
15363
|
+
launchId: ap.launchId || void 0,
|
|
15364
|
+
runtime: ap.config.runtime,
|
|
15365
|
+
...subagentProgressTraceAttrs(event)
|
|
15366
|
+
});
|
|
15367
|
+
}
|
|
14812
15368
|
recordRuntimeRecoveryActivity(agentId, ap, event) {
|
|
14813
15369
|
this.sendToServer({
|
|
14814
15370
|
type: "agent:activity",
|
|
14815
15371
|
agentId,
|
|
14816
|
-
activity: ap.lastActivity || "online",
|
|
15372
|
+
activity: ap.lastActivity || ap.lastActivityKind || "online",
|
|
15373
|
+
activityKind: ap.lastActivityKind || "online",
|
|
14817
15374
|
detail: ap.lastActivityDetail || "",
|
|
15375
|
+
detailKind: ap.lastActivityDetailKind || "none",
|
|
14818
15376
|
entries: [runtimeRecoveryTrajectoryEntry(event)],
|
|
14819
15377
|
launchId: ap.launchId || void 0,
|
|
14820
15378
|
clientSeq: this.nextActivityClientSeq(agentId)
|
|
@@ -14905,7 +15463,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14905
15463
|
pid: typeof ap.runtime.pid === "number" ? ap.runtime.pid : void 0
|
|
14906
15464
|
};
|
|
14907
15465
|
}
|
|
14908
|
-
startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
|
|
15466
|
+
startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false, resumeMessages) {
|
|
14909
15467
|
const startSnapshot = this.agentStarts.snapshot();
|
|
14910
15468
|
return {
|
|
14911
15469
|
agentId,
|
|
@@ -14916,6 +15474,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14916
15474
|
launch_id_present: Boolean(launchId),
|
|
14917
15475
|
wake_message_present: Boolean(wakeMessage),
|
|
14918
15476
|
wake_message_transient: Boolean(wakeMessage && wakeMessageTransient),
|
|
15477
|
+
resume_messages_count: resumeMessages?.length ?? 0,
|
|
14919
15478
|
unread_channels_count: unreadSummary ? Object.keys(unreadSummary).length : 0,
|
|
14920
15479
|
resume_prompt_present: Boolean(resumePrompt),
|
|
14921
15480
|
queue_depth: startSnapshot.queueDepth,
|
|
@@ -15042,7 +15601,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15042
15601
|
rebindRunningStart(agentId, start, reason) {
|
|
15043
15602
|
const ap = this.agents.get(agentId);
|
|
15044
15603
|
if (!ap) {
|
|
15045
|
-
this.
|
|
15604
|
+
this.lifecycleRecords.setPendingStartRebind(agentId, {
|
|
15605
|
+
...start,
|
|
15606
|
+
stopEpochAtRebind: this.lifecycleRecords.stopEpoch(agentId)
|
|
15607
|
+
});
|
|
15046
15608
|
return false;
|
|
15047
15609
|
}
|
|
15048
15610
|
const previousLaunchId = ap.launchId;
|
|
@@ -15058,7 +15620,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15058
15620
|
...start.config,
|
|
15059
15621
|
sessionId: nextConfigSessionId
|
|
15060
15622
|
};
|
|
15061
|
-
this.
|
|
15623
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15062
15624
|
config: this.buildRestartSafeConfig(ap.config, nextConfigSessionId),
|
|
15063
15625
|
sessionId: nextConfigSessionId,
|
|
15064
15626
|
launchId: nextLaunchId
|
|
@@ -15076,32 +15638,41 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15076
15638
|
}
|
|
15077
15639
|
return true;
|
|
15078
15640
|
}
|
|
15079
|
-
async startAgent(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
|
|
15080
|
-
this.recordDaemonTrace("daemon.agent.start.requested", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
|
|
15641
|
+
async startAgent(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false, resumeMessages) {
|
|
15642
|
+
this.recordDaemonTrace("daemon.agent.start.requested", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages));
|
|
15081
15643
|
if (this.agents.has(agentId)) {
|
|
15082
15644
|
this.recordDaemonTrace("daemon.agent.start.ignored", {
|
|
15083
|
-
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
|
|
15645
|
+
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages),
|
|
15084
15646
|
reason: "already_running"
|
|
15085
15647
|
});
|
|
15086
|
-
this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_running");
|
|
15648
|
+
this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages }, "already_running");
|
|
15087
15649
|
logger.info(`[Agent ${agentId}] Start rebound (already running)`);
|
|
15088
15650
|
return;
|
|
15089
15651
|
}
|
|
15090
15652
|
if (this.agentStarts.hasStarting(agentId)) {
|
|
15091
15653
|
this.recordDaemonTrace("daemon.agent.start.ignored", {
|
|
15092
|
-
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
|
|
15654
|
+
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages),
|
|
15093
15655
|
reason: "already_starting"
|
|
15094
15656
|
});
|
|
15095
|
-
this.
|
|
15657
|
+
this.lifecycleRecords.setPendingStartRebind(agentId, {
|
|
15658
|
+
config,
|
|
15659
|
+
wakeMessage,
|
|
15660
|
+
unreadSummary,
|
|
15661
|
+
resumePrompt,
|
|
15662
|
+
launchId,
|
|
15663
|
+
wakeMessageTransient,
|
|
15664
|
+
resumeMessages,
|
|
15665
|
+
stopEpochAtRebind: this.lifecycleRecords.stopEpoch(agentId)
|
|
15666
|
+
});
|
|
15096
15667
|
logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
|
|
15097
15668
|
return;
|
|
15098
15669
|
}
|
|
15099
15670
|
if (this.agentStarts.hasQueued(agentId)) {
|
|
15100
15671
|
this.recordDaemonTrace("daemon.agent.start.ignored", {
|
|
15101
|
-
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
|
|
15672
|
+
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages),
|
|
15102
15673
|
reason: "already_queued"
|
|
15103
15674
|
});
|
|
15104
|
-
this.rebindQueuedStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_queued");
|
|
15675
|
+
this.rebindQueuedStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages }, "already_queued");
|
|
15105
15676
|
logger.info(`[Agent ${agentId}] Queued start rebound (startup already queued)`);
|
|
15106
15677
|
return;
|
|
15107
15678
|
}
|
|
@@ -15111,6 +15682,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15111
15682
|
config,
|
|
15112
15683
|
wakeMessage,
|
|
15113
15684
|
wakeMessageTransient,
|
|
15685
|
+
resumeMessages,
|
|
15114
15686
|
unreadSummary,
|
|
15115
15687
|
resumePrompt,
|
|
15116
15688
|
launchId,
|
|
@@ -15118,7 +15690,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15118
15690
|
reject
|
|
15119
15691
|
};
|
|
15120
15692
|
this.agentStarts.enqueue(item);
|
|
15121
|
-
this.recordDaemonTrace("daemon.agent.start.queued", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
|
|
15693
|
+
this.recordDaemonTrace("daemon.agent.start.queued", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages));
|
|
15122
15694
|
const startSnapshot = this.agentStarts.snapshot();
|
|
15123
15695
|
this.enterNoProcessResidency(
|
|
15124
15696
|
"queued_start",
|
|
@@ -15141,7 +15713,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15141
15713
|
if (pumpState.kind === "rate_limited") {
|
|
15142
15714
|
const { item: next, waitMs } = pumpState;
|
|
15143
15715
|
this.recordDaemonTrace("daemon.agent.start.rate_limited", {
|
|
15144
|
-
...this.startQueueTraceAttrs(next.agentId, next.config, next.wakeMessage, next.unreadSummary, next.resumePrompt, next.launchId, next.wakeMessageTransient),
|
|
15716
|
+
...this.startQueueTraceAttrs(next.agentId, next.config, next.wakeMessage, next.unreadSummary, next.resumePrompt, next.launchId, next.wakeMessageTransient, next.resumeMessages),
|
|
15145
15717
|
wait_ms: waitMs
|
|
15146
15718
|
});
|
|
15147
15719
|
this.agentStarts.schedulePump(waitMs, () => this.pumpAgentStartQueue());
|
|
@@ -15153,7 +15725,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15153
15725
|
const { item: item2 } = dequeued;
|
|
15154
15726
|
this.closeNoProcessResidency(item2.agentId, "suppressed", { negativeEvidenceBucket: "stale_queue_item" });
|
|
15155
15727
|
this.recordDaemonTrace("daemon.agent.start.skipped", {
|
|
15156
|
-
...this.startQueueTraceAttrs(item2.agentId, item2.config, item2.wakeMessage, item2.unreadSummary, item2.resumePrompt, item2.launchId, item2.wakeMessageTransient),
|
|
15728
|
+
...this.startQueueTraceAttrs(item2.agentId, item2.config, item2.wakeMessage, item2.unreadSummary, item2.resumePrompt, item2.launchId, item2.wakeMessageTransient, item2.resumeMessages),
|
|
15157
15729
|
reason: "stale_queue_item"
|
|
15158
15730
|
});
|
|
15159
15731
|
this.pumpAgentStartQueue();
|
|
@@ -15163,13 +15735,16 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15163
15735
|
if (this.agents.has(item.agentId) || this.agentStarts.hasStarting(item.agentId)) {
|
|
15164
15736
|
this.closeNoProcessResidency(item.agentId, "suppressed", { negativeEvidenceBucket: "already_running_or_starting" });
|
|
15165
15737
|
this.recordDaemonTrace("daemon.agent.start.skipped", {
|
|
15166
|
-
...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
|
|
15738
|
+
...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient, item.resumeMessages),
|
|
15167
15739
|
reason: "already_running_or_starting"
|
|
15168
15740
|
});
|
|
15169
15741
|
if (this.agents.has(item.agentId)) {
|
|
15170
15742
|
this.rebindRunningStart(item.agentId, item, "already_running_or_starting");
|
|
15171
15743
|
} else {
|
|
15172
|
-
this.
|
|
15744
|
+
this.lifecycleRecords.setPendingStartRebind(item.agentId, {
|
|
15745
|
+
...item,
|
|
15746
|
+
stopEpochAtRebind: this.lifecycleRecords.stopEpoch(item.agentId)
|
|
15747
|
+
});
|
|
15173
15748
|
}
|
|
15174
15749
|
logger.info(`[Agent ${item.agentId}] Queued start skipped (already running or starting)`);
|
|
15175
15750
|
item.resolve();
|
|
@@ -15190,7 +15765,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15190
15765
|
logger.info(
|
|
15191
15766
|
`[Agent ${item.agentId}] Dequeued start (remaining=${startSnapshot.queueDepth}, active=${startSnapshot.activeStarts})`
|
|
15192
15767
|
);
|
|
15193
|
-
this.recordDaemonTrace("daemon.agent.start.dequeued", this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient));
|
|
15768
|
+
this.recordDaemonTrace("daemon.agent.start.dequeued", this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient, item.resumeMessages));
|
|
15194
15769
|
this.startAgentNow(
|
|
15195
15770
|
item.agentId,
|
|
15196
15771
|
item.config,
|
|
@@ -15198,7 +15773,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15198
15773
|
item.unreadSummary,
|
|
15199
15774
|
item.resumePrompt,
|
|
15200
15775
|
item.launchId,
|
|
15201
|
-
item.wakeMessageTransient ?? false
|
|
15776
|
+
item.wakeMessageTransient ?? false,
|
|
15777
|
+
item.resumeMessages
|
|
15202
15778
|
).then(() => {
|
|
15203
15779
|
this.releaseAgentStartSlot(item.agentId, "spawn attempted");
|
|
15204
15780
|
item.resolve();
|
|
@@ -15229,7 +15805,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15229
15805
|
this.startingInboxes.cancelStart(agentId);
|
|
15230
15806
|
this.assertStartPendingDeliveryInvariants("cancel-queued-start");
|
|
15231
15807
|
this.recordDaemonTrace("daemon.agent.start.cancelled", {
|
|
15232
|
-
...this.startQueueTraceAttrs(agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
|
|
15808
|
+
...this.startQueueTraceAttrs(agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient, item.resumeMessages),
|
|
15233
15809
|
reason
|
|
15234
15810
|
}, "cancelled");
|
|
15235
15811
|
logger.info(`[Agent ${agentId}] Queued start cancelled (${reason})`);
|
|
@@ -15240,7 +15816,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15240
15816
|
const cancelled = this.agentStarts.cancelAllQueued((item) => {
|
|
15241
15817
|
this.closeNoProcessResidency(item.agentId, "suppressed", { negativeEvidenceBucket: "start_cancelled" });
|
|
15242
15818
|
this.recordDaemonTrace("daemon.agent.start.cancelled", {
|
|
15243
|
-
...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
|
|
15819
|
+
...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient, item.resumeMessages),
|
|
15244
15820
|
reason
|
|
15245
15821
|
}, "cancelled");
|
|
15246
15822
|
logger.info(`[Agent ${item.agentId}] Queued start cancelled (${reason})`);
|
|
@@ -15251,25 +15827,35 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15251
15827
|
this.startingInboxes.cancelAllStarts();
|
|
15252
15828
|
this.assertStartPendingDeliveryInvariants("cancel-all-queued-starts");
|
|
15253
15829
|
}
|
|
15254
|
-
async startAgentNow(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
|
|
15830
|
+
async startAgentNow(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false, resumeMessages) {
|
|
15255
15831
|
if (this.agents.has(agentId)) {
|
|
15256
15832
|
this.recordDaemonTrace("daemon.agent.spawn.skipped", {
|
|
15257
|
-
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
|
|
15833
|
+
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages),
|
|
15258
15834
|
reason: "already_running"
|
|
15259
15835
|
});
|
|
15260
|
-
this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_running");
|
|
15836
|
+
this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages }, "already_running");
|
|
15261
15837
|
logger.info(`[Agent ${agentId}] Start rebound (already running)`);
|
|
15262
15838
|
return;
|
|
15263
15839
|
}
|
|
15264
15840
|
if (this.agentStarts.hasStarting(agentId)) {
|
|
15265
15841
|
this.recordDaemonTrace("daemon.agent.spawn.skipped", {
|
|
15266
|
-
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
|
|
15842
|
+
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages),
|
|
15267
15843
|
reason: "already_starting"
|
|
15268
15844
|
});
|
|
15269
|
-
this.
|
|
15845
|
+
this.lifecycleRecords.setPendingStartRebind(agentId, {
|
|
15846
|
+
config,
|
|
15847
|
+
wakeMessage,
|
|
15848
|
+
unreadSummary,
|
|
15849
|
+
resumePrompt,
|
|
15850
|
+
launchId,
|
|
15851
|
+
wakeMessageTransient,
|
|
15852
|
+
resumeMessages,
|
|
15853
|
+
stopEpochAtRebind: this.lifecycleRecords.stopEpoch(agentId)
|
|
15854
|
+
});
|
|
15270
15855
|
logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
|
|
15271
15856
|
return;
|
|
15272
15857
|
}
|
|
15858
|
+
let startStopEpoch = this.lifecycleRecords.stopEpoch(agentId);
|
|
15273
15859
|
this.agentStarts.markStarting(agentId);
|
|
15274
15860
|
let agentProcess = null;
|
|
15275
15861
|
let pendingStartRebind;
|
|
@@ -15299,9 +15885,9 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15299
15885
|
}
|
|
15300
15886
|
}
|
|
15301
15887
|
}
|
|
15302
|
-
pendingStartRebind = this.
|
|
15888
|
+
pendingStartRebind = this.lifecycleRecords.getPendingStartRebind(agentId);
|
|
15303
15889
|
if (pendingStartRebind) {
|
|
15304
|
-
this.
|
|
15890
|
+
this.lifecycleRecords.deletePendingStartRebind(agentId);
|
|
15305
15891
|
const previousWakeMessage = wakeMessage;
|
|
15306
15892
|
this.startingInboxes.rebindWake(
|
|
15307
15893
|
agentId,
|
|
@@ -15314,6 +15900,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15314
15900
|
unreadSummary = pendingStartRebind.unreadSummary;
|
|
15315
15901
|
resumePrompt = pendingStartRebind.resumePrompt;
|
|
15316
15902
|
launchId = pendingStartRebind.launchId || launchId;
|
|
15903
|
+
resumeMessages = pendingStartRebind.resumeMessages;
|
|
15904
|
+
startStopEpoch = pendingStartRebind.stopEpochAtRebind ?? startStopEpoch;
|
|
15317
15905
|
if (pendingStartRebind.wakeMessage) {
|
|
15318
15906
|
wakeMessage = pendingStartRebind.wakeMessage;
|
|
15319
15907
|
wakeMessageTransient = pendingStartRebind.wakeMessageTransient === true;
|
|
@@ -15328,7 +15916,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15328
15916
|
deadlineUnixMs: this.clockNow() + runtimeStartTimeoutMs()
|
|
15329
15917
|
}
|
|
15330
15918
|
);
|
|
15331
|
-
this.recordDaemonTrace("daemon.agent.spawn.started", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
|
|
15919
|
+
this.recordDaemonTrace("daemon.agent.spawn.started", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient, resumeMessages));
|
|
15332
15920
|
const driver = this.driverResolver(config.runtime || "claude");
|
|
15333
15921
|
const legacyWakeRuntimeProfile = wakeMessage ? runtimeProfileNotificationFromMessage(wakeMessage) : null;
|
|
15334
15922
|
if (legacyWakeRuntimeProfile?.kind === "migration") {
|
|
@@ -15359,7 +15947,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15359
15947
|
let promptSource;
|
|
15360
15948
|
let wakeMessageDeliveredAsInboxUpdate = false;
|
|
15361
15949
|
let startingInboxDeliveredAsInput = false;
|
|
15950
|
+
let resumeCatchupDeliveredAsInput = false;
|
|
15362
15951
|
const startingInboxMessages = this.startingInboxes.values(agentId);
|
|
15952
|
+
const resumeCatchupMessages = isResume && !wakeMessage && !resumePrompt ? resumeMessages ?? [] : [];
|
|
15953
|
+
const resumeCatchupInputMessages = resumeCatchupMessages.length > 0 ? [...resumeCatchupMessages, ...startingInboxMessages] : [];
|
|
15363
15954
|
if (runtimeConfig.runtimeProfileControl && !wakeMessage) {
|
|
15364
15955
|
prompt = driver.supportsNativeStandingPrompt ? NATIVE_STANDING_PROMPT_STARTUP_INPUT : formatRuntimeProfileControlStartupInput(runtimeConfig.runtimeProfileControl, driver);
|
|
15365
15956
|
promptSource = "runtime_profile_control";
|
|
@@ -15399,6 +15990,22 @@ You also have unread messages in other channels:`;
|
|
|
15399
15990
|
Use the inbox/read commands at a natural breakpoint if you choose to inspect those targets.`;
|
|
15400
15991
|
}
|
|
15401
15992
|
}
|
|
15993
|
+
} else if (resumeCatchupInputMessages.length > 0) {
|
|
15994
|
+
resumeCatchupDeliveredAsInput = true;
|
|
15995
|
+
prompt = this.formatConcreteMessagesRuntimeInput(resumeCatchupInputMessages, driver);
|
|
15996
|
+
promptSource = "resume_catchup_inbox";
|
|
15997
|
+
if (unreadSummary && Object.keys(unreadSummary).length > 0) {
|
|
15998
|
+
prompt += `
|
|
15999
|
+
|
|
16000
|
+
Some unread channels may not be included in this bounded startup batch:`;
|
|
16001
|
+
for (const [ch, count] of Object.entries(unreadSummary)) {
|
|
16002
|
+
prompt += `
|
|
16003
|
+
- ${ch}: ${count} unread`;
|
|
16004
|
+
}
|
|
16005
|
+
prompt += `
|
|
16006
|
+
|
|
16007
|
+
Use the inbox/read commands at a natural breakpoint if you choose to inspect those targets.`;
|
|
16008
|
+
}
|
|
15402
16009
|
} else if (startingInboxMessages.length > 0) {
|
|
15403
16010
|
startingInboxDeliveredAsInput = true;
|
|
15404
16011
|
prompt = this.formatInboxUpdateRuntimeInput(startingInboxMessages, driver);
|
|
@@ -15426,27 +16033,32 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15426
16033
|
prompt,
|
|
15427
16034
|
standingPrompt,
|
|
15428
16035
|
resumePrompt,
|
|
15429
|
-
messages: wakeMessage ? [wakeMessage] : void 0,
|
|
16036
|
+
messages: wakeMessage ? [wakeMessage] : resumeCatchupInputMessages.length > 0 ? resumeCatchupInputMessages : void 0,
|
|
15430
16037
|
unreadSummary,
|
|
15431
16038
|
sessionIdPresent: isResume,
|
|
15432
16039
|
nativeStandingPrompt: Boolean(driver.supportsNativeStandingPrompt)
|
|
15433
16040
|
});
|
|
15434
16041
|
const effectiveLaunchId = launchId || null;
|
|
15435
|
-
const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !runtimeConfig.runtimeProfileControl && (!unreadSummary || Object.keys(unreadSummary).length === 0);
|
|
16042
|
+
const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !runtimeConfig.runtimeProfileControl && resumeCatchupInputMessages.length === 0 && (!unreadSummary || Object.keys(unreadSummary).length === 0);
|
|
15436
16043
|
if (canDeferEmptyStart) {
|
|
15437
16044
|
const pendingMessages = this.startingInboxes.drainOnSpawn(agentId);
|
|
15438
16045
|
this.agentStarts.clearStarting(agentId);
|
|
15439
16046
|
this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "defer_until_concrete_message" });
|
|
15440
16047
|
this.assertStartPendingDeliveryInvariants("defer-empty-start-drain");
|
|
15441
|
-
this.
|
|
16048
|
+
if (this.lifecycleRecords.stopEpochChanged(agentId, startStopEpoch)) {
|
|
16049
|
+
this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "explicit_stop" });
|
|
16050
|
+
logger.info(`[Agent ${agentId}] Deferred ${driver.id} spawn suppressed by stop request`);
|
|
16051
|
+
return;
|
|
16052
|
+
}
|
|
16053
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15442
16054
|
config: this.buildRestartSafeConfig(runtimeConfig, runtimeConfig.sessionId || null),
|
|
15443
16055
|
sessionId: runtimeConfig.sessionId || null,
|
|
15444
16056
|
launchId: effectiveLaunchId
|
|
15445
16057
|
});
|
|
15446
16058
|
this.sendAgentStatus(agentId, "active", effectiveLaunchId);
|
|
15447
|
-
this.broadcastActivity(agentId, "online", "Process idle");
|
|
16059
|
+
this.broadcastActivity(agentId, "online", "Process idle", [], void 0, "idle");
|
|
15448
16060
|
this.recordDaemonTrace("daemon.agent.spawn.deferred", {
|
|
15449
|
-
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, effectiveLaunchId || void 0, wakeMessageTransient),
|
|
16061
|
+
...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, effectiveLaunchId || void 0, wakeMessageTransient, resumeMessages),
|
|
15450
16062
|
pending_messages_count: pendingMessages.length,
|
|
15451
16063
|
reason: "defer_until_concrete_message"
|
|
15452
16064
|
});
|
|
@@ -15481,51 +16093,53 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15481
16093
|
const initialSessionId = this.initialAgentProcessSessionId(driver, liveProcessConfig);
|
|
15482
16094
|
const restartSessionId = initialSessionId || (driver.requiresSessionInitForDelivery ? liveProcessConfig.sessionId || null : null);
|
|
15483
16095
|
const processInstanceId = randomUUID6();
|
|
16096
|
+
const startupInputMessages = wakeMessageDeliveredAsInboxUpdate && wakeMessage ? [wakeMessage, ...startingInboxMessages] : resumeCatchupDeliveredAsInput ? resumeCatchupInputMessages : startingInboxMessages;
|
|
15484
16097
|
agentProcess = {
|
|
15485
16098
|
runtime,
|
|
15486
16099
|
driver,
|
|
15487
|
-
inbox:
|
|
16100
|
+
inbox: startupInputMessages,
|
|
15488
16101
|
config: liveProcessConfig,
|
|
15489
16102
|
sessionId: initialSessionId,
|
|
15490
16103
|
sessionReadyForDelivery: this.initialSessionReadyForDelivery(driver, liveProcessConfig, initialSessionId),
|
|
15491
16104
|
launchId: effectiveLaunchId,
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
16105
|
+
startup: createAgentProcessStartupState({
|
|
16106
|
+
wakeMessage,
|
|
16107
|
+
unreadSummary,
|
|
16108
|
+
resumePrompt
|
|
16109
|
+
}),
|
|
15495
16110
|
notifications: new RuntimeNotificationState(),
|
|
15496
|
-
activityHeartbeat:
|
|
15497
|
-
startupTimeoutTimer: null,
|
|
15498
|
-
startupReadinessSatisfied: false,
|
|
16111
|
+
activityHeartbeat: { kind: "inactive" },
|
|
15499
16112
|
readinessTransition: null,
|
|
15500
|
-
|
|
15501
|
-
|
|
15502
|
-
compactionWatchdog: null,
|
|
15503
|
-
compactionStartedAt: null,
|
|
16113
|
+
activation: { kind: "idle" },
|
|
16114
|
+
compaction: { kind: "none" },
|
|
15504
16115
|
runtimeProgress: new RuntimeProgressState(Date.now()),
|
|
15505
16116
|
runtimeTraceSpan: null,
|
|
15506
16117
|
runtimeTraceCounters: createRuntimeTraceCounters(),
|
|
15507
16118
|
runtimeTelemetryResultSeq: 0,
|
|
16119
|
+
lastActivityKind: "offline",
|
|
15508
16120
|
lastActivity: "",
|
|
15509
16121
|
lastActivityDetail: "",
|
|
16122
|
+
lastActivityDetailKind: "none",
|
|
15510
16123
|
recentStdout: [],
|
|
15511
16124
|
recentStderr: [],
|
|
15512
16125
|
lastRuntimeError: null,
|
|
15513
|
-
|
|
15514
|
-
runtimeErrorSinceProgress: false,
|
|
16126
|
+
decisionErrorWindow: new DecisionErrorWindow(),
|
|
15515
16127
|
runtimeErrorDeliveryBackoff: createRuntimeErrorDeliveryBackoffState(),
|
|
15516
16128
|
spawnError: null,
|
|
15517
16129
|
processInstanceId,
|
|
15518
16130
|
spawnedAtMs: Date.now(),
|
|
15519
|
-
|
|
15520
|
-
exitSignal: null,
|
|
15521
|
-
stalledRecoverySigtermTimer: null,
|
|
16131
|
+
exit: { kind: "live", stalledRecoverySigtermTimer: null },
|
|
15522
16132
|
runtimeProfileTurnControl: liveProcessConfig.runtimeProfileControl ? runtimeProfileTurnControl(liveProcessConfig.runtimeProfileControl.kind, liveProcessConfig.runtimeProfileControl.key, "agent_config") : null,
|
|
15523
16133
|
pendingTrajectory: null,
|
|
15524
16134
|
gatedSteering: createGatedSteeringState()
|
|
15525
16135
|
};
|
|
15526
16136
|
this.startingInboxes.drainOnSpawn(agentId);
|
|
15527
16137
|
this.agents.set(agentId, agentProcess);
|
|
15528
|
-
this.
|
|
16138
|
+
if (this.lifecycleRecords.stopEpochChanged(agentId, startStopEpoch)) {
|
|
16139
|
+
await this.cleanupStoppedRuntimeStart(agentId, agentProcess);
|
|
16140
|
+
return;
|
|
16141
|
+
}
|
|
16142
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15529
16143
|
config: this.buildRestartSafeConfig(runtimeConfig, restartSessionId),
|
|
15530
16144
|
sessionId: restartSessionId,
|
|
15531
16145
|
launchId: effectiveLaunchId
|
|
@@ -15533,13 +16147,17 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15533
16147
|
if (pendingStartRebind) {
|
|
15534
16148
|
this.recordStartRebind(agentId, pendingStartRebind, "startup_registered", originalLaunchId, effectiveLaunchId, agentProcess.sessionId);
|
|
15535
16149
|
}
|
|
15536
|
-
this.startRuntimeTrace(agentId, agentProcess, "spawn", wakeMessage ? [wakeMessage] : void 0, runtimeInputTraceAttrs);
|
|
16150
|
+
this.startRuntimeTrace(agentId, agentProcess, "spawn", wakeMessage ? [wakeMessage] : resumeCatchupInputMessages.length > 0 ? resumeCatchupInputMessages : void 0, runtimeInputTraceAttrs);
|
|
15537
16151
|
this.agentStarts.clearStarting(agentId);
|
|
15538
16152
|
if (runtimeConfig.runtimeProfileControl) {
|
|
15539
16153
|
this.ackInjectedRuntimeProfileControl(agentId, runtimeConfig.runtimeProfileControl, agentProcess.launchId);
|
|
15540
16154
|
}
|
|
15541
16155
|
if (wakeMessageDeliveredAsInboxUpdate) {
|
|
15542
16156
|
this.recordInboxUpdateProjection(agentId, agentProcess, agentProcess.inbox, "spawn_wake_inbox_update", "wake", prompt);
|
|
16157
|
+
} else if (resumeCatchupDeliveredAsInput) {
|
|
16158
|
+
this.recordInboxUpdateProjection(agentId, agentProcess, resumeCatchupInputMessages, "spawn_resume_catchup_inbox", "wake", prompt);
|
|
16159
|
+
this.consumeVisibleMessages(agentId, { messages: resumeCatchupInputMessages, source: "spawn_resume_catchup_inbox" });
|
|
16160
|
+
this.ackInjectedRuntimeProfileMessages(agentId, resumeCatchupInputMessages, agentProcess.launchId);
|
|
15543
16161
|
} else if (startingInboxDeliveredAsInput) {
|
|
15544
16162
|
this.recordInboxUpdateProjection(agentId, agentProcess, startingInboxMessages, "spawn_starting_inbox_update", "wake", prompt);
|
|
15545
16163
|
this.consumeVisibleMessages(agentId, { messages: startingInboxMessages, source: "spawn_starting_inbox_update" });
|
|
@@ -15564,7 +16182,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15564
16182
|
if (driver.id === "codex" && isCodexProviderReconnectLog(text)) {
|
|
15565
16183
|
if (current) {
|
|
15566
16184
|
current.recentStderr = pushRecentStderr(current.recentStderr, text);
|
|
15567
|
-
current.
|
|
16185
|
+
current.decisionErrorWindow.recordStderr(text);
|
|
15568
16186
|
}
|
|
15569
16187
|
this.recordDaemonTrace("daemon.agent.provider_reconnect", {
|
|
15570
16188
|
agentId,
|
|
@@ -15574,14 +16192,14 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15574
16192
|
});
|
|
15575
16193
|
this.broadcastActivity(agentId, "working", "Codex reconnecting to provider\u2026", [
|
|
15576
16194
|
{ kind: "text", text }
|
|
15577
|
-
]);
|
|
16195
|
+
], void 0, "runtime_reconnecting");
|
|
15578
16196
|
logger.info(`[Agent ${agentId} stderr]: ${text}`);
|
|
15579
16197
|
return;
|
|
15580
16198
|
}
|
|
15581
16199
|
if (driver.id === "codex" && isCodexBenignTransportLog(text)) return;
|
|
15582
16200
|
if (current) {
|
|
15583
16201
|
current.recentStderr = pushRecentStderr(current.recentStderr, text);
|
|
15584
|
-
current.
|
|
16202
|
+
current.decisionErrorWindow.recordStderr(text);
|
|
15585
16203
|
}
|
|
15586
16204
|
logger.error(`[Agent ${agentId} stderr]: ${text}`);
|
|
15587
16205
|
});
|
|
@@ -15603,8 +16221,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15603
16221
|
runtime.on("exit", ({ code, signal }) => {
|
|
15604
16222
|
const current = this.agents.get(agentId);
|
|
15605
16223
|
if (current && current.runtime === runtime) {
|
|
15606
|
-
current
|
|
15607
|
-
current.
|
|
16224
|
+
this.clearStalledRecoverySigtermWatchdog(current);
|
|
16225
|
+
current.exit = { kind: "exited", code, signal };
|
|
15608
16226
|
}
|
|
15609
16227
|
const exitTraceAttrs = this.runtimeExitTraceAttrs.get(runtime);
|
|
15610
16228
|
this.recordDaemonTrace("daemon.agent.process.exited", {
|
|
@@ -15629,7 +16247,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15629
16247
|
exit_code: code,
|
|
15630
16248
|
exit_signal: signal,
|
|
15631
16249
|
cause: exitCause,
|
|
15632
|
-
last_event_kind: agentProcess.
|
|
16250
|
+
last_event_kind: agentProcess.lastActivityKind || void 0,
|
|
15633
16251
|
last_event_age_ms_bucket: bucketMs(staleForMs),
|
|
15634
16252
|
uptime_ms_bucket: bucketMs(Date.now() - agentProcess.spawnedAtMs)
|
|
15635
16253
|
}, code === 0 ? "ok" : "error");
|
|
@@ -15641,19 +16259,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15641
16259
|
const ap = this.agents.get(agentId);
|
|
15642
16260
|
if (ap.runtime !== runtime) return;
|
|
15643
16261
|
ap.notifications.clearTimer();
|
|
15644
|
-
this.
|
|
15645
|
-
if (ap.pendingTrajectory?.timer) {
|
|
15646
|
-
clearTimeout(ap.pendingTrajectory.timer);
|
|
15647
|
-
}
|
|
15648
|
-
if (ap.activityHeartbeat) {
|
|
15649
|
-
clearInterval(ap.activityHeartbeat);
|
|
15650
|
-
}
|
|
16262
|
+
this.disposeAgentProcessTimers(ap, { includeCompactionWatchdog: false });
|
|
15651
16263
|
this.closeRuntimeReadinessTransition(ap, "terminal");
|
|
15652
16264
|
this.closeActivationTransition(ap, "terminal");
|
|
15653
|
-
|
|
15654
|
-
|
|
15655
|
-
const finalCode = ap.exitCode ?? code;
|
|
15656
|
-
const finalSignal = ap.exitSignal ?? signal;
|
|
16265
|
+
const finalCode = ap.exit.kind === "exited" ? ap.exit.code ?? code : code;
|
|
16266
|
+
const finalSignal = ap.exit.kind === "exited" ? ap.exit.signal ?? signal : signal;
|
|
15657
16267
|
const expectedTerminationReason = ap.gatedSteering.expectedTerminationReason;
|
|
15658
16268
|
const startupTimeoutTermination = expectedTerminationReason === "startup_timeout";
|
|
15659
16269
|
const startupRequestErrorTermination = expectedTerminationReason === "startup_request_error";
|
|
@@ -15697,52 +16307,59 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15697
16307
|
[{
|
|
15698
16308
|
kind: "text",
|
|
15699
16309
|
text: `Stored ${runtimeLabel} session ${staleSessionId} ${reasonText}. Falling back to a cold start; earlier runtime context may not be restored.`
|
|
15700
|
-
}]
|
|
16310
|
+
}],
|
|
16311
|
+
void 0,
|
|
16312
|
+
"runtime_unavailable"
|
|
15701
16313
|
);
|
|
15702
|
-
this.
|
|
16314
|
+
this.lifecycleRecords.setPendingSpawnCause(agentId, "restart_crash");
|
|
15703
16315
|
this.startAgent(
|
|
15704
16316
|
agentId,
|
|
15705
16317
|
restartConfig,
|
|
15706
|
-
ap.
|
|
15707
|
-
ap.
|
|
15708
|
-
ap.
|
|
16318
|
+
ap.startup.wakeMessage,
|
|
16319
|
+
ap.startup.unreadSummary,
|
|
16320
|
+
ap.startup.resumePrompt,
|
|
15709
16321
|
ap.launchId || void 0
|
|
15710
16322
|
).catch((err) => {
|
|
15711
16323
|
logger.error(`[Agent ${agentId}] Cold start recovery failed`, err);
|
|
15712
|
-
this.
|
|
16324
|
+
this.lifecycleRecords.deletePendingSpawnCause(agentId);
|
|
15713
16325
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
15714
|
-
this.broadcastActivity(agentId, "offline", `Crashed (${summary})`, [], ap.launchId);
|
|
16326
|
+
this.broadcastActivity(agentId, "offline", `Crashed (${summary})`, [], ap.launchId, "runtime_crashed");
|
|
15715
16327
|
});
|
|
15716
16328
|
return;
|
|
15717
16329
|
}
|
|
15718
16330
|
if (processEndedCleanly) {
|
|
16331
|
+
const pendingRestartMessages = ap.inbox.splice(0).filter((message) => !this.isTransientDelivery(message));
|
|
15719
16332
|
let queuedWakeMessage;
|
|
15720
|
-
|
|
15721
|
-
|
|
15722
|
-
|
|
15723
|
-
|
|
15724
|
-
|
|
15725
|
-
|
|
16333
|
+
const bufferedRestartMessages = [];
|
|
16334
|
+
for (const message of pendingRestartMessages) {
|
|
16335
|
+
if (!queuedWakeMessage && !this.shouldDeferWakeMessage(agentId, ap.driver, message)) {
|
|
16336
|
+
queuedWakeMessage = message;
|
|
16337
|
+
} else {
|
|
16338
|
+
bufferedRestartMessages.push(message);
|
|
15726
16339
|
}
|
|
15727
16340
|
}
|
|
15728
|
-
const unreadSummary2 = queuedWakeMessage ? buildUnreadSummary(ap.inbox, formatChannelLabel(queuedWakeMessage)) : void 0;
|
|
15729
16341
|
if (queuedWakeMessage) {
|
|
15730
16342
|
logger.info(`[Agent ${agentId}] Turn completed; restarting immediately for queued message`);
|
|
15731
16343
|
const nextConfig = this.buildRestartSafeConfig(ap.config, ap.sessionId);
|
|
15732
|
-
this.
|
|
16344
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15733
16345
|
config: nextConfig,
|
|
15734
16346
|
sessionId: ap.sessionId,
|
|
15735
16347
|
launchId: ap.launchId
|
|
15736
16348
|
});
|
|
15737
|
-
this.
|
|
15738
|
-
this.
|
|
16349
|
+
this.broadcastMessageReceivedActivity(agentId);
|
|
16350
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
15739
16351
|
if (expectedTerminationReason === "stalled_recovery") {
|
|
15740
|
-
this.
|
|
16352
|
+
this.lifecycleRecords.setPendingSpawnCause(agentId, "restart_stall");
|
|
16353
|
+
}
|
|
16354
|
+
const startPromise = this.startAgent(agentId, nextConfig, queuedWakeMessage, void 0, void 0, ap.launchId || void 0);
|
|
16355
|
+
if (bufferedRestartMessages.length > 0) {
|
|
16356
|
+
this.startingInboxes.bufferMessagesDuringStart(agentId, bufferedRestartMessages);
|
|
16357
|
+
this.assertStartPendingDeliveryInvariants("clean-exit-pending-inbox-transfer");
|
|
15741
16358
|
}
|
|
15742
|
-
|
|
16359
|
+
startPromise.catch((err) => {
|
|
15743
16360
|
logger.error(`[Agent ${agentId}] Failed to continue with queued message`, err);
|
|
15744
16361
|
if (this.reportRunnerCredentialMintFailure(agentId, err, ap.launchId, "queued_continuation")) {
|
|
15745
|
-
this.
|
|
16362
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15746
16363
|
config: nextConfig,
|
|
15747
16364
|
sessionId: ap.sessionId,
|
|
15748
16365
|
launchId: ap.launchId
|
|
@@ -15762,16 +16379,16 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15762
16379
|
});
|
|
15763
16380
|
return;
|
|
15764
16381
|
}
|
|
15765
|
-
this.
|
|
16382
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15766
16383
|
config: nextConfig,
|
|
15767
16384
|
sessionId: ap.sessionId,
|
|
15768
16385
|
launchId: ap.launchId
|
|
15769
16386
|
});
|
|
15770
|
-
this.broadcastActivity(agentId, "online", "Process idle");
|
|
16387
|
+
this.broadcastActivity(agentId, "online", "Process idle", [], void 0, "idle");
|
|
15771
16388
|
});
|
|
15772
16389
|
return;
|
|
15773
16390
|
}
|
|
15774
|
-
this.
|
|
16391
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15775
16392
|
config: this.buildRestartSafeConfig(ap.config, ap.sessionId),
|
|
15776
16393
|
sessionId: ap.sessionId,
|
|
15777
16394
|
launchId: ap.launchId
|
|
@@ -15779,11 +16396,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15779
16396
|
if (!ap.driver.supportsStdinNotification) {
|
|
15780
16397
|
logger.info(`[Agent ${agentId}] Turn completed; cached idle state for future restart`);
|
|
15781
16398
|
}
|
|
15782
|
-
this.broadcastActivity(agentId, "online", "Process idle");
|
|
16399
|
+
this.broadcastActivity(agentId, "online", "Process idle", [], void 0, "idle");
|
|
15783
16400
|
} else {
|
|
15784
16401
|
const reason = formatCrashReason(finalCode, finalSignal, ap);
|
|
15785
16402
|
if (terminalFailureDetail && isProviderStreamFailureText(terminalFailureDetail.detail)) {
|
|
15786
|
-
this.
|
|
16403
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15787
16404
|
config: this.buildRestartSafeConfig(ap.config, ap.sessionId),
|
|
15788
16405
|
sessionId: ap.sessionId,
|
|
15789
16406
|
launchId: ap.launchId
|
|
@@ -15794,10 +16411,12 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15794
16411
|
this.cacheStartupTimeoutRetryConfig(agentId, ap);
|
|
15795
16412
|
logger.warn(`[Agent ${agentId}] Startup timeout cleanup completed (${reason})`);
|
|
15796
16413
|
} else if (startupRequestErrorTermination) {
|
|
15797
|
-
this.
|
|
16414
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
16415
|
+
this.resetRuntimeErrorFingerprintFenceIfNonresident(agentId, "startup_request_error_cleanup", ap);
|
|
15798
16416
|
logger.warn(`[Agent ${agentId}] Startup request failure cleanup completed (${reason})`);
|
|
15799
16417
|
} else {
|
|
15800
|
-
this.
|
|
16418
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
16419
|
+
this.resetRuntimeErrorFingerprintFenceIfNonresident(agentId, "nonrecoverable_process_close", ap);
|
|
15801
16420
|
logger.error(`[Agent ${agentId}] Process crashed (${reason}) \u2014 marking inactive`);
|
|
15802
16421
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
15803
16422
|
}
|
|
@@ -15808,11 +16427,12 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15808
16427
|
"error",
|
|
15809
16428
|
terminalFailureDetail.detail,
|
|
15810
16429
|
[{ kind: "text", text: `Error: ${terminalFailureDetail.detail}` }],
|
|
15811
|
-
ap.launchId
|
|
16430
|
+
ap.launchId,
|
|
16431
|
+
"runtime_error"
|
|
15812
16432
|
);
|
|
15813
16433
|
}
|
|
15814
16434
|
} else if (!startupRequestErrorTermination) {
|
|
15815
|
-
this.broadcastActivity(agentId, "offline", `Crashed (${summary})`, [], ap.launchId);
|
|
16435
|
+
this.broadcastActivity(agentId, "offline", `Crashed (${summary})`, [], ap.launchId, "runtime_crashed");
|
|
15816
16436
|
}
|
|
15817
16437
|
}
|
|
15818
16438
|
}
|
|
@@ -15832,10 +16452,20 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15832
16452
|
error_present: Boolean(startResult.error),
|
|
15833
16453
|
runtime_error_class: diagnostics?.spanAttrs.runtime_error_class
|
|
15834
16454
|
}, "error");
|
|
16455
|
+
if (startResult.error) {
|
|
16456
|
+
agentProcess.lastRuntimeError = startResult.error;
|
|
16457
|
+
agentProcess.decisionErrorWindow.recordRuntimeError(startResult.error);
|
|
16458
|
+
}
|
|
16459
|
+
if (startResult.error && diagnostics?.spanAttrs.runtime_error_action_required === true) {
|
|
16460
|
+
const visibleErrorMessage = formatRuntimeLoginRequiredMessage(agentProcess.driver.id);
|
|
16461
|
+
this.broadcastActivity(agentId, "error", visibleErrorMessage, [
|
|
16462
|
+
{ kind: "text", text: `Error: ${visibleErrorMessage}` }
|
|
16463
|
+
], agentProcess.launchId, "runtime_error");
|
|
16464
|
+
}
|
|
15835
16465
|
throw new Error(`Runtime session failed to start: ${startResult.reason}${startResult.error ? ` (${startResult.error})` : ""}`);
|
|
15836
16466
|
}
|
|
15837
16467
|
this.closeNoProcessResidency(agentId, "advanced");
|
|
15838
|
-
if (this.
|
|
16468
|
+
if (this.lifecycleRecords.deleteTerminalFailure(agentId)) {
|
|
15839
16469
|
this.closeNoProcessResidency(agentId, "advanced", { negativeEvidenceBucket: "terminal_recovery_start_succeeded" });
|
|
15840
16470
|
}
|
|
15841
16471
|
this.assertStartPendingDeliveryInvariants("spawn-drain");
|
|
@@ -15845,8 +16475,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15845
16475
|
new_session: false,
|
|
15846
16476
|
process_pid_present: typeof runtime.pid === "number"
|
|
15847
16477
|
});
|
|
15848
|
-
const pendingCause = this.
|
|
15849
|
-
this.
|
|
16478
|
+
const pendingCause = this.lifecycleRecords.getPendingSpawnCause(agentId);
|
|
16479
|
+
this.lifecycleRecords.deletePendingSpawnCause(agentId);
|
|
15850
16480
|
const startCause = pendingCause ?? (isResume ? "session_resume" : wakeMessage ? "wake_message" : "explicit_start");
|
|
15851
16481
|
this.recordDaemonTrace("daemon.runtime.process.spawn", {
|
|
15852
16482
|
...this.processLifecycleIdentityAttrs(agentId, agentProcess),
|
|
@@ -15859,7 +16489,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15859
16489
|
if (pendingStartRebind && agentProcess.sessionId) {
|
|
15860
16490
|
this.sendToServer({ type: "agent:session", agentId, sessionId: agentProcess.sessionId, launchId: agentProcess.launchId || void 0 });
|
|
15861
16491
|
}
|
|
15862
|
-
this.broadcastActivity(agentId, "working", "Starting\u2026");
|
|
16492
|
+
this.broadcastActivity(agentId, "working", "Starting\u2026", [], void 0, "starting");
|
|
15863
16493
|
this.startRuntimeStartupTimeout(agentId, agentProcess, startCause);
|
|
15864
16494
|
if (wakeMessage || startingInboxMessages.length > 0) {
|
|
15865
16495
|
this.openActivationTransition(agentId, agentProcess, startCause);
|
|
@@ -15870,31 +16500,59 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15870
16500
|
} catch (err) {
|
|
15871
16501
|
this.agentStarts.clearStarting(agentId);
|
|
15872
16502
|
this.closeNoProcessResidency(agentId, "terminal", { negativeEvidenceBucket: "runtime_start_failed" });
|
|
15873
|
-
this.
|
|
16503
|
+
this.lifecycleRecords.deletePendingStartRebind(agentId);
|
|
15874
16504
|
this.cleanupFailedRuntimeStart(agentId, agentProcess, err);
|
|
15875
16505
|
throw err;
|
|
15876
16506
|
}
|
|
15877
16507
|
}
|
|
16508
|
+
async cleanupStoppedRuntimeStart(agentId, ap) {
|
|
16509
|
+
if (this.agents.get(agentId) !== ap) return;
|
|
16510
|
+
this.agentStarts.clearStarting(agentId);
|
|
16511
|
+
this.lifecycleRecords.deletePendingStartRebind(agentId);
|
|
16512
|
+
this.lifecycleRecords.deletePendingSpawnCause(agentId);
|
|
16513
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
16514
|
+
this.startingInboxes.cancelStart(agentId);
|
|
16515
|
+
ap.notifications.clearTimer();
|
|
16516
|
+
this.disposeAgentProcessTimers(ap);
|
|
16517
|
+
this.closeRuntimeReadinessTransition(ap, "terminal");
|
|
16518
|
+
this.closeActivationTransition(ap, "terminal");
|
|
16519
|
+
cleanupAgentCredentialProxy(agentId, ap.launchId);
|
|
16520
|
+
this.revokeManagedRunnerCredential(agentId, ap.config, ap.launchId);
|
|
16521
|
+
this.agents.delete(agentId);
|
|
16522
|
+
this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "explicit_stop" });
|
|
16523
|
+
this.assertStartPendingDeliveryInvariants("runtime-start-stop-epoch-fence");
|
|
16524
|
+
this.runtimeExitTraceAttrs.set(ap.runtime, {
|
|
16525
|
+
stop_source: "explicit_request",
|
|
16526
|
+
stop_wait_requested: false,
|
|
16527
|
+
stop_silent: false,
|
|
16528
|
+
stop_epoch_fence: true
|
|
16529
|
+
});
|
|
16530
|
+
try {
|
|
16531
|
+
await ap.runtime.stop({ signal: "SIGTERM", reason: "explicit_request" });
|
|
16532
|
+
} catch (err) {
|
|
16533
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
16534
|
+
logger.warn(`[Agent ${agentId}] Failed to stop runtime suppressed by stop epoch: ${reason}`);
|
|
16535
|
+
}
|
|
16536
|
+
logger.info(`[Agent ${agentId}] Runtime start discarded after stop request`);
|
|
16537
|
+
}
|
|
16538
|
+
suppressFailedRestartAfterStop(agentId, stopEpochAtRestart, source) {
|
|
16539
|
+
if (!this.lifecycleRecords.stopEpochChanged(agentId, stopEpochAtRestart)) return false;
|
|
16540
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
16541
|
+
this.lifecycleRecords.deletePendingStartRebind(agentId);
|
|
16542
|
+
this.lifecycleRecords.deletePendingSpawnCause(agentId);
|
|
16543
|
+
this.startingInboxes.cancelStart(agentId);
|
|
16544
|
+
this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "explicit_stop" });
|
|
16545
|
+
this.assertStartPendingDeliveryInvariants(`${source}-stop-epoch-fence`);
|
|
16546
|
+
logger.info(`[Agent ${agentId}] Failed ${source} restart suppressed after stop request`);
|
|
16547
|
+
return true;
|
|
16548
|
+
}
|
|
15878
16549
|
cleanupFailedRuntimeStart(agentId, ap, err) {
|
|
15879
16550
|
if (!ap) return;
|
|
15880
16551
|
if (this.agents.get(agentId) !== ap) return;
|
|
15881
16552
|
ap.notifications.clearTimer();
|
|
15882
|
-
|
|
15883
|
-
clearTimeout(ap.pendingTrajectory.timer);
|
|
15884
|
-
ap.pendingTrajectory.timer = null;
|
|
15885
|
-
}
|
|
15886
|
-
if (ap.activityHeartbeat) {
|
|
15887
|
-
clearInterval(ap.activityHeartbeat);
|
|
15888
|
-
ap.activityHeartbeat = null;
|
|
15889
|
-
}
|
|
15890
|
-
if (ap.compactionWatchdog) {
|
|
15891
|
-
clearTimeout(ap.compactionWatchdog);
|
|
15892
|
-
ap.compactionWatchdog = null;
|
|
15893
|
-
}
|
|
16553
|
+
this.disposeAgentProcessTimers(ap);
|
|
15894
16554
|
this.closeRuntimeReadinessTransition(ap, "terminal");
|
|
15895
16555
|
this.closeActivationTransition(ap, "terminal");
|
|
15896
|
-
this.clearRuntimeStartupTimeout(ap);
|
|
15897
|
-
this.clearStalledRecoverySigtermWatchdog(ap);
|
|
15898
16556
|
this.endRuntimeTrace(ap, "error", {
|
|
15899
16557
|
outcome: "runtime-start-failed",
|
|
15900
16558
|
failure_detail: err instanceof Error ? err.message : String(err),
|
|
@@ -15904,36 +16562,26 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15904
16562
|
cleanupAgentCredentialProxy(agentId, ap.launchId);
|
|
15905
16563
|
this.revokeManagedRunnerCredential(agentId, ap.config, ap.launchId);
|
|
15906
16564
|
this.agents.delete(agentId);
|
|
15907
|
-
this.
|
|
15908
|
-
if (this.
|
|
16565
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
16566
|
+
if (this.lifecycleRecords.deleteTerminalFailure(agentId)) {
|
|
15909
16567
|
this.closeNoProcessResidency(agentId, "terminal", { negativeEvidenceBucket: "runtime_start_failed" });
|
|
15910
16568
|
}
|
|
16569
|
+
this.resetRuntimeErrorFingerprintFenceIfNonresident(agentId, "runtime_start_failed_cleanup", ap);
|
|
15911
16570
|
}
|
|
15912
16571
|
cleanupTerminalRuntimeFailure(agentId, ap, detail) {
|
|
15913
16572
|
if (this.agents.get(agentId) !== ap) return;
|
|
15914
16573
|
ap.notifications.clear();
|
|
15915
|
-
this.
|
|
15916
|
-
if (ap.pendingTrajectory?.timer) {
|
|
15917
|
-
clearTimeout(ap.pendingTrajectory.timer);
|
|
15918
|
-
ap.pendingTrajectory.timer = null;
|
|
15919
|
-
}
|
|
15920
|
-
if (ap.activityHeartbeat) {
|
|
15921
|
-
clearInterval(ap.activityHeartbeat);
|
|
15922
|
-
ap.activityHeartbeat = null;
|
|
15923
|
-
}
|
|
15924
|
-
this.clearCompactionWatchdog(ap);
|
|
16574
|
+
this.disposeAgentProcessTimers(ap);
|
|
15925
16575
|
this.closeRuntimeReadinessTransition(ap, "terminal");
|
|
15926
16576
|
this.closeActivationTransition(ap, "terminal");
|
|
15927
|
-
this.clearRuntimeStartupTimeout(ap);
|
|
15928
|
-
this.clearStalledRecoverySigtermWatchdog(ap);
|
|
15929
16577
|
cleanupAgentCredentialProxy(agentId, ap.launchId);
|
|
15930
16578
|
this.revokeManagedRunnerCredential(agentId, ap.config, ap.launchId);
|
|
15931
|
-
this.
|
|
16579
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
15932
16580
|
if (ap.inbox.length > 0) {
|
|
15933
16581
|
this.startingInboxes.bufferMessagesDuringStart(agentId, ap.inbox);
|
|
15934
16582
|
}
|
|
15935
16583
|
this.agents.delete(agentId);
|
|
15936
|
-
this.
|
|
16584
|
+
this.lifecycleRecords.setTerminalFailure(agentId, { detail, launchId: ap.launchId });
|
|
15937
16585
|
this.enterNoProcessResidency(
|
|
15938
16586
|
"terminal_runtime_error",
|
|
15939
16587
|
this.noProcessResidencyIdentity(agentId, ap.config, ap.launchId, "terminal_runtime_error", ap.driver.id),
|
|
@@ -15968,7 +16616,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
15968
16616
|
cacheStartupTimeoutRetryConfig(agentId, ap) {
|
|
15969
16617
|
const retrySessionId = this.restartSafeSessionId(ap);
|
|
15970
16618
|
const retryConfig = this.buildRestartSafeConfig(ap.config, retrySessionId);
|
|
15971
|
-
this.
|
|
16619
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15972
16620
|
config: retryConfig,
|
|
15973
16621
|
sessionId: retrySessionId,
|
|
15974
16622
|
launchId: ap.launchId
|
|
@@ -16204,10 +16852,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16204
16852
|
return messages.some((message) => !runtimeProfileNotificationFromMessage(message));
|
|
16205
16853
|
}
|
|
16206
16854
|
async stopAgent(agentId, { wait = false, silent = false } = {}) {
|
|
16855
|
+
this.lifecycleRecords.recordStop(agentId);
|
|
16207
16856
|
this.cancelQueuedAgentStart(agentId, "stop requested");
|
|
16208
|
-
this.
|
|
16209
|
-
this.
|
|
16210
|
-
if (this.
|
|
16857
|
+
this.lifecycleRecords.deletePendingStartRebind(agentId);
|
|
16858
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
16859
|
+
if (this.lifecycleRecords.deleteTerminalFailure(agentId)) {
|
|
16211
16860
|
this.closeNoProcessResidency(agentId, "suppressed", { negativeEvidenceBucket: "explicit_stop" });
|
|
16212
16861
|
}
|
|
16213
16862
|
const ap = this.agents.get(agentId);
|
|
@@ -16218,17 +16867,12 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16218
16867
|
return;
|
|
16219
16868
|
}
|
|
16220
16869
|
ap.notifications.clearTimer();
|
|
16221
|
-
this.
|
|
16222
|
-
if (ap.activityHeartbeat) {
|
|
16223
|
-
clearInterval(ap.activityHeartbeat);
|
|
16224
|
-
}
|
|
16225
|
-
this.clearCompactionWatchdog(ap);
|
|
16226
|
-
this.clearStalledRecoverySigtermWatchdog(ap);
|
|
16870
|
+
this.disposeAgentProcessTimers(ap);
|
|
16227
16871
|
cleanupAgentCredentialProxy(agentId, ap.launchId);
|
|
16228
16872
|
this.revokeManagedRunnerCredential(agentId, ap.config, ap.launchId);
|
|
16229
16873
|
this.agents.delete(agentId);
|
|
16230
16874
|
if (!silent) {
|
|
16231
|
-
this.
|
|
16875
|
+
this.lifecycleRecords.deleteActivityClientSeq(agentId);
|
|
16232
16876
|
this.agentVisibleDelivery.clearAgent(agentId);
|
|
16233
16877
|
this.resetSpawnFailBackoff(agentId, "suppressed");
|
|
16234
16878
|
this.resetRuntimeErrorFingerprintFence(agentId, "explicit_stop", ap);
|
|
@@ -16246,7 +16890,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16246
16890
|
if (!silent) {
|
|
16247
16891
|
this.sendRuntimeProfileReportFor(agentId, ap.config, ap.sessionId, ap.launchId, "stop");
|
|
16248
16892
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
16249
|
-
this.broadcastActivity(agentId, "offline", "Stopped");
|
|
16893
|
+
this.broadcastActivity(agentId, "offline", "Stopped", [], void 0, "stopped");
|
|
16250
16894
|
logger.info(`[Agent ${agentId}] Stopped by request`);
|
|
16251
16895
|
}
|
|
16252
16896
|
if (wait) {
|
|
@@ -16320,8 +16964,9 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16320
16964
|
}));
|
|
16321
16965
|
return true;
|
|
16322
16966
|
}
|
|
16323
|
-
const
|
|
16324
|
-
if (
|
|
16967
|
+
const lifecycleRecord = this.agentLifecycleRecord(agentId);
|
|
16968
|
+
if (lifecycleRecord?.kind === "terminal") {
|
|
16969
|
+
const { terminalFailure } = lifecycleRecord;
|
|
16325
16970
|
if (transientDelivery) {
|
|
16326
16971
|
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
16327
16972
|
outcome: "transient_dropped_terminal_runtime_error_no_process",
|
|
@@ -16329,7 +16974,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16329
16974
|
process_present: false,
|
|
16330
16975
|
cached_idle_config_present: false,
|
|
16331
16976
|
terminal_runtime_failure: true,
|
|
16332
|
-
launchId:
|
|
16977
|
+
launchId: terminalFailure.launchId || void 0
|
|
16333
16978
|
}));
|
|
16334
16979
|
return true;
|
|
16335
16980
|
}
|
|
@@ -16342,14 +16987,14 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16342
16987
|
cached_idle_config_present: false,
|
|
16343
16988
|
terminal_runtime_failure: true,
|
|
16344
16989
|
starting_inbox_count: startingInboxCount,
|
|
16345
|
-
launchId:
|
|
16990
|
+
launchId: terminalFailure.launchId || void 0
|
|
16346
16991
|
}));
|
|
16347
|
-
this.sendAgentStatus(agentId, "inactive",
|
|
16348
|
-
this.broadcastActivity(agentId, "error",
|
|
16992
|
+
this.sendAgentStatus(agentId, "inactive", terminalFailure.launchId);
|
|
16993
|
+
this.broadcastActivity(agentId, "error", terminalFailure.detail, [], terminalFailure.launchId, "runtime_error");
|
|
16349
16994
|
return true;
|
|
16350
16995
|
}
|
|
16351
|
-
|
|
16352
|
-
|
|
16996
|
+
if (lifecycleRecord?.kind === "idle" || lifecycleRecord?.kind === "cooldown") {
|
|
16997
|
+
const cached = lifecycleRecord.restartSnapshot;
|
|
16353
16998
|
const driver = this.driverResolver(cached.config.runtime || "claude");
|
|
16354
16999
|
if (!transientDelivery && this.shouldDeferWakeMessage(agentId, driver, message)) {
|
|
16355
17000
|
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
@@ -16364,8 +17009,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16364
17009
|
return true;
|
|
16365
17010
|
}
|
|
16366
17011
|
logger.info(`[Agent ${agentId}] Starting from idle state for new message`);
|
|
16367
|
-
if (
|
|
16368
|
-
const state =
|
|
17012
|
+
if (lifecycleRecord.kind === "cooldown") {
|
|
17013
|
+
const state = lifecycleRecord.spawnFailBackoff;
|
|
16369
17014
|
const startingInboxCount = this.startingInboxes.bufferDuringStart(agentId, message);
|
|
16370
17015
|
this.assertStartPendingDeliveryInvariants("delivery-spawn-fail-cooldown");
|
|
16371
17016
|
this.enterSpawnFailCooldownResidency(agentId, cached, state.untilMs, "idle_auto_restart", "spawn_fail_cooldown_active");
|
|
@@ -16383,7 +17028,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16383
17028
|
}));
|
|
16384
17029
|
return true;
|
|
16385
17030
|
}
|
|
16386
|
-
this.
|
|
17031
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
17032
|
+
const restartStopEpoch = this.lifecycleRecords.stopEpoch(agentId);
|
|
16387
17033
|
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
16388
17034
|
outcome: "auto_restart_from_idle",
|
|
16389
17035
|
accepted: true,
|
|
@@ -16399,8 +17045,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16399
17045
|
return true;
|
|
16400
17046
|
}, (err) => {
|
|
16401
17047
|
logger.error(`[Agent ${agentId}] Failed to auto-restart`, err);
|
|
17048
|
+
if (this.suppressFailedRestartAfterStop(agentId, restartStopEpoch, "idle-auto-restart")) {
|
|
17049
|
+
return false;
|
|
17050
|
+
}
|
|
16402
17051
|
if (this.reportRunnerCredentialMintFailure(agentId, err, cached.launchId, "idle_auto_restart")) {
|
|
16403
|
-
this.
|
|
17052
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, cached);
|
|
16404
17053
|
const report2 = this.recordSpawnFailure(agentId, "runner_credential_mint");
|
|
16405
17054
|
this.assertStartPendingDeliveryInvariants("idle-auto-restart-runner-credential-mint-failure");
|
|
16406
17055
|
if (report2.backoffActive) {
|
|
@@ -16416,7 +17065,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16416
17065
|
});
|
|
16417
17066
|
return false;
|
|
16418
17067
|
}
|
|
16419
|
-
this.
|
|
17068
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, cached);
|
|
16420
17069
|
const report = this.recordSpawnFailure(agentId, "spawn_error");
|
|
16421
17070
|
this.assertStartPendingDeliveryInvariants("idle-auto-restart-spawn-failure");
|
|
16422
17071
|
if (report.backoffActive) {
|
|
@@ -16462,7 +17111,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16462
17111
|
cached_idle_config_present: false
|
|
16463
17112
|
}), "error");
|
|
16464
17113
|
this.sendAgentStatus(agentId, "inactive", null);
|
|
16465
|
-
this.broadcastActivity(agentId, "offline", "Process unavailable; restart required");
|
|
17114
|
+
this.broadcastActivity(agentId, "offline", "Process unavailable; restart required", [], void 0, "runtime_unavailable");
|
|
16466
17115
|
return false;
|
|
16467
17116
|
}
|
|
16468
17117
|
const isIdle = this.isApmIdle(ap);
|
|
@@ -16522,7 +17171,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16522
17171
|
inbox_count: ap.inbox.length
|
|
16523
17172
|
}));
|
|
16524
17173
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
16525
|
-
this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail);
|
|
17174
|
+
this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail, [], void 0, "runtime_error");
|
|
16526
17175
|
return true;
|
|
16527
17176
|
}
|
|
16528
17177
|
}
|
|
@@ -16533,7 +17182,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16533
17182
|
if (transientDelivery) {
|
|
16534
17183
|
this.commitApmIdleState(agentId, ap, false);
|
|
16535
17184
|
this.startRuntimeTrace(agentId, ap, "stdin-idle-delivery", [message]);
|
|
16536
|
-
this.
|
|
17185
|
+
this.broadcastMessageReceivedActivity(agentId);
|
|
16537
17186
|
const stdinAccepted2 = this.deliverMessagesViaStdin(
|
|
16538
17187
|
agentId,
|
|
16539
17188
|
ap,
|
|
@@ -16579,7 +17228,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16579
17228
|
const nextMessages = [...ap.inbox];
|
|
16580
17229
|
this.commitApmIdleState(agentId, ap, false);
|
|
16581
17230
|
this.startRuntimeTrace(agentId, ap, "stdin-idle-delivery", [message]);
|
|
16582
|
-
this.
|
|
17231
|
+
this.broadcastMessageReceivedActivity(agentId);
|
|
16583
17232
|
const stdinAccepted = this.deliverInboxUpdateViaStdin(
|
|
16584
17233
|
agentId,
|
|
16585
17234
|
ap,
|
|
@@ -16768,7 +17417,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16768
17417
|
}
|
|
16769
17418
|
async stopAll() {
|
|
16770
17419
|
this.cancelAllQueuedAgentStarts("daemon shutdown");
|
|
16771
|
-
this.
|
|
17420
|
+
this.lifecycleRecords.clearRestartSnapshots();
|
|
16772
17421
|
const pids = [];
|
|
16773
17422
|
for (const ap of this.agents.values()) {
|
|
16774
17423
|
if (typeof ap.runtime.pid === "number") pids.push(ap.runtime.pid);
|
|
@@ -16878,7 +17527,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16878
17527
|
}
|
|
16879
17528
|
getIdleAgentSessionIds() {
|
|
16880
17529
|
const result = [];
|
|
16881
|
-
for (const [agentId, { sessionId, launchId }] of this.
|
|
17530
|
+
for (const [agentId, { sessionId, launchId }] of this.lifecycleRecords.restartSnapshotEntries()) {
|
|
16882
17531
|
if (this.agents.has(agentId)) continue;
|
|
16883
17532
|
if (sessionId) result.push({ agentId, sessionId, launchId });
|
|
16884
17533
|
}
|
|
@@ -16915,7 +17564,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16915
17564
|
running.runtime.currentRuntimeHomeDir
|
|
16916
17565
|
);
|
|
16917
17566
|
}
|
|
16918
|
-
const idle = this.
|
|
17567
|
+
const idle = this.lifecycleRecords.getRestartSnapshot(agentId);
|
|
16919
17568
|
if (idle) {
|
|
16920
17569
|
return this.buildRuntimeProfileReport(agentId, idle.config, idle.sessionId, idle.launchId);
|
|
16921
17570
|
}
|
|
@@ -16931,7 +17580,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16931
17580
|
seen.add(agentId);
|
|
16932
17581
|
}
|
|
16933
17582
|
}
|
|
16934
|
-
for (const agentId of this.
|
|
17583
|
+
for (const agentId of this.lifecycleRecords.restartSnapshotAgentIds()) {
|
|
16935
17584
|
if (seen.has(agentId)) continue;
|
|
16936
17585
|
const report = this.getAgentRuntimeProfileReport(agentId);
|
|
16937
17586
|
if (report) reports.push(report);
|
|
@@ -17034,11 +17683,12 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17034
17683
|
});
|
|
17035
17684
|
return true;
|
|
17036
17685
|
}
|
|
17037
|
-
const
|
|
17038
|
-
if (
|
|
17686
|
+
const lifecycleRecord = this.agentLifecycleRecord(agentId);
|
|
17687
|
+
if (lifecycleRecord?.kind === "idle" || lifecycleRecord?.kind === "cooldown") {
|
|
17688
|
+
const cached = lifecycleRecord.restartSnapshot;
|
|
17039
17689
|
logger.info(`[Agent ${agentId}] Starting from idle state for runtime profile ${kind} ${key}`);
|
|
17040
|
-
if (
|
|
17041
|
-
const state =
|
|
17690
|
+
if (lifecycleRecord.kind === "cooldown") {
|
|
17691
|
+
const state = lifecycleRecord.spawnFailBackoff;
|
|
17042
17692
|
this.enterSpawnFailCooldownResidency(agentId, cached, state.untilMs, "runtime_profile_auto_restart", "spawn_fail_cooldown_active");
|
|
17043
17693
|
span.end("ok", {
|
|
17044
17694
|
attrs: {
|
|
@@ -17051,15 +17701,26 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17051
17701
|
});
|
|
17052
17702
|
return true;
|
|
17053
17703
|
}
|
|
17054
|
-
this.
|
|
17704
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
17705
|
+
const restartStopEpoch = this.lifecycleRecords.stopEpoch(agentId);
|
|
17055
17706
|
return this.startAgent(agentId, cached.config, message, void 0, void 0, cached.launchId || void 0).then(() => {
|
|
17056
17707
|
this.resetSpawnFailBackoff(agentId);
|
|
17057
17708
|
this.assertStartPendingDeliveryInvariants("runtime-profile-auto-restart-success");
|
|
17058
17709
|
return true;
|
|
17059
17710
|
}, (err) => {
|
|
17060
17711
|
logger.error(`[Agent ${agentId}] Failed to auto-restart for runtime profile notification`, err);
|
|
17712
|
+
if (this.suppressFailedRestartAfterStop(agentId, restartStopEpoch, "runtime-profile-auto-restart")) {
|
|
17713
|
+
span.end("ok", {
|
|
17714
|
+
attrs: {
|
|
17715
|
+
outcome: "suppressed_after_stop",
|
|
17716
|
+
runtime: cached.config.runtime,
|
|
17717
|
+
launchId: cached.launchId || void 0
|
|
17718
|
+
}
|
|
17719
|
+
});
|
|
17720
|
+
return false;
|
|
17721
|
+
}
|
|
17061
17722
|
if (this.reportRunnerCredentialMintFailure(agentId, err, cached.launchId, "runtime_profile_auto_restart")) {
|
|
17062
|
-
this.
|
|
17723
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, cached);
|
|
17063
17724
|
const report2 = this.recordSpawnFailure(agentId, "runner_credential_mint");
|
|
17064
17725
|
this.assertStartPendingDeliveryInvariants("runtime-profile-auto-restart-runner-credential-mint-failure");
|
|
17065
17726
|
if (report2.backoffActive) {
|
|
@@ -17082,7 +17743,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17082
17743
|
});
|
|
17083
17744
|
return false;
|
|
17084
17745
|
}
|
|
17085
|
-
this.
|
|
17746
|
+
this.lifecycleRecords.setRestartSnapshot(agentId, cached);
|
|
17086
17747
|
const report = this.recordSpawnFailure(agentId, "spawn_error");
|
|
17087
17748
|
this.assertStartPendingDeliveryInvariants("runtime-profile-auto-restart-spawn-failure");
|
|
17088
17749
|
if (report.backoffActive) {
|
|
@@ -17119,7 +17780,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17119
17780
|
continue;
|
|
17120
17781
|
}
|
|
17121
17782
|
const title = runtimeProfileNotificationTitle(notification.kind);
|
|
17122
|
-
this.broadcastActivity(agentId, "working", title, [{ kind: "system", title, text: message.content }], launchId);
|
|
17783
|
+
this.broadcastActivity(agentId, "working", title, [{ kind: "system", title, text: message.content }], launchId, "system_message");
|
|
17123
17784
|
this.sendToServer({
|
|
17124
17785
|
type: "agent:runtime_profile:daemon_release_notice:ack",
|
|
17125
17786
|
agentId,
|
|
@@ -17148,7 +17809,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17148
17809
|
span.end("ok", { attrs: { outcome: "deprecated_noop_completed" } });
|
|
17149
17810
|
return;
|
|
17150
17811
|
}
|
|
17151
|
-
this.broadcastActivity(agentId, "working", title, [{ kind: "system", title, text: control.message }], launchId);
|
|
17812
|
+
this.broadcastActivity(agentId, "working", title, [{ kind: "system", title, text: control.message }], launchId, "system_message");
|
|
17152
17813
|
this.sendToServer({
|
|
17153
17814
|
type: "agent:runtime_profile:daemon_release_notice:ack",
|
|
17154
17815
|
agentId,
|
|
@@ -17198,7 +17859,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17198
17859
|
return deleteWorkspaceDirectory(this.dataDir, directoryName);
|
|
17199
17860
|
}
|
|
17200
17861
|
// Workspace file browsing
|
|
17201
|
-
async getFileTree(agentId, dirPath) {
|
|
17862
|
+
async getFileTree(agentId, dirPath, includeHidden = false) {
|
|
17202
17863
|
const agentDir = path14.join(this.dataDir, agentId);
|
|
17203
17864
|
try {
|
|
17204
17865
|
await stat2(agentDir);
|
|
@@ -17211,9 +17872,16 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17211
17872
|
if (!resolved.startsWith(agentDir + path14.sep) && resolved !== agentDir) {
|
|
17212
17873
|
return [];
|
|
17213
17874
|
}
|
|
17875
|
+
const relativePath = path14.relative(agentDir, resolved);
|
|
17876
|
+
if (isWorkspaceNeverVisibleHiddenPath(relativePath)) {
|
|
17877
|
+
return [];
|
|
17878
|
+
}
|
|
17879
|
+
if (!includeHidden && isWorkspaceHiddenPath(relativePath)) {
|
|
17880
|
+
return [];
|
|
17881
|
+
}
|
|
17214
17882
|
targetDir = resolved;
|
|
17215
17883
|
}
|
|
17216
|
-
return this.listDirectoryChildren(targetDir, agentDir);
|
|
17884
|
+
return this.listDirectoryChildren(targetDir, agentDir, includeHidden);
|
|
17217
17885
|
}
|
|
17218
17886
|
async readFile(agentId, filePath) {
|
|
17219
17887
|
const agentDir = path14.join(this.dataDir, agentId);
|
|
@@ -17221,6 +17889,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17221
17889
|
if (!resolved.startsWith(agentDir + path14.sep) && resolved !== agentDir) {
|
|
17222
17890
|
throw new Error("Access denied");
|
|
17223
17891
|
}
|
|
17892
|
+
const relativePath = path14.relative(agentDir, resolved);
|
|
17893
|
+
if (isWorkspaceNeverVisibleHiddenPath(relativePath) || isWorkspaceSecretFilePath(relativePath)) {
|
|
17894
|
+
throw new Error("Preview is disabled for sensitive workspace files");
|
|
17895
|
+
}
|
|
17224
17896
|
const info = await stat2(resolved);
|
|
17225
17897
|
if (info.isDirectory()) throw new Error("Cannot read a directory");
|
|
17226
17898
|
const ext = path14.extname(resolved).toLowerCase();
|
|
@@ -17256,7 +17928,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17256
17928
|
};
|
|
17257
17929
|
async getSessionTranscript(agentId) {
|
|
17258
17930
|
const agent = this.agents.get(agentId);
|
|
17259
|
-
const idle = this.
|
|
17931
|
+
const idle = this.lifecycleRecords.getRestartSnapshot(agentId);
|
|
17260
17932
|
const config = agent?.config ?? idle?.config ?? null;
|
|
17261
17933
|
const actualSessionId = agent?.sessionId || idle?.sessionId || null;
|
|
17262
17934
|
if (!config) {
|
|
@@ -17433,7 +18105,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17433
18105
|
}
|
|
17434
18106
|
async listSkills(agentId, runtimeHint) {
|
|
17435
18107
|
const agent = this.agents.get(agentId);
|
|
17436
|
-
const idle = this.
|
|
18108
|
+
const idle = this.lifecycleRecords.getRestartSnapshot(agentId);
|
|
17437
18109
|
const config = agent?.config ?? idle?.config ?? null;
|
|
17438
18110
|
const runtime = runtimeHint || config?.runtime || "claude";
|
|
17439
18111
|
const workspaceDir = path14.join(this.dataDir, agentId);
|
|
@@ -17533,12 +18205,19 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17533
18205
|
* should carry explicit reason/correlation/window attrs so the server no
|
|
17534
18206
|
* longer infers lifecycle semantics from generic activity strings.
|
|
17535
18207
|
*/
|
|
17536
|
-
broadcastActivity(agentId,
|
|
18208
|
+
broadcastActivity(agentId, activityKind, detail, extraTrajectory = [], launchIdOverride, detailKind = "other", activityDisplay = activityKind, subagentLineage) {
|
|
17537
18209
|
const ap = this.agents.get(agentId);
|
|
17538
18210
|
const entries = [...extraTrajectory];
|
|
17539
18211
|
const hasToolStart = entries.some((e) => e.kind === "tool_start");
|
|
17540
18212
|
if (!hasToolStart) {
|
|
17541
|
-
entries.push({
|
|
18213
|
+
entries.push({
|
|
18214
|
+
kind: "status",
|
|
18215
|
+
activity: activityKind,
|
|
18216
|
+
activityKind,
|
|
18217
|
+
detail,
|
|
18218
|
+
detailKind,
|
|
18219
|
+
...subagentLineage ? { subagent: subagentLineage } : {}
|
|
18220
|
+
});
|
|
17542
18221
|
}
|
|
17543
18222
|
const launchId = launchIdOverride || ap?.launchId || void 0;
|
|
17544
18223
|
const clientSeq = this.nextActivityClientSeq(agentId);
|
|
@@ -17546,23 +18225,28 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17546
18225
|
this.sendToServer({
|
|
17547
18226
|
type: "agent:activity",
|
|
17548
18227
|
agentId,
|
|
17549
|
-
activity,
|
|
18228
|
+
activity: activityDisplay,
|
|
18229
|
+
activityKind,
|
|
17550
18230
|
detail,
|
|
18231
|
+
detailKind,
|
|
17551
18232
|
entries,
|
|
17552
18233
|
launchId,
|
|
17553
18234
|
clientSeq,
|
|
17554
18235
|
producerFactId
|
|
17555
18236
|
});
|
|
17556
|
-
this.recordActivityProducedTrace(agentId,
|
|
18237
|
+
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId);
|
|
17557
18238
|
if (ap) {
|
|
17558
|
-
ap.
|
|
18239
|
+
ap.lastActivityKind = activityKind;
|
|
18240
|
+
ap.lastActivity = activityDisplay;
|
|
17559
18241
|
ap.lastActivityDetail = detail;
|
|
17560
|
-
|
|
17561
|
-
|
|
17562
|
-
|
|
18242
|
+
ap.lastActivityDetailKind = detailKind;
|
|
18243
|
+
if (activityKind === "working" || activityKind === "thinking") {
|
|
18244
|
+
if (ap.activityHeartbeat.kind === "inactive") {
|
|
18245
|
+
const timer = setInterval(() => {
|
|
17563
18246
|
if (this.markRuntimeProgressStaleIfNeeded(agentId, ap)) return;
|
|
17564
18247
|
this.recordRuntimeTraceEvent(agentId, ap, "activity.heartbeat.sent", {
|
|
17565
|
-
activity: ap.
|
|
18248
|
+
activity: ap.lastActivityKind,
|
|
18249
|
+
detailKind: ap.lastActivityDetailKind
|
|
17566
18250
|
});
|
|
17567
18251
|
const heartbeatLaunchId = launchIdOverride || ap.launchId || void 0;
|
|
17568
18252
|
const heartbeatClientSeq = this.nextActivityClientSeq(agentId);
|
|
@@ -17571,23 +18255,23 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17571
18255
|
type: "agent:activity",
|
|
17572
18256
|
agentId,
|
|
17573
18257
|
activity: ap.lastActivity,
|
|
18258
|
+
activityKind: ap.lastActivityKind,
|
|
17574
18259
|
detail: ap.lastActivityDetail,
|
|
18260
|
+
detailKind: ap.lastActivityDetailKind,
|
|
17575
18261
|
launchId: heartbeatLaunchId,
|
|
17576
18262
|
clientSeq: heartbeatClientSeq,
|
|
17577
18263
|
producerFactId: heartbeatProducerFactId
|
|
17578
18264
|
});
|
|
17579
|
-
this.recordActivityProducedTrace(agentId, ap.
|
|
18265
|
+
this.recordActivityProducedTrace(agentId, ap.lastActivityKind, ap.lastActivityDetail, ap.lastActivityDetailKind, [], ap, heartbeatLaunchId, heartbeatClientSeq, heartbeatProducerFactId);
|
|
17580
18266
|
}, ACTIVITY_HEARTBEAT_MS);
|
|
18267
|
+
ap.activityHeartbeat = { kind: "active", timer };
|
|
17581
18268
|
}
|
|
17582
18269
|
} else {
|
|
17583
|
-
|
|
17584
|
-
clearInterval(ap.activityHeartbeat);
|
|
17585
|
-
ap.activityHeartbeat = null;
|
|
17586
|
-
}
|
|
18270
|
+
this.clearActivityHeartbeat(ap);
|
|
17587
18271
|
}
|
|
17588
18272
|
}
|
|
17589
18273
|
}
|
|
17590
|
-
recordActivityProducedTrace(agentId,
|
|
18274
|
+
recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId) {
|
|
17591
18275
|
const runtimeContext = ap?.config.runtimeContext;
|
|
17592
18276
|
this.recordDaemonTrace("daemon.agent.activity.produced", {
|
|
17593
18277
|
agentId,
|
|
@@ -17595,8 +18279,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17595
18279
|
server_id: runtimeContext?.serverId,
|
|
17596
18280
|
machine_id: runtimeContext?.machineId,
|
|
17597
18281
|
process_instance_id: ap?.processInstanceId,
|
|
17598
|
-
activity,
|
|
18282
|
+
activity: activityKind,
|
|
18283
|
+
activity_kind: activityKind,
|
|
17599
18284
|
detail_present: Boolean(detail),
|
|
18285
|
+
detail_kind: detailKind,
|
|
17600
18286
|
entry_kinds: entries.map((e) => e.kind).join(","),
|
|
17601
18287
|
ap_present: Boolean(ap),
|
|
17602
18288
|
launchId,
|
|
@@ -17638,8 +18324,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17638
18324
|
*/
|
|
17639
18325
|
respondToActivityProbe(agentId, probeId) {
|
|
17640
18326
|
const ap = this.agents.get(agentId);
|
|
17641
|
-
const
|
|
18327
|
+
const activityKind = ap?.lastActivityKind || "offline";
|
|
18328
|
+
const activity = ap?.lastActivity || activityKind;
|
|
17642
18329
|
const detail = ap?.lastActivityDetail || (ap ? "" : "Agent not running");
|
|
18330
|
+
const detailKind = ap?.lastActivityDetailKind || (ap ? "none" : "runtime_unavailable");
|
|
17643
18331
|
const launchId = ap?.launchId || void 0;
|
|
17644
18332
|
const clientSeq = this.nextActivityClientSeq(agentId);
|
|
17645
18333
|
const producerFactId = this.buildActivityProducerFactId(agentId, launchId, clientSeq);
|
|
@@ -17647,29 +18335,28 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17647
18335
|
type: "agent:activity",
|
|
17648
18336
|
agentId,
|
|
17649
18337
|
activity,
|
|
18338
|
+
activityKind,
|
|
17650
18339
|
detail,
|
|
18340
|
+
detailKind,
|
|
17651
18341
|
launchId,
|
|
17652
18342
|
probeId,
|
|
17653
18343
|
clientSeq,
|
|
17654
18344
|
producerFactId
|
|
17655
18345
|
});
|
|
17656
|
-
this.recordActivityProducedTrace(agentId,
|
|
18346
|
+
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, [], ap, launchId, clientSeq, producerFactId);
|
|
17657
18347
|
}
|
|
17658
18348
|
flushPendingTrajectory(agentId) {
|
|
17659
18349
|
const ap = this.agents.get(agentId);
|
|
17660
18350
|
const pending = ap?.pendingTrajectory;
|
|
17661
18351
|
if (!ap || !pending) return;
|
|
17662
|
-
|
|
18352
|
+
clearTimeout(pending.timer);
|
|
17663
18353
|
ap.pendingTrajectory = null;
|
|
17664
18354
|
const text = pending.text.length > MAX_TRAJECTORY_TEXT ? pending.text.slice(0, MAX_TRAJECTORY_TEXT) + "\u2026" : pending.text;
|
|
17665
18355
|
if (!text) return;
|
|
17666
|
-
|
|
17667
|
-
|
|
17668
|
-
} else {
|
|
17669
|
-
this.broadcastActivity(agentId, "thinking", "", [{ kind: "text", text }]);
|
|
17670
|
-
}
|
|
18356
|
+
const entry = pending.kind === "thinking" ? { kind: "thinking", text, ...pending.subagent ? { subagent: pending.subagent } : {} } : { kind: "text", text, ...pending.subagent ? { subagent: pending.subagent } : {} };
|
|
18357
|
+
this.broadcastActivity(agentId, "thinking", "", [entry], void 0, "none");
|
|
17671
18358
|
}
|
|
17672
|
-
queueTrajectoryText(agentId, kind, text) {
|
|
18359
|
+
queueTrajectoryText(agentId, kind, text, subagent) {
|
|
17673
18360
|
const ap = this.agents.get(agentId);
|
|
17674
18361
|
if (!ap) {
|
|
17675
18362
|
this.recordDaemonTrace("daemon.agent.activity.skipped", {
|
|
@@ -17681,37 +18368,38 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17681
18368
|
return;
|
|
17682
18369
|
}
|
|
17683
18370
|
if (!text) {
|
|
17684
|
-
this.broadcastActivity(agentId, "thinking", "");
|
|
18371
|
+
this.broadcastActivity(agentId, "thinking", "", [], void 0, "none");
|
|
17685
18372
|
return;
|
|
17686
18373
|
}
|
|
17687
18374
|
const pending = ap.pendingTrajectory;
|
|
17688
|
-
|
|
18375
|
+
const sameLineage = JSON.stringify(pending?.subagent ?? null) === JSON.stringify(subagent ?? null);
|
|
18376
|
+
if (pending && pending.kind === kind && sameLineage) {
|
|
17689
18377
|
pending.text += text;
|
|
17690
|
-
|
|
18378
|
+
clearTimeout(pending.timer);
|
|
17691
18379
|
pending.timer = setTimeout(() => this.flushPendingTrajectory(agentId), TRAJECTORY_COALESCE_MS);
|
|
17692
18380
|
return;
|
|
17693
18381
|
}
|
|
17694
18382
|
this.flushPendingTrajectory(agentId);
|
|
17695
|
-
if (ap.
|
|
17696
|
-
this.broadcastActivity(agentId, "thinking", "");
|
|
18383
|
+
if (ap.lastActivityKind !== "thinking" || ap.lastActivityDetailKind !== "none") {
|
|
18384
|
+
this.broadcastActivity(agentId, "thinking", "", [], void 0, "none");
|
|
17697
18385
|
}
|
|
17698
18386
|
ap.pendingTrajectory = {
|
|
17699
18387
|
kind,
|
|
17700
18388
|
text,
|
|
18389
|
+
...subagent ? { subagent } : {},
|
|
17701
18390
|
timer: setTimeout(() => this.flushPendingTrajectory(agentId), TRAJECTORY_COALESCE_MS)
|
|
17702
18391
|
};
|
|
17703
18392
|
}
|
|
17704
18393
|
clearCompactionWatchdog(ap) {
|
|
17705
|
-
if (ap.
|
|
17706
|
-
clearTimeout(ap.
|
|
17707
|
-
ap.compactionWatchdog = null;
|
|
18394
|
+
if (ap.compaction.kind === "active" && ap.compaction.watchdog) {
|
|
18395
|
+
clearTimeout(ap.compaction.watchdog);
|
|
17708
18396
|
}
|
|
17709
|
-
ap.
|
|
18397
|
+
ap.compaction = { kind: "none" };
|
|
17710
18398
|
}
|
|
17711
18399
|
clearStalledRecoverySigtermWatchdog(ap) {
|
|
17712
|
-
if (!ap.stalledRecoverySigtermTimer) return;
|
|
17713
|
-
clearTimeout(ap.stalledRecoverySigtermTimer);
|
|
17714
|
-
ap.
|
|
18400
|
+
if (ap.exit.kind !== "live" || !ap.exit.stalledRecoverySigtermTimer) return;
|
|
18401
|
+
clearTimeout(ap.exit.stalledRecoverySigtermTimer);
|
|
18402
|
+
ap.exit = { ...ap.exit, stalledRecoverySigtermTimer: null };
|
|
17715
18403
|
}
|
|
17716
18404
|
mergeRuntimeExitTraceAttrs(runtime, attrs) {
|
|
17717
18405
|
this.runtimeExitTraceAttrs.set(runtime, {
|
|
@@ -17723,8 +18411,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17723
18411
|
this.clearStalledRecoverySigtermWatchdog(ap);
|
|
17724
18412
|
const timeoutMs = stalledRecoverySigtermTimeoutMs();
|
|
17725
18413
|
const runtimeAtSignal = ap.runtime;
|
|
17726
|
-
|
|
17727
|
-
ap.stalledRecoverySigtermTimer
|
|
18414
|
+
const timer = setTimeout(() => {
|
|
18415
|
+
if (ap.exit.kind === "live" && ap.exit.stalledRecoverySigtermTimer === timer) {
|
|
18416
|
+
ap.exit = { ...ap.exit, stalledRecoverySigtermTimer: null };
|
|
18417
|
+
}
|
|
17728
18418
|
const current = this.agents.get(agentId);
|
|
17729
18419
|
if (!current || current !== ap || current.runtime !== runtimeAtSignal || current.gatedSteering.expectedTerminationReason !== "stalled_recovery") {
|
|
17730
18420
|
return;
|
|
@@ -17781,26 +18471,29 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17781
18471
|
logger.warn(`[Agent ${agentId}] Failed to force kill stalled ${runtimeLabel} process: ${reason}`);
|
|
17782
18472
|
}
|
|
17783
18473
|
}, timeoutMs);
|
|
18474
|
+
if (ap.exit.kind === "live") {
|
|
18475
|
+
ap.exit = { ...ap.exit, stalledRecoverySigtermTimer: timer };
|
|
18476
|
+
}
|
|
17784
18477
|
}
|
|
17785
18478
|
startCompactionWatchdog(agentId, ap) {
|
|
17786
18479
|
this.clearCompactionWatchdog(ap);
|
|
17787
18480
|
const startedAt = Date.now();
|
|
17788
|
-
|
|
17789
|
-
ap.compactionWatchdog = setTimeout(() => {
|
|
18481
|
+
const watchdog = setTimeout(() => {
|
|
17790
18482
|
this.markCompactionStale(agentId, startedAt);
|
|
17791
18483
|
}, COMPACTION_STALE_MS);
|
|
18484
|
+
ap.compaction = { kind: "active", startedAt, watchdog };
|
|
17792
18485
|
}
|
|
17793
18486
|
markCompactionStale(agentId, startedAt) {
|
|
17794
18487
|
const ap = this.agents.get(agentId);
|
|
17795
|
-
if (!ap || ap.
|
|
17796
|
-
ap.
|
|
17797
|
-
this.broadcastActivity(agentId, "working", "Context compaction still running; no finish event observed");
|
|
18488
|
+
if (!ap || ap.compaction.kind !== "active" || ap.compaction.startedAt !== startedAt) return;
|
|
18489
|
+
ap.compaction = { ...ap.compaction, watchdog: null };
|
|
18490
|
+
this.broadcastActivity(agentId, "working", "Context compaction still running; no finish event observed", [], void 0, "compaction_stale");
|
|
17798
18491
|
}
|
|
17799
18492
|
completeCompactionIfActive(agentId, detail = "Context compaction finished", options = {}) {
|
|
17800
18493
|
const ap = this.agents.get(agentId);
|
|
17801
|
-
if (!ap ||
|
|
18494
|
+
if (!ap || ap.compaction.kind !== "active") return;
|
|
17802
18495
|
this.clearCompactionWatchdog(ap);
|
|
17803
|
-
this.broadcastActivity(agentId, "working", detail, [{ kind: "compaction_finished" }]);
|
|
18496
|
+
this.broadcastActivity(agentId, "working", detail, [{ kind: "compaction_finished" }], void 0, "compaction_finished");
|
|
17804
18497
|
const reduction = reduceApmGatedCompaction(ap.gatedSteering, { kind: "compaction_finished" });
|
|
17805
18498
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, {
|
|
17806
18499
|
event: "compaction_finished",
|
|
@@ -17813,7 +18506,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17813
18506
|
}
|
|
17814
18507
|
interruptCompactionIfActive(agentId) {
|
|
17815
18508
|
const ap = this.agents.get(agentId);
|
|
17816
|
-
if (!ap ||
|
|
18509
|
+
if (!ap || ap.compaction.kind !== "active" && !ap.gatedSteering.compacting) return;
|
|
17817
18510
|
this.clearCompactionWatchdog(ap);
|
|
17818
18511
|
const reduction = reduceApmGatedCompaction(ap.gatedSteering, { kind: "compaction_interrupted" });
|
|
17819
18512
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState);
|
|
@@ -18016,8 +18709,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18016
18709
|
* for diagnostics, user-facing reporting, and sticky terminal-failure gating.
|
|
18017
18710
|
*/
|
|
18018
18711
|
invalidateRecoveryErrorView(ap) {
|
|
18019
|
-
ap.
|
|
18020
|
-
ap.runtimeErrorSinceProgress = false;
|
|
18712
|
+
ap.decisionErrorWindow.noteRuntimeProgress();
|
|
18021
18713
|
}
|
|
18022
18714
|
recordGatedSteeringEvent(agentId, ap, event, attrs = {}) {
|
|
18023
18715
|
if (ap.runtime.descriptor.busyDelivery !== "gated") return;
|
|
@@ -18096,7 +18788,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18096
18788
|
runtime_error_backoff_remaining_ms: runtimeErrorBackoffRemainingMs,
|
|
18097
18789
|
runtime_error_backoff_attempts: ap.runtimeErrorDeliveryBackoff.attempts,
|
|
18098
18790
|
runtime_error_backoff_reason: ap.runtimeErrorDeliveryBackoff.reason || void 0,
|
|
18099
|
-
runtime_error_backoff_timer_scheduled: scheduled || ap
|
|
18791
|
+
runtime_error_backoff_timer_scheduled: scheduled || this.runtimeErrorDeliveryBackoffTimerScheduled(ap),
|
|
18100
18792
|
delivered_messages_count: 0
|
|
18101
18793
|
});
|
|
18102
18794
|
return false;
|
|
@@ -18133,7 +18825,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18133
18825
|
});
|
|
18134
18826
|
return false;
|
|
18135
18827
|
}
|
|
18136
|
-
this.
|
|
18828
|
+
this.broadcastMessageReceivedActivity(agentId);
|
|
18137
18829
|
let accepted = true;
|
|
18138
18830
|
if (runtimeProfileMessages.length > 0) {
|
|
18139
18831
|
ap.inbox.splice(0, ap.inbox.length, ...ordinaryMessageCandidates);
|
|
@@ -18226,7 +18918,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18226
18918
|
* deliver, so explicit starts with no activation produce no phase-6 row.
|
|
18227
18919
|
*/
|
|
18228
18920
|
openActivationTransition(agentId, ap, launchSource) {
|
|
18229
|
-
if (ap.
|
|
18921
|
+
if (ap.activation.kind !== "idle") return;
|
|
18230
18922
|
const identity = this.launchIdentityAttrs(agentId, ap, launchSource);
|
|
18231
18923
|
const state = {
|
|
18232
18924
|
stateInstanceId: randomUUID6(),
|
|
@@ -18234,7 +18926,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18234
18926
|
identity,
|
|
18235
18927
|
negativeEvidenceBucket: launchReadinessNegativeEvidence(identity)
|
|
18236
18928
|
};
|
|
18237
|
-
ap.
|
|
18929
|
+
ap.activation = { kind: "open", transition: state };
|
|
18238
18930
|
this.recordDaemonTrace(LAUNCH_ACTIVATION_DELIVERY_TRANSITION_SPAN, buildLaunchActivationEnterAttrs(state));
|
|
18239
18931
|
}
|
|
18240
18932
|
/**
|
|
@@ -18245,10 +18937,14 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18245
18937
|
* delivered on `advanced` so later normal deliveries are not re-counted.
|
|
18246
18938
|
*/
|
|
18247
18939
|
closeActivationTransition(ap, closeResult, deliveredVia) {
|
|
18248
|
-
if (
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18940
|
+
if (ap.activation.kind !== "open") {
|
|
18941
|
+
if (closeResult === "advanced" && ap.activation.kind === "idle") {
|
|
18942
|
+
ap.activation = { kind: "delivered" };
|
|
18943
|
+
}
|
|
18944
|
+
return;
|
|
18945
|
+
}
|
|
18946
|
+
const state = ap.activation.transition;
|
|
18947
|
+
ap.activation = closeResult === "advanced" ? { kind: "delivered" } : { kind: "closed" };
|
|
18252
18948
|
this.recordDaemonTrace(
|
|
18253
18949
|
LAUNCH_ACTIVATION_DELIVERY_TRANSITION_SPAN,
|
|
18254
18950
|
buildLaunchActivationCloseAttrs(state, closeResult, this.launchTransitionSeq++, deliveredVia),
|
|
@@ -18266,15 +18962,22 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18266
18962
|
fenced ? Date.now() + timeoutMs : null
|
|
18267
18963
|
);
|
|
18268
18964
|
if (!fenced) return;
|
|
18269
|
-
ap.
|
|
18965
|
+
if (ap.startup.kind !== "waiting") return;
|
|
18966
|
+
const timer = setTimeout(() => {
|
|
18270
18967
|
this.handleRuntimeStartupTimeout(agentId, ap, timeoutMs);
|
|
18271
18968
|
}, timeoutMs);
|
|
18272
|
-
|
|
18969
|
+
timer.unref?.();
|
|
18970
|
+
ap.startup = { ...ap.startup, timer };
|
|
18273
18971
|
}
|
|
18274
18972
|
clearRuntimeStartupTimeout(ap) {
|
|
18275
|
-
if (!ap.
|
|
18276
|
-
clearTimeout(ap.
|
|
18277
|
-
ap.
|
|
18973
|
+
if (ap.startup.kind !== "waiting" || !ap.startup.timer) return;
|
|
18974
|
+
clearTimeout(ap.startup.timer);
|
|
18975
|
+
ap.startup = { ...ap.startup, timer: null };
|
|
18976
|
+
}
|
|
18977
|
+
markRuntimeStartupReady(ap) {
|
|
18978
|
+
if (ap.startup.kind === "ready") return;
|
|
18979
|
+
this.clearRuntimeStartupTimeout(ap);
|
|
18980
|
+
ap.startup = agentProcessStartupReady(ap.startup);
|
|
18278
18981
|
}
|
|
18279
18982
|
runtimeStartupReadinessSatisfiedByEvent(ap, event) {
|
|
18280
18983
|
if ((ap.driver.startupReadiness ?? "first_event") !== "initial_turn") {
|
|
@@ -18286,7 +18989,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18286
18989
|
const current = this.agents.get(agentId);
|
|
18287
18990
|
if (current !== ap) return;
|
|
18288
18991
|
const reduction = reduceApmStartupTimeoutTermination(ap.gatedSteering, {
|
|
18289
|
-
hasRuntimeProgressEvent: ap.
|
|
18992
|
+
hasRuntimeProgressEvent: ap.startup.kind === "ready"
|
|
18290
18993
|
});
|
|
18291
18994
|
if (!reduction.shouldTerminate) {
|
|
18292
18995
|
this.clearRuntimeStartupTimeout(ap);
|
|
@@ -18298,7 +19001,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18298
19001
|
const terminalFailureDetail = classifyTerminalFailure(ap);
|
|
18299
19002
|
const detail = terminalFailureDetail?.detail ?? formatRuntimeStartTimeoutMessage(ap.driver.id);
|
|
18300
19003
|
ap.lastRuntimeError = detail;
|
|
18301
|
-
ap.
|
|
19004
|
+
ap.decisionErrorWindow.recordRuntimeError(detail);
|
|
18302
19005
|
ap.runtimeProgress.markStale();
|
|
18303
19006
|
const staleForMs = Math.max(timeoutMs, ap.runtimeProgress.ageMs());
|
|
18304
19007
|
const diagnostic = buildRuntimeStallDiagnostic(ap, staleForMs, Math.max(1, Math.floor(staleForMs / 6e4)));
|
|
@@ -18316,7 +19019,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18316
19019
|
...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_stalled")
|
|
18317
19020
|
});
|
|
18318
19021
|
logger.warn(`[Agent ${agentId}] ${ap.driver.id} did not reach startup readiness within ${timeoutMs}ms; terminating process`);
|
|
18319
|
-
this.broadcastActivity(agentId, "error", detail, [{ kind: "text", text: `Error: ${detail}` }], ap.launchId);
|
|
19022
|
+
this.broadcastActivity(agentId, "error", detail, [{ kind: "text", text: `Error: ${detail}` }], ap.launchId, "runtime_error");
|
|
18320
19023
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
18321
19024
|
this.cacheStartupTimeoutRetryConfig(agentId, ap);
|
|
18322
19025
|
try {
|
|
@@ -18339,7 +19042,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18339
19042
|
const reduction = reduceApmStartupRequestErrorTermination(ap.gatedSteering);
|
|
18340
19043
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "startup_request_error" });
|
|
18341
19044
|
ap.lastRuntimeError = event.message;
|
|
18342
|
-
ap.
|
|
19045
|
+
ap.decisionErrorWindow.recordRuntimeError(event.message);
|
|
18343
19046
|
ap.runtimeProgress.markStale();
|
|
18344
19047
|
ap.notifications.clearPending();
|
|
18345
19048
|
ap.notifications.clearTimer();
|
|
@@ -18370,9 +19073,9 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18370
19073
|
);
|
|
18371
19074
|
this.broadcastActivity(agentId, "error", visibleErrorMessage, [
|
|
18372
19075
|
{ kind: "text", text: `Error: ${visibleErrorMessage}` }
|
|
18373
|
-
], ap.launchId);
|
|
19076
|
+
], ap.launchId, "runtime_error");
|
|
18374
19077
|
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
18375
|
-
this.
|
|
19078
|
+
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
18376
19079
|
try {
|
|
18377
19080
|
this.runtimeExitTraceAttrs.set(ap.runtime, {
|
|
18378
19081
|
stop_source: "startup_request_error",
|
|
@@ -18390,17 +19093,34 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18390
19093
|
return /thinking.*redacted_thinking|redacted_thinking.*thinking/i.test(message) && /cannot be modified/i.test(message) || /messages\.\d+\.content\.\d+\.text\.start_timestamp:\s*Extra inputs are not permitted/i.test(message);
|
|
18391
19094
|
}
|
|
18392
19095
|
markRuntimeProgressStaleIfNeeded(agentId, ap) {
|
|
18393
|
-
if (ap.
|
|
19096
|
+
if (ap.lastActivityKind !== "working" && ap.lastActivityKind !== "thinking") return false;
|
|
18394
19097
|
if (ap.runtimeProgress.isStale) return true;
|
|
18395
19098
|
const staleForMs = ap.runtimeProgress.ageMs();
|
|
18396
19099
|
if (staleForMs < RUNTIME_PROGRESS_STALE_MS) return false;
|
|
19100
|
+
const subprocessPidAlive = this.probeRuntimeProcessLiveness(ap);
|
|
19101
|
+
if (subprocessPidAlive === true) {
|
|
19102
|
+
this.recordDaemonTrace("daemon.runtime.stall.suppressed_alive", {
|
|
19103
|
+
...this.processLifecycleIdentityAttrs(agentId, ap),
|
|
19104
|
+
last_event_kind: ap.lastActivityKind || void 0,
|
|
19105
|
+
last_event_age_ms_bucket: bucketMs(staleForMs),
|
|
19106
|
+
subprocess_pid_alive: true,
|
|
19107
|
+
subprocess_socket_alive: !ap.runtime.closed,
|
|
19108
|
+
daemon_connected_to_server: this.serverConnected()
|
|
19109
|
+
});
|
|
19110
|
+
this.recordRuntimeTraceEvent(agentId, ap, "runtime.progress.silent_alive", {
|
|
19111
|
+
staleForMs: bucketMs(staleForMs),
|
|
19112
|
+
lastActivity: ap.lastActivityKind || void 0,
|
|
19113
|
+
lastActivityDetailKind: ap.lastActivityDetailKind
|
|
19114
|
+
});
|
|
19115
|
+
return false;
|
|
19116
|
+
}
|
|
18397
19117
|
ap.runtimeProgress.markStale();
|
|
18398
19118
|
const staleForMinutes = Math.max(1, Math.floor(staleForMs / 6e4));
|
|
18399
19119
|
const diagnostic = buildRuntimeStallDiagnostic(ap, staleForMs, staleForMinutes);
|
|
18400
19120
|
const projection = projectApmRuntimeProgressStalledTrace({
|
|
18401
19121
|
turnReason: diagnostic.turnReason,
|
|
18402
19122
|
staleForMs,
|
|
18403
|
-
lastActivity: ap.
|
|
19123
|
+
lastActivity: ap.lastActivityKind,
|
|
18404
19124
|
lastActivityDetailPresent: diagnostic.lastActivityDetailPresent,
|
|
18405
19125
|
lastActivityDetailKind: diagnostic.lastActivityDetailKind
|
|
18406
19126
|
});
|
|
@@ -18413,26 +19133,28 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18413
19133
|
...runtimeTraceCounterAttrs(ap),
|
|
18414
19134
|
...this.finalizeRuntimeProfileTurnControl(agentId, ap, "runtime_stalled")
|
|
18415
19135
|
});
|
|
18416
|
-
let subprocessPidAlive;
|
|
18417
|
-
if (typeof ap.runtime.pid === "number") {
|
|
18418
|
-
try {
|
|
18419
|
-
process.kill(ap.runtime.pid, 0);
|
|
18420
|
-
subprocessPidAlive = true;
|
|
18421
|
-
} catch {
|
|
18422
|
-
subprocessPidAlive = false;
|
|
18423
|
-
}
|
|
18424
|
-
}
|
|
18425
19136
|
this.recordDaemonTrace("daemon.runtime.stall.detected", {
|
|
18426
19137
|
...this.processLifecycleIdentityAttrs(agentId, ap),
|
|
18427
|
-
last_event_kind: ap.
|
|
19138
|
+
last_event_kind: ap.lastActivityKind || void 0,
|
|
18428
19139
|
last_event_age_ms_bucket: bucketMs(staleForMs),
|
|
18429
19140
|
subprocess_pid_alive: subprocessPidAlive,
|
|
18430
19141
|
subprocess_socket_alive: !ap.runtime.closed,
|
|
18431
19142
|
daemon_connected_to_server: this.serverConnected()
|
|
18432
19143
|
}, "error");
|
|
18433
|
-
this.broadcastActivity(agentId, "error", diagnostic.detail);
|
|
19144
|
+
this.broadcastActivity(agentId, "error", diagnostic.detail, [], void 0, "runtime_stalled");
|
|
18434
19145
|
return true;
|
|
18435
19146
|
}
|
|
19147
|
+
probeRuntimeProcessLiveness(ap) {
|
|
19148
|
+
const pid = ap.runtime.pid;
|
|
19149
|
+
if (typeof pid !== "number") return void 0;
|
|
19150
|
+
try {
|
|
19151
|
+
process.kill(pid, 0);
|
|
19152
|
+
return true;
|
|
19153
|
+
} catch (err) {
|
|
19154
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
|
|
19155
|
+
return code === "EPERM" ? true : false;
|
|
19156
|
+
}
|
|
19157
|
+
}
|
|
18436
19158
|
recoverStaleProcessForQueuedMessageIfNeeded(agentId, ap) {
|
|
18437
19159
|
const staleForMs = ap.runtimeProgress.ageMs();
|
|
18438
19160
|
const reduction = reduceApmStalledRecoveryTermination(ap.gatedSteering, {
|
|
@@ -18457,7 +19179,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18457
19179
|
reason: "stalled_recovery",
|
|
18458
19180
|
turnReason: diagnostic.turnReason,
|
|
18459
19181
|
staleForMs,
|
|
18460
|
-
lastActivity: ap.
|
|
19182
|
+
lastActivity: ap.lastActivityKind,
|
|
18461
19183
|
lastActivityDetailPresent: diagnostic.lastActivityDetailPresent,
|
|
18462
19184
|
lastActivityDetailKind: diagnostic.lastActivityDetailKind,
|
|
18463
19185
|
pendingMessages: ap.inbox.length,
|
|
@@ -18476,7 +19198,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18476
19198
|
logger.warn(
|
|
18477
19199
|
`[Agent ${agentId}] ${runtimeLabel} process stalled for ${staleForMinutes}m with ${ap.inbox.length} queued message(s); terminating for restart`
|
|
18478
19200
|
);
|
|
18479
|
-
this.broadcastActivity(agentId, "working", `Restarting stalled ${runtimeLabel} runtime for queued message
|
|
19201
|
+
this.broadcastActivity(agentId, "working", `Restarting stalled ${runtimeLabel} runtime for queued message`, [], void 0, "stalled_recovery");
|
|
18480
19202
|
try {
|
|
18481
19203
|
this.runtimeExitTraceAttrs.set(ap.runtime, projection.processExitAttrs);
|
|
18482
19204
|
this.startStalledRecoverySigtermWatchdog(agentId, ap, runtimeLabel, ap.inbox.length, staleForMs);
|
|
@@ -18534,9 +19256,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18534
19256
|
if (ap) {
|
|
18535
19257
|
const wasStalled = ap.runtimeProgress.isStale;
|
|
18536
19258
|
if (this.runtimeStartupReadinessSatisfiedByEvent(ap, event)) {
|
|
18537
|
-
ap
|
|
19259
|
+
this.markRuntimeStartupReady(ap);
|
|
18538
19260
|
this.closeRuntimeReadinessTransition(ap, "advanced");
|
|
18539
|
-
this.clearRuntimeStartupTimeout(ap);
|
|
18540
19261
|
}
|
|
18541
19262
|
this.noteRuntimeTraceCounter(ap, event);
|
|
18542
19263
|
const eventAttrs = event.kind === "internal_progress" ? {
|
|
@@ -18544,6 +19265,15 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18544
19265
|
source: event.source,
|
|
18545
19266
|
itemType: event.itemType,
|
|
18546
19267
|
payloadBytes: event.payloadBytes
|
|
19268
|
+
} : event.kind === "subagent_progress" ? {
|
|
19269
|
+
kind: event.kind,
|
|
19270
|
+
source: event.source,
|
|
19271
|
+
phase: event.phase,
|
|
19272
|
+
parent_tool_use_id_present: Boolean(event.parentToolUseId),
|
|
19273
|
+
subagent_type_present: Boolean(event.subagentType),
|
|
19274
|
+
task_id_present: Boolean(event.taskId),
|
|
19275
|
+
last_tool_name_present: Boolean(event.lastToolName),
|
|
19276
|
+
payloadBytes: event.payloadBytes
|
|
18547
19277
|
} : event.kind === "runtime_diagnostic" ? runtimeDiagnosticTraceAttrs(event) : event.kind === "runtime_recovery" ? runtimeRecoveryTraceAttrs(event) : { kind: event.kind };
|
|
18548
19278
|
this.recordRuntimeTraceEvent(agentId, ap, "runtime.event.received", eventAttrs);
|
|
18549
19279
|
const recordProgressObservedAfterStall = () => {
|
|
@@ -18565,6 +19295,15 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18565
19295
|
itemType: event.itemType,
|
|
18566
19296
|
payloadBytes: event.payloadBytes
|
|
18567
19297
|
});
|
|
19298
|
+
this.maybeBroadcastRuntimeProgressActivity(agentId, ap);
|
|
19299
|
+
return;
|
|
19300
|
+
}
|
|
19301
|
+
if (event.kind === "subagent_progress") {
|
|
19302
|
+
this.noteRuntimeProgress(ap, event.kind);
|
|
19303
|
+
recordProgressObservedAfterStall();
|
|
19304
|
+
this.invalidateRecoveryErrorView(ap);
|
|
19305
|
+
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
19306
|
+
this.recordSubagentProgressActivity(agentId, ap, event);
|
|
18568
19307
|
return;
|
|
18569
19308
|
}
|
|
18570
19309
|
if (event.kind === "runtime_diagnostic") {
|
|
@@ -18601,7 +19340,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18601
19340
|
break;
|
|
18602
19341
|
case "thinking": {
|
|
18603
19342
|
this.completeCompactionIfActive(agentId, "Context compaction finished (inferred from resumed output)");
|
|
18604
|
-
this.queueTrajectoryText(agentId, "thinking", event.text);
|
|
19343
|
+
this.queueTrajectoryText(agentId, "thinking", event.text, event.subagent);
|
|
18605
19344
|
if (ap) {
|
|
18606
19345
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
18607
19346
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
@@ -18612,7 +19351,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18612
19351
|
}
|
|
18613
19352
|
case "text": {
|
|
18614
19353
|
this.completeCompactionIfActive(agentId, "Context compaction finished (inferred from resumed output)");
|
|
18615
|
-
this.queueTrajectoryText(agentId, "text", event.text);
|
|
19354
|
+
this.queueTrajectoryText(agentId, "text", event.text, event.subagent);
|
|
18616
19355
|
if (ap) {
|
|
18617
19356
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
18618
19357
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
@@ -18639,8 +19378,9 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18639
19378
|
this.broadcastActivity(agentId, "working", detail, [{
|
|
18640
19379
|
kind: "tool_start",
|
|
18641
19380
|
toolName: invocation.toolName,
|
|
18642
|
-
toolInput: inputSummary
|
|
18643
|
-
|
|
19381
|
+
toolInput: inputSummary,
|
|
19382
|
+
...event.subagent ? { subagent: event.subagent } : {}
|
|
19383
|
+
}], void 0, event.subagent ? "subagent_activity" : this.toolActivityDetailKind(invocation.toolName));
|
|
18644
19384
|
break;
|
|
18645
19385
|
}
|
|
18646
19386
|
case "tool_output": {
|
|
@@ -18664,7 +19404,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18664
19404
|
this.flushPendingTrajectory(agentId);
|
|
18665
19405
|
if (ap) this.recordRuntimeTraceEvent(agentId, ap, "runtime.context_compaction.started");
|
|
18666
19406
|
if (ap) this.startCompactionWatchdog(agentId, ap);
|
|
18667
|
-
this.broadcastActivity(agentId, "working", "Compacting context", [{ kind: "compaction_started" }]);
|
|
19407
|
+
this.broadcastActivity(agentId, "working", "Compacting context", [{ kind: "compaction_started" }], void 0, "compacting_context");
|
|
18668
19408
|
if (ap) {
|
|
18669
19409
|
const reduction = reduceApmGatedCompaction(ap.gatedSteering, { kind: "compaction_started" });
|
|
18670
19410
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "compaction_started" });
|
|
@@ -18674,7 +19414,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18674
19414
|
this.flushPendingTrajectory(agentId);
|
|
18675
19415
|
if (ap) this.recordRuntimeTraceEvent(agentId, ap, "runtime.context_compaction.finished");
|
|
18676
19416
|
if (ap) this.clearCompactionWatchdog(ap);
|
|
18677
|
-
this.broadcastActivity(agentId, "working", "Context compaction finished", [{ kind: "compaction_finished" }]);
|
|
19417
|
+
this.broadcastActivity(agentId, "working", "Context compaction finished", [{ kind: "compaction_finished" }], void 0, "compaction_finished");
|
|
18678
19418
|
if (ap) {
|
|
18679
19419
|
const reduction = reduceApmGatedCompaction(ap.gatedSteering, { kind: "compaction_finished" });
|
|
18680
19420
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "compaction_finished" });
|
|
@@ -18684,7 +19424,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18684
19424
|
case "review_started":
|
|
18685
19425
|
this.flushPendingTrajectory(agentId);
|
|
18686
19426
|
if (ap) this.recordRuntimeTraceEvent(agentId, ap, "runtime.review_mode.started");
|
|
18687
|
-
this.broadcastActivity(agentId, "working", "Reviewing changes");
|
|
19427
|
+
this.broadcastActivity(agentId, "working", "Reviewing changes", [], void 0, "reviewing_changes");
|
|
18688
19428
|
if (ap) {
|
|
18689
19429
|
const reduction = reduceApmGatedReview(ap.gatedSteering, { kind: "review_started" });
|
|
18690
19430
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "review_started" });
|
|
@@ -18693,7 +19433,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18693
19433
|
case "review_finished":
|
|
18694
19434
|
this.flushPendingTrajectory(agentId);
|
|
18695
19435
|
if (ap) this.recordRuntimeTraceEvent(agentId, ap, "runtime.review_mode.finished");
|
|
18696
|
-
this.broadcastActivity(agentId, "working", "Review finished");
|
|
19436
|
+
this.broadcastActivity(agentId, "working", "Review finished", [], void 0, "review_finished");
|
|
18697
19437
|
if (ap) {
|
|
18698
19438
|
const reduction = reduceApmGatedReview(ap.gatedSteering, { kind: "review_finished" });
|
|
18699
19439
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "review_finished" });
|
|
@@ -18730,20 +19470,20 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18730
19470
|
if (!this.executeApmGatedSteeringEffect(agentId, ap, deliverStdinEffect)) {
|
|
18731
19471
|
this.commitApmIdleState(agentId, ap, true);
|
|
18732
19472
|
if (stickyTerminalFailure) {
|
|
18733
|
-
this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail);
|
|
19473
|
+
this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail, [], void 0, "runtime_error");
|
|
18734
19474
|
} else if (ap.lastRuntimeError && ap.runtimeErrorDeliveryBackoff.attempts > 0) {
|
|
18735
|
-
this.broadcastActivity(agentId, "error", ap.lastRuntimeError);
|
|
19475
|
+
this.broadcastActivity(agentId, "error", ap.lastRuntimeError, [], void 0, "runtime_error");
|
|
18736
19476
|
} else {
|
|
18737
|
-
this.broadcastActivity(agentId, "online", "Idle");
|
|
19477
|
+
this.broadcastActivity(agentId, "online", "Idle", [], void 0, "idle");
|
|
18738
19478
|
}
|
|
18739
19479
|
}
|
|
18740
19480
|
} else {
|
|
18741
19481
|
if (stickyTerminalFailure) {
|
|
18742
|
-
this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail);
|
|
19482
|
+
this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail, [], void 0, "runtime_error");
|
|
18743
19483
|
} else if (ap.lastRuntimeError) {
|
|
18744
|
-
this.broadcastActivity(agentId, "error", ap.lastRuntimeError);
|
|
19484
|
+
this.broadcastActivity(agentId, "error", ap.lastRuntimeError, [], void 0, "runtime_error");
|
|
18745
19485
|
} else {
|
|
18746
|
-
this.broadcastActivity(agentId, "online", "Idle");
|
|
19486
|
+
this.broadcastActivity(agentId, "online", "Idle", [], void 0, "idle");
|
|
18747
19487
|
}
|
|
18748
19488
|
}
|
|
18749
19489
|
this.endRuntimeTrace(ap, stickyTerminalFailure ? "error" : "ok", {
|
|
@@ -18775,7 +19515,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18775
19515
|
this.flushPendingTrajectory(agentId);
|
|
18776
19516
|
if (ap) {
|
|
18777
19517
|
ap.lastRuntimeError = event.message;
|
|
18778
|
-
ap.
|
|
19518
|
+
ap.decisionErrorWindow.recordRuntimeError(event.message);
|
|
18779
19519
|
}
|
|
18780
19520
|
let visibleErrorMessage = event.message;
|
|
18781
19521
|
if (ap) {
|
|
@@ -18856,7 +19596,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18856
19596
|
}
|
|
18857
19597
|
this.broadcastActivity(agentId, "error", visibleErrorMessage, [
|
|
18858
19598
|
{ kind: "text", text: `Error: ${visibleErrorMessage}` }
|
|
18859
|
-
]);
|
|
19599
|
+
], void 0, "runtime_error");
|
|
18860
19600
|
break;
|
|
18861
19601
|
}
|
|
18862
19602
|
}
|
|
@@ -18936,7 +19676,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18936
19676
|
"error",
|
|
18937
19677
|
`Start failed: ${reason}`,
|
|
18938
19678
|
[{ kind: "text", text: `Error: ${reason}` }],
|
|
18939
|
-
launchId
|
|
19679
|
+
launchId,
|
|
19680
|
+
"runtime_error"
|
|
18940
19681
|
);
|
|
18941
19682
|
return true;
|
|
18942
19683
|
}
|
|
@@ -19004,7 +19745,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
19004
19745
|
runtime_error_backoff_remaining_ms: runtimeErrorBackoffRemainingMs,
|
|
19005
19746
|
runtime_error_backoff_attempts: ap.runtimeErrorDeliveryBackoff.attempts,
|
|
19006
19747
|
runtime_error_backoff_reason: ap.runtimeErrorDeliveryBackoff.reason || void 0,
|
|
19007
|
-
runtime_error_backoff_timer_scheduled: scheduled || ap
|
|
19748
|
+
runtime_error_backoff_timer_scheduled: scheduled || this.runtimeErrorDeliveryBackoffTimerScheduled(ap)
|
|
19008
19749
|
});
|
|
19009
19750
|
return false;
|
|
19010
19751
|
}
|
|
@@ -19158,6 +19899,22 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
19158
19899
|
"]"
|
|
19159
19900
|
].join("\n");
|
|
19160
19901
|
}
|
|
19902
|
+
formatConcreteMessagesRuntimeInput(messages, driver) {
|
|
19903
|
+
if (messages.length === 1) {
|
|
19904
|
+
return `New message received:
|
|
19905
|
+
|
|
19906
|
+
${formatIncomingMessage(messages[0], incomingMessageFormatOptionsForDriver(driver))}
|
|
19907
|
+
|
|
19908
|
+
Respond as appropriate. Complete all your work before stopping.
|
|
19909
|
+
${RESPONSE_TARGET_HINT}`;
|
|
19910
|
+
}
|
|
19911
|
+
return `New messages received:
|
|
19912
|
+
|
|
19913
|
+
${messages.map((message) => formatIncomingMessage(message, incomingMessageFormatOptionsForDriver(driver))).join("\n")}
|
|
19914
|
+
|
|
19915
|
+
Respond as appropriate. Complete all your work before stopping.
|
|
19916
|
+
${RESPONSE_TARGET_HINT}`;
|
|
19917
|
+
}
|
|
19161
19918
|
recordInboxUpdateProjection(agentId, ap, messages, source, mode, renderedInput, totalPendingMessages = messages.length) {
|
|
19162
19919
|
const rows = projectAgentInboxSnapshot(messages);
|
|
19163
19920
|
const projectionAttrs = this.inboxProjectionTraceAttrs(rows, totalPendingMessages);
|
|
@@ -19362,7 +20119,7 @@ ${RESPONSE_TARGET_HINT}`);
|
|
|
19362
20119
|
return true;
|
|
19363
20120
|
}
|
|
19364
20121
|
/** List ONE level of a directory — directories returned without children (lazy-loaded on demand) */
|
|
19365
|
-
async listDirectoryChildren(dir, rootDir) {
|
|
20122
|
+
async listDirectoryChildren(dir, rootDir, includeHidden = false) {
|
|
19366
20123
|
let entries;
|
|
19367
20124
|
try {
|
|
19368
20125
|
entries = await readdir2(dir, { withFileTypes: true });
|
|
@@ -19376,7 +20133,9 @@ ${RESPONSE_TARGET_HINT}`);
|
|
|
19376
20133
|
});
|
|
19377
20134
|
const nodes = [];
|
|
19378
20135
|
for (const entry of entries) {
|
|
19379
|
-
|
|
20136
|
+
const isHidden = entry.name.startsWith(".");
|
|
20137
|
+
if (entry.name === "node_modules") continue;
|
|
20138
|
+
if (isHidden && (!includeHidden || isWorkspaceNeverVisibleHiddenEntry(entry.name))) continue;
|
|
19380
20139
|
const fullPath = path14.join(dir, entry.name);
|
|
19381
20140
|
const relativePath = path14.relative(rootDir, fullPath);
|
|
19382
20141
|
let info;
|
|
@@ -19386,9 +20145,9 @@ ${RESPONSE_TARGET_HINT}`);
|
|
|
19386
20145
|
continue;
|
|
19387
20146
|
}
|
|
19388
20147
|
if (entry.isDirectory()) {
|
|
19389
|
-
nodes.push({ name: entry.name, path: relativePath, isDirectory: true, size: 0, modifiedAt: info.mtime.toISOString() });
|
|
20148
|
+
nodes.push({ name: entry.name, path: relativePath, isDirectory: true, size: 0, modifiedAt: info.mtime.toISOString(), isHidden });
|
|
19390
20149
|
} else {
|
|
19391
|
-
nodes.push({ name: entry.name, path: relativePath, isDirectory: false, size: info.size, modifiedAt: info.mtime.toISOString() });
|
|
20150
|
+
nodes.push({ name: entry.name, path: relativePath, isDirectory: false, size: info.size, modifiedAt: info.mtime.toISOString(), isHidden });
|
|
19392
20151
|
}
|
|
19393
20152
|
}
|
|
19394
20153
|
return nodes;
|
|
@@ -19426,6 +20185,7 @@ var DaemonConnection = class {
|
|
|
19426
20185
|
lastDroppedSendLogAt = 0;
|
|
19427
20186
|
lastInboundAt = null;
|
|
19428
20187
|
lastInboundMessageKind = null;
|
|
20188
|
+
inboundProbeInFlight = false;
|
|
19429
20189
|
pendingActivityByAgent = /* @__PURE__ */ new Map();
|
|
19430
20190
|
latestObservedLaunchIdByAgent = /* @__PURE__ */ new Map();
|
|
19431
20191
|
constructor(options) {
|
|
@@ -19579,11 +20339,44 @@ var DaemonConnection = class {
|
|
|
19579
20339
|
}
|
|
19580
20340
|
resetWatchdog() {
|
|
19581
20341
|
this.clearWatchdog();
|
|
20342
|
+
this.inboundProbeInFlight = false;
|
|
20343
|
+
this.scheduleWatchdogDeadline();
|
|
20344
|
+
}
|
|
20345
|
+
scheduleWatchdogDeadline() {
|
|
19582
20346
|
const ms = this.options.inboundWatchdogMs ?? INBOUND_WATCHDOG_MS;
|
|
19583
20347
|
this.watchdogTimer = this.clock.setTimeout(() => {
|
|
19584
|
-
|
|
20348
|
+
if (!this.inboundProbeInFlight && this.ws?.readyState === WebSocket.OPEN) {
|
|
20349
|
+
this.inboundProbeInFlight = true;
|
|
20350
|
+
logger.info(`[Daemon] No inbound traffic for ${ms / 1e3}s \u2014 sending liveness probe`);
|
|
20351
|
+
this.trace("daemon.connection.inbound_probe_sent", {
|
|
20352
|
+
inbound_watchdog_ms: ms,
|
|
20353
|
+
last_inbound_message_kind: this.lastInboundMessageKind,
|
|
20354
|
+
last_inbound_age_ms_bucket: this.lastInboundAgeBucket(),
|
|
20355
|
+
ws_ready_state: this.ws.readyState,
|
|
20356
|
+
reconnecting: this.shouldConnect
|
|
20357
|
+
});
|
|
20358
|
+
try {
|
|
20359
|
+
this.ws.send(JSON.stringify({ type: "ping" }));
|
|
20360
|
+
} catch (err) {
|
|
20361
|
+
this.trace("daemon.connection.inbound_probe_send_failed", {
|
|
20362
|
+
inbound_watchdog_ms: ms,
|
|
20363
|
+
error_class: err instanceof Error ? err.name : typeof err,
|
|
20364
|
+
ws_ready_state: this.ws?.readyState ?? null,
|
|
20365
|
+
reconnecting: this.shouldConnect
|
|
20366
|
+
}, "error");
|
|
20367
|
+
try {
|
|
20368
|
+
this.ws?.terminate();
|
|
20369
|
+
} catch {
|
|
20370
|
+
}
|
|
20371
|
+
return;
|
|
20372
|
+
}
|
|
20373
|
+
this.scheduleWatchdogDeadline();
|
|
20374
|
+
return;
|
|
20375
|
+
}
|
|
20376
|
+
logger.warn(`[Daemon] No inbound traffic after liveness probe \u2014 forcing reconnect`);
|
|
19585
20377
|
this.trace("daemon.connection.watchdog_timeout", {
|
|
19586
20378
|
inbound_watchdog_ms: ms,
|
|
20379
|
+
probe_in_flight: this.inboundProbeInFlight,
|
|
19587
20380
|
last_inbound_message_kind: this.lastInboundMessageKind,
|
|
19588
20381
|
last_inbound_age_ms_bucket: this.lastInboundAgeBucket(),
|
|
19589
20382
|
ws_ready_state: this.ws?.readyState ?? null,
|
|
@@ -19912,7 +20705,8 @@ var DIAGNOSTIC_ID_ATTRS = /* @__PURE__ */ new Set([
|
|
|
19912
20705
|
"machine_id",
|
|
19913
20706
|
"process_instance_id",
|
|
19914
20707
|
"launch_id",
|
|
19915
|
-
"correlation_id"
|
|
20708
|
+
"correlation_id",
|
|
20709
|
+
"migration_attempt_id"
|
|
19916
20710
|
]);
|
|
19917
20711
|
var DIAGNOSTIC_ERROR_ATTRS = /* @__PURE__ */ new Set([
|
|
19918
20712
|
"runtime_error_class",
|
|
@@ -20363,6 +21157,66 @@ function readPositiveIntegerEnv2(name, fallback) {
|
|
|
20363
21157
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
20364
21158
|
}
|
|
20365
21159
|
|
|
21160
|
+
// src/computerMigrationGuard.ts
|
|
21161
|
+
import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync8 } from "fs";
|
|
21162
|
+
import path18 from "path";
|
|
21163
|
+
var LegacyDaemonKeyAdoptedByComputerError = class extends Error {
|
|
21164
|
+
code = "LEGACY_DAEMON_KEY_ADOPTED_BY_COMPUTER";
|
|
21165
|
+
attachmentPath;
|
|
21166
|
+
serverId;
|
|
21167
|
+
constructor(match) {
|
|
21168
|
+
const serverDisplay = match.serverSlug ? `/${match.serverSlug}` : match.serverId;
|
|
21169
|
+
const startCommand = match.serverSlug ? `raft-computer start /${match.serverSlug}` : "raft-computer start";
|
|
21170
|
+
super(
|
|
21171
|
+
`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.`
|
|
21172
|
+
);
|
|
21173
|
+
this.name = "LegacyDaemonKeyAdoptedByComputerError";
|
|
21174
|
+
this.attachmentPath = match.attachmentPath;
|
|
21175
|
+
this.serverId = match.serverId;
|
|
21176
|
+
}
|
|
21177
|
+
};
|
|
21178
|
+
function daemonApiKeyFingerprint(apiKey) {
|
|
21179
|
+
return getDaemonMachineLockId(apiKey).slice("machine-".length);
|
|
21180
|
+
}
|
|
21181
|
+
function findAdoptedComputerForLegacyFingerprint(slockHome, legacyApiKeyFingerprint) {
|
|
21182
|
+
const serversDir = path18.join(slockHome, "computer", "servers");
|
|
21183
|
+
if (!existsSync9(serversDir)) return null;
|
|
21184
|
+
let serverDirs;
|
|
21185
|
+
try {
|
|
21186
|
+
serverDirs = readdirSync6(serversDir);
|
|
21187
|
+
} catch {
|
|
21188
|
+
return null;
|
|
21189
|
+
}
|
|
21190
|
+
for (const serverId of serverDirs) {
|
|
21191
|
+
const attachmentPath = path18.join(serversDir, serverId, "runner.state.json");
|
|
21192
|
+
let raw;
|
|
21193
|
+
try {
|
|
21194
|
+
raw = readFileSync8(attachmentPath, "utf8");
|
|
21195
|
+
} catch {
|
|
21196
|
+
continue;
|
|
21197
|
+
}
|
|
21198
|
+
try {
|
|
21199
|
+
const attachment = JSON.parse(raw);
|
|
21200
|
+
if (attachment.kind === "computer-attachment" && attachment.adoptedFromLegacy === true && attachment.legacyApiKeyFingerprint === legacyApiKeyFingerprint) {
|
|
21201
|
+
return {
|
|
21202
|
+
attachmentPath,
|
|
21203
|
+
serverId: typeof attachment.serverId === "string" && attachment.serverId.length > 0 ? attachment.serverId : serverId,
|
|
21204
|
+
serverSlug: typeof attachment.serverSlug === "string" && attachment.serverSlug.length > 0 ? attachment.serverSlug : void 0,
|
|
21205
|
+
serverMachineId: typeof attachment.serverMachineId === "string" && attachment.serverMachineId.length > 0 ? attachment.serverMachineId : void 0
|
|
21206
|
+
};
|
|
21207
|
+
}
|
|
21208
|
+
} catch {
|
|
21209
|
+
continue;
|
|
21210
|
+
}
|
|
21211
|
+
}
|
|
21212
|
+
return null;
|
|
21213
|
+
}
|
|
21214
|
+
function assertLegacyDaemonKeyNotAdoptedByComputer(options) {
|
|
21215
|
+
const legacyApiKeyFingerprint = daemonApiKeyFingerprint(options.apiKey);
|
|
21216
|
+
const match = findAdoptedComputerForLegacyFingerprint(options.slockHome, legacyApiKeyFingerprint);
|
|
21217
|
+
if (match) throw new LegacyDaemonKeyAdoptedByComputerError(match);
|
|
21218
|
+
}
|
|
21219
|
+
|
|
20366
21220
|
// src/core.ts
|
|
20367
21221
|
var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
20368
21222
|
var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
|
|
@@ -20534,13 +21388,13 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
|
|
|
20534
21388
|
}
|
|
20535
21389
|
}
|
|
20536
21390
|
function resolveSlockCliPath(moduleUrl = import.meta.url) {
|
|
20537
|
-
const thisDir =
|
|
20538
|
-
const bundledDistPath =
|
|
21391
|
+
const thisDir = path19.dirname(fileURLToPath(moduleUrl));
|
|
21392
|
+
const bundledDistPath = path19.resolve(thisDir, "cli", "index.js");
|
|
20539
21393
|
try {
|
|
20540
21394
|
accessSync(bundledDistPath);
|
|
20541
21395
|
return bundledDistPath;
|
|
20542
21396
|
} catch {
|
|
20543
|
-
const workspaceDistPath =
|
|
21397
|
+
const workspaceDistPath = path19.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
|
|
20544
21398
|
accessSync(workspaceDistPath);
|
|
20545
21399
|
return workspaceDistPath;
|
|
20546
21400
|
}
|
|
@@ -20554,7 +21408,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
|
20554
21408
|
}
|
|
20555
21409
|
async function runBundledSlockCli(argv) {
|
|
20556
21410
|
process.argv = [process.execPath, "slock", ...argv];
|
|
20557
|
-
await import("./dist-
|
|
21411
|
+
await import("./dist-Y3VRAU5E.js");
|
|
20558
21412
|
}
|
|
20559
21413
|
function detectRuntimes(tracer = noopTracer) {
|
|
20560
21414
|
const ids = [];
|
|
@@ -20666,7 +21520,7 @@ function summarizeIncomingMessage(msg) {
|
|
|
20666
21520
|
case "agent:runtime_profile:daemon_release_notice":
|
|
20667
21521
|
return `(agent=${msg.agentId}, notice=${msg.noticeKey})`;
|
|
20668
21522
|
case "agent:workspace:list":
|
|
20669
|
-
return `(agent=${msg.agentId}, dir=${msg.dirPath || "."})`;
|
|
21523
|
+
return `(agent=${msg.agentId}, dir=${msg.dirPath || "."}, hidden=${msg.includeHidden ? "yes" : "no"})`;
|
|
20670
21524
|
case "agent:workspace:read":
|
|
20671
21525
|
return `(agent=${msg.agentId}, path=${msg.path})`;
|
|
20672
21526
|
case "agent:skills:list":
|
|
@@ -20695,7 +21549,7 @@ var DaemonCore = class {
|
|
|
20695
21549
|
options;
|
|
20696
21550
|
daemonVersion;
|
|
20697
21551
|
// When this runner is launched by a managed Computer service, the
|
|
20698
|
-
// service exports
|
|
21552
|
+
// service exports RAFT_COMPUTER_VERSION (the `@botiverse/raft-computer`
|
|
20699
21553
|
// bundle version). Reported in `ready` so the server can surface the
|
|
20700
21554
|
// Computer's own version (distinct from the underlying daemonVersion).
|
|
20701
21555
|
computerVersion;
|
|
@@ -20722,7 +21576,7 @@ var DaemonCore = class {
|
|
|
20722
21576
|
constructor(options) {
|
|
20723
21577
|
this.options = options;
|
|
20724
21578
|
this.daemonVersion = options.daemonVersion ?? readDaemonVersion();
|
|
20725
|
-
this.computerVersion = (process.env.
|
|
21579
|
+
this.computerVersion = (process.env.RAFT_COMPUTER_VERSION || "").trim() || null;
|
|
20726
21580
|
this.slockCliPath = options.slockCliPath ?? resolveSlockCliPathOrEmpty();
|
|
20727
21581
|
this.slockHome = resolveSlockHome();
|
|
20728
21582
|
process.env[SLOCK_HOME_ENV] = this.slockHome;
|
|
@@ -20762,7 +21616,7 @@ var DaemonCore = class {
|
|
|
20762
21616
|
}
|
|
20763
21617
|
resolveMachineStateRoot() {
|
|
20764
21618
|
if (this.options.machineStateDir) return this.options.machineStateDir;
|
|
20765
|
-
if (this.options.dataDir) return
|
|
21619
|
+
if (this.options.dataDir) return path19.join(path19.dirname(this.options.dataDir), "machines");
|
|
20766
21620
|
return resolveDefaultMachineStateRoot();
|
|
20767
21621
|
}
|
|
20768
21622
|
shouldEnableLocalTrace() {
|
|
@@ -20790,7 +21644,7 @@ var DaemonCore = class {
|
|
|
20790
21644
|
sinks: [this.localTraceSink]
|
|
20791
21645
|
}));
|
|
20792
21646
|
this.agentManager.setTracer(this.tracer);
|
|
20793
|
-
this.agentManager.setCliTransportTraceDir(
|
|
21647
|
+
this.agentManager.setCliTransportTraceDir(path19.join(machineDir, "traces"));
|
|
20794
21648
|
}
|
|
20795
21649
|
installTraceBundleUploader(machineDir) {
|
|
20796
21650
|
if (!this.shouldEnableLocalTrace()) return;
|
|
@@ -20816,6 +21670,10 @@ var DaemonCore = class {
|
|
|
20816
21670
|
`[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.`
|
|
20817
21671
|
);
|
|
20818
21672
|
}
|
|
21673
|
+
assertLegacyDaemonKeyNotAdoptedByComputer({
|
|
21674
|
+
slockHome: this.slockHome,
|
|
21675
|
+
apiKey: this.options.apiKey
|
|
21676
|
+
});
|
|
20819
21677
|
if (!this.machineLock) {
|
|
20820
21678
|
this.machineLock = acquireDaemonMachineLock({
|
|
20821
21679
|
apiKey: this.options.apiKey,
|
|
@@ -21038,7 +21896,8 @@ var DaemonCore = class {
|
|
|
21038
21896
|
msg.unreadSummary,
|
|
21039
21897
|
msg.resumePrompt,
|
|
21040
21898
|
msg.launchId,
|
|
21041
|
-
wakeMessageTransient
|
|
21899
|
+
wakeMessageTransient,
|
|
21900
|
+
msg.resumeMessages
|
|
21042
21901
|
);
|
|
21043
21902
|
this.coreStartingAgentIds.delete(msg.agentId);
|
|
21044
21903
|
if (wakeDeliveryAck) {
|
|
@@ -21186,8 +22045,8 @@ var DaemonCore = class {
|
|
|
21186
22045
|
break;
|
|
21187
22046
|
}
|
|
21188
22047
|
case "agent:workspace:list":
|
|
21189
|
-
this.agentManager.getFileTree(msg.agentId, msg.dirPath).then((files) => {
|
|
21190
|
-
this.connection.send({ type: "agent:workspace:file_tree", agentId: msg.agentId, files, dirPath: msg.dirPath });
|
|
22048
|
+
this.agentManager.getFileTree(msg.agentId, msg.dirPath, Boolean(msg.includeHidden)).then((files) => {
|
|
22049
|
+
this.connection.send({ type: "agent:workspace:file_tree", agentId: msg.agentId, files, dirPath: msg.dirPath, includeHidden: Boolean(msg.includeHidden) });
|
|
21191
22050
|
});
|
|
21192
22051
|
break;
|
|
21193
22052
|
case "agent:workspace:read":
|