privateer-agent 0.12.33 → 0.12.34
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/package.json +1 -1
- package/src/cli/chat.ts +9 -0
- package/src/engine/events.ts +14 -1
- package/src/remote/relayClient.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "privateer-agent",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.34",
|
|
4
4
|
"description": "Privacy-first terminal coding agent — bring your own model across 20 providers (Anthropic, OpenAI, OpenRouter, Google, local Ollama…). Safe-by-default permissions, MCP, sub-agents, workflows, and verifiable TEE inference. Built on the Pi toolkit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/cli/chat.ts
CHANGED
|
@@ -329,6 +329,15 @@ async function main() {
|
|
|
329
329
|
async function runTurn(text: string, remote: boolean, echo = true): Promise<void> {
|
|
330
330
|
if (turnActive) {
|
|
331
331
|
console.log(`\n${DIM}(busy — a turn is already running)${RESET}`);
|
|
332
|
+
// Say it to the DRIVER too, not just to this terminal's own console. An
|
|
333
|
+
// app-driven prompt refused here used to vanish: the app had already echoed
|
|
334
|
+
// the message into its feed and lit the thinking pill (submit() in
|
|
335
|
+
// RemoteDriveContext does both before transmitting), and the only trace of
|
|
336
|
+
// the refusal was a dim line on a terminal nobody was looking at. The driver
|
|
337
|
+
// saw their own message sit under a spinner forever. A notice does not close
|
|
338
|
+
// their turn, and must not — a turn IS running, and it is the one they are
|
|
339
|
+
// watching — but it tells them this message was not added to it.
|
|
340
|
+
if (remote) relay?.sendNotice("Not sent — this terminal is already running a turn. Wait for it to finish, or press Stop.");
|
|
332
341
|
return;
|
|
333
342
|
}
|
|
334
343
|
turnActive = true;
|
package/src/engine/events.ts
CHANGED
|
@@ -36,7 +36,20 @@ export type EngineEvent =
|
|
|
36
36
|
| { type: "retrying"; attempt: number; max: number; delayMs: number; reason: string }
|
|
37
37
|
// `error` is the short user-facing message; `hint` is an optional actionable
|
|
38
38
|
// next step rendered dim beneath it. Both are already secret-redacted.
|
|
39
|
-
| { type: "error"; error: string; hint?: string; retryable?: boolean }
|
|
39
|
+
| { type: "error"; error: string; hint?: string; retryable?: boolean }
|
|
40
|
+
// The turn is still running and has produced nothing for `sinceMs`. Emitted by a
|
|
41
|
+
// HOST that supervises turns (today: the desktop's turnSupervisor), never by the
|
|
42
|
+
// engine — the engine has no clock and no view of the turn as a whole.
|
|
43
|
+
//
|
|
44
|
+
// It exists because silence is ambiguous and the app cannot resolve it: a tool
|
|
45
|
+
// call emits at its start and its end and nothing in between, so a fifteen-minute
|
|
46
|
+
// build, a stalled model socket and a dead agent all look identical from the far
|
|
47
|
+
// side of the relay. This is the frame that says which. `tool`/`toolMs` name what
|
|
48
|
+
// is being waited on when something is.
|
|
49
|
+
//
|
|
50
|
+
// It is NOT turn activity: it must not reset a "silent for 4m" clock, or it would
|
|
51
|
+
// erase the very thing it was sent to report.
|
|
52
|
+
| { type: "still-working"; sinceMs: number; tool?: string; toolMs?: number };
|
|
40
53
|
|
|
41
54
|
export const emptyUsage = (): UsageTotals => ({
|
|
42
55
|
inputTokens: 0,
|
|
@@ -373,6 +373,11 @@ function projectEvent(ev: EngineEvent): Record<string, unknown> {
|
|
|
373
373
|
return { type: "aborted" };
|
|
374
374
|
case "step-finish":
|
|
375
375
|
return { type: "step-finish" };
|
|
376
|
+
// Fields, not just the tag: the default below would drop sinceMs/tool and the
|
|
377
|
+
// frame would arrive saying "something is happening" without saying what or
|
|
378
|
+
// for how long, which is the whole of its content.
|
|
379
|
+
case "still-working":
|
|
380
|
+
return { type: "still-working", sinceMs: ev.sinceMs, tool: ev.tool, toolMs: ev.toolMs };
|
|
376
381
|
default:
|
|
377
382
|
// text/reasoning are coalesced in sendEvent and never reach here.
|
|
378
383
|
return { type: ev.type };
|