alvin-bot 5.6.2 → 5.8.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/CHANGELOG.md +29 -0
- package/README.md +1 -1
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -130
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -443
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -0
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1831
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,565 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Agent SDK Provider
|
|
3
|
-
*
|
|
4
|
-
* Wraps the existing Claude Agent SDK integration as a provider.
|
|
5
|
-
* This is the "premium" provider with full tool use (Read, Write, Bash, etc.)
|
|
6
|
-
*
|
|
7
|
-
* Requires: Claude CLI installed & logged in (Max subscription)
|
|
8
|
-
*/
|
|
9
|
-
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
10
|
-
import { readFileSync } from "fs";
|
|
11
|
-
import { resolve, dirname } from "path";
|
|
12
|
-
import { fileURLToPath } from "url";
|
|
13
|
-
import { execFile } from "child_process";
|
|
14
|
-
import { promisify } from "util";
|
|
15
|
-
import { findClaudeBinary } from "../find-claude-binary.js";
|
|
16
|
-
import { buildAlvinMcpServer } from "../services/alvin-mcp-tools.js";
|
|
17
|
-
import { buildRuntimeHeader } from "./runtime-header.js";
|
|
18
|
-
const execFileAsync = promisify(execFile);
|
|
19
|
-
/**
|
|
20
|
-
* Detects the Claude CLI "Not logged in" error message. The CLI emits this
|
|
21
|
-
* as normal assistant text when no valid OAuth token is present, so we have
|
|
22
|
-
* to treat that output as an error in the SDK path too.
|
|
23
|
-
*/
|
|
24
|
-
export function isAuthErrorOutput(text) {
|
|
25
|
-
if (!text)
|
|
26
|
-
return false;
|
|
27
|
-
return /^\s*not logged in\b/i.test(text);
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Detects Anthropic's rate-limit / quota-exhausted gateway responses.
|
|
31
|
-
* These are NOT model outputs — they come back as a single text chunk with
|
|
32
|
-
* output_tokens = 0 before the model even sees the prompt. Without this
|
|
33
|
-
* detection, the bot would forward the gateway message as if it were the
|
|
34
|
-
* assistant's reply ("(Keine Antwort)" or the raw quota text), masking the
|
|
35
|
-
* real cause and wasting more calls on retries.
|
|
36
|
-
*
|
|
37
|
-
* Covers the observed variants:
|
|
38
|
-
* - "You're out of extra usage · resets 9pm (Europe/Berlin)"
|
|
39
|
-
* - "You've reached your weekly usage limit. …"
|
|
40
|
-
* - "Rate limit exceeded"
|
|
41
|
-
* - Claude Max / Pro quota messages in both EN/DE
|
|
42
|
-
*/
|
|
43
|
-
export function isQuotaLimitOutput(text) {
|
|
44
|
-
if (!text)
|
|
45
|
-
return false;
|
|
46
|
-
const t = text.trim();
|
|
47
|
-
if (t.length === 0)
|
|
48
|
-
return false;
|
|
49
|
-
return (/you['’]re out of extra usage/i.test(t) ||
|
|
50
|
-
/reached (your |the )?(weekly |monthly |daily )?(usage|rate) limit/i.test(t) ||
|
|
51
|
-
/rate[- ]?limit(ed)? (exceeded|reached)/i.test(t) ||
|
|
52
|
-
/quota exceeded/i.test(t) ||
|
|
53
|
-
/usage limit reached/i.test(t) ||
|
|
54
|
-
/limit (reached|hit) for (this|your) (week|month|day)/i.test(t) ||
|
|
55
|
-
/resets? \d{1,2}(am|pm|:)/i.test(t) && /usage|limit/i.test(t));
|
|
56
|
-
}
|
|
57
|
-
const BOT_PROJECT_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
58
|
-
// Load CLAUDE.md once at startup
|
|
59
|
-
let botClaudeMd = "";
|
|
60
|
-
try {
|
|
61
|
-
botClaudeMd = readFileSync(resolve(BOT_PROJECT_ROOT, "CLAUDE.md"), "utf-8");
|
|
62
|
-
botClaudeMd = botClaudeMd.replaceAll("docs/", `${BOT_PROJECT_ROOT}/docs/`);
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// CLAUDE.md not found — continue without
|
|
66
|
-
}
|
|
67
|
-
// Checkpoint thresholds
|
|
68
|
-
const CHECKPOINT_TOOL_THRESHOLD = 15;
|
|
69
|
-
const CHECKPOINT_MSG_THRESHOLD = 10;
|
|
70
|
-
export class ClaudeSDKProvider {
|
|
71
|
-
config;
|
|
72
|
-
// Cache the availability check: execFile on every user message would block
|
|
73
|
-
// the bot for ~0-5s each time. A 60s cache is safe — the CLI binary does
|
|
74
|
-
// not disappear mid-session.
|
|
75
|
-
availabilityCache = null;
|
|
76
|
-
static AVAILABILITY_CACHE_MS = 60_000;
|
|
77
|
-
constructor(config) {
|
|
78
|
-
this.config = {
|
|
79
|
-
type: "claude-sdk",
|
|
80
|
-
name: "Claude (Agent SDK)",
|
|
81
|
-
// "inherit" = don't pass model: to the SDK → Claude CLI default wins
|
|
82
|
-
// (currently Opus 4.7 on Max subscription). Override with an alias
|
|
83
|
-
// ("opus" | "sonnet" | "haiku") or a full ID ("claude-opus-4-7").
|
|
84
|
-
model: "inherit",
|
|
85
|
-
supportsTools: true,
|
|
86
|
-
supportsVision: true,
|
|
87
|
-
supportsStreaming: true,
|
|
88
|
-
...config,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
async *query(options) {
|
|
92
|
-
// Clean env to prevent nested session errors
|
|
93
|
-
const cleanEnv = { ...process.env };
|
|
94
|
-
delete cleanEnv.CLAUDECODE;
|
|
95
|
-
delete cleanEnv.CLAUDE_CODE_ENTRYPOINT;
|
|
96
|
-
// Build prompt with optional checkpoint reminder
|
|
97
|
-
let prompt = options.prompt;
|
|
98
|
-
const sessionState = options._sessionState;
|
|
99
|
-
if (sessionState) {
|
|
100
|
-
// Checkpoint reminder injection with COOLDOWN.
|
|
101
|
-
//
|
|
102
|
-
// Old behaviour: once either threshold was crossed, the hint got
|
|
103
|
-
// prepended to EVERY subsequent turn's prompt. That forced Claude
|
|
104
|
-
// to detour through memory-file reads/writes on every single turn,
|
|
105
|
-
// which bloated turn latency in long sessions and was a major
|
|
106
|
-
// contributor to the 5-minute hard timeout firing.
|
|
107
|
-
//
|
|
108
|
-
// New behaviour: inject only every CHECKPOINT_REMINDER_EVERY turns
|
|
109
|
-
// after the threshold is reached. At messageCount 10 → injected,
|
|
110
|
-
// 11/12/13/14 → skipped, 15 → injected again, etc. 80% reduction
|
|
111
|
-
// in per-turn overhead while still giving Claude periodic reminders.
|
|
112
|
-
const CHECKPOINT_REMINDER_EVERY = 5;
|
|
113
|
-
const overThreshold = sessionState.toolUseCount >= CHECKPOINT_TOOL_THRESHOLD ||
|
|
114
|
-
sessionState.messageCount >= CHECKPOINT_MSG_THRESHOLD;
|
|
115
|
-
const onCooldownBeat = sessionState.messageCount % CHECKPOINT_REMINDER_EVERY === 0;
|
|
116
|
-
if (overThreshold && onCooldownBeat) {
|
|
117
|
-
prompt = `[CHECKPOINT] Du hast bereits ${sessionState.toolUseCount} Tool-Aufrufe und ${sessionState.messageCount} Nachrichten in dieser Session. Schreibe jetzt einen Checkpoint in deine Memory-Datei (docs/memory/YYYY-MM-DD.md) bevor du diese Anfrage bearbeitest.\n\n${prompt}`;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
// Build system prompt. The runtime-header is injected ABOVE the CLAUDE.md
|
|
121
|
-
// contents so its values (BOT_VERSION, install path, runtime) outrank any
|
|
122
|
-
// stale "Version: x.y.z" line that may still live in CLAUDE.md.
|
|
123
|
-
const runtimeHeader = buildRuntimeHeader();
|
|
124
|
-
const systemPrompt = options.systemPrompt
|
|
125
|
-
? `${runtimeHeader}\n\n${options.systemPrompt}\n\n${botClaudeMd}`
|
|
126
|
-
: `${runtimeHeader}\n\n${botClaudeMd}`;
|
|
127
|
-
// Build a real AbortController the SDK can call .abort() on.
|
|
128
|
-
// The previous implementation cast a plain {signal} object to AbortController,
|
|
129
|
-
// which broke SDK-internal cancellation and left orphan subprocesses.
|
|
130
|
-
let internalAbortController;
|
|
131
|
-
if (options.abortSignal) {
|
|
132
|
-
internalAbortController = new AbortController();
|
|
133
|
-
if (options.abortSignal.aborted) {
|
|
134
|
-
internalAbortController.abort();
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
options.abortSignal.addEventListener("abort", () => internalAbortController?.abort(), { once: true });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
try {
|
|
141
|
-
const claudePath = findClaudeBinary();
|
|
142
|
-
// v4.13 — Register Alvin's custom MCP server if the caller provided
|
|
143
|
-
// dispatch context. The server exposes `alvin_dispatch_agent` which
|
|
144
|
-
// spawns truly detached `claude -p` subprocesses (independent of the
|
|
145
|
-
// main SDK subprocess's lifecycle). When Claude calls it, the bot
|
|
146
|
-
// can abort this query without killing the dispatched sub-agent.
|
|
147
|
-
const mcpServers = {};
|
|
148
|
-
if (options.alvinDispatchContext) {
|
|
149
|
-
mcpServers.alvin = buildAlvinMcpServer(options.alvinDispatchContext);
|
|
150
|
-
}
|
|
151
|
-
// v4.13 — MCP tool names must be explicitly whitelisted via allowedTools
|
|
152
|
-
// in the form `mcp__<server>__<tool>`. Without this, Claude can see the
|
|
153
|
-
// tool in the catalog but cannot actually invoke it.
|
|
154
|
-
const defaultAllowed = [
|
|
155
|
-
"Read", "Write", "Edit", "Bash", "Glob", "Grep",
|
|
156
|
-
"WebSearch", "WebFetch", "Task",
|
|
157
|
-
];
|
|
158
|
-
if (options.alvinDispatchContext) {
|
|
159
|
-
defaultAllowed.push("mcp__alvin__dispatch_agent");
|
|
160
|
-
}
|
|
161
|
-
// v4.15 — Forward model selection to the Agent SDK. Resolution order:
|
|
162
|
-
// 1. options.model (per-query override — e.g. workspace `model:` field)
|
|
163
|
-
// 2. this.config.model (provider-level default — e.g. claude-sonnet)
|
|
164
|
-
// 3. "inherit" → don't pass model: → Claude CLI default (Opus 4.7 on Max)
|
|
165
|
-
// Aliases "opus" | "sonnet" | "haiku" auto-resolve to the latest tier.
|
|
166
|
-
const rawModel = options.model ?? this.config.model;
|
|
167
|
-
const modelOverride = rawModel && rawModel !== "inherit" ? rawModel : undefined;
|
|
168
|
-
// v4.15.1 — Suppress fallbackModel when the primary model is already
|
|
169
|
-
// Haiku. The Agent SDK rejects identical model/fallbackModel pairs with
|
|
170
|
-
// "Fallback model cannot be the same as the main model", which then
|
|
171
|
-
// cascades all the way down the provider fallback chain (→ Ollama
|
|
172
|
-
// on-demand boot → noticeable latency spike). For opus/sonnet/inherit,
|
|
173
|
-
// keep Haiku as the rate-limit fallback.
|
|
174
|
-
const primaryIsHaiku = (modelOverride ?? "").toLowerCase().includes("haiku");
|
|
175
|
-
const fallbackModel = primaryIsHaiku ? undefined : "haiku";
|
|
176
|
-
const q = query({
|
|
177
|
-
prompt: options.steerChannel
|
|
178
|
-
? options.steerChannel
|
|
179
|
-
: prompt,
|
|
180
|
-
options: {
|
|
181
|
-
cwd: options.workingDir || process.cwd(),
|
|
182
|
-
abortController: internalAbortController,
|
|
183
|
-
resume: options.sessionId ?? undefined,
|
|
184
|
-
pathToClaudeCodeExecutable: claudePath,
|
|
185
|
-
permissionMode: "bypassPermissions",
|
|
186
|
-
allowDangerouslySkipPermissions: true,
|
|
187
|
-
env: cleanEnv,
|
|
188
|
-
settingSources: ["user", "project"],
|
|
189
|
-
// v4.12.2 — options.allowedTools can override the default full set.
|
|
190
|
-
// Used by sub-agents with toolset="readonly"/"research" to restrict
|
|
191
|
-
// what Claude can do. Default = full access + alvin MCP tools.
|
|
192
|
-
allowedTools: options.allowedTools ?? defaultAllowed,
|
|
193
|
-
// v4.13 — Conditionally pass the MCP server config so the inline
|
|
194
|
-
// dispatch tool is visible. Empty object = no custom tools.
|
|
195
|
-
mcpServers: Object.keys(mcpServers).length > 0 ? mcpServers : undefined,
|
|
196
|
-
systemPrompt,
|
|
197
|
-
effort: (options.effort || "medium"),
|
|
198
|
-
maxTurns: 50,
|
|
199
|
-
betas: ["context-1m-2025-08-07"],
|
|
200
|
-
...(modelOverride ? { model: modelOverride } : {}),
|
|
201
|
-
// v4.19.0 — per-workspace temperature override. Passed through to
|
|
202
|
-
// the Agent SDK; providers that don't use it just drop it.
|
|
203
|
-
...(typeof options.temperature === "number" ? { temperature: options.temperature } : {}),
|
|
204
|
-
// Prefer Haiku as fallback on rate-limit/overload — cheap and
|
|
205
|
-
// fast, keeps the bot responsive when the primary tier is
|
|
206
|
-
// throttled. Omitted when the primary IS Haiku (SDK requires
|
|
207
|
-
// distinct model/fallbackModel values — see v4.15.1 fix above).
|
|
208
|
-
...(fallbackModel ? { fallbackModel } : {}),
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
// v5.1 — Expose the SDK query handle to the caller so requestStop()
|
|
212
|
-
// can interrupt it via q.interrupt() + transport.process.kill().
|
|
213
|
-
try {
|
|
214
|
-
options.onQueryHandle?.(q);
|
|
215
|
-
}
|
|
216
|
-
catch { /* non-fatal */ }
|
|
217
|
-
let accumulatedText = "";
|
|
218
|
-
let capturedSessionId = options.sessionId || "";
|
|
219
|
-
let localToolUseCount = 0;
|
|
220
|
-
for await (const message of q) {
|
|
221
|
-
// v5.1 — Bail immediately if the caller set abortSignal while iterating.
|
|
222
|
-
if (options.abortSignal?.aborted) {
|
|
223
|
-
try {
|
|
224
|
-
q.return?.();
|
|
225
|
-
}
|
|
226
|
-
catch { /* ignore */ }
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
// System init — capture session ID
|
|
230
|
-
if (message.type === "system" && "subtype" in message && message.subtype === "init") {
|
|
231
|
-
const sysMsg = message;
|
|
232
|
-
capturedSessionId = sysMsg.session_id;
|
|
233
|
-
}
|
|
234
|
-
// Assistant message — text + tool use
|
|
235
|
-
if (message.type === "assistant") {
|
|
236
|
-
const assistantMsg = message;
|
|
237
|
-
capturedSessionId = assistantMsg.session_id;
|
|
238
|
-
if (assistantMsg.message?.content) {
|
|
239
|
-
for (const block of assistantMsg.message.content) {
|
|
240
|
-
if ("text" in block && block.text) {
|
|
241
|
-
// Guard against "Not logged in" leaking as assistant text.
|
|
242
|
-
// If the very first text chunk matches the CLI auth-error
|
|
243
|
-
// pattern, surface it as an error chunk instead of rendering
|
|
244
|
-
// it as a normal response.
|
|
245
|
-
if (!accumulatedText && isAuthErrorOutput(block.text)) {
|
|
246
|
-
yield {
|
|
247
|
-
type: "error",
|
|
248
|
-
error: "Claude CLI is not logged in. Run `claude login` on this machine.",
|
|
249
|
-
};
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
// v4.18.4 — Guard against Anthropic rate-limit / quota-exhausted
|
|
253
|
-
// gateway messages that also arrive as a single text chunk (with
|
|
254
|
-
// output_tokens = 0). Pass them through as a friendly text chunk
|
|
255
|
-
// (NOT an error — would trigger fallback cascade to Ollama) and
|
|
256
|
-
// mark the provider as degraded so the next heartbeat re-checks.
|
|
257
|
-
if (!accumulatedText && isQuotaLimitOutput(block.text)) {
|
|
258
|
-
const hint = "⚠️ " + block.text.trim() +
|
|
259
|
-
"\n\nTop up the plan or wait for the reset. No message was sent to Claude.";
|
|
260
|
-
this.invalidateAvailabilityCache();
|
|
261
|
-
yield {
|
|
262
|
-
type: "text",
|
|
263
|
-
text: hint,
|
|
264
|
-
delta: hint,
|
|
265
|
-
sessionId: capturedSessionId,
|
|
266
|
-
};
|
|
267
|
-
accumulatedText = hint;
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
accumulatedText += block.text;
|
|
271
|
-
yield {
|
|
272
|
-
type: "text",
|
|
273
|
-
text: accumulatedText,
|
|
274
|
-
delta: block.text,
|
|
275
|
-
sessionId: capturedSessionId,
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
if ("name" in block) {
|
|
279
|
-
localToolUseCount++;
|
|
280
|
-
// v4.12.1 — Extract run_in_background from the raw input
|
|
281
|
-
// object BEFORE the 500-char JSON truncation below. This is
|
|
282
|
-
// load-bearing: for long prompts the serialized input can
|
|
283
|
-
// exceed 500 chars, and naive post-truncation parsing would
|
|
284
|
-
// lose the flag and misclassify sync tasks as async (→ false
|
|
285
|
-
// 10-min abort on legitimate long-running sub-agents).
|
|
286
|
-
// See src/handlers/stuck-timer.ts and message.ts for the
|
|
287
|
-
// consumer side.
|
|
288
|
-
let runInBackground;
|
|
289
|
-
if ("input" in block &&
|
|
290
|
-
block.input &&
|
|
291
|
-
typeof block.input === "object") {
|
|
292
|
-
const input = block.input;
|
|
293
|
-
if (input.run_in_background === true)
|
|
294
|
-
runInBackground = true;
|
|
295
|
-
else if (input.run_in_background === false)
|
|
296
|
-
runInBackground = false;
|
|
297
|
-
}
|
|
298
|
-
// Serialise the tool input (parameters) so the message
|
|
299
|
-
// handler can surface detail for specific tools — most
|
|
300
|
-
// importantly the "Task" tool where `input.description`
|
|
301
|
-
// describes what sub-task Claude is delegating.
|
|
302
|
-
let toolInputStr;
|
|
303
|
-
if ("input" in block && block.input !== undefined) {
|
|
304
|
-
try {
|
|
305
|
-
const raw = JSON.stringify(block.input);
|
|
306
|
-
// cap at 500 chars to keep status lines manageable
|
|
307
|
-
toolInputStr = raw.length > 500 ? raw.slice(0, 500) + "…" : raw;
|
|
308
|
-
}
|
|
309
|
-
catch {
|
|
310
|
-
// unserializable — skip
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
// Tool-use blocks in the Anthropic API always have an `id`
|
|
314
|
-
// at runtime, but the SDK's .d.ts shape doesn't guarantee it
|
|
315
|
-
// — defensive cast. Used by the task-aware stuck timer to
|
|
316
|
-
// correlate tool_use → tool_result for sync tracking.
|
|
317
|
-
const toolUseId = block.id;
|
|
318
|
-
yield {
|
|
319
|
-
type: "tool_use",
|
|
320
|
-
toolName: block.name,
|
|
321
|
-
toolInput: toolInputStr,
|
|
322
|
-
toolUseId,
|
|
323
|
-
runInBackground,
|
|
324
|
-
sessionId: capturedSessionId,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
// User message — tool_results from the Claude API arrive as user
|
|
331
|
-
// messages in the SDK protocol. We surface tool_result blocks as
|
|
332
|
-
// chunks so the message handler can detect Agent async_launched
|
|
333
|
-
// payloads and register them with the watcher (Fix #17 Stage 2).
|
|
334
|
-
if (message.type === "user") {
|
|
335
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
336
|
-
const userMsg = message;
|
|
337
|
-
const content = userMsg.message?.content;
|
|
338
|
-
if (Array.isArray(content)) {
|
|
339
|
-
for (const block of content) {
|
|
340
|
-
if (block &&
|
|
341
|
-
typeof block === "object" &&
|
|
342
|
-
block.type === "tool_result" &&
|
|
343
|
-
typeof block.tool_use_id === "string") {
|
|
344
|
-
// The `content` field on a tool_result block can be a
|
|
345
|
-
// plain string OR an array of content blocks. Normalize
|
|
346
|
-
// to a single string so the chunk consumer doesn't need
|
|
347
|
-
// to know about the SDK shape.
|
|
348
|
-
let contentText = "";
|
|
349
|
-
if (typeof block.content === "string") {
|
|
350
|
-
contentText = block.content;
|
|
351
|
-
}
|
|
352
|
-
else if (Array.isArray(block.content)) {
|
|
353
|
-
contentText = block.content
|
|
354
|
-
.map((c) => {
|
|
355
|
-
if (c && typeof c === "object" && "text" in c) {
|
|
356
|
-
const t = c.text;
|
|
357
|
-
return typeof t === "string" ? t : "";
|
|
358
|
-
}
|
|
359
|
-
return "";
|
|
360
|
-
})
|
|
361
|
-
.join("");
|
|
362
|
-
}
|
|
363
|
-
yield {
|
|
364
|
-
type: "tool_result",
|
|
365
|
-
toolUseId: block.tool_use_id,
|
|
366
|
-
toolResultContent: contentText,
|
|
367
|
-
sessionId: capturedSessionId,
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
// Result — done (extract full usage including cache tokens)
|
|
374
|
-
if (message.type === "result") {
|
|
375
|
-
const resultMsg = message;
|
|
376
|
-
const usage = "usage" in resultMsg ? resultMsg.usage : null;
|
|
377
|
-
const inputTok = usage
|
|
378
|
-
? (usage.input_tokens || 0) + (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0)
|
|
379
|
-
: 0;
|
|
380
|
-
const outputTok = usage?.output_tokens || 0;
|
|
381
|
-
// v4.18.3 — Silent-empty-stream detection (replaces 4.18.2 approach).
|
|
382
|
-
//
|
|
383
|
-
// If the stream terminated cleanly but produced ZERO text chunks,
|
|
384
|
-
// something went wrong that the SDK didn't surface as an error.
|
|
385
|
-
// Most common cause: the OAuth token in the Keychain was rotated
|
|
386
|
-
// (e.g. right after /extra-usage or /login) while our in-memory
|
|
387
|
-
// SDK client still held the old one — the CLI subprocess silently
|
|
388
|
-
// gets a 401, emits no text, and we complete with
|
|
389
|
-
// accumulatedText === "".
|
|
390
|
-
//
|
|
391
|
-
// CRITICAL: we must NOT yield an "error" chunk here — the registry's
|
|
392
|
-
// queryWithFallback() treats that as "primary failed" and kicks off
|
|
393
|
-
// a full failover to the next provider (Ollama). That's exactly
|
|
394
|
-
// wrong: the next CLI subprocess would have picked up the fresh
|
|
395
|
-
// token by itself. Instead we:
|
|
396
|
-
// 1. Invalidate the availability cache so the next heartbeat
|
|
397
|
-
// re-probes `claude auth status` with a fresh subprocess.
|
|
398
|
-
// 2. Return a friendly "text" chunk explaining what happened,
|
|
399
|
-
// so the user sees a clear message (not "(Keine Antwort)")
|
|
400
|
-
// and knows to resend — without tripping the failover.
|
|
401
|
-
if (accumulatedText === "" && outputTok === 0) {
|
|
402
|
-
this.invalidateAvailabilityCache();
|
|
403
|
-
// v4.19.2 — Diagnostic logging: when the Agent SDK returns an
|
|
404
|
-
// empty stream, we need enough detail to tell apart the possible
|
|
405
|
-
// causes (auth, quota, context overflow, model rejection, MCP
|
|
406
|
-
// init failure). The message handler-level reset was fine for
|
|
407
|
-
// stale-session recovery but gave us no signal on WHY it went
|
|
408
|
-
// empty in the first place.
|
|
409
|
-
try {
|
|
410
|
-
const diag = {
|
|
411
|
-
subtype: resultMsg.subtype,
|
|
412
|
-
is_error: resultMsg.is_error,
|
|
413
|
-
num_turns: resultMsg.num_turns,
|
|
414
|
-
duration_ms: resultMsg.duration_ms,
|
|
415
|
-
duration_api_ms: resultMsg.duration_api_ms,
|
|
416
|
-
total_cost_usd: resultMsg.total_cost_usd,
|
|
417
|
-
session_id: resultMsg.session_id,
|
|
418
|
-
passed_session_id: options.sessionId ?? null,
|
|
419
|
-
usage,
|
|
420
|
-
modelOverride,
|
|
421
|
-
cwd: options.workingDir,
|
|
422
|
-
effort: options.effort,
|
|
423
|
-
systemPromptLen: systemPrompt.length,
|
|
424
|
-
promptLen: prompt.length,
|
|
425
|
-
historyLen: options.history?.length ?? 0,
|
|
426
|
-
allowedToolsCount: (options.allowedTools ?? defaultAllowed).length,
|
|
427
|
-
hasMcp: Object.keys(mcpServers).length > 0,
|
|
428
|
-
};
|
|
429
|
-
console.warn(`[empty-stream] SDK returned 0 output tokens — diagnostic dump:`, JSON.stringify(diag));
|
|
430
|
-
}
|
|
431
|
-
catch (diagErr) {
|
|
432
|
-
console.warn(`[empty-stream] SDK returned 0 output tokens (diagnostic serialisation failed: ${diagErr})`);
|
|
433
|
-
}
|
|
434
|
-
const hint = "⚠️ Claude antwortete mit leerem Stream. " +
|
|
435
|
-
"Meist Folge einer stale SDK-Session nach /extra-usage, /login oder Token-Refresh. " +
|
|
436
|
-
"Ich starte die Session automatisch neu — bitte schick die Nachricht einfach nochmal.";
|
|
437
|
-
yield {
|
|
438
|
-
type: "text",
|
|
439
|
-
text: hint,
|
|
440
|
-
delta: hint,
|
|
441
|
-
sessionId: resultMsg.session_id || capturedSessionId,
|
|
442
|
-
// v4.18.5 — Signal to the message handler that it should clear
|
|
443
|
-
// session.sessionId now. Without this the next query resumes
|
|
444
|
-
// the same stale sessionId and produces another empty stream
|
|
445
|
-
// in a loop that burns credits until the user manually /new's.
|
|
446
|
-
sessionResetRequested: true,
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
// V56-T1 — Surface the SDK's authoritative final answer
|
|
450
|
-
// separately from the accumulated narration. SDKResultSuccess
|
|
451
|
-
// carries a single `result: string` that is the agent's actual
|
|
452
|
-
// outcome (NOT the concatenation of every assistant turn).
|
|
453
|
-
// SDKResultError has no `result` field — leave finalResult
|
|
454
|
-
// undefined there so consumers fall back to buffered text.
|
|
455
|
-
// This is the same source the detached-dispatch path already
|
|
456
|
-
// prefers (`{"type":"result"}.result` in async-agent-parser).
|
|
457
|
-
const finalResult = "subtype" in resultMsg &&
|
|
458
|
-
resultMsg.subtype === "success" &&
|
|
459
|
-
typeof resultMsg.result === "string"
|
|
460
|
-
? resultMsg.result
|
|
461
|
-
: undefined;
|
|
462
|
-
yield {
|
|
463
|
-
type: "done",
|
|
464
|
-
text: accumulatedText || "",
|
|
465
|
-
...(finalResult !== undefined ? { finalResult } : {}),
|
|
466
|
-
sessionId: resultMsg.session_id || capturedSessionId,
|
|
467
|
-
costUsd: "total_cost_usd" in resultMsg ? resultMsg.total_cost_usd : 0,
|
|
468
|
-
inputTokens: inputTok,
|
|
469
|
-
outputTokens: outputTok,
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
catch (err) {
|
|
475
|
-
if (err instanceof Error && err.message.includes("abort")) {
|
|
476
|
-
yield { type: "error", error: "Request aborted" };
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
yield {
|
|
480
|
-
type: "error",
|
|
481
|
-
error: `Claude SDK error: ${err instanceof Error ? err.message : String(err)}`,
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
async isAvailable() {
|
|
487
|
-
// Cached availability check. The previous implementation called execSync
|
|
488
|
-
// on every user message, blocking the Node event loop for up to 5s per
|
|
489
|
-
// query. We now use async execFile and cache the result for 60s.
|
|
490
|
-
const now = Date.now();
|
|
491
|
-
if (this.availabilityCache && this.availabilityCache.expiresAt > now) {
|
|
492
|
-
return this.availabilityCache.result;
|
|
493
|
-
}
|
|
494
|
-
const cache = (result) => {
|
|
495
|
-
this.availabilityCache = {
|
|
496
|
-
result,
|
|
497
|
-
expiresAt: now + ClaudeSDKProvider.AVAILABILITY_CACHE_MS,
|
|
498
|
-
};
|
|
499
|
-
return result;
|
|
500
|
-
};
|
|
501
|
-
try {
|
|
502
|
-
const claudePath = findClaudeBinary();
|
|
503
|
-
if (!claudePath)
|
|
504
|
-
return cache(false);
|
|
505
|
-
// Step 1: binary exists?
|
|
506
|
-
await execFileAsync(claudePath, ["--version"], { timeout: 5000 });
|
|
507
|
-
// Step 2: actually authenticated?
|
|
508
|
-
//
|
|
509
|
-
// We used to use `claude -p "ping" --output-format text` and sniff
|
|
510
|
-
// the stdout for "Not logged in". That spawned a full SDK query,
|
|
511
|
-
// consumed tokens, and took 5-10 seconds warm — occasionally
|
|
512
|
-
// crossing our timeout on cold starts or under load, leading to
|
|
513
|
-
// false-positive "unavailable" reports that cascaded into heartbeat
|
|
514
|
-
// failures and unnecessary fallback to Ollama.
|
|
515
|
-
//
|
|
516
|
-
// `claude auth status` is the purpose-built command: fast (~150ms),
|
|
517
|
-
// no token cost, no SDK init, returns structured JSON with an
|
|
518
|
-
// explicit `loggedIn` boolean. Much cleaner.
|
|
519
|
-
try {
|
|
520
|
-
const { stdout } = await execFileAsync(claudePath, ["auth", "status"], { timeout: 5000 });
|
|
521
|
-
const parsed = JSON.parse(stdout);
|
|
522
|
-
if (parsed.loggedIn === true) {
|
|
523
|
-
return cache(true);
|
|
524
|
-
}
|
|
525
|
-
// loggedIn === false (or missing) — not authenticated
|
|
526
|
-
return cache(false);
|
|
527
|
-
}
|
|
528
|
-
catch (authErr) {
|
|
529
|
-
// Older claude CLI versions may not expose `auth status` as JSON,
|
|
530
|
-
// or may exit non-zero when not logged in. Fall back to the
|
|
531
|
-
// sniff-stdout approach for backward compat.
|
|
532
|
-
try {
|
|
533
|
-
const { stdout: probeOut } = await execFileAsync(claudePath, ["-p", "ping", "--output-format", "text"], { timeout: 15000 });
|
|
534
|
-
// v4.18.4 — treat quota-exhausted as "unavailable" so heartbeat
|
|
535
|
-
// surfaces it and stops wasting extra-usage credits on retries.
|
|
536
|
-
return cache(!isAuthErrorOutput(probeOut) && !isQuotaLimitOutput(probeOut));
|
|
537
|
-
}
|
|
538
|
-
catch {
|
|
539
|
-
// Both checks failed — treat as unavailable
|
|
540
|
-
void authErr;
|
|
541
|
-
return cache(false);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
catch {
|
|
546
|
-
return cache(false);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
/** v4.15.2 — Clear the cached isAvailable() result. Called by the
|
|
550
|
-
* heartbeat service after detecting macOS sleep/wake so the first
|
|
551
|
-
* post-wake probe doesn't serve a stale "unavailable" from hours ago. */
|
|
552
|
-
invalidateAvailabilityCache() {
|
|
553
|
-
this.availabilityCache = null;
|
|
554
|
-
}
|
|
555
|
-
getInfo() {
|
|
556
|
-
const model = this.config.model === "inherit"
|
|
557
|
-
? "CLI default (latest)"
|
|
558
|
-
: this.config.model;
|
|
559
|
-
return {
|
|
560
|
-
name: this.config.name,
|
|
561
|
-
model,
|
|
562
|
-
status: "✅ Agent SDK (CLI auth)",
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
}
|
|
1
|
+
const _0x4e769c=_0x1e8b,_0x5c88d4=_0x1e8b;(function(_0xbfb2c4,_0x1f37ec){const _0x3985df=_0x1e8b,_0x4e85bd=_0x1e8b,_0x4d91ad=_0xbfb2c4();while(!![]){try{const _0x38aacf=-parseInt(_0x3985df(0x14c))/(0x126a+0x1508+-0x1*0x2771)*(-parseInt(_0x3985df(0xb2))/(-0x122a+-0x4c8+0x16f4))+-parseInt(_0x3985df(0xe8))/(-0xf58+0x39*-0x66+0x2611)*(-parseInt(_0x3985df(0xe4))/(-0x8f5*0x1+0x906*0x3+0x71*-0x29))+parseInt(_0x3985df(0x118))/(-0x14ee+-0x2f3+0x7*0x36a)+-parseInt(_0x4e85bd(0x12b))/(-0x90b+0x1798+-0xe87)+-parseInt(_0x4e85bd(0xd4))/(0x936+0x2*-0xf7b+-0x15c7*-0x1)+-parseInt(_0x3985df(0xaf))/(-0x20e4+-0x2*-0x9f7+-0x2*-0x67f)*(-parseInt(_0x3985df(0x156))/(0x1a23+0x10*0x4d+-0x1eea))+-parseInt(_0x4e85bd(0xf3))/(0x174d+-0x57a*0x1+-0x11c9);if(_0x38aacf===_0x1f37ec)break;else _0x4d91ad['push'](_0x4d91ad['shift']());}catch(_0x3ce9eb){_0x4d91ad['push'](_0x4d91ad['shift']());}}}(_0x4d4e,0x1*-0x866b7+0xddabe+0xaf7f*0x3));const _0x3a3eef=(function(){let _0x16be5e=!![];return function(_0x322fea,_0x57cec6){const _0x3dc848=_0x16be5e?function(){if(_0x57cec6){const _0x4eb6ef=_0x57cec6['apply'](_0x322fea,arguments);return _0x57cec6=null,_0x4eb6ef;}}:function(){};return _0x16be5e=![],_0x3dc848;};}()),_0x1dcebd=_0x3a3eef(this,function(){const _0x43bb21=_0x1e8b,_0x5c12a5=_0x1e8b;return _0x1dcebd[_0x43bb21(0x108)]()[_0x5c12a5(0xfb)](_0x43bb21(0x153)+'+$')[_0x43bb21(0x108)]()[_0x43bb21(0xec)+'r'](_0x1dcebd)[_0x5c12a5(0xfb)](_0x5c12a5(0x153)+'+$');});_0x1dcebd();import{query}from'@anthropic-ai/claude-agent-sdk';import{readFileSync}from'fs';import{resolve,dirname}from'path';function _0x4d4e(){const _0x19d095=['B3n0AwmGC2vYAq','igjPDhrLihnJAa','D29YA2LUz0rPCG','DxrMltG','Dg90ywXFy29ZDa','ywDLlcaVBg9NAq','DxnHz2u','ifrVB2WTqxvMCG','w2vTChr5lxn0CG','C3rLzxjdAgfUBG','BwnWx19HBhzPBG','ifn0CMvHBs4G','ls12zxjZAw9U','A2v5CW','Bg9Nz2vKsw4','zwzMB3j0','C2vZC2LVBKLK','y2XHDwrLlxnKAW','v2vIrMv0y2G','AxnJAcbUzxuG4Ocu','odfeDufSsLy','Dg9VBf91C2vFAq','BwfSlG','A2DYB3vUza','AguGCgXHBIbVCG','igLZig5VDcbSBW','q2XHDwrLifnesW','kcGOlISPkYKRkq','zxr1CM5LzcaWia','ywXPC2f0Aw9Uia','ouX4CgTzBq','yxnZAxn0yw50','D2fYBG','zMfPBgvKoIa','BwfW','BNr3B3j0zxrLia','x3rVA2vUCW','ywjVCNrLza','BIbVzgvYifrVAW','DwzLihvUzca','ie5Hy2HYAwnODa','AgLZDg9YEq','DxnLCG','mJK1oduZnMPxDfrWqW','C3nPB24GBMfJAa','x2LUChv0x3rVAW','mty1otrpBLbtuem','BMfTzq','Dgv4Da','CgLUzW','4PQG77IpienSyxvKzsbH','igvYCM9YoIa','BwvZC2fNzunVDq','CMv0DxjU','igrPzsbtzxnZAq','BM93','B24Gyxv0B21HDa','ls1VDxrWDxqTzG','BMzYywDLigjLyq','igXVz2LUycbVBG','v3jPDgu','B3jTyxq','uMvHza','x3vZza','ywrKrxzLBNrmAq','DhjPBq','BgvUz3rO','DgnOq29UDgv4Da','ChjVBxb0','C3vIDhLWzq','B3j0zwq','ywjVCNrtAwDUyq','zg9JCY8','qvzbsuXbqKLmsq','rv9ftLrswvbpsq','cGPuB3aGDxaGDa','zgXL','yxzHAwXHyMLSAq','CNvUx2LUx2jHyW','ihrOAxmGBwfJAa','mJq2odqXn3byC1jxza','DhLdywnOzq','ywX2Aw5eAxnWyq','ywX2Aw4','ywjVCNq','zhvYyxrPB25FBq','C3vJy2vZCW','C3rLBMvY','x2fNzw50','B25rDwvYEuHHBG','Dg9VBfvZzunVDq','CY9Tzw1VCNKVwq','vfLFq0fdsevFtq','Dg9mB3DLCKnHCW','AgfPA3u','ywXSB3DLzfrVBW','mJC1mdy3mND1q290rq','zhuGzgLLC2uGqq','x3nLC3nPB25tDa','z2v0sw5MBW','m1ngwvvVra','B3v0Chv0ihrVAW','x19KAxnWyxrJAa','rgf0zwKGkgrVyW','y29UC3rYDwn0BW','Dg9VBf91C2u','DgvZDa','ihDHAxqGzM9Yia','CMjLAxrLC3qUcG','qMfZAa','Aw5OzxjPDa','mteXnteWq0PurvDd','Aw5WDxq','zw4TuMvMCMvZAa','zhvYyxrPB25Fyq','CgLFBxm','vgfZAW','CMvWBgfJzufSBa','zxiGu2vZC2LVBG','C2vHCMnO','vf0GrhuGAgfZDa','4PQG77Ipia','zxjYB3i','zwfTxsbtreSGCG','AwnRigrPzsboyq','zw52','y2HYAwnODcbLAq','zg9Uzq','q0Xbvurfx0npra','Dw4GygnSyxvKzq','zxHWAxjLC0f0','DhLWzq','Dg9tDhjPBMC','ChvZAa','Aw5LlG','AxnbCNjHEq','v2vIu2vHCMnO','C3LZDgvT','rwrPDa','zw5ZiokaLcbKAwfN','y3DK','zsbLAw5LCIbZDa','B3v0Chv0x3rVAW','qxzHAwXHyMLSAq','BNvTyMvY','C2vZC2LVBL9Pza','l2rVy3mV','B2jQzwn0','mtq5mdm1Ce95z3bx','DgvTCgvYyxr1CG','Bw9KzwW','Dg9VBf9Yzxn1Ba','y29UDgvUDa','DgHLihjLC2v0lG','BwqPigjLDM9Yia','y2fJAgvFy3jLyq','y29UzMLN','q0Xbvurfq09erq','C2XPy2u','CMvZDwX0','lIbty2HYzwLIzq','AxnbDMfPBgfIBa','BwvZC2fNzq','ywXLifnesY1tzq','C3rHDhvZ','AxnFzxjYB3i','q0XjigrLzMf1Ba','ntqYmdqXofjsrwz1DW','DcaOBgf0zxn0kq','w0nirunlue9jtG','C3rYAw5N','C3rYAw5NAwz5','AM9PBG','BM9ZDgLJigr1Bq','BNvTx3r1CM5Z','zw5Z','BMzHy2GGBM9JAa','Aw52ywXPzgf0zq','DgLVBL9PBNb1Da','yxv0Aa'];_0x4d4e=function(){return _0x19d095;};return _0x4d4e();}import{fileURLToPath}from'url';import{execFile}from'child_process';import{promisify}from'util';import{findClaudeBinary}from'../find-claude-binary.js';import{buildAlvinMcpServer}from'../services/alvin-mcp-tools.js';import{buildRuntimeHeader}from'./runtime-header.js';const execFileAsync=promisify(execFile);export function isAuthErrorOutput(_0x40b941){const _0x4d6a27=_0x1e8b;if(!_0x40b941)return![];return/^\s*not logged in\b/i[_0x4d6a27(0xee)](_0x40b941);}function _0x1e8b(_0x4b7a8a,_0x156bdb){_0x4b7a8a=_0x4b7a8a-(-0x26f2+0x5de+0xa6*0x34);const _0x14464a=_0x4d4e();let _0x184489=_0x14464a[_0x4b7a8a];if(_0x1e8b['aHghaC']===undefined){var _0x24325d=function(_0x54c861){const _0x104b2a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x39b662='',_0x55b294='',_0x305e93=_0x39b662+_0x24325d;for(let _0x2bbf75=-0x706*0x2+0xc4b+-0x1*-0x1c1,_0x34ae4a,_0x5d2193,_0x486079=-0x1f09+0x194*-0x6+0x2881*0x1;_0x5d2193=_0x54c861['charAt'](_0x486079++);~_0x5d2193&&(_0x34ae4a=_0x2bbf75%(0x1bf*0x16+-0xacc+-0x1b9a*0x1)?_0x34ae4a*(0x1836+0x1*-0x17e1+0x7*-0x3)+_0x5d2193:_0x5d2193,_0x2bbf75++%(0x7c6+-0x92f*0x3+0x13cb))?_0x39b662+=_0x305e93['charCodeAt'](_0x486079+(0x6b2+-0x1d56+0x16ae*0x1))-(-0x10ef+0x20c4+-0xfcb)!==0xd*-0x4d+0x1d*-0xdf+-0x1d2c*-0x1?String['fromCharCode'](-0x2406+0x1*-0x101e+0x3523&_0x34ae4a>>(-(0x22c3*0x1+0xdd*-0x13+0x51*-0x3a)*_0x2bbf75&0xe56+-0x75d*-0x1+0x1f*-0xb3)):_0x2bbf75:0x2606+-0xe*0x29+0x4*-0x8f2){_0x5d2193=_0x104b2a['indexOf'](_0x5d2193);}for(let _0x14447a=-0x2363+0x1395+0xfce,_0x5b14da=_0x39b662['length'];_0x14447a<_0x5b14da;_0x14447a++){_0x55b294+='%'+('00'+_0x39b662['charCodeAt'](_0x14447a)['toString'](-0x210e+0xd06+-0x1*-0x1418))['slice'](-(-0x67*-0x50+-0x626*-0x2+-0x163d*0x2));}return decodeURIComponent(_0x55b294);};_0x1e8b['hmAOsY']=_0x24325d,_0x1e8b['qNnGuk']={},_0x1e8b['aHghaC']=!![];}const _0x30adc6=_0x14464a[0x13a5+-0x43*-0x26+-0x3*0x9dd],_0x369580=_0x4b7a8a+_0x30adc6,_0x1635cb=_0x1e8b['qNnGuk'][_0x369580];if(!_0x1635cb){const _0x3a8aa2=function(_0x53e9df){this['lJBBVf']=_0x53e9df,this['DYDpex']=[0x4c9+-0x831+0x369,0x22c9+-0x1*-0x2653+-0x491c,0x17c7+0x80d+-0x3*0xa9c],this['uZltxK']=function(){return'newState';},this['vrAkJL']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['DBCyiC']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x3a8aa2['prototype']['MtgOsl']=function(){const _0x4d5f2e=new RegExp(this['vrAkJL']+this['DBCyiC']),_0x3ae279=_0x4d5f2e['test'](this['uZltxK']['toString']())?--this['DYDpex'][-0x61+0x658+-0x5f6*0x1]:--this['DYDpex'][0x146b+0x719+-0x4*0x6e1];return this['inlTkd'](_0x3ae279);},_0x3a8aa2['prototype']['inlTkd']=function(_0x2b3bbc){if(!Boolean(~_0x2b3bbc))return _0x2b3bbc;return this['yMLfgC'](this['lJBBVf']);},_0x3a8aa2['prototype']['yMLfgC']=function(_0x2c731a){for(let _0x2afee6=-0xa38*0x2+0x4*0x83+0x1264,_0x432d2b=this['DYDpex']['length'];_0x2afee6<_0x432d2b;_0x2afee6++){this['DYDpex']['push'](Math['round'](Math['random']())),_0x432d2b=this['DYDpex']['length'];}return _0x2c731a(this['DYDpex'][0x5*0x494+-0xc85*0x2+0x226]);},new _0x3a8aa2(_0x1e8b)['MtgOsl'](),_0x184489=_0x1e8b['hmAOsY'](_0x184489),_0x1e8b['qNnGuk'][_0x369580]=_0x184489;}else _0x184489=_0x1635cb;return _0x184489;}export function isQuotaLimitOutput(_0x10b92d){const _0x3c1ce7=_0x1e8b,_0x427738=_0x1e8b;if(!_0x10b92d)return![];const _0x4ba0a1=_0x10b92d[_0x3c1ce7(0xc5)]();if(_0x4ba0a1[_0x3c1ce7(0xc6)]===-0x1f09+0x194*-0x6+0x2881*0x1)return![];return/you['’]re out of extra usage/i['test'](_0x4ba0a1)||/reached (your |the )?(weekly |monthly |daily )?(usage|rate) limit/i['test'](_0x4ba0a1)||/rate[- ]?limit(ed)? (exceeded|reached)/i[_0x3c1ce7(0xee)](_0x4ba0a1)||/quota exceeded/i[_0x3c1ce7(0xee)](_0x4ba0a1)||/usage limit reached/i[_0x3c1ce7(0xee)](_0x4ba0a1)||/limit (reached|hit) for (this|your) (week|month|day)/i['test'](_0x4ba0a1)||/resets? \d{1,2}(am|pm|:)/i[_0x427738(0xee)](_0x4ba0a1)&&/usage|limit/i[_0x3c1ce7(0xee)](_0x4ba0a1);}const BOT_PROJECT_ROOT=resolve(dirname(fileURLToPath(import.meta.url)),'../..');let botClaudeMd='';try{botClaudeMd=readFileSync(resolve(BOT_PROJECT_ROOT,'CLAUDE.md'),_0x4e769c(0x13b)),botClaudeMd=botClaudeMd[_0x5c88d4(0xf9)](_0x4e769c(0xcc),BOT_PROJECT_ROOT+_0x5c88d4(0x116));}catch{}const CHECKPOINT_TOOL_THRESHOLD=0x1bf*0x16+-0xacc+-0x1b8f*0x1,CHECKPOINT_MSG_THRESHOLD=0x1836+0x1*-0x17e1+0x19*-0x3;export class ClaudeSDKProvider{[_0x4e769c(0x120)];[_0x5c88d4(0xd1)+'tyCache']=null;static [_0x4e769c(0xcd)+_0x5c88d4(0xe0)+'S']=0x5d4d+-0x1e0e*0xb+0x1d7ad;constructor(_0x112148){const _0x54ef7f=_0x4e769c;this['config']={'type':_0x54ef7f(0x149),'name':'Claude\x20(Ag'+'ent\x20SDK)','model':'inherit','supportsTools':!![],'supportsVision':!![],'supportsStreaming':!![],..._0x112148};}async*['query'](_0x57a729){const _0x3bcdbc=_0x4e769c,_0x23df5c=_0x5c88d4,_0x3e5ab0={...process[_0x3bcdbc(0x101)]};delete _0x3e5ab0[_0x23df5c(0x121)],delete _0x3e5ab0[_0x3bcdbc(0x104)+_0x23df5c(0xce)+'NT'];let _0x5c0c09=_0x57a729[_0x3bcdbc(0xc8)];const _0xabde41=_0x57a729[_0x3bcdbc(0xe6)+'ate'];if(_0xabde41){const _0x14464a=0x6b2+-0x1d56+0x16a9*0x1,_0x184489=_0xabde41[_0x3bcdbc(0xde)+'nt']>=CHECKPOINT_TOOL_THRESHOLD||_0xabde41[_0x23df5c(0xb8)+'nt']>=CHECKPOINT_MSG_THRESHOLD,_0x24325d=_0xabde41[_0x23df5c(0xb8)+'nt']%_0x14464a===-0x10ef+0x20c4+-0xfd5;_0x184489&&_0x24325d&&(_0x5c0c09=_0x23df5c(0x12d)+_0x23df5c(0xfc)+'\x20bereits\x20'+_0xabde41[_0x3bcdbc(0xde)+'nt']+(_0x3bcdbc(0x13f)+_0x3bcdbc(0xab))+_0xabde41[_0x3bcdbc(0xb8)+'nt']+(_0x23df5c(0xac)+'en\x20in\x20dies'+_0x23df5c(0xfa)+_0x3bcdbc(0x124)+'\x20jetzt\x20ein'+'en\x20Checkpo'+'int\x20in\x20dei'+'ne\x20Memory-'+_0x3bcdbc(0xeb)+_0x3bcdbc(0xdf)+'YYY-MM-DD.'+_0x3bcdbc(0x11e)+_0x3bcdbc(0xe5)+_0x3bcdbc(0xbe)+_0x3bcdbc(0xf0)+'\x0a')+_0x5c0c09);}const _0x1f64e5=buildRuntimeHeader(),_0x4b7a8a=_0x57a729['systemProm'+'pt']?_0x1f64e5+'\x0a\x0a'+_0x57a729['systemProm'+'pt']+'\x0a\x0a'+botClaudeMd:_0x1f64e5+'\x0a\x0a'+botClaudeMd;let _0x156bdb;_0x57a729[_0x23df5c(0xcb)+'l']&&(_0x156bdb=new AbortController(),_0x57a729[_0x3bcdbc(0xcb)+'l'][_0x3bcdbc(0xa9)]?_0x156bdb[_0x3bcdbc(0xd8)]():_0x57a729[_0x23df5c(0xcb)+'l'][_0x23df5c(0xc4)+_0x3bcdbc(0xdb)](_0x3bcdbc(0xd8),()=>_0x156bdb?.[_0x23df5c(0xd8)](),{'once':!![]}));try{const _0x30adc6=findClaudeBinary(),_0x369580={};_0x57a729[_0x3bcdbc(0xd6)+_0x3bcdbc(0xc7)]&&(_0x369580[_0x3bcdbc(0xd7)]=buildAlvinMcpServer(_0x57a729['alvinDispa'+'tchContext']));const _0x1635cb=[_0x23df5c(0xc2),_0x23df5c(0xc0),_0x23df5c(0x10e),_0x23df5c(0xf1),'Glob','Grep',_0x23df5c(0x10c),_0x23df5c(0x14a),_0x3bcdbc(0xf8)];_0x57a729[_0x3bcdbc(0xd6)+_0x3bcdbc(0xc7)]&&_0x1635cb[_0x23df5c(0x109)](_0x23df5c(0x142)+_0x3bcdbc(0xea)+_0x3bcdbc(0xdc));const _0x54c861=_0x57a729[_0x3bcdbc(0x11a)]??this['config'][_0x23df5c(0x11a)],_0x104b2a=_0x54c861&&_0x54c861!==_0x3bcdbc(0xf2)?_0x54c861:undefined,_0x39b662=(_0x104b2a??'')[_0x3bcdbc(0xe1)+'e']()['includes'](_0x23df5c(0xe2)),_0x55b294=_0x39b662?undefined:_0x3bcdbc(0xe2),_0x305e93=query({'prompt':_0x57a729[_0x3bcdbc(0x141)+'el']?_0x57a729[_0x3bcdbc(0x141)+'el']:_0x5c0c09,'options':{'cwd':_0x57a729[_0x23df5c(0x13a)]||process[_0x3bcdbc(0x110)](),'abortController':_0x156bdb,'resume':_0x57a729['sessionId']??undefined,'pathToClaudeCodeExecutable':_0x30adc6,'permissionMode':'bypassPerm'+'issions','allowDangerouslySkipPermissions':!![],'env':_0x3e5ab0,'settingSources':[_0x3bcdbc(0xae),'project'],'allowedTools':_0x57a729[_0x3bcdbc(0xe3)+'ls']??_0x1635cb,'mcpServers':Object[_0x23df5c(0x145)](_0x369580)[_0x3bcdbc(0xc6)]>0xd*-0x4d+0x1d*-0xdf+-0x1d2c*-0x1?_0x369580:undefined,'systemPrompt':_0x4b7a8a,'effort':_0x57a729[_0x3bcdbc(0x147)]||'medium','maxTurns':0x32,'betas':['context-1m'+'-2025-08-0'+'7'],..._0x104b2a?{'model':_0x104b2a}:{},...typeof _0x57a729['temperatur'+'e']===_0x23df5c(0x114)?{'temperature':_0x57a729[_0x3bcdbc(0x119)+'e']}:{},..._0x55b294?{'fallbackModel':_0x55b294}:{}}});try{_0x57a729[_0x3bcdbc(0xdd)+_0x3bcdbc(0xd0)]?.(_0x305e93);}catch{}let _0x2bbf75='',_0x34ae4a=_0x57a729[_0x3bcdbc(0x148)]||'',_0x5d2193=-0x2406+0x1*-0x101e+0x3424;for await(const _0x486079 of _0x305e93){if(_0x57a729[_0x23df5c(0xcb)+'l']?.[_0x23df5c(0xa9)]){try{_0x305e93[_0x23df5c(0xb9)]?.();}catch{}break;}if(_0x486079[_0x23df5c(0x107)]===_0x3bcdbc(0x10d)&&_0x3bcdbc(0xc9)in _0x486079&&_0x486079['subtype']==='init'){const _0x14447a=_0x486079;_0x34ae4a=_0x14447a[_0x23df5c(0x115)];}if(_0x486079[_0x3bcdbc(0x107)]===_0x23df5c(0x157)){const _0x5b14da=_0x486079;_0x34ae4a=_0x5b14da['session_id'];if(_0x5b14da['message']?.[_0x3bcdbc(0x11c)])for(const _0x3a8aa2 of _0x5b14da[_0x3bcdbc(0x126)]['content']){if(_0x23df5c(0xb4)in _0x3a8aa2&&_0x3a8aa2[_0x3bcdbc(0xb4)]){if(!_0x2bbf75&&isAuthErrorOutput(_0x3a8aa2[_0x23df5c(0xb4)])){yield{'type':'error','error':'Claude\x20CLI'+_0x3bcdbc(0x151)+'gged\x20in.\x20R'+_0x23df5c(0x105)+_0x23df5c(0xbf)+_0x3bcdbc(0xd3)+_0x3bcdbc(0x10a)};return;}if(!_0x2bbf75&&isQuotaLimitOutput(_0x3a8aa2['text'])){const _0x53e9df=_0x3bcdbc(0xfd)+_0x3a8aa2[_0x23df5c(0xb4)][_0x23df5c(0xc5)]()+(_0x23df5c(0xcf)+_0x23df5c(0x150)+_0x3bcdbc(0xef)+_0x23df5c(0x11d)+'\x20No\x20messag'+'e\x20was\x20sent'+'\x20to\x20Claude'+'.');this['invalidate'+_0x23df5c(0x113)+_0x3bcdbc(0xd5)](),yield{'type':_0x3bcdbc(0xb4),'text':_0x53e9df,'delta':_0x53e9df,'sessionId':_0x34ae4a},_0x2bbf75=_0x53e9df;continue;}_0x2bbf75+=_0x3a8aa2[_0x23df5c(0xb4)],yield{'type':_0x3bcdbc(0xb4),'text':_0x2bbf75,'delta':_0x3a8aa2[_0x3bcdbc(0xb4)],'sessionId':_0x34ae4a};}if(_0x23df5c(0xb3)in _0x3a8aa2){_0x5d2193++;let _0x4d5f2e;if(_0x3bcdbc(0xf4)in _0x3a8aa2&&_0x3a8aa2[_0x23df5c(0xf4)]&&typeof _0x3a8aa2[_0x23df5c(0xf4)]==='object'){const _0x2c731a=_0x3a8aa2['input'];if(_0x2c731a['run_in_bac'+_0x3bcdbc(0x14f)]===!![])_0x4d5f2e=!![];else{if(_0x2c731a[_0x23df5c(0xd2)+_0x3bcdbc(0x14f)]===![])_0x4d5f2e=![];}}let _0x3ae279;if(_0x23df5c(0xf4)in _0x3a8aa2&&_0x3a8aa2[_0x3bcdbc(0xf4)]!==undefined)try{const _0x2afee6=JSON[_0x3bcdbc(0x12f)](_0x3a8aa2['input']);_0x3ae279=_0x2afee6[_0x23df5c(0xc6)]>0x22c3*0x1+0xdd*-0x13+0x4b*-0x38?_0x2afee6[_0x3bcdbc(0x122)](0xe56+-0x75d*-0x1+0xb*-0x1f9,0x2606+-0xe*0x29+0x2*-0x10ea)+'…':_0x2afee6;}catch{}const _0x2b3bbc=_0x3a8aa2['id'];yield{'type':_0x23df5c(0xed),'toolName':_0x3a8aa2[_0x3bcdbc(0xb3)],'toolInput':_0x3ae279,'toolUseId':_0x2b3bbc,'runInBackground':_0x4d5f2e,'sessionId':_0x34ae4a};}}}if(_0x486079[_0x3bcdbc(0x107)]===_0x23df5c(0xae)){const _0x432d2b=_0x486079,_0x568903=_0x432d2b['message']?.[_0x3bcdbc(0x11c)];if(Array[_0x23df5c(0x10b)](_0x568903))for(const _0x59ed75 of _0x568903){if(_0x59ed75&&typeof _0x59ed75===_0x3bcdbc(0x117)&&_0x59ed75[_0x3bcdbc(0x107)]===_0x23df5c(0x11b)+'t'&&typeof _0x59ed75['tool_use_i'+'d']===_0x23df5c(0x12e)){let _0x230176='';if(typeof _0x59ed75[_0x3bcdbc(0x11c)]==='string')_0x230176=_0x59ed75[_0x3bcdbc(0x11c)];else Array[_0x23df5c(0x10b)](_0x59ed75[_0x3bcdbc(0x11c)])&&(_0x230176=_0x59ed75[_0x23df5c(0x11c)][_0x3bcdbc(0xa6)](_0x5be94f=>{const _0x2c2642=_0x23df5c,_0x417f87=_0x23df5c;if(_0x5be94f&&typeof _0x5be94f===_0x2c2642(0x117)&&_0x2c2642(0xb4)in _0x5be94f){const _0x5bc1da=_0x5be94f[_0x2c2642(0xb4)];return typeof _0x5bc1da===_0x417f87(0x12e)?_0x5bc1da:'';}return'';})[_0x3bcdbc(0x130)](''));yield{'type':'tool_resul'+'t','toolUseId':_0x59ed75[_0x3bcdbc(0x14d)+'d'],'toolResultContent':_0x230176,'sessionId':_0x34ae4a};}}}if(_0x486079['type']===_0x23df5c(0x123)){const _0x16c7ff=_0x486079,_0xa2f8a7=_0x23df5c(0x13e)in _0x16c7ff?_0x16c7ff[_0x3bcdbc(0x13e)]:null,_0x1e8d78=_0xa2f8a7?(_0xa2f8a7['input_toke'+'ns']||-0x2363+0x1395+0xfce)+(_0xa2f8a7[_0x3bcdbc(0x11f)+_0x3bcdbc(0x136)+_0x23df5c(0xa8)]||-0x210e+0xd06+-0x1*-0x1408)+(_0xa2f8a7['cache_read'+_0x23df5c(0xb1)+_0x23df5c(0x133)]||-0x67*-0x50+-0x626*-0x2+-0x92*0x4e):0x13a5+-0x43*-0x26+-0x3*0x9dd,_0x54289e=_0xa2f8a7?.[_0x23df5c(0x112)+_0x3bcdbc(0x133)]||0x4c9+-0x831+0x368;if(_0x2bbf75===''&&_0x54289e===0x22c9+-0x1*-0x2653+-0x491c){this['invalidate'+'Availabili'+_0x23df5c(0xd5)]();try{const _0x4823ac={'subtype':_0x16c7ff[_0x3bcdbc(0xc9)],'is_error':_0x16c7ff[_0x3bcdbc(0x129)],'num_turns':_0x16c7ff[_0x3bcdbc(0x132)],'duration_ms':_0x16c7ff[_0x23df5c(0xd9)+'s'],'duration_api_ms':_0x16c7ff[_0x3bcdbc(0xf6)+_0x23df5c(0xf7)],'total_cost_usd':_0x16c7ff[_0x3bcdbc(0x13c)+'_usd'],'session_id':_0x16c7ff[_0x3bcdbc(0x115)],'passed_session_id':_0x57a729[_0x23df5c(0x148)]??null,'usage':_0xa2f8a7,'modelOverride':_0x104b2a,'cwd':_0x57a729['workingDir'],'effort':_0x57a729[_0x23df5c(0x147)],'systemPromptLen':_0x4b7a8a[_0x3bcdbc(0xc6)],'promptLen':_0x5c0c09[_0x3bcdbc(0xc6)],'historyLen':_0x57a729[_0x3bcdbc(0xad)]?.['length']??0x17c7+0x80d+-0x3*0xa9c,'allowedToolsCount':(_0x57a729[_0x3bcdbc(0xe3)+'ls']??_0x1635cb)[_0x3bcdbc(0xc6)],'hasMcp':Object[_0x3bcdbc(0x145)](_0x369580)['length']>-0x61+0x658+-0x5f7*0x1};console['warn']('[empty-str'+_0x3bcdbc(0xff)+_0x23df5c(0x154)+'output\x20tok'+_0x23df5c(0x10f)+_0x23df5c(0x131)+'p:',JSON['stringify'](_0x4823ac));}catch(_0x39a570){console[_0x23df5c(0xa4)](_0x3bcdbc(0x140)+'eam]\x20SDK\x20r'+_0x3bcdbc(0x154)+_0x23df5c(0xe9)+'ens\x20(diagn'+_0x23df5c(0x138)+_0x3bcdbc(0x155)+_0x23df5c(0xa5)+_0x39a570+')');}const _0x303985=_0x23df5c(0xb6)+_0x3bcdbc(0xa7)+'mit\x20leerem'+_0x3bcdbc(0x143)+('Meist\x20Folg'+_0x23df5c(0x111)+_0x23df5c(0x127)+_0x3bcdbc(0xb0)+'\x20/extra-us'+_0x23df5c(0x13d)+_0x23df5c(0xaa)+_0x3bcdbc(0xf5)+'.\x20')+('Ich\x20starte'+_0x3bcdbc(0xba)+_0x23df5c(0xbc)+_0x23df5c(0x14b)+_0x3bcdbc(0x139)+_0x3bcdbc(0x100)+_0x23df5c(0x102)+_0x23df5c(0x134)+_0x23df5c(0x14e));yield{'type':_0x3bcdbc(0xb4),'text':_0x303985,'delta':_0x303985,'sessionId':_0x16c7ff[_0x23df5c(0x115)]||_0x34ae4a,'sessionResetRequested':!![]};}const _0x56cbc0='subtype'in _0x16c7ff&&_0x16c7ff[_0x23df5c(0xc9)]===_0x23df5c(0xda)&&typeof _0x16c7ff[_0x3bcdbc(0x123)]===_0x3bcdbc(0x12e)?_0x16c7ff['result']:undefined;yield{'type':_0x23df5c(0x103),'text':_0x2bbf75||'',..._0x56cbc0!==undefined?{'finalResult':_0x56cbc0}:{},'sessionId':_0x16c7ff[_0x23df5c(0x115)]||_0x34ae4a,'costUsd':'total_cost'+_0x3bcdbc(0xc3)in _0x16c7ff?_0x16c7ff[_0x23df5c(0x13c)+_0x3bcdbc(0xc3)]:0x146b+0x719+-0x4*0x6e1,'inputTokens':_0x1e8d78,'outputTokens':_0x54289e};}}}catch(_0x1bc051){_0x1bc051 instanceof Error&&_0x1bc051[_0x3bcdbc(0x126)]['includes']('abort')?yield{'type':_0x23df5c(0xfe),'error':'Request\x20ab'+_0x3bcdbc(0xca)}:yield{'type':_0x23df5c(0xfe),'error':_0x3bcdbc(0x152)+_0x3bcdbc(0xb7)+(_0x1bc051 instanceof Error?_0x1bc051[_0x23df5c(0x126)]:String(_0x1bc051))};}}async[_0x4e769c(0x125)+'e'](){const _0x1f491d=_0x5c88d4,_0x14c4fb=_0x5c88d4,_0x5e615e=Date[_0x1f491d(0xbb)]();if(this[_0x1f491d(0xd1)+_0x1f491d(0xd5)]&&this[_0x1f491d(0xd1)+_0x14c4fb(0xd5)][_0x1f491d(0x106)]>_0x5e615e)return this[_0x1f491d(0xd1)+'tyCache']['result'];const _0x1f05d2=_0x2d0cc0=>{const _0x356ee1=_0x14c4fb,_0x59613f=_0x1f491d;return this[_0x356ee1(0xd1)+'tyCache']={'result':_0x2d0cc0,'expiresAt':_0x5e615e+ClaudeSDKProvider[_0x59613f(0xcd)+_0x356ee1(0xe0)+'S']},_0x2d0cc0;};try{const _0x131854=findClaudeBinary();if(!_0x131854)return _0x1f05d2(![]);await execFileAsync(_0x131854,[_0x1f491d(0x144)],{'timeout':0x1388});try{const {stdout:_0x2facff}=await execFileAsync(_0x131854,[_0x14c4fb(0x137),_0x1f491d(0x128)],{'timeout':0x1388}),_0x291927=JSON['parse'](_0x2facff);if(_0x291927[_0x14c4fb(0x146)]===!![])return _0x1f05d2(!![]);return _0x1f05d2(![]);}catch(_0x1a1451){try{const {stdout:_0x4661fb}=await execFileAsync(_0x131854,['-p',_0x1f491d(0xb5),_0x14c4fb(0xbd)+_0x1f491d(0xc1),_0x14c4fb(0xb4)],{'timeout':0x3a98});return _0x1f05d2(!isAuthErrorOutput(_0x4661fb)&&!isQuotaLimitOutput(_0x4661fb));}catch{return void _0x1a1451,_0x1f05d2(![]);}}}catch{return _0x1f05d2(![]);}}[_0x4e769c(0x135)+'Availabili'+_0x5c88d4(0xd5)](){const _0x5ac024=_0x5c88d4,_0x3ac25b=_0x5c88d4;this[_0x5ac024(0xd1)+_0x5ac024(0xd5)]=null;}[_0x4e769c(0xe7)](){const _0x15a9a0=_0x4e769c,_0x5e85b9=_0x4e769c,_0x54dc9e=this['config']['model']===_0x15a9a0(0xf2)?_0x15a9a0(0x12a)+_0x15a9a0(0x12c):this[_0x5e85b9(0x120)]['model'];return{'name':this[_0x5e85b9(0x120)][_0x15a9a0(0xb3)],'model':_0x54dc9e,'status':'✅\x20Agent\x20SD'+'K\x20(CLI\x20aut'+'h)'};}}
|