alvin-bot 5.7.0 → 5.8.1
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 +25 -0
- package/README.md +25 -31
- 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 -174
- 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 -583
- 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 -86
- 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 -1902
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,418 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure helpers for the async-agent watcher (Fix #17 Stage 2).
|
|
3
|
-
*
|
|
4
|
-
* Two responsibilities, both pure (the file read in parseOutputFileStatus
|
|
5
|
-
* is pure-by-input — same path returns the same shape at that moment in
|
|
6
|
-
* time, no mutation, no side effects):
|
|
7
|
-
*
|
|
8
|
-
* 1. Parse the SDK's plain-text "Async agent launched successfully" tool
|
|
9
|
-
* result into a structured AsyncLaunchedInfo.
|
|
10
|
-
* 2. Read the tail of an outputFile JSONL stream and decide whether the
|
|
11
|
-
* sub-agent is still running, completed, or failed.
|
|
12
|
-
*
|
|
13
|
-
* Format details captured live from @anthropic-ai/claude-agent-sdk@0.2.97
|
|
14
|
-
* on 2026-04-13. See docs/superpowers/specs/sdk-async-agent-outputfile-format.md
|
|
15
|
-
* for the full investigation notes — the SDK's .d.ts shape DOES NOT match
|
|
16
|
-
* what the runtime actually emits, which is why the contract is pinned by
|
|
17
|
-
* tests against real fixtures.
|
|
18
|
-
*/
|
|
19
|
-
import { promises as fs } from "fs";
|
|
20
|
-
// ── Tool-result text parser ──────────────────────────────────────────
|
|
21
|
-
/**
|
|
22
|
-
* Parse the plain-text SDK tool-result content for an `Agent` call with
|
|
23
|
-
* `run_in_background: true`. The format is documented in the spec doc
|
|
24
|
-
* — it's NOT JSON, and the field is `output_file` (snake_case).
|
|
25
|
-
*
|
|
26
|
-
* Accepts:
|
|
27
|
-
* - the raw text string
|
|
28
|
-
* - an Anthropic SDK content array `[{type: "text", text: "..."}]`
|
|
29
|
-
* - null/undefined/non-string → returns null
|
|
30
|
-
*/
|
|
31
|
-
export function parseAsyncLaunchedToolResult(raw) {
|
|
32
|
-
// Normalize to a string
|
|
33
|
-
let text;
|
|
34
|
-
if (raw == null)
|
|
35
|
-
return null;
|
|
36
|
-
if (typeof raw === "string") {
|
|
37
|
-
text = raw;
|
|
38
|
-
}
|
|
39
|
-
else if (Array.isArray(raw)) {
|
|
40
|
-
// SDK content blocks shape
|
|
41
|
-
text = raw
|
|
42
|
-
.map((b) => (b && typeof b === "object" && "text" in b ? String(b.text) : ""))
|
|
43
|
-
.join("");
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
if (!text || text.length === 0)
|
|
49
|
-
return null;
|
|
50
|
-
// Quick gate: avoid expensive matching on non-async tool results
|
|
51
|
-
if (!text.includes("Async agent launched successfully"))
|
|
52
|
-
return null;
|
|
53
|
-
// agentId line: "agentId: <id> (...)" — capture everything up to first space/paren
|
|
54
|
-
const agentMatch = text.match(/agentId:\s*(\S+)/);
|
|
55
|
-
if (!agentMatch)
|
|
56
|
-
return null;
|
|
57
|
-
const agentId = agentMatch[1].trim();
|
|
58
|
-
if (!agentId)
|
|
59
|
-
return null;
|
|
60
|
-
// output_file line: "output_file: <path>" — path may contain spaces, capture
|
|
61
|
-
// until end of line (the path is always on its own line in real output).
|
|
62
|
-
const outFileMatch = text.match(/output_file:\s*(.+?)\s*(?:\n|$)/);
|
|
63
|
-
if (!outFileMatch)
|
|
64
|
-
return null;
|
|
65
|
-
const outputFile = outFileMatch[1].trim();
|
|
66
|
-
if (!outputFile)
|
|
67
|
-
return null;
|
|
68
|
-
return { agentId, outputFile };
|
|
69
|
-
}
|
|
70
|
-
const DEFAULT_TAIL_BYTES = 64 * 1024;
|
|
71
|
-
/**
|
|
72
|
-
* Upper bound for the window-independent final-line read (see
|
|
73
|
-
* readLastCompleteLine). Generous — ~128× the tail window — so any
|
|
74
|
-
* realistic final report is captured, but bounded so a pathological
|
|
75
|
-
* single line can't blow up memory. Beyond this we fall back to the
|
|
76
|
-
* windowed / staleness logic unchanged.
|
|
77
|
-
*/
|
|
78
|
-
const MAX_LAST_LINE_BYTES = 8 * 1024 * 1024;
|
|
79
|
-
/**
|
|
80
|
-
* Read the LAST complete newline-delimited record of the file, regardless
|
|
81
|
-
* of how large it is, by scanning backward from EOF in chunks.
|
|
82
|
-
*
|
|
83
|
-
* Why this exists: for `claude -p --output-format stream-json` the
|
|
84
|
-
* terminating `{"type":"result",...}` event is ALWAYS the final line, but
|
|
85
|
-
* that line embeds the entire final report and is frequently larger than
|
|
86
|
-
* DEFAULT_TAIL_BYTES (e.g. an agent that writes a long status report
|
|
87
|
-
* after an auto-declined AskUserQuestion). The windowed tail read drops
|
|
88
|
-
* such a line as a truncated head fragment, so completion was missed and
|
|
89
|
-
* the agent sat "running" until the 12 h timeout — never auto-delivered.
|
|
90
|
-
* Reading the true final line makes completion detection independent of
|
|
91
|
-
* the tail-window size.
|
|
92
|
-
*
|
|
93
|
-
* Returns the final record WITHOUT its trailing newline, or null if the
|
|
94
|
-
* file is empty, the final line is not newline-terminated (still being
|
|
95
|
-
* written), or the line exceeds MAX_LAST_LINE_BYTES. In every null case
|
|
96
|
-
* the caller falls through to the existing windowed/staleness logic with
|
|
97
|
-
* no behavior change.
|
|
98
|
-
*/
|
|
99
|
-
async function readLastCompleteLine(path, size) {
|
|
100
|
-
if (size <= 0)
|
|
101
|
-
return null;
|
|
102
|
-
let fh;
|
|
103
|
-
try {
|
|
104
|
-
fh = await fs.open(path, "r");
|
|
105
|
-
const chunkSize = 64 * 1024;
|
|
106
|
-
let pos = size;
|
|
107
|
-
let collected = Buffer.alloc(0);
|
|
108
|
-
while (pos > 0) {
|
|
109
|
-
if (size - pos > MAX_LAST_LINE_BYTES)
|
|
110
|
-
return null;
|
|
111
|
-
const readLen = Math.min(chunkSize, pos);
|
|
112
|
-
pos -= readLen;
|
|
113
|
-
const buf = Buffer.alloc(readLen);
|
|
114
|
-
await fh.read(buf, 0, readLen, pos);
|
|
115
|
-
collected = Buffer.concat([buf, collected]);
|
|
116
|
-
// Strip exactly one trailing newline (the file terminator) so we
|
|
117
|
-
// search for the delimiter BEFORE the final record, not after it.
|
|
118
|
-
let end = collected.length;
|
|
119
|
-
if (end > 0 && collected[end - 1] === 0x0a) {
|
|
120
|
-
end--;
|
|
121
|
-
if (end > 0 && collected[end - 1] === 0x0d)
|
|
122
|
-
end--;
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
// No terminating newline → final line still being written.
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
if (end <= 0) {
|
|
129
|
-
// File is just a newline (or empty after trim) — nothing usable.
|
|
130
|
-
if (pos === 0)
|
|
131
|
-
return null;
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
const nl = collected.lastIndexOf(0x0a, end - 1);
|
|
135
|
-
if (nl >= 0) {
|
|
136
|
-
return collected.toString("utf-8", nl + 1, end);
|
|
137
|
-
}
|
|
138
|
-
if (pos === 0) {
|
|
139
|
-
// Whole file is a single (newline-terminated) record.
|
|
140
|
-
return collected.toString("utf-8", 0, end);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
finally {
|
|
149
|
-
try {
|
|
150
|
-
await fh?.close();
|
|
151
|
-
}
|
|
152
|
-
catch {
|
|
153
|
-
/* ignore */
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* v4.12.4 — Default staleness window for partial-output delivery.
|
|
159
|
-
*
|
|
160
|
-
* If an outputFile has not been written to for at least this long AND
|
|
161
|
-
* there is usable assistant text content in it, treat it as "completed
|
|
162
|
-
* with partial output" rather than leaving it to time out at 12h with
|
|
163
|
-
* an empty banner. 5 minutes is a balance between:
|
|
164
|
-
* - Fast enough to unblock interrupted agents (most useful work is
|
|
165
|
-
* done within a few minutes)
|
|
166
|
-
* - Slow enough to avoid false-positives on slow-but-alive agents
|
|
167
|
-
* (typical tool_use gaps are under 30s)
|
|
168
|
-
*
|
|
169
|
-
* Override per call via opts.stalenessMs, or globally via the
|
|
170
|
-
* ALVIN_SUBAGENT_STALENESS_MS env var. `0` disables the fallback
|
|
171
|
-
* entirely (strict end_turn-only completion detection).
|
|
172
|
-
*/
|
|
173
|
-
const DEFAULT_STALENESS_MS = Number(process.env.ALVIN_SUBAGENT_STALENESS_MS) || 5 * 60 * 1000;
|
|
174
|
-
/**
|
|
175
|
-
* Banner prepended to partial-output deliveries so the user knows the
|
|
176
|
-
* sub-agent was interrupted and this isn't a clean completion.
|
|
177
|
-
*/
|
|
178
|
-
const INTERRUPTED_BANNER = "⚠️ _Sub-Agent wurde unterbrochen — hier ist der partielle Output:_\n\n";
|
|
179
|
-
/**
|
|
180
|
-
* Read the tail of an SDK background-agent outputFile and decide what
|
|
181
|
-
* state the sub-agent is in. See spec doc for the JSONL format. We only
|
|
182
|
-
* read the last `maxTailBytes` of the file because long-running agents
|
|
183
|
-
* (SEO audits etc.) can produce hundreds of KB of intermediate JSONL.
|
|
184
|
-
*
|
|
185
|
-
* v4.12.4 adds staleness-based partial-output delivery. When no
|
|
186
|
-
* `end_turn` marker is present, the parser checks file mtime: if the
|
|
187
|
-
* file hasn't grown in `stalenessMs` AND there is text content in the
|
|
188
|
-
* assistant turns, aggregate the text across all turns (not just the
|
|
189
|
-
* last), prepend an "interrupted" banner, and return "completed". This
|
|
190
|
-
* recovers real work from agents killed mid-execution (e.g. by the
|
|
191
|
-
* v4.12.3 bypass abort propagating through the SDK subprocess).
|
|
192
|
-
*/
|
|
193
|
-
export async function parseOutputFileStatus(path, opts = {}) {
|
|
194
|
-
const maxTailBytes = opts.maxTailBytes ?? DEFAULT_TAIL_BYTES;
|
|
195
|
-
const stalenessMs = opts.stalenessMs ?? DEFAULT_STALENESS_MS;
|
|
196
|
-
let stat;
|
|
197
|
-
try {
|
|
198
|
-
stat = await fs.stat(path);
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
return { state: "missing" };
|
|
202
|
-
}
|
|
203
|
-
if (stat.size === 0) {
|
|
204
|
-
// Empty file is functionally the same as missing — we keep polling.
|
|
205
|
-
return { state: "missing" };
|
|
206
|
-
}
|
|
207
|
-
// Tail-read the last maxTailBytes
|
|
208
|
-
let buf;
|
|
209
|
-
let fh;
|
|
210
|
-
try {
|
|
211
|
-
fh = await fs.open(path, "r");
|
|
212
|
-
const readSize = Math.min(stat.size, maxTailBytes);
|
|
213
|
-
buf = Buffer.alloc(readSize);
|
|
214
|
-
await fh.read(buf, 0, readSize, stat.size - readSize);
|
|
215
|
-
}
|
|
216
|
-
catch {
|
|
217
|
-
return { state: "missing" };
|
|
218
|
-
}
|
|
219
|
-
finally {
|
|
220
|
-
try {
|
|
221
|
-
await fh?.close();
|
|
222
|
-
}
|
|
223
|
-
catch { /* ignore */ }
|
|
224
|
-
}
|
|
225
|
-
const text = buf.toString("utf-8");
|
|
226
|
-
// Split into lines. If we tail-read into the middle of a line (size >
|
|
227
|
-
// maxTailBytes), drop the first line because it's almost certainly
|
|
228
|
-
// truncated. The trailing line is dropped if there's no newline — it's
|
|
229
|
-
// the line being written right now.
|
|
230
|
-
const lines = text.split("\n");
|
|
231
|
-
const tailIsMidLine = stat.size > maxTailBytes;
|
|
232
|
-
const headIncomplete = tailIsMidLine ? 1 : 0;
|
|
233
|
-
const trailIncomplete = text.endsWith("\n") ? 0 : 1;
|
|
234
|
-
const usable = lines
|
|
235
|
-
.slice(headIncomplete, lines.length - (trailIncomplete > 0 ? trailIncomplete : 0))
|
|
236
|
-
.filter((l) => l.length > 0);
|
|
237
|
-
// Window-independent completion check (regression fix). The terminating
|
|
238
|
-
// `{"type":"result",...}` event for `claude -p --output-format
|
|
239
|
-
// stream-json` is ALWAYS the final line, but it embeds the whole final
|
|
240
|
-
// report and is routinely larger than maxTailBytes — the windowed tail
|
|
241
|
-
// below would drop it as a truncated head fragment, leaving the agent
|
|
242
|
-
// mis-classified "running" until the 12 h timeout (so a completed
|
|
243
|
-
// sub-agent is never auto-delivered and the user must ask "status?").
|
|
244
|
-
// Inspect the TRUE final complete line directly so detection no longer
|
|
245
|
-
// depends on the tail-window size. Falls through unchanged when the
|
|
246
|
-
// last line is not a result event (running / killed mid-write / etc.).
|
|
247
|
-
const finalLine = await readLastCompleteLine(path, stat.size);
|
|
248
|
-
if (finalLine) {
|
|
249
|
-
let parsedFinal = null;
|
|
250
|
-
try {
|
|
251
|
-
parsedFinal = JSON.parse(finalLine);
|
|
252
|
-
}
|
|
253
|
-
catch {
|
|
254
|
-
parsedFinal = null;
|
|
255
|
-
}
|
|
256
|
-
if (parsedFinal && parsedFinal.type === "result") {
|
|
257
|
-
let output = typeof parsedFinal.result === "string" ? parsedFinal.result : "";
|
|
258
|
-
if (!output) {
|
|
259
|
-
// Same aggregation fallback as the windowed FIRST PASS: when the
|
|
260
|
-
// result event carries no `result` text, stitch together the
|
|
261
|
-
// assistant text blocks visible in the tail.
|
|
262
|
-
const fragments = [];
|
|
263
|
-
for (const line of usable) {
|
|
264
|
-
let p;
|
|
265
|
-
try {
|
|
266
|
-
p = JSON.parse(line);
|
|
267
|
-
}
|
|
268
|
-
catch {
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
if (p.type === "assistant" && Array.isArray(p.message?.content)) {
|
|
272
|
-
for (const c of p.message.content) {
|
|
273
|
-
if (c?.type === "text" && typeof c.text === "string") {
|
|
274
|
-
fragments.push(c.text);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
output = fragments.join("\n\n").trim();
|
|
280
|
-
}
|
|
281
|
-
const usage = parsedFinal.usage;
|
|
282
|
-
const tokensUsed = usage
|
|
283
|
-
? {
|
|
284
|
-
input: usage.input_tokens ?? 0,
|
|
285
|
-
output: usage.output_tokens ?? 0,
|
|
286
|
-
}
|
|
287
|
-
: undefined;
|
|
288
|
-
return { state: "completed", output, tokensUsed };
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
// v4.13 — FIRST PASS: look for a `{"type":"result"}` event anywhere in
|
|
292
|
-
// the tail. This is the completion signal for `claude -p
|
|
293
|
-
// --output-format stream-json` output (used by the v4.13 dispatch
|
|
294
|
-
// mechanism). When present, the `result` field holds the authoritative
|
|
295
|
-
// final text. If `result.result` is missing, aggregate from all
|
|
296
|
-
// assistant text blocks in the tail. (Retained as a defensive fallback
|
|
297
|
-
// for the rare case the result event is NOT the final line.)
|
|
298
|
-
for (let i = usable.length - 1; i >= 0; i--) {
|
|
299
|
-
let parsed;
|
|
300
|
-
try {
|
|
301
|
-
parsed = JSON.parse(usable[i]);
|
|
302
|
-
}
|
|
303
|
-
catch {
|
|
304
|
-
continue;
|
|
305
|
-
}
|
|
306
|
-
if (parsed.type === "result") {
|
|
307
|
-
// Prefer the authoritative `result` field when present.
|
|
308
|
-
let output = typeof parsed.result === "string" ? parsed.result : "";
|
|
309
|
-
// Fallback: aggregate text from all assistant messages in the tail.
|
|
310
|
-
if (!output) {
|
|
311
|
-
const fragments = [];
|
|
312
|
-
for (const line of usable) {
|
|
313
|
-
let p;
|
|
314
|
-
try {
|
|
315
|
-
p = JSON.parse(line);
|
|
316
|
-
}
|
|
317
|
-
catch {
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
if (p.type === "assistant" &&
|
|
321
|
-
Array.isArray(p.message?.content)) {
|
|
322
|
-
for (const c of p.message.content) {
|
|
323
|
-
if (c?.type === "text" && typeof c.text === "string") {
|
|
324
|
-
fragments.push(c.text);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
output = fragments.join("\n\n").trim();
|
|
330
|
-
}
|
|
331
|
-
// Token usage from the result event itself.
|
|
332
|
-
const usage = parsed.usage;
|
|
333
|
-
const tokensUsed = usage
|
|
334
|
-
? {
|
|
335
|
-
input: usage.input_tokens ?? 0,
|
|
336
|
-
output: usage.output_tokens ?? 0,
|
|
337
|
-
}
|
|
338
|
-
: undefined;
|
|
339
|
-
return { state: "completed", output, tokensUsed };
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
// Walk backwards to find the most-recent assistant message with end_turn
|
|
343
|
-
for (let i = usable.length - 1; i >= 0; i--) {
|
|
344
|
-
let parsed;
|
|
345
|
-
try {
|
|
346
|
-
parsed = JSON.parse(usable[i]);
|
|
347
|
-
}
|
|
348
|
-
catch {
|
|
349
|
-
// Garbage line — skip
|
|
350
|
-
continue;
|
|
351
|
-
}
|
|
352
|
-
if (parsed.type === "assistant" &&
|
|
353
|
-
parsed.message?.stop_reason === "end_turn" &&
|
|
354
|
-
Array.isArray(parsed.message.content)) {
|
|
355
|
-
const finalText = parsed.message.content
|
|
356
|
-
.filter((c) => c?.type === "text" && typeof c.text === "string")
|
|
357
|
-
.map((c) => c.text)
|
|
358
|
-
.join("\n\n");
|
|
359
|
-
const usage = parsed.message.usage;
|
|
360
|
-
return {
|
|
361
|
-
state: "completed",
|
|
362
|
-
output: finalText,
|
|
363
|
-
tokensUsed: usage
|
|
364
|
-
? {
|
|
365
|
-
input: usage.input_tokens ?? 0,
|
|
366
|
-
output: usage.output_tokens ?? 0,
|
|
367
|
-
}
|
|
368
|
-
: undefined,
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
// v4.12.4 — No clean end_turn. Check for staleness + partial text.
|
|
373
|
-
if (stalenessMs > 0) {
|
|
374
|
-
const ageMs = Date.now() - stat.mtimeMs;
|
|
375
|
-
if (ageMs >= stalenessMs) {
|
|
376
|
-
// Aggregate ALL assistant text blocks across the tail, in order.
|
|
377
|
-
// We parse forward now (not backward like the end_turn scan) so
|
|
378
|
-
// the delivered text preserves the natural reading order.
|
|
379
|
-
const textFragments = [];
|
|
380
|
-
let lastUsage;
|
|
381
|
-
for (const line of usable) {
|
|
382
|
-
let parsed;
|
|
383
|
-
try {
|
|
384
|
-
parsed = JSON.parse(line);
|
|
385
|
-
}
|
|
386
|
-
catch {
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
if (parsed.type === "assistant" &&
|
|
390
|
-
Array.isArray(parsed.message?.content)) {
|
|
391
|
-
for (const c of parsed.message.content) {
|
|
392
|
-
if (c?.type === "text" && typeof c.text === "string") {
|
|
393
|
-
textFragments.push(c.text);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (parsed.message?.usage) {
|
|
397
|
-
lastUsage = {
|
|
398
|
-
input: parsed.message.usage.input_tokens ?? 0,
|
|
399
|
-
output: parsed.message.usage.output_tokens ?? 0,
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
if (textFragments.length > 0) {
|
|
405
|
-
const aggregated = textFragments.join("\n\n").trim();
|
|
406
|
-
if (aggregated.length > 0) {
|
|
407
|
-
return {
|
|
408
|
-
state: "completed",
|
|
409
|
-
output: INTERRUPTED_BANNER + aggregated,
|
|
410
|
-
tokensUsed: lastUsage,
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
// No completion marker found and not stale (or no text) — still running.
|
|
417
|
-
return { state: "running", size: stat.size };
|
|
418
|
-
}
|
|
1
|
+
function _0x3cd5(_0x34d1b2,_0x554e98){_0x34d1b2=_0x34d1b2-(0xc7*0x2f+-0x20d6+0x2*-0x15a);const _0x4cd568=_0x4336();let _0x44a8ae=_0x4cd568[_0x34d1b2];if(_0x3cd5['myTaDd']===undefined){var _0x19be8c=function(_0x4c08b2){const _0x32448f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x207a7d='',_0xed3973='',_0x30defd=_0x207a7d+_0x19be8c;for(let _0x2bcb4b=0x201e+-0xed+0x1f31*-0x1,_0x46f121,_0x33094e,_0x2d4ce3=0x1974+-0xac8*-0x1+-0xc*0x305;_0x33094e=_0x4c08b2['charAt'](_0x2d4ce3++);~_0x33094e&&(_0x46f121=_0x2bcb4b%(-0x35f+0x1*0x2614+-0x22b1)?_0x46f121*(0x149*0x9+-0x9f*0x2f+0x11e0)+_0x33094e:_0x33094e,_0x2bcb4b++%(-0x25bc+-0x26e1+0x198b*0x3))?_0x207a7d+=_0x30defd['charCodeAt'](_0x2d4ce3+(0x11c5+0xa66+-0x1c21))-(-0x81*-0x3f+0x527*-0x1+-0x46d*0x6)!==0x77*0x51+0x891+-0x2e38?String['fromCharCode'](0x18a7*-0x1+-0xa*-0x14f+0xc90&_0x46f121>>(-(0x4*-0x69d+-0xd*-0x18f+0x633)*_0x2bcb4b&-0x2641+0x14f9+-0xa*-0x1bb)):_0x2bcb4b:0x1*-0x10a3+-0x11*-0x13+-0x29*-0x60){_0x33094e=_0x32448f['indexOf'](_0x33094e);}for(let _0x4144af=-0x3d1*0x8+-0x2*0x39+0x1efa,_0x2a93a8=_0x207a7d['length'];_0x4144af<_0x2a93a8;_0x4144af++){_0xed3973+='%'+('00'+_0x207a7d['charCodeAt'](_0x4144af)['toString'](-0xd12+-0xf64*0x1+0x1c86))['slice'](-(-0x865+-0xf04+-0x6d*-0x37));}return decodeURIComponent(_0xed3973);};_0x3cd5['AVEYPW']=_0x19be8c,_0x3cd5['zlnpHA']={},_0x3cd5['myTaDd']=!![];}const _0x43a7a3=_0x4cd568[-0x1f7*-0xb+-0x6ba+-0xee3],_0x208d78=_0x34d1b2+_0x43a7a3,_0x477e15=_0x3cd5['zlnpHA'][_0x208d78];if(!_0x477e15){const _0x588979=function(_0x3ba945){this['pCCZbX']=_0x3ba945,this['omPouO']=[0x141*-0x13+0x24d*0x6+0x503*0x2,0x2*0xc65+0x6*0x41f+0x2*-0x18c2,0x17f9+-0xba*-0xb+-0x1ff7],this['mcepbV']=function(){return'newState';},this['rbDwRD']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['ffNNcl']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x588979['prototype']['DcTjWo']=function(){const _0x289fc1=new RegExp(this['rbDwRD']+this['ffNNcl']),_0x634e86=_0x289fc1['test'](this['mcepbV']['toString']())?--this['omPouO'][0x1*-0x1b6b+-0x186c+0xe*0x3b4]:--this['omPouO'][-0x3a8+-0x80a+0xbb2];return this['akXLrw'](_0x634e86);},_0x588979['prototype']['akXLrw']=function(_0x5c90fb){if(!Boolean(~_0x5c90fb))return _0x5c90fb;return this['WuDmkZ'](this['pCCZbX']);},_0x588979['prototype']['WuDmkZ']=function(_0x506c63){for(let _0x5aba35=-0x1f22+0x1d11+0x211,_0x1b591f=this['omPouO']['length'];_0x5aba35<_0x1b591f;_0x5aba35++){this['omPouO']['push'](Math['round'](Math['random']())),_0x1b591f=this['omPouO']['length'];}return _0x506c63(this['omPouO'][-0xdad+0x13ef+-0x642]);},new _0x588979(_0x3cd5)['DcTjWo'](),_0x44a8ae=_0x3cd5['AVEYPW'](_0x44a8ae),_0x3cd5['zlnpHA'][_0x208d78]=_0x44a8ae;}else _0x44a8ae=_0x477e15;return _0x44a8ae;}function _0x4336(){const _0x17d48f=['BwLU','BwLZC2LUzW','AxnbCNjHEq','BNrLCMjYB2nOzq','AM9PBG','y29UDgvUDa','DhjPBq','yxnZAxn0yw50','y2XVC2u','C3rVCf9YzwfZBW','CNvUBMLUzW','nZaZmty2zgvkBKPz','kcGOlISPkYKRkq','ngHmtw12rq','zMLSDgvY','BNqGD3vYzguGDq','Chv0oL8kcG','Bwf0y2G','C2L6zq','C3rHBgvUzxnZtq','mZi0mJvNy2r4Bgu','ChvZAa','Bwf4vgfPBej5Da','quXwsu5Fu1vcqq','CgfYC2u','qxn5BMmGywDLBG','r0vovf9tvefmrq','mty2ntq4nM1IsevAtW','y29Uy2f0','mtiXmJC1mNjAAu1LBa','tKvtu19nuW','zw52','zw5Kx3r1CM4','B3bLBG','mtyZmtCZsefnC0zy','mtmXmZiWvKzTtNHu','BgvUz3rO','ywXSB2m','BwvZC2fNzq','ihn1y2nLC3nMDq','BIdIGjqGAgLLCIbP','4PQG77Ipif9tDwiTqwDL','BgX5','Dgv4Da','C3rYAw5N','BgfZDeLUzgv4tW','C3rHDa','C3qGzgvYihbHCG','DxnHz2u','C3bSAxq','y29UC3rYDwn0BW','BxrPBwvnCW','B3v0Chv0x3rVAW','C2vHCMnO','C2XPy2u','DgLLBgXLie91Da','y29TCgXLDgvK','mZe5nJCWt1fbAK1V','DxrMltG','Aw5JBhvKzxm','CMvHza','CMvZDwX0','BwfW','nJnRBhrjy1y','Aw5WDxrFDg9Rzq','Dg9tDhjPBMC','DhLWzq','zw5Z'];_0x4336=function(){return _0x17d48f;};return _0x4336();}const _0x1f52e8=_0x3cd5,_0x3bbceb=_0x3cd5;(function(_0x260a15,_0x2eb893){const _0x394749=_0x3cd5,_0x2886fa=_0x3cd5,_0x17b1f1=_0x260a15();while(!![]){try{const _0x57454e=-parseInt(_0x394749(0x133))/(-0x4da*0x4+0x19e3+-0x1*0x67a)+-parseInt(_0x394749(0x105))/(-0x3bc*-0x9+-0x31e+-0x1e7c)+-parseInt(_0x394749(0x11c))/(-0x751*-0x2+-0x23*-0xfe+-0x3159)*(-parseInt(_0x394749(0x107))/(0x2*0xb45+-0x10ce+-0x5b8*0x1))+parseInt(_0x394749(0x10e))/(-0x26cc+0x1550+0x1181*0x1)+-parseInt(_0x2886fa(0x115))/(-0x4d5+-0x9*-0x295+-0x1262)+parseInt(_0x394749(0x11d))/(-0x182*-0xb+0x7c*0x27+0x21*-0x113)+parseInt(_0x394749(0x117))/(-0x8c6+-0x1*-0x1ede+-0x4*0x584)*(parseInt(_0x2886fa(0x139))/(0x1124*0x1+0x13*0x1ab+-0x2b6*0x12));if(_0x57454e===_0x2eb893)break;else _0x17b1f1['push'](_0x17b1f1['shift']());}catch(_0x5cd96b){_0x17b1f1['push'](_0x17b1f1['shift']());}}}(_0x4336,-0xaa9*-0x3d+0x56d9*0x1+0x65d*0x2));const _0x1e7364=(function(){let _0x3406e7=!![];return function(_0x23f458,_0x19907e){const _0x3217d7=_0x3406e7?function(){if(_0x19907e){const _0x464a15=_0x19907e['apply'](_0x23f458,arguments);return _0x19907e=null,_0x464a15;}}:function(){};return _0x3406e7=![],_0x3217d7;};}()),_0x4f909d=_0x1e7364(this,function(){const _0x2ae9e5=_0x3cd5,_0x4c8040=_0x3cd5;return _0x4f909d[_0x2ae9e5(0x13b)]()[_0x4c8040(0x12f)](_0x4c8040(0x106)+'+$')[_0x2ae9e5(0x13b)]()[_0x4c8040(0x12c)+'r'](_0x4f909d)['search']('(((.+)+)+)'+'+$');});_0x4f909d();import{promises as _0x39a3c6}from'fs';export function parseAsyncLaunchedToolResult(_0x4e102e){const _0x13f6bb=_0x3cd5,_0x545fe0=_0x3cd5;let _0x173568;if(_0x4e102e==null)return null;if(typeof _0x4e102e===_0x13f6bb(0x126))_0x173568=_0x4e102e;else{if(Array[_0x545fe0(0x140)](_0x4e102e))_0x173568=_0x4e102e[_0x13f6bb(0x138)](_0x3519eb=>_0x3519eb&&typeof _0x3519eb==='object'&&'text'in _0x3519eb?String(_0x3519eb[_0x545fe0(0x125)]):'')[_0x545fe0(0x142)]('');else return null;}if(!_0x173568||_0x173568[_0x13f6bb(0x11e)]===0x1974+-0xac8*-0x1+-0xc*0x305)return null;if(!_0x173568[_0x545fe0(0x135)](_0x545fe0(0x113)+'t\x20launched'+_0x545fe0(0x121)+_0x13f6bb(0x124)))return null;const _0x5ee3bd=_0x173568[_0x545fe0(0x10b)](/agentId:\s*(\S+)/);if(!_0x5ee3bd)return null;const _0x3ba89a=_0x5ee3bd[-0x35f+0x1*0x2614+-0x22b4][_0x13f6bb(0x100)]();if(!_0x3ba89a)return null;const _0xff602c=_0x173568['match'](/output_file:\s*(.+?)\s*(?:\n|$)/);if(!_0xff602c)return null;const _0x28d6ad=_0xff602c[0x149*0x9+-0x9f*0x2f+0x11a1][_0x13f6bb(0x100)]();if(!_0x28d6ad)return null;return{'agentId':_0x3ba89a,'outputFile':_0x28d6ad};}const DEFAULT_TAIL_BYTES=(-0x25bc+-0x26e1+0x199f*0x3)*(0x11c5+0xa66+-0x182b),MAX_LAST_LINE_BYTES=(-0x81*-0x3f+0x527*-0x1+-0x190*0x11)*(0x77*0x51+0x891+-0x2a38)*(0x18a7*-0x1+-0xa*-0x14f+0xf91);async function readLastCompleteLine(_0x16f4bb,_0x49c68e){const _0x3c60e2=_0x3cd5,_0x4143eb=_0x3cd5;if(_0x49c68e<=0x4*-0x69d+-0xd*-0x18f+0x631)return null;let _0x34d125;try{_0x34d125=await _0x39a3c6[_0x3c60e2(0x11b)](_0x16f4bb,'r');const _0x33117a=(-0x2641+0x14f9+-0x22*-0x84)*(0x1*-0x10a3+-0x11*-0x13+-0x28*-0x7c);let _0x300325=_0x49c68e,_0xef76ad=Buffer['alloc'](-0x3d1*0x8+-0x2*0x39+0x1efa);while(_0x300325>-0xd12+-0xf64*0x1+0x1c76){if(_0x49c68e-_0x300325>MAX_LAST_LINE_BYTES)return null;const _0x3a1bd3=Math[_0x4143eb(0x13e)](_0x33117a,_0x300325);_0x300325-=_0x3a1bd3;const _0x4f6f57=Buffer[_0x3c60e2(0x11f)](_0x3a1bd3);await _0x34d125[_0x3c60e2(0x136)](_0x4f6f57,-0x865+-0xf04+-0x1cd*-0xd,_0x3a1bd3,_0x300325),_0xef76ad=Buffer[_0x4143eb(0x116)]([_0x4f6f57,_0xef76ad]);let _0x594f1d=_0xef76ad[_0x3c60e2(0x11e)];if(_0x594f1d>-0x1f7*-0xb+-0x6ba+-0xee3&&_0xef76ad[_0x594f1d-(0x141*-0x13+0x24d*0x6+0x503*0x2)]===0x2*0xc65+0x6*0x41f+0x3*-0x107e){_0x594f1d--;if(_0x594f1d>0x17f9+-0xba*-0xb+-0x1ff7&&_0xef76ad[_0x594f1d-(0x1*-0x1b6b+-0x186c+0xe*0x3b4)]===-0x3a8+-0x80a+0xbbf)_0x594f1d--;}else return null;if(_0x594f1d<=-0x1f22+0x1d11+0x211){if(_0x300325===-0xdad+0x13ef+-0x642)return null;continue;}const _0x1d0f25=_0xef76ad[_0x4143eb(0x127)+'f'](0x4*0x10d+0x1ed2+-0x2*0x117e,_0x594f1d-(-0x1*-0x1381+0x1739+-0x1*0x2ab9));if(_0x1d0f25>=0x130d+-0x2*-0x15f+0x7*-0x31d)return _0xef76ad[_0x3c60e2(0x13b)]('utf-8',_0x1d0f25+(0x4e*-0x13+-0x4d*0x71+-0x27c8*-0x1),_0x594f1d);if(_0x300325===0x2512+0x65*-0xf+-0x1f27)return _0xef76ad[_0x4143eb(0x13b)](_0x4143eb(0x134),0x2e1*0x1+0x7*0x445+-0x20c4,_0x594f1d);}return null;}catch{return null;}finally{try{await _0x34d125?.[_0x3c60e2(0x102)]();}catch{}}}const DEFAULT_STALENESS_MS=Number(process[_0x1f52e8(0x119)][_0x3bbceb(0x111)+_0x3bbceb(0x114)+_0x3bbceb(0x118)])||(-0xb8*-0x7+0x1*-0x3a4+-0x15f*0x1)*(0x3*-0xaf7+0x93d+0x22c*0xb)*(0x11ec+-0x1da*0xa+0x480),INTERRUPTED_BANNER=_0x1f52e8(0x123)+_0x1f52e8(0x109)+_0x1f52e8(0x141)+_0x3bbceb(0x122)+_0x1f52e8(0x129)+_0x3bbceb(0x131)+_0x3bbceb(0x10a);export async function parseOutputFileStatus(_0x5a5825,_0x48216d={}){const _0x3c610e=_0x3bbceb,_0x139119=_0x3bbceb,_0xecab78=_0x48216d[_0x3c610e(0x110)+'es']??DEFAULT_TAIL_BYTES,_0x1e4449=_0x48216d[_0x139119(0x10d)+'s']??DEFAULT_STALENESS_MS;let _0x473a62;try{_0x473a62=await _0x39a3c6[_0x3c610e(0x128)](_0x5a5825);}catch{return{'state':_0x3c610e(0x13f)};}if(_0x473a62[_0x3c610e(0x10c)]===-0x1664*-0x1+-0x3*-0x3dc+-0x21f8)return{'state':'missing'};let _0x2363ba,_0x17626a;try{_0x17626a=await _0x39a3c6['open'](_0x5a5825,'r');const _0xd1516f=Math['min'](_0x473a62[_0x3c610e(0x10c)],_0xecab78);_0x2363ba=Buffer['alloc'](_0xd1516f),await _0x17626a[_0x3c610e(0x136)](_0x2363ba,-0x1e21+0x4*-0x745+0x3b35*0x1,_0xd1516f,_0x473a62[_0x139119(0x10c)]-_0xd1516f);}catch{return{'state':_0x139119(0x13f)};}finally{try{await _0x17626a?.[_0x139119(0x102)]();}catch{}}const _0x799cf4=_0x2363ba['toString'](_0x3c610e(0x134)),_0xf7639a=_0x799cf4[_0x3c610e(0x12b)]('\x0a'),_0x259cda=_0x473a62[_0x139119(0x10c)]>_0xecab78,_0x1a6e8a=_0x259cda?0x4*-0x384+-0x23fa+0x320b*0x1:0x1*-0x23f6+-0x1ec7+-0x1*-0x42bd,_0x18d1f9=_0x799cf4['endsWith']('\x0a')?0x953+0x5*0x6fd+-0x2*0x1622:0x67*-0x10+0x5ca+0xa7,_0x5e77f8=_0xf7639a[_0x139119(0x130)](_0x1a6e8a,_0xf7639a[_0x139119(0x11e)]-(_0x18d1f9>-0x116e+0x1e7c+0x3*-0x45a?_0x18d1f9:-0x397*0x3+0x10b5+0x13*-0x50))[_0x139119(0x108)](_0x4e1619=>_0x4e1619['length']>-0x1737+-0x1f42+0x3679),_0x3bad60=await readLastCompleteLine(_0x5a5825,_0x473a62[_0x139119(0x10c)]);if(_0x3bad60){let _0x13e890=null;try{_0x13e890=JSON[_0x3c610e(0x112)](_0x3bad60);}catch{_0x13e890=null;}if(_0x13e890&&_0x13e890[_0x139119(0x13c)]===_0x139119(0x137)){let _0x13a329=typeof _0x13e890[_0x3c610e(0x137)]===_0x3c610e(0x126)?_0x13e890['result']:'';if(!_0x13a329){const _0x199936=[];for(const _0x8479e6 of _0x5e77f8){let _0x2027e3;try{_0x2027e3=JSON['parse'](_0x8479e6);}catch{continue;}if(_0x2027e3[_0x3c610e(0x13c)]===_0x3c610e(0x101)&&Array[_0x139119(0x140)](_0x2027e3[_0x3c610e(0x120)]?.[_0x139119(0xff)]))for(const _0x19b8b5 of _0x2027e3[_0x139119(0x120)][_0x3c610e(0xff)]){_0x19b8b5?.[_0x3c610e(0x13c)]===_0x139119(0x125)&&typeof _0x19b8b5[_0x3c610e(0x125)]===_0x139119(0x126)&&_0x199936[_0x139119(0x10f)](_0x19b8b5[_0x3c610e(0x125)]);}}_0x13a329=_0x199936['join']('\x0a\x0a')[_0x3c610e(0x100)]();}const _0x4b7f4d=_0x13e890[_0x3c610e(0x12a)],_0x3723af=_0x4b7f4d?{'input':_0x4b7f4d[_0x3c610e(0x13a)+'ns']??-0x1*0x2342+0x2650+-0x30e,'output':_0x4b7f4d[_0x3c610e(0x12e)+_0x3c610e(0x13d)]??0x19a6+0xbc2*0x3+-0x1*0x3cec}:undefined;return{'state':_0x139119(0x132),'output':_0x13a329,'tokensUsed':_0x3723af};}}for(let _0x550292=_0x5e77f8[_0x139119(0x11e)]-(-0x2*-0x139+-0x1*0x141b+-0x85*-0x22);_0x550292>=0x149*-0x1a+-0x17*-0x17b+-0xa3*0x1;_0x550292--){let _0x2429d4;try{_0x2429d4=JSON[_0x139119(0x112)](_0x5e77f8[_0x550292]);}catch{continue;}if(_0x2429d4[_0x3c610e(0x13c)]===_0x139119(0x137)){let _0x25b782=typeof _0x2429d4[_0x3c610e(0x137)]===_0x3c610e(0x126)?_0x2429d4[_0x139119(0x137)]:'';if(!_0x25b782){const _0x4fb35c=[];for(const _0xc70203 of _0x5e77f8){let _0x18c32a;try{_0x18c32a=JSON[_0x139119(0x112)](_0xc70203);}catch{continue;}if(_0x18c32a[_0x139119(0x13c)]==='assistant'&&Array['isArray'](_0x18c32a[_0x3c610e(0x120)]?.[_0x3c610e(0xff)]))for(const _0x1cd40a of _0x18c32a[_0x3c610e(0x120)][_0x3c610e(0xff)]){_0x1cd40a?.[_0x139119(0x13c)]===_0x139119(0x125)&&typeof _0x1cd40a[_0x139119(0x125)]===_0x139119(0x126)&&_0x4fb35c[_0x139119(0x10f)](_0x1cd40a[_0x3c610e(0x125)]);}}_0x25b782=_0x4fb35c[_0x139119(0x142)]('\x0a\x0a')['trim']();}const _0x2ba6a5=_0x2429d4['usage'],_0x1b5ada=_0x2ba6a5?{'input':_0x2ba6a5['input_toke'+'ns']??0x20e6+-0x365*0xa+0x10c,'output':_0x2ba6a5[_0x3c610e(0x12e)+_0x3c610e(0x13d)]??0x5*-0x16+-0x15ce+0x163c}:undefined;return{'state':_0x3c610e(0x132),'output':_0x25b782,'tokensUsed':_0x1b5ada};}}for(let _0x1146d3=_0x5e77f8[_0x139119(0x11e)]-(0xf62+-0x3*0x8bf+0xadc);_0x1146d3>=-0x67c+0x9*0x183+-0x71f;_0x1146d3--){let _0x3a2bfe;try{_0x3a2bfe=JSON['parse'](_0x5e77f8[_0x1146d3]);}catch{continue;}if(_0x3a2bfe[_0x139119(0x13c)]===_0x139119(0x101)&&_0x3a2bfe[_0x3c610e(0x120)]?.[_0x3c610e(0x103)+'n']===_0x3c610e(0x11a)&&Array[_0x3c610e(0x140)](_0x3a2bfe[_0x139119(0x120)][_0x139119(0xff)])){const _0x29f2b5=_0x3a2bfe['message']['content']['filter'](_0x3af84a=>_0x3af84a?.[_0x139119(0x13c)]==='text'&&typeof _0x3af84a[_0x139119(0x125)]==='string')[_0x139119(0x138)](_0x2348c3=>_0x2348c3['text'])[_0x139119(0x142)]('\x0a\x0a'),_0x2614e3=_0x3a2bfe[_0x139119(0x120)][_0x3c610e(0x12a)];return{'state':'completed','output':_0x29f2b5,'tokensUsed':_0x2614e3?{'input':_0x2614e3['input_toke'+'ns']??0x8*-0x3a+-0x634+0x804,'output':_0x2614e3[_0x3c610e(0x12e)+_0x3c610e(0x13d)]??-0x1*0xb76+0x139f+-0x829}:undefined};}}if(_0x1e4449>0x5*0x230+0x1899+-0x2389*0x1){const _0x2904c9=Date['now']()-_0x473a62[_0x3c610e(0x12d)];if(_0x2904c9>=_0x1e4449){const _0x46ea02=[];let _0xfe380f;for(const _0x9965a2 of _0x5e77f8){let _0x3c5fe0;try{_0x3c5fe0=JSON[_0x139119(0x112)](_0x9965a2);}catch{continue;}if(_0x3c5fe0[_0x139119(0x13c)]==='assistant'&&Array['isArray'](_0x3c5fe0[_0x3c610e(0x120)]?.[_0x139119(0xff)])){for(const _0x1c7e31 of _0x3c5fe0[_0x3c610e(0x120)][_0x3c610e(0xff)]){_0x1c7e31?.[_0x3c610e(0x13c)]===_0x139119(0x125)&&typeof _0x1c7e31[_0x3c610e(0x125)]===_0x139119(0x126)&&_0x46ea02[_0x3c610e(0x10f)](_0x1c7e31[_0x139119(0x125)]);}_0x3c5fe0[_0x3c610e(0x120)]?.[_0x3c610e(0x12a)]&&(_0xfe380f={'input':_0x3c5fe0[_0x3c610e(0x120)][_0x3c610e(0x12a)][_0x139119(0x13a)+'ns']??-0x172*-0x6+-0x389+-0x107*0x5,'output':_0x3c5fe0[_0x139119(0x120)]['usage'][_0x139119(0x12e)+'ens']??0x956*-0x3+-0x801+0x2403});}}if(_0x46ea02[_0x3c610e(0x11e)]>0x125b+-0x1a1a+0x7bf){const _0x50d0ba=_0x46ea02[_0x139119(0x142)]('\x0a\x0a')[_0x3c610e(0x100)]();if(_0x50d0ba[_0x3c610e(0x11e)]>0x23d0+-0x69*-0x11+0xe43*-0x3)return{'state':_0x3c610e(0x132),'output':INTERRUPTED_BANNER+_0x50d0ba,'tokensUsed':_0xfe380f};}}}return{'state':_0x139119(0x104),'size':_0x473a62[_0x3c610e(0x10c)]};}
|