@oh-my-pi/pi-coding-agent 16.1.22 → 16.2.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 +99 -1
- package/dist/cli.js +4387 -4164
- package/dist/types/advisor/__tests__/emission-guard.test.d.ts +1 -0
- package/dist/types/advisor/emission-guard.d.ts +73 -0
- package/dist/types/advisor/index.d.ts +1 -0
- package/dist/types/advisor/runtime.d.ts +7 -0
- package/dist/types/advisor/watchdog.d.ts +2 -0
- package/dist/types/cli/flag-tables.d.ts +1 -0
- package/dist/types/cli/gallery-fixtures/search.d.ts +1 -1
- package/dist/types/cli/gc-cli.d.ts +58 -0
- package/dist/types/collab/display-name.d.ts +3 -0
- package/dist/types/collab/host.d.ts +0 -2
- package/dist/types/commands/gc.d.ts +37 -0
- package/dist/types/commands/worktree.d.ts +0 -3
- package/dist/types/config/inline-tool-descriptors-mode.d.ts +13 -0
- package/dist/types/config/model-discovery.d.ts +6 -1
- package/dist/types/config/model-registry.d.ts +6 -2
- package/dist/types/config/model-resolver.d.ts +12 -0
- package/dist/types/config/models-config-schema.d.ts +29 -2
- package/dist/types/config/models-config.d.ts +22 -1
- package/dist/types/config/settings-schema.d.ts +145 -21
- package/dist/types/config/settings.d.ts +13 -0
- package/dist/types/dap/config.d.ts +1 -1
- package/dist/types/edit/hashline/filesystem.d.ts +4 -2
- package/dist/types/edit/renderer.d.ts +4 -0
- package/dist/types/extensibility/extensions/types.d.ts +17 -17
- package/dist/types/extensibility/hooks/types.d.ts +10 -10
- package/dist/types/extensibility/plugins/marketplace/types.d.ts +1 -0
- package/dist/types/internal-urls/__tests__/ssh-protocol.test.d.ts +1 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/registry-helpers.d.ts +2 -0
- package/dist/types/internal-urls/router.d.ts +1 -1
- package/dist/types/internal-urls/ssh-protocol.d.ts +10 -0
- package/dist/types/internal-urls/types.d.ts +19 -2
- package/dist/types/irc/bus.d.ts +6 -0
- package/dist/types/mcp/transports/stdio.d.ts +25 -1
- package/dist/types/modes/components/__tests__/move-overlay.test.d.ts +1 -0
- package/dist/types/modes/components/custom-editor.d.ts +7 -0
- package/dist/types/modes/components/move-overlay.d.ts +23 -0
- package/dist/types/modes/components/plugin-selector.d.ts +2 -1
- package/dist/types/modes/components/queue-mode-selector.d.ts +2 -1
- package/dist/types/modes/components/select-list-mouse-routing.d.ts +2 -0
- package/dist/types/modes/components/settings-defs.d.ts +4 -1
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/show-images-selector.d.ts +2 -1
- package/dist/types/modes/components/status-line/component.d.ts +2 -0
- package/dist/types/modes/components/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/theme-selector.d.ts +2 -1
- package/dist/types/modes/components/thinking-selector.d.ts +2 -1
- package/dist/types/modes/controllers/command-controller.d.ts +10 -1
- package/dist/types/modes/controllers/streaming-reveal.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +10 -1
- package/dist/types/modes/internal-url-autocomplete.d.ts +1 -1
- package/dist/types/modes/running-subagent-badge.d.ts +6 -0
- package/dist/types/modes/theme/mermaid-rendering.test.d.ts +1 -0
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +9 -1
- package/dist/types/sdk.d.ts +2 -2
- package/dist/types/session/agent-session.d.ts +2 -1
- package/dist/types/session/session-listing.d.ts +10 -1
- package/dist/types/session/session-manager.d.ts +13 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
- package/dist/types/ssh/__tests__/connection-manager-args.test.d.ts +1 -0
- package/dist/types/ssh/__tests__/file-transfer-posix-guard.test.d.ts +1 -0
- package/dist/types/ssh/connection-manager.d.ts +2 -0
- package/dist/types/ssh/file-transfer.d.ts +79 -0
- package/dist/types/ssh/utils.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +5 -0
- package/dist/types/task/executor.d.ts +16 -0
- package/dist/types/tiny/text.d.ts +1 -1
- package/dist/types/tools/builtin-names.d.ts +5 -1
- package/dist/types/tools/{find.d.ts → glob.d.ts} +15 -15
- package/dist/types/tools/{search.d.ts → grep.d.ts} +14 -14
- package/dist/types/tools/index.d.ts +3 -3
- package/dist/types/tools/path-utils.d.ts +29 -0
- package/dist/types/tools/plan-mode-guard.d.ts +7 -0
- package/dist/types/tools/read.d.ts +2 -2
- package/dist/types/tools/render-utils.d.ts +8 -0
- package/dist/types/tools/renderers.d.ts +11 -0
- package/dist/types/tools/ssh.d.ts +2 -0
- package/dist/types/tools/todo.d.ts +0 -16
- package/dist/types/tools/write.d.ts +2 -2
- package/dist/types/utils/active-repo-context.d.ts +8 -0
- package/dist/types/utils/image-resize.d.ts +1 -0
- package/dist/types/utils/markit-cache.d.ts +23 -0
- package/dist/types/utils/markit.d.ts +5 -1
- package/dist/types/utils/prompt-path.d.ts +1 -0
- package/dist/types/web/search/providers/duckduckgo.d.ts +14 -0
- package/dist/types/web/search/providers/firecrawl.d.ts +28 -0
- package/dist/types/web/search/providers/tinyfish.d.ts +29 -0
- package/dist/types/web/search/providers/xai.d.ts +13 -0
- package/dist/types/web/search/types.d.ts +18 -2
- package/package.json +30 -15
- package/scripts/bench-guard.ts +1 -1
- package/scripts/build-binary.ts +9 -9
- package/scripts/bundle-dist.ts +2 -2
- package/src/advisor/__tests__/advisor.test.ts +40 -4
- package/src/advisor/__tests__/emission-guard.test.ts +147 -0
- package/src/advisor/advise-tool.ts +1 -1
- package/src/advisor/emission-guard.ts +172 -0
- package/src/advisor/index.ts +1 -0
- package/src/advisor/runtime.ts +11 -0
- package/src/advisor/watchdog.ts +12 -1
- package/src/cli/args.ts +5 -2
- package/src/cli/auth-broker-cli.ts +17 -0
- package/src/cli/config-cli.ts +4 -0
- package/src/cli/flag-tables.ts +7 -4
- package/src/cli/gallery-cli.ts +14 -2
- package/src/cli/gallery-fixtures/edit.ts +60 -0
- package/src/cli/gallery-fixtures/fs.ts +17 -17
- package/src/cli/gallery-fixtures/search.ts +4 -4
- package/src/cli/gc-cli.ts +939 -0
- package/src/cli/usage-cli.ts +20 -1
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli-commands.ts +1 -0
- package/src/collab/display-name.ts +13 -0
- package/src/collab/guest.ts +5 -1
- package/src/collab/host.ts +2 -13
- package/src/commands/gc.ts +46 -0
- package/src/commands/worktree.ts +6 -0
- package/src/config/inline-tool-descriptors-mode.ts +27 -0
- package/src/config/model-discovery.ts +77 -8
- package/src/config/model-registry.ts +89 -11
- package/src/config/model-resolver.ts +39 -1
- package/src/config/models-config-schema.ts +41 -5
- package/src/config/models-config.ts +4 -1
- package/src/config/settings-schema.ts +130 -27
- package/src/config/settings.ts +216 -7
- package/src/cursor.ts +1 -1
- package/src/dap/config.ts +152 -8
- package/src/dap/session.ts +1 -1
- package/src/discovery/helpers.ts +3 -1
- package/src/edit/hashline/diff.ts +14 -3
- package/src/edit/hashline/execute.ts +42 -6
- package/src/edit/hashline/filesystem.ts +49 -8
- package/src/edit/index.ts +1 -0
- package/src/edit/modes/patch.ts +11 -1
- package/src/edit/renderer.ts +140 -13
- package/src/eval/__tests__/agent-bridge.test.ts +101 -0
- package/src/eval/__tests__/julia-prelude.test.ts +18 -0
- package/src/eval/agent-bridge.ts +26 -3
- package/src/eval/jl/runner.jl +7 -1
- package/src/eval/js/tool-bridge.ts +2 -2
- package/src/export/html/index.ts +1 -1
- package/src/export/html/template.js +3 -1
- package/src/export/html/tool-views.generated.js +20 -20
- package/src/extensibility/extensions/types.ts +22 -22
- package/src/extensibility/hooks/types.ts +11 -11
- package/src/extensibility/plugins/legacy-pi-bundled-keys.ts +10 -3
- package/src/extensibility/plugins/legacy-pi-bundled-registry.ts +31 -10
- package/src/extensibility/plugins/marketplace/manager.ts +22 -0
- package/src/extensibility/plugins/marketplace/types.ts +1 -0
- package/src/internal-urls/__tests__/ssh-protocol.test.ts +331 -0
- package/src/internal-urls/docs-index.generated.txt +2 -2
- package/src/internal-urls/docs-index.ts +2 -3
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/registry-helpers.ts +19 -4
- package/src/internal-urls/router.ts +5 -3
- package/src/internal-urls/ssh-protocol.ts +367 -0
- package/src/internal-urls/types.ts +19 -2
- package/src/irc/bus.ts +11 -3
- package/src/lsp/index.ts +8 -1
- package/src/mcp/oauth-discovery.ts +20 -20
- package/src/mcp/tool-bridge.ts +32 -2
- package/src/mcp/transports/stdio.test.ts +20 -3
- package/src/mcp/transports/stdio.ts +45 -14
- package/src/memories/index.ts +1 -1
- package/src/modes/acp/acp-event-mapper.ts +2 -2
- package/src/modes/components/__tests__/move-overlay.test.ts +166 -0
- package/src/modes/components/agent-hub.ts +3 -0
- package/src/modes/components/agent-transcript-viewer.ts +9 -7
- package/src/modes/components/custom-editor.ts +90 -5
- package/src/modes/components/move-overlay.ts +282 -0
- package/src/modes/components/plan-review-overlay.ts +35 -35
- package/src/modes/components/plugin-selector.ts +6 -1
- package/src/modes/components/queue-mode-selector.ts +6 -1
- package/src/modes/components/select-list-mouse-routing.ts +35 -0
- package/src/modes/components/session-selector.ts +11 -10
- package/src/modes/components/settings-defs.ts +14 -1
- package/src/modes/components/settings-selector.ts +196 -29
- package/src/modes/components/show-images-selector.ts +6 -1
- package/src/modes/components/status-line/component.ts +108 -28
- package/src/modes/components/status-line/segments.ts +5 -1
- package/src/modes/components/status-line/types.ts +2 -0
- package/src/modes/components/theme-selector.ts +6 -1
- package/src/modes/components/thinking-selector.ts +6 -1
- package/src/modes/components/tool-execution.ts +25 -9
- package/src/modes/components/tree-selector.ts +5 -5
- package/src/modes/controllers/command-controller.ts +140 -47
- package/src/modes/controllers/event-controller.ts +59 -3
- package/src/modes/controllers/input-controller.ts +70 -4
- package/src/modes/controllers/selector-controller.ts +15 -2
- package/src/modes/controllers/streaming-reveal.ts +17 -0
- package/src/modes/controllers/tool-args-reveal.ts +1 -1
- package/src/modes/interactive-mode.ts +142 -59
- package/src/modes/internal-url-autocomplete.ts +17 -2
- package/src/modes/prompt-action-autocomplete.ts +3 -1
- package/src/modes/running-subagent-badge.ts +13 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +2 -13
- package/src/modes/setup-wizard/scenes/providers.ts +2 -1
- package/src/modes/setup-wizard/scenes/theme.ts +6 -12
- package/src/modes/setup-wizard/scenes/web-search.ts +8 -13
- package/src/modes/setup-wizard/wizard-overlay.ts +6 -5
- package/src/modes/theme/mermaid-rendering.test.ts +53 -0
- package/src/modes/theme/theme.ts +42 -15
- package/src/modes/types.ts +9 -1
- package/src/modes/utils/interactive-context-helpers.ts +1 -1
- package/src/priority.json +15 -0
- package/src/prompts/advisor/active-repo-watchdog.md +6 -0
- package/src/prompts/advisor/system.md +21 -7
- package/src/prompts/agents/designer.md +1 -1
- package/src/prompts/agents/explore.md +1 -1
- package/src/prompts/agents/librarian.md +2 -2
- package/src/prompts/agents/plan.md +2 -2
- package/src/prompts/agents/reviewer.md +1 -1
- package/src/prompts/agents/task.md +2 -2
- package/src/prompts/system/active-repo-context.md +4 -0
- package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
- package/src/prompts/system/plan-mode-active.md +12 -3
- package/src/prompts/system/project-prompt.md +2 -2
- package/src/prompts/system/system-prompt.md +8 -6
- package/src/prompts/tools/bash.md +2 -2
- package/src/prompts/tools/checkpoint.md +1 -1
- package/src/prompts/tools/{find.md → glob.md} +1 -1
- package/src/prompts/tools/{search.md → grep.md} +3 -3
- package/src/prompts/tools/read.md +4 -2
- package/src/sdk.ts +98 -29
- package/src/session/agent-session.ts +828 -191
- package/src/session/session-history-format.ts +2 -2
- package/src/session/session-listing.ts +35 -2
- package/src/session/session-manager.ts +46 -0
- package/src/slash-commands/builtin-registry.ts +158 -22
- package/src/slash-commands/helpers/usage-report.ts +23 -2
- package/src/ssh/__tests__/connection-manager-args.test.ts +69 -0
- package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +68 -0
- package/src/ssh/connection-manager.ts +12 -15
- package/src/ssh/file-transfer.ts +209 -0
- package/src/ssh/utils.ts +24 -0
- package/src/system-prompt.ts +60 -28
- package/src/task/executor.ts +96 -36
- package/src/task/index.ts +3 -3
- package/src/task/render.ts +14 -13
- package/src/task/worktree.ts +38 -1
- package/src/tiny/text.ts +49 -4
- package/src/tiny/worker.ts +3 -3
- package/src/tools/acp-bridge.ts +6 -1
- package/src/tools/bash.ts +2 -2
- package/src/tools/builtin-names.ts +26 -2
- package/src/tools/{find.ts → glob.ts} +48 -42
- package/src/tools/{search.ts → grep.ts} +311 -129
- package/src/tools/index.ts +13 -14
- package/src/tools/irc.ts +6 -2
- package/src/tools/path-utils.ts +64 -1
- package/src/tools/plan-mode-guard.ts +26 -13
- package/src/tools/read.ts +35 -6
- package/src/tools/render-utils.ts +14 -0
- package/src/tools/renderers.ts +15 -4
- package/src/tools/ssh.ts +17 -2
- package/src/tools/todo.ts +4 -26
- package/src/tools/write.ts +25 -9
- package/src/utils/active-repo-context.ts +143 -0
- package/src/utils/edit-mode.ts +19 -2
- package/src/utils/image-resize.ts +88 -7
- package/src/utils/lang-from-path.ts +3 -3
- package/src/utils/markit-cache.ts +166 -0
- package/src/utils/markit.ts +86 -18
- package/src/utils/prompt-path.ts +3 -0
- package/src/utils/shell-snapshot.ts +1 -1
- package/src/utils/title-generator.ts +1 -1
- package/src/web/search/provider.ts +54 -34
- package/src/web/search/providers/duckduckgo.ts +140 -0
- package/src/web/search/providers/firecrawl.ts +144 -0
- package/src/web/search/providers/tinyfish.ts +159 -0
- package/src/web/search/providers/xai.ts +292 -0
- package/src/web/search/providers/zai.ts +142 -56
- package/src/web/search/types.ts +6 -2
package/src/cli/usage-cli.ts
CHANGED
|
@@ -326,7 +326,26 @@ function formatAccountHeader(
|
|
|
326
326
|
const planType = report.metadata?.planType;
|
|
327
327
|
if (typeof planType === "string" && planType) header += chalk.dim(` · plan: ${planType}`);
|
|
328
328
|
const savedResets = report.resetCredits?.availableCount ?? 0;
|
|
329
|
-
if (savedResets > 0)
|
|
329
|
+
if (savedResets > 0) {
|
|
330
|
+
header += chalk.cyan(` · ✦ ${savedResets} saved reset${savedResets === 1 ? "" : "s"}`);
|
|
331
|
+
const credits = report.resetCredits?.credits;
|
|
332
|
+
if (credits) {
|
|
333
|
+
const expiries = credits
|
|
334
|
+
.filter(c => c.expiresAt)
|
|
335
|
+
.map(c => ({ date: c.expiresAt!, ms: Date.parse(c.expiresAt!) }))
|
|
336
|
+
.filter(c => !Number.isNaN(c.ms))
|
|
337
|
+
.sort((a, b) => a.ms - b.ms);
|
|
338
|
+
const upcoming = expiries.find(c => c.ms > nowMs);
|
|
339
|
+
if (upcoming) {
|
|
340
|
+
header += chalk.dim(
|
|
341
|
+
` · soonest expires in ${formatDuration(upcoming.ms - nowMs)} (${upcoming.date.slice(0, 10)})`,
|
|
342
|
+
);
|
|
343
|
+
} else {
|
|
344
|
+
const lastExpired = expiries.at(-1);
|
|
345
|
+
if (lastExpired) header += chalk.dim(` · expired (${lastExpired.date.slice(0, 10)})`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
330
349
|
if (report.fetchedAt && nowMs - report.fetchedAt > 90_000) {
|
|
331
350
|
header += chalk.dim(` · fetched ${formatDuration(nowMs - report.fetchedAt)} ago`);
|
|
332
351
|
}
|
|
@@ -120,7 +120,7 @@ ${chalk.bold("Arguments:")}
|
|
|
120
120
|
|
|
121
121
|
${chalk.bold("Options:")}
|
|
122
122
|
--provider <name> Provider: ${PROVIDERS.join(", ")}
|
|
123
|
-
--recency <value> Recency filter (
|
|
123
|
+
--recency <value> Recency filter (when supported): ${RECENCY_OPTIONS.join(", ")}
|
|
124
124
|
-l, --limit <n> Max results to return
|
|
125
125
|
--compact Render condensed output
|
|
126
126
|
-h, --help Show this help
|
package/src/cli-commands.ts
CHANGED
|
@@ -23,6 +23,7 @@ export const commands: CommandEntry[] = [
|
|
|
23
23
|
{ name: "__complete", load: () => import("./commands/complete").then(m => m.default) },
|
|
24
24
|
{ name: "config", load: () => import("./commands/config").then(m => m.default) },
|
|
25
25
|
{ name: "dry-balance", load: () => import("./commands/dry-balance").then(m => m.default) },
|
|
26
|
+
{ name: "gc", load: () => import("./commands/gc").then(m => m.default) },
|
|
26
27
|
{ name: "grep", load: () => import("./commands/grep").then(m => m.default) },
|
|
27
28
|
{ name: "gallery", load: () => import("./commands/gallery").then(m => m.default) },
|
|
28
29
|
{ name: "grievances", load: () => import("./commands/grievances").then(m => m.default) },
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import type { InteractiveModeContext } from "../modes/types";
|
|
3
|
+
|
|
4
|
+
/** Display name for this process's user in collab sessions. */
|
|
5
|
+
export function collabDisplayName(ctx: InteractiveModeContext): string {
|
|
6
|
+
const configured = (ctx.settings.get("collab.displayName") ?? "").trim();
|
|
7
|
+
if (configured) return configured;
|
|
8
|
+
try {
|
|
9
|
+
return os.userInfo().username;
|
|
10
|
+
} catch {
|
|
11
|
+
return "anonymous";
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/collab/guest.ts
CHANGED
|
@@ -24,7 +24,7 @@ import type { SessionEntry } from "../session/session-entries";
|
|
|
24
24
|
import { shouldDisableReasoning, toReasoningEffort } from "../thinking";
|
|
25
25
|
import { setSessionTerminalTitle } from "../utils/title-generator";
|
|
26
26
|
import { importRoomKey } from "./crypto";
|
|
27
|
-
import { collabDisplayName } from "./
|
|
27
|
+
import { collabDisplayName } from "./display-name";
|
|
28
28
|
import {
|
|
29
29
|
type AgentSnapshot,
|
|
30
30
|
COLLAB_PROTO,
|
|
@@ -276,6 +276,7 @@ export class CollabGuestLink {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
this.#ctx.collabGuest = this;
|
|
279
|
+
this.#ctx.syncRunningSubagentBadge();
|
|
279
280
|
}
|
|
280
281
|
|
|
281
282
|
/** User-initiated leave (or post-disconnect cleanup): restore the previous session. */
|
|
@@ -357,6 +358,7 @@ export class CollabGuestLink {
|
|
|
357
358
|
this.#applyHostState(pending.state);
|
|
358
359
|
this.#ctx.resetObserverRegistry();
|
|
359
360
|
this.#applyAgentSnapshots(pending.agents);
|
|
361
|
+
this.#ctx.syncRunningSubagentBadge();
|
|
360
362
|
this.#assistantStreamSynced = false;
|
|
361
363
|
setSessionTerminalTitle(pending.state.sessionName ?? pending.header.title, pending.state.cwd);
|
|
362
364
|
this.#ctx.chatContainer.clear();
|
|
@@ -440,6 +442,7 @@ export class CollabGuestLink {
|
|
|
440
442
|
break;
|
|
441
443
|
case "agents":
|
|
442
444
|
this.#applyAgentSnapshots(frame.agents);
|
|
445
|
+
this.#ctx.syncRunningSubagentBadge();
|
|
443
446
|
break;
|
|
444
447
|
case "transcript": {
|
|
445
448
|
const resolve = this.#pendingTranscripts.get(frame.reqId);
|
|
@@ -573,6 +576,7 @@ export class CollabGuestLink {
|
|
|
573
576
|
this.#ctx.statusLine.setCollabStatus(null);
|
|
574
577
|
this.#flushPendingTranscripts();
|
|
575
578
|
this.#clearAgentMirror();
|
|
579
|
+
this.#ctx.syncRunningSubagentBadge();
|
|
576
580
|
this.#ctx.resetObserverRegistry();
|
|
577
581
|
this.#clearTransientUi();
|
|
578
582
|
// Replica file stays on disk: it is a valid session file outside the
|
package/src/collab/host.ts
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
|
|
12
12
|
import { timingSafeEqual } from "node:crypto";
|
|
13
13
|
import * as fs from "node:fs/promises";
|
|
14
|
-
import * as os from "node:os";
|
|
15
14
|
import type { ImageContent, TextContent } from "@oh-my-pi/pi-ai";
|
|
16
15
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
17
16
|
import type { BusChannel, AgentEvent as WireAgentEvent, SessionEntry as WireSessionEntry } from "@oh-my-pi/pi-wire";
|
|
@@ -21,8 +20,9 @@ import { type AgentRef, AgentRegistry } from "../registry/agent-registry";
|
|
|
21
20
|
import type { AgentSessionEvent } from "../session/agent-session";
|
|
22
21
|
import { stripImagesFromMessage, USER_INTERRUPT_LABEL } from "../session/messages";
|
|
23
22
|
import type { SessionEntry as StoredSessionEntry } from "../session/session-entries";
|
|
24
|
-
import { TASK_SUBAGENT_LIFECYCLE_CHANNEL, TASK_SUBAGENT_PROGRESS_CHANNEL } from "../task";
|
|
23
|
+
import { TASK_SUBAGENT_LIFECYCLE_CHANNEL, TASK_SUBAGENT_PROGRESS_CHANNEL } from "../task/types";
|
|
25
24
|
import { generateRoomKey, generateWriteToken, importRoomKey } from "./crypto";
|
|
25
|
+
import { collabDisplayName } from "./display-name";
|
|
26
26
|
import {
|
|
27
27
|
type AgentSnapshot,
|
|
28
28
|
COLLAB_PROMPT_MESSAGE_TYPE,
|
|
@@ -102,17 +102,6 @@ const TRANSCRIPT_READ_CAP = 4 * 1024 * 1024;
|
|
|
102
102
|
*/
|
|
103
103
|
const SNAPSHOT_CHUNK_BYTES = 512 * 1024;
|
|
104
104
|
|
|
105
|
-
/** Display name for this process's user in collab sessions. */
|
|
106
|
-
export function collabDisplayName(ctx: InteractiveModeContext): string {
|
|
107
|
-
const configured = (ctx.settings.get("collab.displayName") ?? "").trim();
|
|
108
|
-
if (configured) return configured;
|
|
109
|
-
try {
|
|
110
|
-
return os.userInfo().username;
|
|
111
|
-
} catch {
|
|
112
|
-
return "anonymous";
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
105
|
export class CollabHost {
|
|
117
106
|
#ctx: InteractiveModeContext;
|
|
118
107
|
#socket: CollabSocket | null = null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run on-disk storage maintenance.
|
|
3
|
+
*/
|
|
4
|
+
import { Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
|
+
import { collectGcErrors, type GcCommandArgs, runGcCommand } from "../cli/gc-cli";
|
|
6
|
+
|
|
7
|
+
export default class Gc extends Command {
|
|
8
|
+
static description = "Run storage garbage collection";
|
|
9
|
+
|
|
10
|
+
static flags = {
|
|
11
|
+
apply: Flags.boolean({ description: "Apply changes (default is dry-run)" }),
|
|
12
|
+
json: Flags.boolean({ description: "Output JSON" }),
|
|
13
|
+
"agent-dir": Flags.string({ description: "Agent directory to maintain" }),
|
|
14
|
+
blobs: Flags.boolean({ description: "Sweep unreferenced blobs" }),
|
|
15
|
+
archive: Flags.boolean({ description: "Archive cold sessions" }),
|
|
16
|
+
wal: Flags.boolean({ description: "Checkpoint history/model database WAL files" }),
|
|
17
|
+
"cold-archive-after-days": Flags.integer({ description: "Minimum session age before archiving" }),
|
|
18
|
+
"retain-newest-global": Flags.integer({ description: "Always keep this many newest sessions active" }),
|
|
19
|
+
"retain-newest-per-cwd": Flags.integer({ description: "Always keep this many newest sessions per cwd active" }),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
async run(): Promise<void> {
|
|
23
|
+
const { flags } = await this.parse(Gc);
|
|
24
|
+
const cmd: GcCommandArgs = {
|
|
25
|
+
flags: {
|
|
26
|
+
apply: flags.apply,
|
|
27
|
+
json: flags.json,
|
|
28
|
+
agentDir: flags["agent-dir"],
|
|
29
|
+
blobs: flags.blobs,
|
|
30
|
+
archive: flags.archive,
|
|
31
|
+
wal: flags.wal,
|
|
32
|
+
coldArchiveAfterDays: flags["cold-archive-after-days"],
|
|
33
|
+
retainNewestGlobal: flags["retain-newest-global"],
|
|
34
|
+
retainNewestPerCwd: flags["retain-newest-per-cwd"],
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
const result = await runGcCommand(cmd);
|
|
38
|
+
const errors = collectGcErrors(result);
|
|
39
|
+
if (errors.length > 0) {
|
|
40
|
+
process.stderr.write(
|
|
41
|
+
`GC completed with ${errors.length} error${errors.length === 1 ? "" : "s"}:\n${errors.map(error => `- ${error}`).join("\n")}\n`,
|
|
42
|
+
);
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/commands/worktree.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* List and clean up agent-managed git worktrees under `~/.omp/wt`.
|
|
3
3
|
*/
|
|
4
|
+
import { getProjectDir } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
6
|
import { clearWorktrees, listWorktrees } from "../cli/worktree-cli";
|
|
7
|
+
import { Settings } from "../config/settings";
|
|
6
8
|
|
|
7
9
|
export default class Worktree extends Command {
|
|
8
10
|
static description = "List or clear agent-managed git worktrees (~/.omp/wt)";
|
|
@@ -43,6 +45,10 @@ export default class Worktree extends Command {
|
|
|
43
45
|
|
|
44
46
|
async run(): Promise<void> {
|
|
45
47
|
const { args, flags } = await this.parse(Worktree);
|
|
48
|
+
// Load settings so the `worktree.base` override is applied before we scan
|
|
49
|
+
// — otherwise this command would inspect ~/.omp/wt while the agent created
|
|
50
|
+
// its worktrees under the configured base.
|
|
51
|
+
await Settings.init({ cwd: getProjectDir() });
|
|
46
52
|
if (args.action === "clear") {
|
|
47
53
|
await clearWorktrees({
|
|
48
54
|
all: flags.all ?? false,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { modelFamilyToken } from "@oh-my-pi/pi-catalog/identity";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolves whether full tool descriptors should be inlined into the system
|
|
5
|
+
* prompt (and stripped from provider tool schemas) for a given model and
|
|
6
|
+
* setting.
|
|
7
|
+
*
|
|
8
|
+
* `auto` enforces a per-model policy: inline for Gemini models, off otherwise.
|
|
9
|
+
* Gemini benefits from descriptors in-prompt; other providers keep them in the
|
|
10
|
+
* tool schemas. `on`/`off` are explicit user overrides.
|
|
11
|
+
*
|
|
12
|
+
* @param modelId Canonical model id (e.g. `gemini-3-pro`); resolve aliases via
|
|
13
|
+
* `ModelRegistry.getCanonicalId` before calling so `auto` classifies correctly.
|
|
14
|
+
*/
|
|
15
|
+
export function shouldInlineToolDescriptors(
|
|
16
|
+
setting: "auto" | "on" | "off" | undefined,
|
|
17
|
+
modelId: string | undefined,
|
|
18
|
+
): boolean {
|
|
19
|
+
switch (setting ?? "auto") {
|
|
20
|
+
case "on":
|
|
21
|
+
return true;
|
|
22
|
+
case "off":
|
|
23
|
+
return false;
|
|
24
|
+
default:
|
|
25
|
+
return modelId !== undefined && modelFamilyToken(modelId) === "gemini";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -6,14 +6,19 @@
|
|
|
6
6
|
* discovery lives in pi-catalog's provider-models.
|
|
7
7
|
*/
|
|
8
8
|
import { type ApiKey, type FetchImpl, withAuth } from "@oh-my-pi/pi-ai";
|
|
9
|
-
import type { Api, Model } from "@oh-my-pi/pi-ai/types";
|
|
9
|
+
import type { Api, Model, RemoteCompactionConfig } from "@oh-my-pi/pi-ai/types";
|
|
10
10
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
|
11
11
|
import {
|
|
12
12
|
getBundledModelReferenceIndex,
|
|
13
13
|
resolveModelReference,
|
|
14
14
|
stripBracketedModelIdAffixes,
|
|
15
15
|
} from "@oh-my-pi/pi-catalog/identity";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
fetchLiteLLMRichModels,
|
|
18
|
+
fetchLmStudioNativeModelMetadata,
|
|
19
|
+
OPENAI_COMPAT_DISCOVERY_DEFAULT_CONTEXT_WINDOW,
|
|
20
|
+
OPENAI_COMPAT_DISCOVERY_DEFAULT_MAX_TOKENS,
|
|
21
|
+
} from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
|
|
17
22
|
import type { ModelSpec } from "@oh-my-pi/pi-catalog/types";
|
|
18
23
|
import { isRecord } from "@oh-my-pi/pi-utils";
|
|
19
24
|
import type { ProviderDiscovery } from "./models-config-schema";
|
|
@@ -27,7 +32,8 @@ import type { ProviderDiscovery } from "./models-config-schema";
|
|
|
27
32
|
// mid-stream when models hit the cap on legitimate large tool calls (see
|
|
28
33
|
// issue #1528: `write` payloads >~5KB on deepseek-v4-pro surfaced as
|
|
29
34
|
// "socket connection was closed unexpectedly").
|
|
30
|
-
export const
|
|
35
|
+
export const DISCOVERY_DEFAULT_CONTEXT_WINDOW = OPENAI_COMPAT_DISCOVERY_DEFAULT_CONTEXT_WINDOW;
|
|
36
|
+
export const DISCOVERY_DEFAULT_MAX_TOKENS = OPENAI_COMPAT_DISCOVERY_DEFAULT_MAX_TOKENS;
|
|
31
37
|
|
|
32
38
|
const DEFAULT_OLLAMA_BASE_URL = "http://127.0.0.1:11434";
|
|
33
39
|
const OLLAMA_HOST_DEFAULT_PORT = "11434";
|
|
@@ -89,6 +95,7 @@ export interface DiscoveryProviderConfig {
|
|
|
89
95
|
baseUrl?: string;
|
|
90
96
|
headers?: Record<string, string>;
|
|
91
97
|
compat?: ModelSpec<Api>["compat"];
|
|
98
|
+
remoteCompaction?: RemoteCompactionConfig<Api>;
|
|
92
99
|
discovery: ProviderDiscovery;
|
|
93
100
|
optional?: boolean;
|
|
94
101
|
}
|
|
@@ -209,6 +216,8 @@ export function discoverModelsByProviderType(
|
|
|
209
216
|
return discoverOpenAIModelsList(providerConfig, ctx);
|
|
210
217
|
case "proxy":
|
|
211
218
|
return discoverProxyModels(providerConfig, ctx);
|
|
219
|
+
case "litellm":
|
|
220
|
+
return discoverLiteLLMModels(providerConfig, ctx);
|
|
212
221
|
}
|
|
213
222
|
}
|
|
214
223
|
|
|
@@ -302,7 +311,7 @@ export async function discoverOllamaModels(
|
|
|
302
311
|
input: metadata?.input ?? ["text"],
|
|
303
312
|
imageInputDecoder: "stb",
|
|
304
313
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
305
|
-
contextWindow: metadata?.contextWindow ??
|
|
314
|
+
contextWindow: metadata?.contextWindow ?? DISCOVERY_DEFAULT_CONTEXT_WINDOW,
|
|
306
315
|
maxTokens: Math.min(metadata?.contextWindow ?? Number.POSITIVE_INFINITY, DISCOVERY_DEFAULT_MAX_TOKENS),
|
|
307
316
|
headers: providerConfig.headers,
|
|
308
317
|
} as ModelSpec<Api>);
|
|
@@ -369,7 +378,7 @@ export async function discoverLlamaCppModels(
|
|
|
369
378
|
for (const item of models) {
|
|
370
379
|
const { id } = item;
|
|
371
380
|
if (!id) continue;
|
|
372
|
-
const contextWindow = item.contextWindow ?? serverMetadata?.contextWindow ??
|
|
381
|
+
const contextWindow = item.contextWindow ?? serverMetadata?.contextWindow ?? DISCOVERY_DEFAULT_CONTEXT_WINDOW;
|
|
373
382
|
discovered.push(
|
|
374
383
|
buildModel({
|
|
375
384
|
id,
|
|
@@ -467,7 +476,7 @@ export async function discoverOpenAIModelsList(
|
|
|
467
476
|
toPositiveNumberOrUndefined(item.max_model_len) ??
|
|
468
477
|
toPositiveNumberOrUndefined(item.context_length) ??
|
|
469
478
|
nativeMetadataForModel?.contextWindow ??
|
|
470
|
-
|
|
479
|
+
DISCOVERY_DEFAULT_CONTEXT_WINDOW;
|
|
471
480
|
discovered.push(
|
|
472
481
|
buildModel({
|
|
473
482
|
id,
|
|
@@ -493,6 +502,59 @@ export async function discoverOpenAIModelsList(
|
|
|
493
502
|
return discovered;
|
|
494
503
|
}
|
|
495
504
|
|
|
505
|
+
export async function discoverLiteLLMModels(
|
|
506
|
+
providerConfig: DiscoveryProviderConfig,
|
|
507
|
+
ctx: DiscoveryContext,
|
|
508
|
+
): Promise<Model<Api>[]> {
|
|
509
|
+
const baseUrl = normalizeLiteLLMDiscoveryBaseUrl(providerConfig.baseUrl);
|
|
510
|
+
const references = getBundledModelReferenceIndex();
|
|
511
|
+
const resolveReference = (id: string) => resolveModelReference(id, references) as ModelSpec<Api> | undefined;
|
|
512
|
+
const baseHeaders: Record<string, string> = { ...(providerConfig.headers ?? {}) };
|
|
513
|
+
let headers = baseHeaders;
|
|
514
|
+
const attempt = async (h: Record<string, string>) => {
|
|
515
|
+
headers = h;
|
|
516
|
+
let authError: (Error & { status: number }) | undefined;
|
|
517
|
+
const authAwareFetch: FetchImpl = async (input, init) => {
|
|
518
|
+
const response = await ctx.fetch(input, init);
|
|
519
|
+
if (response.status === 401) {
|
|
520
|
+
authError = new Error(`HTTP ${response.status} from ${String(input)}`) as Error & { status: number };
|
|
521
|
+
authError.status = response.status;
|
|
522
|
+
}
|
|
523
|
+
return response;
|
|
524
|
+
};
|
|
525
|
+
const models = await fetchLiteLLMRichModels({
|
|
526
|
+
api: providerConfig.api,
|
|
527
|
+
provider: providerConfig.provider,
|
|
528
|
+
baseUrl,
|
|
529
|
+
headers: h,
|
|
530
|
+
fetch: authAwareFetch,
|
|
531
|
+
referenceResolver: resolveReference,
|
|
532
|
+
signal: AbortSignal.timeout(10_000),
|
|
533
|
+
});
|
|
534
|
+
if (authError && models === null) {
|
|
535
|
+
throw authError;
|
|
536
|
+
}
|
|
537
|
+
return models;
|
|
538
|
+
};
|
|
539
|
+
const apiKey = await ctx.getBearerApiKeyResolver(providerConfig.provider);
|
|
540
|
+
let richModels: ModelSpec<Api>[] | null;
|
|
541
|
+
try {
|
|
542
|
+
richModels = apiKey
|
|
543
|
+
? await withAuth(apiKey, key => attempt({ ...baseHeaders, Authorization: `Bearer ${key}` }))
|
|
544
|
+
: await attempt(baseHeaders);
|
|
545
|
+
} catch (error) {
|
|
546
|
+
const status = typeof error === "object" && error !== null && "status" in error ? error.status : undefined;
|
|
547
|
+
if (status !== 401) {
|
|
548
|
+
throw error;
|
|
549
|
+
}
|
|
550
|
+
richModels = null;
|
|
551
|
+
}
|
|
552
|
+
if (!richModels || richModels.length === 0) {
|
|
553
|
+
return discoverOpenAIModelsList({ ...providerConfig, baseUrl }, ctx);
|
|
554
|
+
}
|
|
555
|
+
return richModels.map(spec => buildModel({ ...spec, headers }));
|
|
556
|
+
}
|
|
557
|
+
|
|
496
558
|
/**
|
|
497
559
|
* Discover models from an Anthropic+OpenAI-compatible reseller proxy that
|
|
498
560
|
* exposes both `/v1/messages` and `/v1/chat/completions`, advertising each
|
|
@@ -571,7 +633,10 @@ export async function discoverProxyModels(
|
|
|
571
633
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
572
634
|
// Prefer the context_length the API reports for this model; fall
|
|
573
635
|
// back to the bundled reference, then a sane default.
|
|
574
|
-
contextWindow:
|
|
636
|
+
contextWindow:
|
|
637
|
+
toPositiveNumberOrUndefined(item.context_length) ??
|
|
638
|
+
reference?.contextWindow ??
|
|
639
|
+
DISCOVERY_DEFAULT_CONTEXT_WINDOW,
|
|
575
640
|
maxTokens: reference?.maxTokens ?? discoveryDefaultMaxTokens(api),
|
|
576
641
|
headers,
|
|
577
642
|
// OpenAI-compat fields are no-ops on anthropic models; the
|
|
@@ -616,7 +681,11 @@ function toLlamaCppNativeBaseUrl(baseUrl: string): string {
|
|
|
616
681
|
}
|
|
617
682
|
}
|
|
618
683
|
|
|
619
|
-
function
|
|
684
|
+
export function normalizeLiteLLMDiscoveryBaseUrl(baseUrl?: string): string {
|
|
685
|
+
return normalizeOpenAIModelsListBaseUrl(baseUrl ?? "http://localhost:4000/v1");
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
export function normalizeOpenAIModelsListBaseUrl(baseUrl?: string): string {
|
|
620
689
|
const defaultBaseUrl = "http://127.0.0.1:1234/v1";
|
|
621
690
|
const raw = baseUrl || defaultBaseUrl;
|
|
622
691
|
try {
|