@llamaventures/cli 1.2.3 → 1.2.4
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/bin/llama.mjs +44 -3
- package/lib/external.mjs +13 -0
- package/package.json +1 -1
package/bin/llama.mjs
CHANGED
|
@@ -309,13 +309,19 @@ Upload a file (deck / pitch / one-pager):
|
|
|
309
309
|
Interactive REPL (requires existing session):
|
|
310
310
|
llama pitch
|
|
311
311
|
|
|
312
|
+
Wrap up the pitch (asks the agent to call finalize_intake immediately):
|
|
313
|
+
llama pitch finalize # use when you're done — agent stops asking
|
|
314
|
+
|
|
312
315
|
Inspect / clean up:
|
|
313
316
|
llama pitch status # session id, idle minutes, finalized?
|
|
314
317
|
llama pitch end # clear local session state
|
|
315
318
|
|
|
316
319
|
Caps (server-enforced):
|
|
317
|
-
5 sessions per IP per day, 3 per email per day,
|
|
320
|
+
5 sessions per IP per day, 3 per email per day, 60min idle timeout,
|
|
318
321
|
100 messages per session, 1M tokens per session.
|
|
322
|
+
|
|
323
|
+
Environment:
|
|
324
|
+
LLAMA_API_URL override base URL (dev: http://localhost:3000)
|
|
319
325
|
`);
|
|
320
326
|
return;
|
|
321
327
|
}
|
|
@@ -403,14 +409,49 @@ Caps (server-enforced):
|
|
|
403
409
|
cleared: !!had,
|
|
404
410
|
session_file: EXTERNAL_SESSION_FILE,
|
|
405
411
|
note: had
|
|
406
|
-
? "Local session state cleared. Server-side session may still be active until idle timeout (
|
|
412
|
+
? "Local session state cleared. Server-side session may still be active until idle timeout (60min)."
|
|
407
413
|
: "No local session was active.",
|
|
408
414
|
});
|
|
409
415
|
return;
|
|
410
416
|
}
|
|
411
417
|
|
|
418
|
+
if (action === "finalize") {
|
|
419
|
+
// Founder-initiated finalize: send a sentinel token in the chat
|
|
420
|
+
// stream that the system prompt recognizes as "wrap up now." The
|
|
421
|
+
// intake agent calls finalize_intake on this turn with whatever
|
|
422
|
+
// fields are recorded — no extra questions, no confirmation prompt.
|
|
423
|
+
// Local session is left as-is; on next read its `finalized=true`
|
|
424
|
+
// reflects the server's status.
|
|
425
|
+
const session = readExternalSession();
|
|
426
|
+
if (!session) {
|
|
427
|
+
throw new Error(
|
|
428
|
+
"No active pitch session. Run `llama pitch start --name \"...\" --email \"...\"` first."
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
if (session.finalized) {
|
|
432
|
+
throw new Error(
|
|
433
|
+
"This pitch session is already finalized. Run `llama pitch end` to clear local state."
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
process.stderr.write("Asking the agent to wrap up...\n");
|
|
437
|
+
const result = await sendExternalMessage("[FOUNDER_FINALIZE_REQUEST]");
|
|
438
|
+
process.stdout.write(result.text + "\n");
|
|
439
|
+
if (result.finalized) {
|
|
440
|
+
process.stderr.write("\n--- Pitch session finalized ---\n");
|
|
441
|
+
if (result.finalize_payload) {
|
|
442
|
+
process.stderr.write(JSON.stringify(result.finalize_payload, null, 2) + "\n");
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
process.stderr.write(
|
|
446
|
+
"\n⚠ Agent did not call finalize_intake on this turn. " +
|
|
447
|
+
"Try `llama pitch finalize` once more, or `llama pitch end` to abandon.\n"
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
412
453
|
// No action → REPL mode (requires existing session)
|
|
413
|
-
if (action === undefined || (rest.length === 0 && !["start", "say", "upload", "status", "end"].includes(action))) {
|
|
454
|
+
if (action === undefined || (rest.length === 0 && !["start", "say", "upload", "status", "end", "finalize"].includes(action))) {
|
|
414
455
|
// Treat any unknown bare action as "join existing session in REPL mode"
|
|
415
456
|
const session = readExternalSession();
|
|
416
457
|
if (!session) {
|
package/lib/external.mjs
CHANGED
|
@@ -100,6 +100,10 @@ export async function startExternalSession({ name, email }) {
|
|
|
100
100
|
pow_nonce: powNonce,
|
|
101
101
|
user_agent: "@llamaventures/cli",
|
|
102
102
|
}),
|
|
103
|
+
// Cap at 60s — start-session is PoW + DB insert, never legitimate
|
|
104
|
+
// beyond a few seconds. Without this, a network hang freezes the CLI
|
|
105
|
+
// indefinitely.
|
|
106
|
+
signal: AbortSignal.timeout(60_000),
|
|
103
107
|
});
|
|
104
108
|
|
|
105
109
|
if (!res.ok) {
|
|
@@ -218,6 +222,11 @@ export async function sendExternalMessage(message, { attachments, onChunk } = {}
|
|
|
218
222
|
message,
|
|
219
223
|
...(attachments ? { attachments } : {}),
|
|
220
224
|
}),
|
|
225
|
+
// 180s ceiling — covers a legitimate slow agent turn (multi-tool
|
|
226
|
+
// call + deck read + Sonnet ~2k token reply ≈ 90-120s in practice)
|
|
227
|
+
// while still detecting a dead connection. Without this, a hung
|
|
228
|
+
// SSE stream freezes the CLI indefinitely.
|
|
229
|
+
signal: AbortSignal.timeout(180_000),
|
|
221
230
|
});
|
|
222
231
|
|
|
223
232
|
if (!res.ok) {
|
|
@@ -343,6 +352,10 @@ export async function uploadExternalFile(filePath) {
|
|
|
343
352
|
method: "POST",
|
|
344
353
|
headers: { Cookie: `external_session=${session.session_id}` },
|
|
345
354
|
body: formData,
|
|
355
|
+
// 180s ceiling — covers a 50MB upload over a slow tether (~280KB/s).
|
|
356
|
+
// Faster networks return in seconds; this only kicks in on a dead
|
|
357
|
+
// connection so the CLI doesn't hang forever.
|
|
358
|
+
signal: AbortSignal.timeout(180_000),
|
|
346
359
|
});
|
|
347
360
|
|
|
348
361
|
if (!res.ok) {
|