@oh-my-pi/pi-coding-agent 16.3.9 → 16.3.11

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/cli.js +2738 -2738
  3. package/dist/types/modes/interactive-mode.d.ts +5 -3
  4. package/dist/types/modes/session-observer-registry.d.ts +3 -1
  5. package/dist/types/session/agent-session.d.ts +11 -7
  6. package/dist/types/task/renderer.d.ts +0 -1
  7. package/dist/types/tools/browser/run-cancellation.d.ts +11 -0
  8. package/dist/types/tools/browser/tab-protocol.d.ts +1 -0
  9. package/dist/types/tools/tool-errors.d.ts +1 -1
  10. package/package.json +12 -12
  11. package/src/config/model-discovery.ts +18 -2
  12. package/src/internal-urls/docs-index.generated.txt +1 -1
  13. package/src/modes/components/__tests__/skill-message.test.ts +2 -0
  14. package/src/modes/components/agent-hub.ts +17 -2
  15. package/src/modes/components/skill-message.ts +1 -1
  16. package/src/modes/index.ts +0 -7
  17. package/src/modes/interactive-mode.ts +54 -18
  18. package/src/modes/session-observer-registry.ts +11 -8
  19. package/src/prompts/system/title-system.md +10 -10
  20. package/src/sdk.ts +18 -0
  21. package/src/session/agent-session.ts +25 -13
  22. package/src/system-prompt.test.ts +34 -1
  23. package/src/system-prompt.ts +24 -8
  24. package/src/task/render.test.ts +134 -1
  25. package/src/task/render.ts +24 -6
  26. package/src/task/renderer.ts +0 -1
  27. package/src/tools/browser/cmux/cmux-tab.ts +7 -3
  28. package/src/tools/browser/run-cancellation.ts +28 -8
  29. package/src/tools/browser/tab-protocol.ts +1 -1
  30. package/src/tools/browser/tab-supervisor.ts +4 -4
  31. package/src/tools/browser/tab-worker.ts +19 -7
  32. package/src/tools/irc.ts +18 -2
  33. package/src/tools/tool-errors.ts +3 -3
  34. package/src/utils/title-generator.ts +40 -65
  35. package/src/prompts/system/title-system-marker.md +0 -17
@@ -33,7 +33,7 @@ import { TranscriptContainer } from "./components/transcript-container.js";
33
33
  import { EventController } from "./controllers/event-controller.js";
34
34
  import { type LoopLimitRuntime } from "./loop-limit.js";
35
35
  import { OAuthManualInputManager } from "./oauth-manual-input.js";
36
- import type { ObservableSession } from "./session-observer-registry.js";
36
+ import { type ObservableSession } from "./session-observer-registry.js";
37
37
  import type { Theme } from "./theme/theme.js";
38
38
  import type { CompactionQueuedMessage, InteractiveModeContext, InteractiveModeInitOptions, InteractiveSelectorDialogOptions, SubmittedUserInput, TodoItem, TodoPhase } from "./types.js";
39
39
  /**
@@ -63,7 +63,7 @@ export interface InteractiveModeOptions {
63
63
  }
64
64
  /**
65
65
  * Build the anchored subagent HUD block: a bold accent "Subagents" header plus
66
- * one tree row per running agent in the same `Id: description` shape the
66
+ * a bounded set of running-agent rows in the same `Id: description` shape the
67
67
  * inline task rows use (muted task preview when no description was given).
68
68
  * Layout mirrors the Todos HUD exactly: unindented header, then
69
69
  * `renderTreeList` rows (dim connectors) shifted right by one space.
@@ -217,7 +217,9 @@ export declare class InteractiveMode implements InteractiveModeContext {
217
217
  finishPendingSubmission(input: SubmittedUserInput): void;
218
218
  updateEditorBorderColor(): void;
219
219
  /** Refresh the running-subagents status badge from the active local or collab registry. */
220
- syncRunningSubagentBadge(): void;
220
+ syncRunningSubagentBadge(options?: {
221
+ requestRender?: boolean;
222
+ }): void;
221
223
  rebuildChatFromMessages(): void;
222
224
  /**
223
225
  * Render the ctrl+p model-role cycle chip track into its own anchored
@@ -21,10 +21,12 @@ export interface ObservableSession {
21
21
  /** Latest progress snapshot from the subagent executor */
22
22
  progress?: AgentProgress;
23
23
  }
24
+ /** Coarse source of an observer change; callers use it to separate lifecycle work from high-frequency progress. */
25
+ export type SessionObserverChangeKind = "main" | "reset" | "lifecycle" | "progress";
24
26
  export declare class SessionObserverRegistry {
25
27
  #private;
26
28
  /** Add a change listener. Returns unsubscribe function. */
27
- onChange(cb: () => void): () => void;
29
+ onChange(cb: (kind: SessionObserverChangeKind) => void): () => void;
28
30
  setMainSession(sessionFile?: string): void;
29
31
  getSessions(): ObservableSession[];
30
32
  getActiveSubagentCount(): number;
@@ -423,6 +423,7 @@ export interface SessionStats {
423
423
  };
424
424
  premiumRequests: number;
425
425
  cost: number;
426
+ contextUsage?: ContextUsage;
426
427
  }
427
428
  /** Advisor statistics for /advisor status command. */
428
429
  export interface AdvisorStats {
@@ -1160,15 +1161,18 @@ export declare class AgentSession {
1160
1161
  /** Whether there are pending Python messages waiting to be flushed */
1161
1162
  get hasPendingPythonMessages(): boolean;
1162
1163
  /**
1163
- * Surfaces (and consumes) pending IRC incoming records before the next model
1164
+ * Surfaces and consumes pending IRC incoming records before the next model
1164
1165
  * step can inject them automatically.
1165
1166
  *
1166
- * The inbox tool injects the formatted body into the tool result, so the
1167
- * model sees it once via the result. Leaving the record in either pending
1168
- * IRC queue would deliver it a second time at the next step boundary —
1169
- * including on `peek`, which is why peek also drains here.
1170
- */
1171
- drainPendingIrcInboxMessages(agentId: string): IrcMessage[];
1167
+ * Tool results already expose the formatted body to the model. Leaving the
1168
+ * same record in either pending IRC queue would deliver it a second time at
1169
+ * the next step boundary including on `peek`, which is why inbox peeks
1170
+ * also drain here.
1171
+ */
1172
+ drainPendingIrcInboxMessages(agentId: string, opts?: {
1173
+ from?: string;
1174
+ limit?: number;
1175
+ }): IrcMessage[];
1172
1176
  /**
1173
1177
  * Deliver an IRC message into this session (recipient side; called by the
1174
1178
  * IrcBus). Emits the `irc_message` session event for UI cards and injects
@@ -10,5 +10,4 @@ export declare const taskToolRenderer: {
10
10
  readonly renderCall: typeof renderCall;
11
11
  readonly renderResult: typeof renderResult;
12
12
  readonly mergeCallAndResult: true;
13
- readonly animatedPartialResult: true;
14
13
  };
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Marks a run-scoped promise as observed without changing its behavior for awaited callers.
3
+ *
4
+ * Browser run teardown aborts can reject promises created for evaluated code after user code
5
+ * has stopped observing them (for example fire-and-forget `wait()`/facade calls). In 16.3.0
6
+ * those zero-consumer rejections reached the process-level `unhandledRejection` handler and
7
+ * killed every subagent sharing the process (issues #4499/#4672). Attaching a no-op rejection
8
+ * handler at creation makes the promise observed while returning the original promise so callers
9
+ * that do await it still receive the rejection.
10
+ */
11
+ export declare function markHandled<T>(promise: Promise<T>): Promise<T>;
1
12
  /** Sleeps inside evaluated browser code while honoring the owning run's cancellation signal. */
2
13
  export declare function waitForBrowserRun(ms: number, signal: AbortSignal): Promise<void>;
3
14
  /** Binds a long-lived browser facade to one evaluated run's abort signal. */
@@ -80,6 +80,7 @@ export type WorkerInbound = {
80
80
  } | {
81
81
  type: "abort";
82
82
  id: string;
83
+ expectedCleanup?: boolean;
83
84
  } | {
84
85
  type: "tool-reply";
85
86
  id: string;
@@ -19,7 +19,7 @@ export declare class ToolError extends Error {
19
19
  */
20
20
  export declare class ToolAbortError extends Error {
21
21
  static readonly MESSAGE = "Operation aborted";
22
- constructor(message?: string);
22
+ constructor(message?: string, options?: ErrorOptions);
23
23
  }
24
24
  /**
25
25
  * Throw ToolAbortError if the signal is aborted.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "16.3.9",
4
+ "version": "16.3.11",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -56,17 +56,17 @@
56
56
  "@agentclientprotocol/sdk": "0.25.0",
57
57
  "@babel/parser": "^7.29.7",
58
58
  "@mozilla/readability": "^0.6.0",
59
- "@oh-my-pi/hashline": "16.3.9",
60
- "@oh-my-pi/omp-stats": "16.3.9",
61
- "@oh-my-pi/pi-agent-core": "16.3.9",
62
- "@oh-my-pi/pi-ai": "16.3.9",
63
- "@oh-my-pi/pi-catalog": "16.3.9",
64
- "@oh-my-pi/pi-mnemopi": "16.3.9",
65
- "@oh-my-pi/pi-natives": "16.3.9",
66
- "@oh-my-pi/pi-tui": "16.3.9",
67
- "@oh-my-pi/pi-utils": "16.3.9",
68
- "@oh-my-pi/pi-wire": "16.3.9",
69
- "@oh-my-pi/snapcompact": "16.3.9",
59
+ "@oh-my-pi/hashline": "16.3.11",
60
+ "@oh-my-pi/omp-stats": "16.3.11",
61
+ "@oh-my-pi/pi-agent-core": "16.3.11",
62
+ "@oh-my-pi/pi-ai": "16.3.11",
63
+ "@oh-my-pi/pi-catalog": "16.3.11",
64
+ "@oh-my-pi/pi-mnemopi": "16.3.11",
65
+ "@oh-my-pi/pi-natives": "16.3.11",
66
+ "@oh-my-pi/pi-tui": "16.3.11",
67
+ "@oh-my-pi/pi-utils": "16.3.11",
68
+ "@oh-my-pi/pi-wire": "16.3.11",
69
+ "@oh-my-pi/snapcompact": "16.3.11",
70
70
  "@opentelemetry/api": "^1.9.1",
71
71
  "@opentelemetry/context-async-hooks": "^2.7.1",
72
72
  "@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
@@ -158,6 +158,7 @@ type LlamaCppDiscoveredModelRuntimeMetadata = {
158
158
 
159
159
  type LlamaCppModelListEntry = {
160
160
  id: string;
161
+ input?: ("text" | "image")[];
161
162
  runtimeContextWindow?: number;
162
163
  /**
163
164
  * `--ctx-size` extracted from the entry's `status.args` (rendered CLI arg
@@ -276,6 +277,20 @@ function extractLlamaCppModelContextWindows(
276
277
  };
277
278
  }
278
279
 
280
+ function extractLlamaCppModelInputCapabilities(item: Record<string, unknown>): ("text" | "image")[] | undefined {
281
+ const architecture = item.architecture;
282
+ if (!isRecord(architecture) || !Array.isArray(architecture.input_modalities)) {
283
+ return undefined;
284
+ }
285
+ const modalities = new Set<string>();
286
+ for (const modality of architecture.input_modalities) {
287
+ if (typeof modality === "string") {
288
+ modalities.add(modality.toLowerCase());
289
+ }
290
+ }
291
+ return modalities.has("image") ? ["text", "image"] : ["text"];
292
+ }
293
+
279
294
  function parseLlamaCppModelList(payload: unknown): LlamaCppModelListEntry[] {
280
295
  if (!isRecord(payload) || !Array.isArray(payload.data)) {
281
296
  return [];
@@ -287,6 +302,7 @@ function parseLlamaCppModelList(payload: unknown): LlamaCppModelListEntry[] {
287
302
  return [
288
303
  {
289
304
  id: item.id,
305
+ input: extractLlamaCppModelInputCapabilities(item),
290
306
  ...extractLlamaCppModelContextWindows(item),
291
307
  configuredContextWindow: extractLlamaCppConfiguredContextWindow(item),
292
308
  },
@@ -545,7 +561,7 @@ export async function discoverLlamaCppModels(
545
561
  provider: providerConfig.provider,
546
562
  baseUrl,
547
563
  reasoning: false,
548
- input: serverMetadata?.input ?? ["text"],
564
+ input: item.input ?? serverMetadata?.input ?? ["text"],
549
565
  imageInputDecoder: "stb",
550
566
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
551
567
  contextWindow,
@@ -595,7 +611,7 @@ export async function discoverLlamaCppModelRuntimeMetadata(
595
611
  entry.configuredContextWindow ??
596
612
  serverMetadata?.contextWindow ??
597
613
  entry.trainingContextWindow;
598
- const input = serverMetadata?.input;
614
+ const input = entry.input ?? serverMetadata?.input;
599
615
  if (contextWindow === undefined) {
600
616
  return input === undefined ? undefined : { input };
601
617
  }