my-pi 0.1.90 → 0.1.92
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/README.md +5 -0
- package/dist/api.d.ts +12 -0
- package/dist/api.js +1 -1
- package/dist/{builtin-registry-CYdEeqrp.js → builtin-registry-B6QcMbgI.js} +15 -2
- package/dist/builtin-registry-B6QcMbgI.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{session-name-arDf91uJ.js → session-name-Bv0hXAnV.js} +2 -2
- package/dist/session-name-Bv0hXAnV.js.map +1 -0
- package/dist/umans-provider-CHiuQuuc.js +244 -0
- package/dist/umans-provider-CHiuQuuc.js.map +1 -0
- package/package.json +11 -11
- package/dist/builtin-registry-CYdEeqrp.js.map +0 -1
- package/dist/session-name-arDf91uJ.js.map +0 -1
package/README.md
CHANGED
|
@@ -115,6 +115,11 @@ pnpx my-pi@latest observability
|
|
|
115
115
|
Pi handles model authentication natively. For provider-specific model
|
|
116
116
|
examples, see the Pi docs and the relevant extension/package README.
|
|
117
117
|
|
|
118
|
+
Umans.ai is available as a built-in provider. Run `/login`, choose API
|
|
119
|
+
key auth, then choose Umans; select models like `umans/umans-coder` or
|
|
120
|
+
`umans/umans-flash`. The provider can also read `UMANS_API_KEY` and
|
|
121
|
+
can be disabled with `--no-umans-provider`.
|
|
122
|
+
|
|
118
123
|
OpenRouter Fusion is configured by default: `my-pi` injects a
|
|
119
124
|
non-Anthropic Fusion panel/judge only for `openrouter/fusion`.
|
|
120
125
|
Configure it in `~/.pi/agent/my-pi-settings.json` under
|
package/dist/api.d.ts
CHANGED
|
@@ -51,6 +51,18 @@ declare const BUILTIN_EXTENSION_REGISTRY: readonly [{
|
|
|
51
51
|
readonly cli_description: "Disable OpenRouter Fusion non-Anthropic config";
|
|
52
52
|
readonly aliases: readonly ["openrouter-fusion-config", "fusion-budget"];
|
|
53
53
|
readonly load: () => Promise<ExtensionFactory$1>;
|
|
54
|
+
}, {
|
|
55
|
+
readonly key: "umans-provider";
|
|
56
|
+
readonly label: "Umans provider";
|
|
57
|
+
readonly docs_label: "Umans provider";
|
|
58
|
+
readonly description: "Umans.ai Anthropic Messages provider with API key login support";
|
|
59
|
+
readonly default_enabled: true;
|
|
60
|
+
readonly option_name: "umans_provider";
|
|
61
|
+
readonly cli_arg: "no-umans-provider";
|
|
62
|
+
readonly cli_flag: "--no-umans-provider";
|
|
63
|
+
readonly cli_description: "Disable built-in Umans provider";
|
|
64
|
+
readonly aliases: readonly ["umans-provider", "umans"];
|
|
65
|
+
readonly load: () => Promise<ExtensionFactory$1>;
|
|
54
66
|
}, {
|
|
55
67
|
readonly key: "footer";
|
|
56
68
|
readonly label: "Footer";
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as BUILTIN_EXTENSION_REGISTRY, t as BUILTIN_EXTENSIONS } from "./builtin-registry-
|
|
1
|
+
import { n as BUILTIN_EXTENSION_REGISTRY, t as BUILTIN_EXTENSIONS } from "./builtin-registry-B6QcMbgI.js";
|
|
2
2
|
import { n as save_settings, t as load_settings } from "./settings-CTk0ws43.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { existsSync, readdirSync } from "node:fs";
|
|
@@ -45,6 +45,19 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
45
45
|
aliases: ["openrouter-fusion-config", "fusion-budget"],
|
|
46
46
|
load: async () => (await import("./openrouter-fusion-config-D92_sO0Y.js")).default
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
key: "umans-provider",
|
|
50
|
+
label: "Umans provider",
|
|
51
|
+
docs_label: "Umans provider",
|
|
52
|
+
description: "Umans.ai Anthropic Messages provider with API key login support",
|
|
53
|
+
default_enabled: true,
|
|
54
|
+
option_name: "umans_provider",
|
|
55
|
+
cli_arg: "no-umans-provider",
|
|
56
|
+
cli_flag: "--no-umans-provider",
|
|
57
|
+
cli_description: "Disable built-in Umans provider",
|
|
58
|
+
aliases: ["umans-provider", "umans"],
|
|
59
|
+
load: async () => (await import("./umans-provider-CHiuQuuc.js")).default
|
|
60
|
+
},
|
|
48
61
|
{
|
|
49
62
|
key: "footer",
|
|
50
63
|
label: "Footer",
|
|
@@ -317,7 +330,7 @@ const BUILTIN_EXTENSION_REGISTRY = [
|
|
|
317
330
|
],
|
|
318
331
|
reason: "UI-only session naming is only useful in interactive mode"
|
|
319
332
|
},
|
|
320
|
-
load: async () => (await import("./session-name-
|
|
333
|
+
load: async () => (await import("./session-name-Bv0hXAnV.js")).default
|
|
321
334
|
},
|
|
322
335
|
{
|
|
323
336
|
key: "confirm-destructive",
|
|
@@ -414,4 +427,4 @@ const BUILTIN_EXTENSIONS = BUILTIN_EXTENSION_REGISTRY.map(({ load: _load, ...ext
|
|
|
414
427
|
//#endregion
|
|
415
428
|
export { BUILTIN_EXTENSION_REGISTRY as n, BUILTIN_EXTENSIONS as t };
|
|
416
429
|
|
|
417
|
-
//# sourceMappingURL=builtin-registry-
|
|
430
|
+
//# sourceMappingURL=builtin-registry-B6QcMbgI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-registry-B6QcMbgI.js","names":[],"sources":["../src/extensions/builtin-registry.ts"],"sourcesContent":["import type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\n\nexport type BuiltinExtensionRuntimeMode =\n\t| 'interactive'\n\t| 'print'\n\t| 'json'\n\t| 'rpc';\n\ntype BuiltinExtensionLoader = () => Promise<ExtensionFactory>;\n\nexport interface BuiltinExtensionManifestEntry {\n\tkey: string;\n\tlabel: string;\n\tdocs_label: string;\n\tdescription: string;\n\tdefault_enabled: boolean;\n\toption_name: string;\n\tcli_arg: string;\n\tcli_flag: `--${string}`;\n\tcli_description: string;\n\taliases: readonly string[];\n\tmode_constraints?: {\n\t\tdisabled_in: readonly BuiltinExtensionRuntimeMode[];\n\t\treason: string;\n\t};\n\texternal_package_name?: string;\n\tload: BuiltinExtensionLoader;\n}\n\nexport const BUILTIN_EXTENSION_REGISTRY = [\n\t{\n\t\tkey: 'context-sidecar',\n\t\tlabel: 'Context sidecar',\n\t\tdocs_label: 'SQLite context sidecar',\n\t\tdescription: 'Local SQLite FTS sidecar for oversized tool output',\n\t\tdefault_enabled: true,\n\t\toption_name: 'context_sidecar',\n\t\tcli_arg: 'no-context-sidecar',\n\t\tcli_flag: '--no-context-sidecar',\n\t\tcli_description:\n\t\t\t'Disable SQLite context sidecar for large tool output',\n\t\taliases: ['context-sidecar', 'context', 'sidecar'],\n\t\texternal_package_name: '@spences10/pi-context',\n\t\tload: async () => (await import('@spences10/pi-context')).default,\n\t},\n\t{\n\t\tkey: 'mcp',\n\t\tlabel: 'MCP',\n\t\tdocs_label: 'MCP',\n\t\tdescription: 'MCP server integration and /mcp command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'mcp',\n\t\tcli_arg: 'no-mcp',\n\t\tcli_flag: '--no-mcp',\n\t\tcli_description: 'Disable built-in MCP extension',\n\t\taliases: ['mcp'],\n\t\texternal_package_name: '@spences10/pi-mcp',\n\t\tload: async () => (await import('@spences10/pi-mcp')).default,\n\t},\n\t{\n\t\tkey: 'openrouter-fusion-config',\n\t\tlabel: 'OpenRouter Fusion config',\n\t\tdocs_label: 'OpenRouter Fusion config guard',\n\t\tdescription:\n\t\t\t'Keeps OpenRouter Fusion off Anthropic by injecting a non-Anthropic panel and judge',\n\t\tdefault_enabled: true,\n\t\toption_name: 'openrouter_fusion_config',\n\t\tcli_arg: 'no-openrouter-fusion-config',\n\t\tcli_flag: '--no-openrouter-fusion-config',\n\t\tcli_description: 'Disable OpenRouter Fusion non-Anthropic config',\n\t\taliases: ['openrouter-fusion-config', 'fusion-budget'],\n\t\tload: async () =>\n\t\t\t(await import('./openrouter-fusion-config/index.js')).default,\n\t},\n\t{\n\t\tkey: 'umans-provider',\n\t\tlabel: 'Umans provider',\n\t\tdocs_label: 'Umans provider',\n\t\tdescription:\n\t\t\t'Umans.ai Anthropic Messages provider with API key login support',\n\t\tdefault_enabled: true,\n\t\toption_name: 'umans_provider',\n\t\tcli_arg: 'no-umans-provider',\n\t\tcli_flag: '--no-umans-provider',\n\t\tcli_description: 'Disable built-in Umans provider',\n\t\taliases: ['umans-provider', 'umans'],\n\t\tload: async () =>\n\t\t\t(await import('./umans-provider/index.js')).default,\n\t},\n\t{\n\t\tkey: 'footer',\n\t\tlabel: 'Footer',\n\t\tdocs_label: 'Footer',\n\t\tdescription: 'Configurable interactive footer/statusline',\n\t\tdefault_enabled: true,\n\t\toption_name: 'footer',\n\t\tcli_arg: 'no-footer',\n\t\tcli_flag: '--no-footer',\n\t\tcli_description: 'Disable custom footer/statusline',\n\t\taliases: ['footer', 'statusline', 'status-line'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Footer only renders in the interactive TUI',\n\t\t},\n\t\tload: async () => (await import('./footer/index.js')).default,\n\t},\n\t{\n\t\tkey: 'skills',\n\t\tlabel: 'Skills',\n\t\tdocs_label: 'Skills',\n\t\tdescription: 'Managed pi-native skills and /skills command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'skills',\n\t\tcli_arg: 'no-skills',\n\t\tcli_flag: '--no-skills',\n\t\tcli_description: 'Disable built-in skills extension',\n\t\taliases: ['skills', 'skill'],\n\t\texternal_package_name: '@spences10/pi-skills',\n\t\tload: async () => (await import('@spences10/pi-skills')).default,\n\t},\n\t{\n\t\tkey: 'skill-importer',\n\t\tlabel: 'Skill importer',\n\t\tdocs_label: 'Skill importer',\n\t\tdescription:\n\t\t\t'Import external Claude/plugin skills into Pi-native storage',\n\t\tdefault_enabled: true,\n\t\toption_name: 'skill_importer',\n\t\tcli_arg: 'no-skill-importer',\n\t\tcli_flag: '--no-skill-importer',\n\t\tcli_description: 'Disable external skill importer extension',\n\t\taliases: ['skill-importer', 'import-skills', 'skill-import'],\n\t\texternal_package_name: '@spences10/pi-skill-importer',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-skill-importer')).default,\n\t},\n\t{\n\t\tkey: 'filter-output',\n\t\tlabel: 'Secret redaction',\n\t\tdocs_label: 'Secret redaction',\n\t\tdescription:\n\t\t\t'Redacts secrets from tool output before the model sees them',\n\t\tdefault_enabled: true,\n\t\toption_name: 'filter_output',\n\t\tcli_arg: 'no-filter',\n\t\tcli_flag: '--no-filter',\n\t\tcli_description: 'Disable secret redaction in tool output',\n\t\taliases: [\n\t\t\t'filter-output',\n\t\t\t'filter_output',\n\t\t\t'filter',\n\t\t\t'redaction',\n\t\t\t'secret-redaction',\n\t\t\t'output-redaction',\n\t\t],\n\t\texternal_package_name: '@spences10/pi-redact',\n\t\tload: async () => (await import('@spences10/pi-redact')).default,\n\t},\n\t{\n\t\tkey: 'recall',\n\t\tlabel: 'Recall',\n\t\tdocs_label: 'Recall',\n\t\tdescription: 'pirecall reminder and background session sync',\n\t\tdefault_enabled: true,\n\t\toption_name: 'recall',\n\t\tcli_arg: 'no-recall',\n\t\tcli_flag: '--no-recall',\n\t\tcli_description: 'Disable recall extension',\n\t\taliases: ['recall', 'pirecall'],\n\t\texternal_package_name: '@spences10/pi-recall',\n\t\tload: async () => (await import('@spences10/pi-recall')).default,\n\t},\n\t{\n\t\tkey: 'nopeek',\n\t\tlabel: 'Nopeek',\n\t\tdocs_label: 'Nopeek',\n\t\tdescription:\n\t\t\t'nopeek reminder for secret-safe environment loading',\n\t\tdefault_enabled: true,\n\t\toption_name: 'nopeek',\n\t\tcli_arg: 'no-nopeek',\n\t\tcli_flag: '--no-nopeek',\n\t\tcli_description: 'Disable nopeek reminder extension',\n\t\taliases: ['nopeek', 'secrets', 'secret-loading'],\n\t\texternal_package_name: '@spences10/pi-nopeek',\n\t\tload: async () => (await import('@spences10/pi-nopeek')).default,\n\t},\n\t{\n\t\tkey: 'observability',\n\t\tlabel: 'Observability',\n\t\tdocs_label: 'Live observability',\n\t\tdescription:\n\t\t\t'Optional live event stream and local browser dashboard',\n\t\tdefault_enabled: true,\n\t\toption_name: 'observability',\n\t\tcli_arg: 'no-observability',\n\t\tcli_flag: '--no-observability',\n\t\tcli_description: 'Disable live observability extension',\n\t\taliases: ['observability', 'obs', 'live-events'],\n\t\texternal_package_name: '@spences10/pi-observability',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-observability')).default,\n\t},\n\t{\n\t\tkey: 'omnisearch',\n\t\tlabel: 'Omnisearch',\n\t\tdocs_label: 'Omnisearch',\n\t\tdescription: 'mcp-omnisearch reminder for verified web research',\n\t\tdefault_enabled: true,\n\t\toption_name: 'omnisearch',\n\t\tcli_arg: 'no-omnisearch',\n\t\tcli_flag: '--no-omnisearch',\n\t\tcli_description: 'Disable mcp-omnisearch reminder extension',\n\t\taliases: ['omnisearch', 'search', 'web-search', 'research'],\n\t\texternal_package_name: '@spences10/pi-omnisearch',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-omnisearch')).default,\n\t},\n\t{\n\t\tkey: 'sqlite-tools',\n\t\tlabel: 'SQLite tools',\n\t\tdocs_label: 'SQLite tools',\n\t\tdescription:\n\t\t\t'mcp-sqlite-tools reminder for safer SQLite database work',\n\t\tdefault_enabled: true,\n\t\toption_name: 'sqlite_tools',\n\t\tcli_arg: 'no-sqlite-tools',\n\t\tcli_flag: '--no-sqlite-tools',\n\t\tcli_description: 'Disable mcp-sqlite-tools reminder extension',\n\t\taliases: ['sqlite-tools', 'sqlite', 'mcp-sqlite-tools'],\n\t\texternal_package_name: '@spences10/pi-sqlite-tools',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-sqlite-tools')).default,\n\t},\n\t{\n\t\tkey: 'startup-screen',\n\t\tlabel: 'Startup screen',\n\t\tdocs_label: 'Startup screen',\n\t\tdescription:\n\t\t\t'Pixel-art gradient startup header for interactive sessions',\n\t\tdefault_enabled: true,\n\t\toption_name: 'startup_screen',\n\t\tcli_arg: 'no-startup-screen',\n\t\tcli_flag: '--no-startup-screen',\n\t\tcli_description: 'Disable the custom startup screen',\n\t\taliases: ['startup-screen', 'startup', 'header', 'splash'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Startup screen only renders in the interactive TUI',\n\t\t},\n\t\tload: async () =>\n\t\t\t(await import('./startup-screen/index.js')).default,\n\t},\n\t{\n\t\tkey: 'prompt-presets',\n\t\tlabel: 'Prompt presets',\n\t\tdocs_label: 'Prompt presets',\n\t\tdescription:\n\t\t\t'Runtime prompt preset selection and /prompt-preset command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'prompt_presets',\n\t\tcli_arg: 'no-prompt-presets',\n\t\tcli_flag: '--no-prompt-presets',\n\t\tcli_description: 'Disable prompt presets extension',\n\t\taliases: ['prompt-preset', 'preset', 'presets'],\n\t\tload: async () =>\n\t\t\t(await import('./prompt-presets/index.js')).default,\n\t},\n\t{\n\t\tkey: 'git-ui',\n\t\tlabel: 'Git UI',\n\t\tdocs_label: 'Git staging UI',\n\t\tdescription: 'Interactive source control staging panel',\n\t\tdefault_enabled: true,\n\t\toption_name: 'git_ui',\n\t\tcli_arg: 'no-git-ui',\n\t\tcli_flag: '--no-git-ui',\n\t\tcli_description: 'Disable built-in Git staging UI',\n\t\taliases: ['git-ui', 'git', 'source-control', 'scm'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Git UI is only useful in interactive mode',\n\t\t},\n\t\texternal_package_name: '@spences10/pi-git-ui',\n\t\tload: async () => (await import('@spences10/pi-git-ui')).default,\n\t},\n\t{\n\t\tkey: 'lsp',\n\t\tlabel: 'LSP',\n\t\tdocs_label: 'LSP',\n\t\tdescription:\n\t\t\t'Language Server Protocol tools (diagnostics, hover, definition, references)',\n\t\tdefault_enabled: true,\n\t\toption_name: 'lsp',\n\t\tcli_arg: 'no-lsp',\n\t\tcli_flag: '--no-lsp',\n\t\tcli_description: 'Disable LSP extension',\n\t\taliases: ['lsp', 'language-server'],\n\t\texternal_package_name: '@spences10/pi-lsp',\n\t\tload: async () => (await import('@spences10/pi-lsp')).default,\n\t},\n\t{\n\t\tkey: 'session-name',\n\t\tlabel: 'Session name',\n\t\tdocs_label: 'Session auto-naming',\n\t\tdescription:\n\t\t\t'AI-powered session auto-naming and /session-name command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'session_name',\n\t\tcli_arg: 'no-session-name',\n\t\tcli_flag: '--no-session-name',\n\t\tcli_description: 'Disable session name extension',\n\t\taliases: ['session-name', 'session', 'auto-name'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason:\n\t\t\t\t'UI-only session naming is only useful in interactive mode',\n\t\t},\n\t\tload: async () =>\n\t\t\t(await import('./session-name/index.js')).default,\n\t},\n\t{\n\t\tkey: 'confirm-destructive',\n\t\tlabel: 'Confirm destructive',\n\t\tdocs_label: 'Destructive action confirmation',\n\t\tdescription:\n\t\t\t'Prompt before destructive tool calls like file deletes, overwrites, and hard resets',\n\t\tdefault_enabled: true,\n\t\toption_name: 'confirm_destructive',\n\t\tcli_arg: 'no-confirm-destructive',\n\t\tcli_flag: '--no-confirm-destructive',\n\t\tcli_description: 'Disable destructive action confirmations',\n\t\taliases: ['confirm-destructive', 'confirm'],\n\t\texternal_package_name: '@spences10/pi-confirm-destructive',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-confirm-destructive')).default,\n\t},\n\t{\n\t\tkey: 'hooks-resolution',\n\t\tlabel: 'Hooks resolution',\n\t\tdocs_label: 'Hooks resolution',\n\t\tdescription:\n\t\t\t'Claude Code style PreToolUse and PostToolUse hook compatibility from .claude, .rulesync, and .pi configs',\n\t\tdefault_enabled: true,\n\t\toption_name: 'hooks_resolution',\n\t\tcli_arg: 'no-hooks',\n\t\tcli_flag: '--no-hooks',\n\t\tcli_description: 'Disable Claude-style hook execution',\n\t\taliases: ['hooks-resolution', 'hooks'],\n\t\tload: async () =>\n\t\t\t(await import('./hooks-resolution/index.js')).default,\n\t},\n\t{\n\t\tkey: 'svelte-guardrails',\n\t\tlabel: 'Svelte guardrails',\n\t\tdocs_label: 'Svelte guardrails',\n\t\tdescription:\n\t\t\t'Blocks discouraged Svelte patterns like $effect before agents write them',\n\t\tdefault_enabled: true,\n\t\toption_name: 'svelte_guardrails',\n\t\tcli_arg: 'no-svelte-guardrails',\n\t\tcli_flag: '--no-svelte-guardrails',\n\t\tcli_description: 'Disable Svelte guardrails',\n\t\taliases: ['svelte-guardrails', 'svelte'],\n\t\texternal_package_name: '@spences10/pi-svelte-guardrails',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-svelte-guardrails')).default,\n\t},\n\t{\n\t\tkey: 'coding-preferences',\n\t\tlabel: 'Coding preferences',\n\t\tdocs_label: 'Coding preferences',\n\t\tdescription:\n\t\t\t'Blocks configured coding workflow anti-patterns from JSON preferences',\n\t\tdefault_enabled: true,\n\t\toption_name: 'coding_preferences',\n\t\tcli_arg: 'no-coding-preferences',\n\t\tcli_flag: '--no-coding-preferences',\n\t\tcli_description: 'Disable coding preferences guardrails',\n\t\taliases: ['coding-preferences', 'preferences', 'prefs'],\n\t\texternal_package_name: '@spences10/pi-coding-preferences',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-coding-preferences')).default,\n\t},\n\t{\n\t\tkey: 'handoff',\n\t\tlabel: 'Handoff',\n\t\tdocs_label: 'Handoff',\n\t\tdescription:\n\t\t\t'Help command for Pi continuation primitives like /fork, /tree, /export, /import, and /share',\n\t\tdefault_enabled: true,\n\t\toption_name: 'handoff',\n\t\tcli_arg: 'no-handoff',\n\t\tcli_flag: '--no-handoff',\n\t\tcli_description: 'Disable handoff helper command',\n\t\taliases: ['handoff', 'continuation'],\n\t\tload: async () => (await import('./handoff/index.js')).default,\n\t},\n\t{\n\t\tkey: 'team-mode',\n\t\tlabel: 'Team mode',\n\t\tdocs_label: 'Team mode',\n\t\tdescription:\n\t\t\t'Experimental orchestrator/team mode with RPC teammates, tasks, and mailboxes',\n\t\tdefault_enabled: true,\n\t\toption_name: 'team_mode',\n\t\tcli_arg: 'no-team-mode',\n\t\tcli_flag: '--no-team-mode',\n\t\tcli_description: 'Disable experimental team mode extension',\n\t\taliases: ['team-mode', 'team', 'teammates'],\n\t\texternal_package_name: '@spences10/pi-team-mode',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-team-mode')).default,\n\t},\n] as const satisfies readonly BuiltinExtensionManifestEntry[];\n\nexport type BuiltinExtensionKey =\n\t(typeof BUILTIN_EXTENSION_REGISTRY)[number]['key'];\n\nexport type BuiltinExtensionOptionName =\n\t(typeof BUILTIN_EXTENSION_REGISTRY)[number]['option_name'];\n\nexport type BuiltinExtensionInfo = Omit<\n\tBuiltinExtensionManifestEntry,\n\t'load'\n> & {\n\tkey: BuiltinExtensionKey;\n\toption_name: BuiltinExtensionOptionName;\n};\n\nexport const BUILTIN_EXTENSIONS: BuiltinExtensionInfo[] =\n\tBUILTIN_EXTENSION_REGISTRY.map(\n\t\t({ load: _load, ...extension }) => extension,\n\t);\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as BUILTIN_EXTENSIONS } from "./builtin-registry-
|
|
2
|
+
import { t as BUILTIN_EXTENSIONS } from "./builtin-registry-B6QcMbgI.js";
|
|
3
3
|
import { defineCommand, renderUsage, runMain } from "citty";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BorderedLoader, convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { complete } from "@earendil-works/pi-ai";
|
|
2
|
+
import { complete } from "@earendil-works/pi-ai/compat";
|
|
3
3
|
//#region src/extensions/session-name/index.ts
|
|
4
4
|
const SYSTEM_PROMPT = `You are a session naming assistant. Given a conversation history, generate a short, descriptive session name (2-5 words) that captures the main topic or task.
|
|
5
5
|
|
|
@@ -118,4 +118,4 @@ async function session_name(pi) {
|
|
|
118
118
|
//#endregion
|
|
119
119
|
export { session_name as default };
|
|
120
120
|
|
|
121
|
-
//# sourceMappingURL=session-name-
|
|
121
|
+
//# sourceMappingURL=session-name-Bv0hXAnV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-name-Bv0hXAnV.js","names":[],"sources":["../src/extensions/session-name/index.ts"],"sourcesContent":["// Session name — AI-powered session naming\n// Adapted from Thomas Lopes' pi dotfiles\n\nimport { complete, type Message } from '@earendil-works/pi-ai/compat';\nimport type {\n\tExtensionAPI,\n\tSessionEntry,\n} from '@earendil-works/pi-coding-agent';\nimport {\n\tBorderedLoader,\n\tconvertToLlm,\n\tserializeConversation,\n} from '@earendil-works/pi-coding-agent';\n\nconst SYSTEM_PROMPT = `You are a session naming assistant. Given a conversation history, generate a short, descriptive session name (2-5 words) that captures the main topic or task.\n\nGuidelines:\n- Be concise but specific\n- Use kebab-case only\n- Focus on the core task/question\n- Avoid generic names like \"discussion\" or \"conversation\"\n- No quotes, no punctuation at the end\n\nExamples:\n- \"fix auth bug\" -> \"fix-auth-bug\"\n- \"how do I deploy to vercel\" -> \"vercel-deployment\"\n- \"explain react hooks\" -> \"react-hooks-explanation\"\n- \"optimize database queries\" -> \"db-query-optimization\"\n\nOutput ONLY the session name, nothing else.`;\n\nconst AUTO_NAME_THRESHOLD = 1;\nconst MAX_CHARS = 4000;\nconst MAX_NAME_LEN = 50;\n\nfunction clean_name(value: string): string {\n\treturn value\n\t\t.replace(/^[\"']|[\"']$/g, '')\n\t\t.normalize('NFKD')\n\t\t.replace(/[\\u0300-\\u036f]/g, '')\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.slice(0, MAX_NAME_LEN)\n\t\t.replace(/-+$/g, '');\n}\n\nfunction truncate_conversation(value: string): string {\n\treturn value.length > MAX_CHARS\n\t\t? value.slice(0, MAX_CHARS) + '\\n...'\n\t\t: value;\n}\n\nasync function generate_session_name(\n\tctx: {\n\t\tmodelRegistry: {\n\t\t\tgetApiKeyAndHeaders: (\n\t\t\t\tmodel: NonNullable<\n\t\t\t\t\tParameters<\n\t\t\t\t\t\tParameters<ExtensionAPI['registerCommand']>[1]['handler']\n\t\t\t\t\t>[1]['model']\n\t\t\t\t>,\n\t\t\t) => Promise<any>;\n\t\t};\n\t},\n\tmodel: NonNullable<\n\t\tParameters<\n\t\t\tParameters<ExtensionAPI['registerCommand']>[1]['handler']\n\t\t>[1]['model']\n\t>,\n\tconversation_text: string,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);\n\tif (!auth.ok || !auth.apiKey) {\n\t\tthrow new Error(\n\t\t\tauth.ok ? `No API key for ${model.provider}` : auth.error,\n\t\t);\n\t}\n\n\tconst user_message: Message = {\n\t\trole: 'user',\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: 'text',\n\t\t\t\ttext: `## Conversation History\\n\\n${truncate_conversation(conversation_text)}\\n\\nGenerate a concise session name for this conversation.`,\n\t\t\t},\n\t\t],\n\t\ttimestamp: Date.now(),\n\t};\n\n\tconst response = await complete(\n\t\tmodel,\n\t\t{ systemPrompt: SYSTEM_PROMPT, messages: [user_message] },\n\t\t{ apiKey: auth.apiKey, headers: auth.headers, signal },\n\t);\n\n\tif (response.stopReason === 'aborted') {\n\t\treturn null;\n\t}\n\n\treturn clean_name(\n\t\tresponse.content\n\t\t\t.filter(\n\t\t\t\t(c): c is { type: 'text'; text: string } => c.type === 'text',\n\t\t\t)\n\t\t\t.map((c) => c.text.trim())\n\t\t\t.join(' '),\n\t);\n}\n\nexport default async function session_name(pi: ExtensionAPI) {\n\tlet auto_named_attempted = false;\n\n\tpi.on('agent_end', async (_event, ctx) => {\n\t\tif (!ctx.hasUI || !ctx.model) return;\n\t\tif (pi.getSessionName() || auto_named_attempted) return;\n\n\t\tconst branch = ctx.sessionManager.getBranch();\n\t\tconst user_messages = branch.filter(\n\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\tentry.type === 'message' && entry.message.role === 'user',\n\t\t);\n\t\tif (user_messages.length < AUTO_NAME_THRESHOLD) return;\n\n\t\tauto_named_attempted = true;\n\t\tconst messages = branch\n\t\t\t.filter(\n\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\tentry.type === 'message',\n\t\t\t)\n\t\t\t.map((entry) => entry.message);\n\t\tif (messages.length === 0) return;\n\n\t\tconst conversation_text = serializeConversation(\n\t\t\tconvertToLlm(messages),\n\t\t);\n\n\t\tgenerate_session_name(ctx, ctx.model, conversation_text)\n\t\t\t.then((name) => {\n\t\t\t\tif (!name) return;\n\t\t\t\tpi.setSessionName(name);\n\t\t\t\tctx.ui.notify(`Auto-named: ${name}`, 'info');\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t});\n\t});\n\n\tpi.on('session_start', async () => {\n\t\tauto_named_attempted = false;\n\t});\n\n\tpi.registerCommand('session-name', {\n\t\tdescription:\n\t\t\t'Set, show, or auto-generate the current session name',\n\t\thandler: async (args, ctx) => {\n\t\t\tconst trimmed = args.trim();\n\n\t\t\tif (!trimmed) {\n\t\t\t\tconst current = pi.getSessionName();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tcurrent ? `Session: ${current}` : 'No session name set',\n\t\t\t\t\t'info',\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (trimmed === '--auto' || trimmed === '-a') {\n\t\t\t\tif (!ctx.hasUI || !ctx.model) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t'Auto-naming requires interactive mode and a selected model',\n\t\t\t\t\t\t'error',\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst messages = branch\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\t\t\tentry.type === 'message',\n\t\t\t\t\t)\n\t\t\t\t\t.map((entry) => entry.message);\n\t\t\t\tif (messages.length === 0) {\n\t\t\t\t\tctx.ui.notify('No conversation to analyze', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst conversation_text = serializeConversation(\n\t\t\t\t\tconvertToLlm(messages),\n\t\t\t\t);\n\n\t\t\t\tconst result = await ctx.ui.custom<string | null>(\n\t\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\t\tconst loader = new BorderedLoader(\n\t\t\t\t\t\t\ttui,\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\t'Generating session name...',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tloader.onAbort = () => done(null);\n\n\t\t\t\t\t\tgenerate_session_name(\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\tctx.model!,\n\t\t\t\t\t\t\tconversation_text,\n\t\t\t\t\t\t\tloader.signal,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.then(done)\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t\t\t\t\t\tdone(null);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn loader;\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (result === null) {\n\t\t\t\t\tctx.ui.notify('Auto-naming cancelled', 'info');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result) {\n\t\t\t\t\tctx.ui.notify('Failed to generate name', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tpi.setSessionName(result);\n\t\t\t\tctx.ui.notify(`Session named: ${result}`, 'info');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpi.setSessionName(clean_name(trimmed));\n\t\t\tctx.ui.notify(`Session named: ${clean_name(trimmed)}`, 'info');\n\t\t},\n\t});\n}\n"],"mappings":";;;AAcA,MAAM,gBAAgB;;;;;;;;;;;;;;;;AAiBtB,MAAM,sBAAsB;AAC5B,MAAM,YAAY;AAClB,MAAM,eAAe;AAErB,SAAS,WAAW,OAAuB;CAC1C,OAAO,MACL,QAAQ,gBAAgB,EAAE,CAAC,CAC3B,UAAU,MAAM,CAAC,CACjB,QAAQ,oBAAoB,EAAE,CAAC,CAC/B,YAAY,CAAC,CACb,QAAQ,eAAe,GAAG,CAAC,CAC3B,QAAQ,YAAY,EAAE,CAAC,CACvB,MAAM,GAAG,YAAY,CAAC,CACtB,QAAQ,QAAQ,EAAE;AACrB;AAEA,SAAS,sBAAsB,OAAuB;CACrD,OAAO,MAAM,SAAS,YACnB,MAAM,MAAM,GAAG,SAAS,IAAI,UAC5B;AACJ;AAEA,eAAe,sBACd,KAWA,OAKA,mBACA,QACyB;CACzB,MAAM,OAAO,MAAM,IAAI,cAAc,oBAAoB,KAAK;CAC9D,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,QACrB,MAAM,IAAI,MACT,KAAK,KAAK,kBAAkB,MAAM,aAAa,KAAK,KACrD;CAcD,MAAM,WAAW,MAAM,SACtB,OACA;EAAE,cAAc;EAAe,UAAU,CAAC;GAZ1C,MAAM;GACN,SAAS,CACR;IACC,MAAM;IACN,MAAM,8BAA8B,sBAAsB,iBAAiB,EAAE;GAC9E,CACD;GACA,WAAW,KAAK,IAAI;EAKiC,CAAC;CAAE,GACxD;EAAE,QAAQ,KAAK;EAAQ,SAAS,KAAK;EAAS;CAAO,CACtD;CAEA,IAAI,SAAS,eAAe,WAC3B,OAAO;CAGR,OAAO,WACN,SAAS,QACP,QACC,MAA2C,EAAE,SAAS,MACxD,CAAC,CACA,KAAK,MAAM,EAAE,KAAK,KAAK,CAAC,CAAC,CACzB,KAAK,GAAG,CACX;AACD;AAEA,eAA8B,aAAa,IAAkB;CAC5D,IAAI,uBAAuB;CAE3B,GAAG,GAAG,aAAa,OAAO,QAAQ,QAAQ;EACzC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,OAAO;EAC9B,IAAI,GAAG,eAAe,KAAK,sBAAsB;EAEjD,MAAM,SAAS,IAAI,eAAe,UAAU;EAK5C,IAJsB,OAAO,QAC3B,UACA,MAAM,SAAS,aAAa,MAAM,QAAQ,SAAS,MAErC,CAAC,CAAC,SAAS,qBAAqB;EAEhD,uBAAuB;EACvB,MAAM,WAAW,OACf,QACC,UACA,MAAM,SAAS,SACjB,CAAC,CACA,KAAK,UAAU,MAAM,OAAO;EAC9B,IAAI,SAAS,WAAW,GAAG;EAE3B,MAAM,oBAAoB,sBACzB,aAAa,QAAQ,CACtB;EAEA,sBAAsB,KAAK,IAAI,OAAO,iBAAiB,CAAC,CACtD,MAAM,SAAS;GACf,IAAI,CAAC,MAAM;GACX,GAAG,eAAe,IAAI;GACtB,IAAI,GAAG,OAAO,eAAe,QAAQ,MAAM;EAC5C,CAAC,CAAC,CACD,OAAO,QAAQ;GACf,QAAQ,MAAM,uBAAuB,GAAG;EACzC,CAAC;CACH,CAAC;CAED,GAAG,GAAG,iBAAiB,YAAY;EAClC,uBAAuB;CACxB,CAAC;CAED,GAAG,gBAAgB,gBAAgB;EAClC,aACC;EACD,SAAS,OAAO,MAAM,QAAQ;GAC7B,MAAM,UAAU,KAAK,KAAK;GAE1B,IAAI,CAAC,SAAS;IACb,MAAM,UAAU,GAAG,eAAe;IAClC,IAAI,GAAG,OACN,UAAU,YAAY,YAAY,uBAClC,MACD;IACA;GACD;GAEA,IAAI,YAAY,YAAY,YAAY,MAAM;IAC7C,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,OAAO;KAC7B,IAAI,GAAG,OACN,8DACA,OACD;KACA;IACD;IAGA,MAAM,WADS,IAAI,eAAe,UACZ,CAAC,CACrB,QACC,UACA,MAAM,SAAS,SACjB,CAAC,CACA,KAAK,UAAU,MAAM,OAAO;IAC9B,IAAI,SAAS,WAAW,GAAG;KAC1B,IAAI,GAAG,OAAO,8BAA8B,OAAO;KACnD;IACD;IAEA,MAAM,oBAAoB,sBACzB,aAAa,QAAQ,CACtB;IAEA,MAAM,SAAS,MAAM,IAAI,GAAG,QAC1B,KAAK,OAAO,KAAK,SAAS;KAC1B,MAAM,SAAS,IAAI,eAClB,KACA,OACA,4BACD;KACA,OAAO,gBAAgB,KAAK,IAAI;KAEhC,sBACC,KACA,IAAI,OACJ,mBACA,OAAO,MACR,CAAC,CACC,KAAK,IAAI,CAAC,CACV,OAAO,QAAQ;MACf,QAAQ,MAAM,uBAAuB,GAAG;MACxC,KAAK,IAAI;KACV,CAAC;KAEF,OAAO;IACR,CACD;IAEA,IAAI,WAAW,MAAM;KACpB,IAAI,GAAG,OAAO,yBAAyB,MAAM;KAC7C;IACD;IACA,IAAI,CAAC,QAAQ;KACZ,IAAI,GAAG,OAAO,2BAA2B,OAAO;KAChD;IACD;IAEA,GAAG,eAAe,MAAM;IACxB,IAAI,GAAG,OAAO,kBAAkB,UAAU,MAAM;IAChD;GACD;GAEA,GAAG,eAAe,WAAW,OAAO,CAAC;GACrC,IAAI,GAAG,OAAO,kBAAkB,WAAW,OAAO,KAAK,MAAM;EAC9D;CACD,CAAC;AACF"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
//#region src/extensions/umans-provider/index.ts
|
|
2
|
+
const DEFAULT_BASE_URL = "https://api.code.umans.ai";
|
|
3
|
+
const API_KEY_ENV = "UMANS_API_KEY";
|
|
4
|
+
const USER_AGENT = "my-pi-umans-provider/0.1.0";
|
|
5
|
+
const STATIC_UMANS_CATALOG = {
|
|
6
|
+
"umans-kimi-k2.6": {
|
|
7
|
+
name: "umans-kimi-k2.6",
|
|
8
|
+
display_name: "Umans Kimi K2.6",
|
|
9
|
+
capabilities: {
|
|
10
|
+
max_completion_tokens: 262144,
|
|
11
|
+
recommended_max_tokens: 32768,
|
|
12
|
+
context_window: 262144,
|
|
13
|
+
supports_vision: true,
|
|
14
|
+
supports_tools: true,
|
|
15
|
+
reasoning: {
|
|
16
|
+
supported: true,
|
|
17
|
+
can_disable: true,
|
|
18
|
+
levels: [
|
|
19
|
+
"none",
|
|
20
|
+
"minimal",
|
|
21
|
+
"low",
|
|
22
|
+
"medium",
|
|
23
|
+
"high",
|
|
24
|
+
"xhigh",
|
|
25
|
+
"max"
|
|
26
|
+
],
|
|
27
|
+
default_level: "medium"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"umans-kimi-k2.7": {
|
|
32
|
+
name: "umans-kimi-k2.7",
|
|
33
|
+
display_name: "Umans Kimi K2.7 Code",
|
|
34
|
+
capabilities: {
|
|
35
|
+
max_completion_tokens: 262144,
|
|
36
|
+
recommended_max_tokens: 32768,
|
|
37
|
+
context_window: 262144,
|
|
38
|
+
supports_vision: true,
|
|
39
|
+
supports_tools: true,
|
|
40
|
+
reasoning: {
|
|
41
|
+
supported: true,
|
|
42
|
+
can_disable: false,
|
|
43
|
+
levels: [
|
|
44
|
+
"minimal",
|
|
45
|
+
"low",
|
|
46
|
+
"medium",
|
|
47
|
+
"high",
|
|
48
|
+
"xhigh",
|
|
49
|
+
"max"
|
|
50
|
+
],
|
|
51
|
+
default_level: "medium"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"umans-glm-5.2": {
|
|
56
|
+
name: "umans-glm-5.2",
|
|
57
|
+
display_name: "Umans GLM 5.2",
|
|
58
|
+
capabilities: {
|
|
59
|
+
max_completion_tokens: 131072,
|
|
60
|
+
recommended_max_tokens: 131071,
|
|
61
|
+
context_window: 405504,
|
|
62
|
+
supports_vision: "via-handoff",
|
|
63
|
+
supports_tools: true,
|
|
64
|
+
reasoning: {
|
|
65
|
+
supported: true,
|
|
66
|
+
can_disable: true,
|
|
67
|
+
levels: [
|
|
68
|
+
"none",
|
|
69
|
+
"minimal",
|
|
70
|
+
"low",
|
|
71
|
+
"medium",
|
|
72
|
+
"high",
|
|
73
|
+
"xhigh",
|
|
74
|
+
"max"
|
|
75
|
+
],
|
|
76
|
+
default_level: "medium"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"umans-coder": {
|
|
81
|
+
name: "umans-coder",
|
|
82
|
+
display_name: "Umans Coder",
|
|
83
|
+
capabilities: {
|
|
84
|
+
max_completion_tokens: 262144,
|
|
85
|
+
recommended_max_tokens: 32768,
|
|
86
|
+
context_window: 262144,
|
|
87
|
+
supports_vision: true,
|
|
88
|
+
supports_tools: true,
|
|
89
|
+
reasoning: {
|
|
90
|
+
supported: true,
|
|
91
|
+
can_disable: false,
|
|
92
|
+
levels: [
|
|
93
|
+
"minimal",
|
|
94
|
+
"low",
|
|
95
|
+
"medium",
|
|
96
|
+
"high",
|
|
97
|
+
"xhigh",
|
|
98
|
+
"max"
|
|
99
|
+
],
|
|
100
|
+
default_level: "medium"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"umans-flash": {
|
|
105
|
+
name: "umans-flash",
|
|
106
|
+
display_name: "Umans Flash",
|
|
107
|
+
capabilities: {
|
|
108
|
+
max_completion_tokens: 262144,
|
|
109
|
+
recommended_max_tokens: 32768,
|
|
110
|
+
context_window: 262144,
|
|
111
|
+
supports_vision: true,
|
|
112
|
+
supports_tools: true,
|
|
113
|
+
reasoning: {
|
|
114
|
+
supported: true,
|
|
115
|
+
can_disable: true,
|
|
116
|
+
levels: [
|
|
117
|
+
"none",
|
|
118
|
+
"minimal",
|
|
119
|
+
"low",
|
|
120
|
+
"medium",
|
|
121
|
+
"high",
|
|
122
|
+
"xhigh",
|
|
123
|
+
"max"
|
|
124
|
+
],
|
|
125
|
+
default_level: "medium"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"umans-qwen3.6-35b-a3b": {
|
|
130
|
+
name: "umans-qwen3.6-35b-a3b",
|
|
131
|
+
display_name: "Umans Qwen3.6 35B A3B",
|
|
132
|
+
capabilities: {
|
|
133
|
+
max_completion_tokens: 262144,
|
|
134
|
+
recommended_max_tokens: 32768,
|
|
135
|
+
context_window: 262144,
|
|
136
|
+
supports_vision: true,
|
|
137
|
+
supports_tools: true,
|
|
138
|
+
reasoning: {
|
|
139
|
+
supported: true,
|
|
140
|
+
can_disable: true,
|
|
141
|
+
levels: [
|
|
142
|
+
"none",
|
|
143
|
+
"minimal",
|
|
144
|
+
"low",
|
|
145
|
+
"medium",
|
|
146
|
+
"high",
|
|
147
|
+
"xhigh",
|
|
148
|
+
"max"
|
|
149
|
+
],
|
|
150
|
+
default_level: "medium"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
function safe_max_tokens(recommended, cap) {
|
|
156
|
+
let value = typeof recommended === "number" && recommended > 0 ? recommended : 32768;
|
|
157
|
+
if (typeof cap === "number" && cap > 0) value = Math.min(value, cap - 1);
|
|
158
|
+
return Math.max(value, 1);
|
|
159
|
+
}
|
|
160
|
+
function is_record(value) {
|
|
161
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
162
|
+
}
|
|
163
|
+
function normalize_umans_catalog(value) {
|
|
164
|
+
const source = is_record(value) && is_record(value.data) ? value.data : value;
|
|
165
|
+
if (!is_record(source)) return {};
|
|
166
|
+
const catalog = {};
|
|
167
|
+
for (const [id, info] of Object.entries(source)) {
|
|
168
|
+
if (!is_record(info)) continue;
|
|
169
|
+
const capabilities = is_record(info.capabilities) ? info.capabilities : {};
|
|
170
|
+
catalog[id] = {
|
|
171
|
+
name: typeof info.name === "string" ? info.name : id,
|
|
172
|
+
display_name: typeof info.display_name === "string" ? info.display_name : id,
|
|
173
|
+
deprecation: info.deprecation,
|
|
174
|
+
capabilities
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return catalog;
|
|
178
|
+
}
|
|
179
|
+
async function fetch_umans_catalog(base_url, api_key) {
|
|
180
|
+
const headers = { "user-agent": USER_AGENT };
|
|
181
|
+
if (api_key) headers.authorization = `Bearer ${api_key}`;
|
|
182
|
+
const response = await fetch(`${base_url.replace(/\/$/, "")}/v1/models/info`, { headers });
|
|
183
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
184
|
+
return normalize_umans_catalog(await response.json());
|
|
185
|
+
}
|
|
186
|
+
function to_pi_models(catalog) {
|
|
187
|
+
return Object.entries(catalog).filter(([, info]) => !info.deprecation).map(([id, info]) => {
|
|
188
|
+
const capabilities = info.capabilities ?? {};
|
|
189
|
+
const input = capabilities.supports_vision ? ["text", "image"] : ["text"];
|
|
190
|
+
return {
|
|
191
|
+
id,
|
|
192
|
+
name: info.display_name ?? id,
|
|
193
|
+
maxTokens: safe_max_tokens(capabilities.recommended_max_tokens, capabilities.max_completion_tokens),
|
|
194
|
+
contextWindow: capabilities.context_window ?? 262144,
|
|
195
|
+
reasoning: capabilities.reasoning?.supported === true,
|
|
196
|
+
input,
|
|
197
|
+
cost: {
|
|
198
|
+
input: 0,
|
|
199
|
+
output: 0,
|
|
200
|
+
cacheRead: 0,
|
|
201
|
+
cacheWrite: 0
|
|
202
|
+
},
|
|
203
|
+
supportsTools: capabilities.supports_tools !== false
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
async function login_umans(callbacks) {
|
|
208
|
+
const key = (await callbacks.onPrompt({ message: "Enter your Umans API key:" })).trim();
|
|
209
|
+
if (!key) throw new Error("Umans API key is required");
|
|
210
|
+
return {
|
|
211
|
+
refresh: key,
|
|
212
|
+
access: key,
|
|
213
|
+
expires: Date.now() + 100 * 365 * 24 * 60 * 60 * 1e3
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
const extension = async (pi) => {
|
|
217
|
+
if (process.env.UMANS_DISABLE === "1") return;
|
|
218
|
+
const base_url = process.env.UMANS_BASE_URL?.trim() || DEFAULT_BASE_URL;
|
|
219
|
+
let catalog = STATIC_UMANS_CATALOG;
|
|
220
|
+
try {
|
|
221
|
+
const live_catalog = await fetch_umans_catalog(base_url, process.env[API_KEY_ENV]);
|
|
222
|
+
if (Object.keys(live_catalog).length > 0) catalog = live_catalog;
|
|
223
|
+
} catch {
|
|
224
|
+
catalog = STATIC_UMANS_CATALOG;
|
|
225
|
+
}
|
|
226
|
+
pi.registerProvider("umans", {
|
|
227
|
+
name: "Umans",
|
|
228
|
+
baseUrl: base_url,
|
|
229
|
+
apiKey: `$${API_KEY_ENV}`,
|
|
230
|
+
api: "anthropic-messages",
|
|
231
|
+
authHeader: true,
|
|
232
|
+
models: to_pi_models(catalog),
|
|
233
|
+
oauth: {
|
|
234
|
+
name: "Umans",
|
|
235
|
+
login: login_umans,
|
|
236
|
+
refreshToken: (credentials) => Promise.resolve(credentials),
|
|
237
|
+
getApiKey: (credentials) => credentials.access
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
//#endregion
|
|
242
|
+
export { extension as default };
|
|
243
|
+
|
|
244
|
+
//# sourceMappingURL=umans-provider-CHiuQuuc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"umans-provider-CHiuQuuc.js","names":[],"sources":["../src/extensions/umans-provider/index.ts"],"sourcesContent":["import type {\n\tOAuthCredentials,\n\tOAuthLoginCallbacks,\n} from '@earendil-works/pi-ai';\nimport type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\n\nconst DEFAULT_BASE_URL = 'https://api.code.umans.ai';\nconst API_KEY_ENV = 'UMANS_API_KEY';\nconst USER_AGENT = 'my-pi-umans-provider/0.1.0';\n\ninterface ReasoningInfo {\n\tsupported: boolean;\n\tcan_disable: boolean;\n\tlevels: string[];\n\tdefault_level: string;\n}\n\ninterface ModelCapabilities {\n\tmax_completion_tokens?: number;\n\trecommended_max_tokens?: number;\n\tcontext_window?: number;\n\tsupports_vision?: boolean | 'via-handoff';\n\tsupports_tools?: boolean;\n\treasoning?: ReasoningInfo;\n}\n\ninterface UmansModelInfo {\n\tname: string;\n\tdisplay_name?: string;\n\tdeprecation?: unknown;\n\tcapabilities: ModelCapabilities;\n}\n\nexport const STATIC_UMANS_CATALOG: Record<string, UmansModelInfo> = {\n\t'umans-kimi-k2.6': {\n\t\tname: 'umans-kimi-k2.6',\n\t\tdisplay_name: 'Umans Kimi K2.6',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-kimi-k2.7': {\n\t\tname: 'umans-kimi-k2.7',\n\t\tdisplay_name: 'Umans Kimi K2.7 Code',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: false,\n\t\t\t\tlevels: ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-glm-5.2': {\n\t\tname: 'umans-glm-5.2',\n\t\tdisplay_name: 'Umans GLM 5.2',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 131072,\n\t\t\trecommended_max_tokens: 131071,\n\t\t\tcontext_window: 405504,\n\t\t\tsupports_vision: 'via-handoff',\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-coder': {\n\t\tname: 'umans-coder',\n\t\tdisplay_name: 'Umans Coder',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: false,\n\t\t\t\tlevels: ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-flash': {\n\t\tname: 'umans-flash',\n\t\tdisplay_name: 'Umans Flash',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n\t'umans-qwen3.6-35b-a3b': {\n\t\tname: 'umans-qwen3.6-35b-a3b',\n\t\tdisplay_name: 'Umans Qwen3.6 35B A3B',\n\t\tcapabilities: {\n\t\t\tmax_completion_tokens: 262144,\n\t\t\trecommended_max_tokens: 32768,\n\t\t\tcontext_window: 262144,\n\t\t\tsupports_vision: true,\n\t\t\tsupports_tools: true,\n\t\t\treasoning: {\n\t\t\t\tsupported: true,\n\t\t\t\tcan_disable: true,\n\t\t\t\tlevels: [\n\t\t\t\t\t'none',\n\t\t\t\t\t'minimal',\n\t\t\t\t\t'low',\n\t\t\t\t\t'medium',\n\t\t\t\t\t'high',\n\t\t\t\t\t'xhigh',\n\t\t\t\t\t'max',\n\t\t\t\t],\n\t\t\t\tdefault_level: 'medium',\n\t\t\t},\n\t\t},\n\t},\n};\n\nfunction safe_max_tokens(recommended?: number, cap?: number): number {\n\tlet value =\n\t\ttypeof recommended === 'number' && recommended > 0\n\t\t\t? recommended\n\t\t\t: 32768;\n\tif (typeof cap === 'number' && cap > 0)\n\t\tvalue = Math.min(value, cap - 1);\n\treturn Math.max(value, 1);\n}\n\nfunction is_record(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\t!!value && typeof value === 'object' && !Array.isArray(value)\n\t);\n}\n\nexport function normalize_umans_catalog(\n\tvalue: unknown,\n): Record<string, UmansModelInfo> {\n\tconst source =\n\t\tis_record(value) && is_record(value.data) ? value.data : value;\n\tif (!is_record(source)) return {};\n\n\tconst catalog: Record<string, UmansModelInfo> = {};\n\tfor (const [id, info] of Object.entries(source)) {\n\t\tif (!is_record(info)) continue;\n\t\tconst capabilities = is_record(info.capabilities)\n\t\t\t? info.capabilities\n\t\t\t: {};\n\t\tcatalog[id] = {\n\t\t\tname: typeof info.name === 'string' ? info.name : id,\n\t\t\tdisplay_name:\n\t\t\t\ttypeof info.display_name === 'string'\n\t\t\t\t\t? info.display_name\n\t\t\t\t\t: id,\n\t\t\tdeprecation: info.deprecation,\n\t\t\tcapabilities: capabilities as ModelCapabilities,\n\t\t};\n\t}\n\treturn catalog;\n}\n\nexport async function fetch_umans_catalog(\n\tbase_url: string,\n\tapi_key?: string,\n): Promise<Record<string, UmansModelInfo>> {\n\tconst headers: Record<string, string> = {\n\t\t'user-agent': USER_AGENT,\n\t};\n\tif (api_key) headers.authorization = `Bearer ${api_key}`;\n\n\tconst response = await fetch(\n\t\t`${base_url.replace(/\\/$/, '')}/v1/models/info`,\n\t\t{ headers },\n\t);\n\tif (!response.ok) throw new Error(`HTTP ${response.status}`);\n\treturn normalize_umans_catalog(await response.json());\n}\n\nexport function to_pi_models(\n\tcatalog: Record<string, UmansModelInfo>,\n) {\n\treturn Object.entries(catalog)\n\t\t.filter(([, info]) => !info.deprecation)\n\t\t.map(([id, info]) => {\n\t\t\tconst capabilities = info.capabilities ?? {};\n\t\t\tconst input: ('text' | 'image')[] = capabilities.supports_vision\n\t\t\t\t? ['text', 'image']\n\t\t\t\t: ['text'];\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tname: info.display_name ?? id,\n\t\t\t\tmaxTokens: safe_max_tokens(\n\t\t\t\t\tcapabilities.recommended_max_tokens,\n\t\t\t\t\tcapabilities.max_completion_tokens,\n\t\t\t\t),\n\t\t\t\tcontextWindow: capabilities.context_window ?? 262144,\n\t\t\t\treasoning: capabilities.reasoning?.supported === true,\n\t\t\t\tinput,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t\tsupportsTools: capabilities.supports_tools !== false,\n\t\t\t};\n\t\t});\n}\n\nasync function login_umans(\n\tcallbacks: OAuthLoginCallbacks,\n): Promise<OAuthCredentials> {\n\tconst api_key = await callbacks.onPrompt({\n\t\tmessage: 'Enter your Umans API key:',\n\t});\n\tconst key = api_key.trim();\n\tif (!key) throw new Error('Umans API key is required');\n\treturn {\n\t\trefresh: key,\n\t\taccess: key,\n\t\texpires: Date.now() + 100 * 365 * 24 * 60 * 60 * 1000,\n\t};\n}\n\nconst extension: ExtensionFactory = async (pi) => {\n\tif (process.env.UMANS_DISABLE === '1') return;\n\n\tconst base_url =\n\t\tprocess.env.UMANS_BASE_URL?.trim() || DEFAULT_BASE_URL;\n\tlet catalog = STATIC_UMANS_CATALOG;\n\ttry {\n\t\tconst live_catalog = await fetch_umans_catalog(\n\t\t\tbase_url,\n\t\t\tprocess.env[API_KEY_ENV],\n\t\t);\n\t\tif (Object.keys(live_catalog).length > 0) catalog = live_catalog;\n\t} catch {\n\t\tcatalog = STATIC_UMANS_CATALOG;\n\t}\n\n\tpi.registerProvider('umans', {\n\t\tname: 'Umans',\n\t\tbaseUrl: base_url,\n\t\tapiKey: `$${API_KEY_ENV}`,\n\t\tapi: 'anthropic-messages',\n\t\tauthHeader: true,\n\t\tmodels: to_pi_models(catalog),\n\t\toauth: {\n\t\t\tname: 'Umans',\n\t\t\tlogin: login_umans,\n\t\t\trefreshToken: (credentials: OAuthCredentials) =>\n\t\t\t\tPromise.resolve(credentials),\n\t\t\tgetApiKey: (credentials: OAuthCredentials) =>\n\t\t\t\tcredentials.access,\n\t\t},\n\t});\n};\n\nexport default extension;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.92",
|
|
4
4
|
"description": "Composable pi coding agent with MCP, LSP, prompt presets, and local eval telemetry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@earendil-works/pi-ai": "0.
|
|
47
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
48
|
-
"@earendil-works/pi-tui": "0.
|
|
46
|
+
"@earendil-works/pi-ai": "0.80.2",
|
|
47
|
+
"@earendil-works/pi-coding-agent": "0.80.2",
|
|
48
|
+
"@earendil-works/pi-tui": "0.80.2",
|
|
49
49
|
"citty": "^0.2.2",
|
|
50
50
|
"typebox": "^1.1.38",
|
|
51
51
|
"@spences10/pi-project-trust": "0.0.14",
|
|
52
|
-
"@spences10/pi-
|
|
52
|
+
"@spences10/pi-settings": "0.0.1",
|
|
53
53
|
"@spences10/pi-tui-modal": "0.0.20",
|
|
54
|
-
"@spences10/pi-
|
|
54
|
+
"@spences10/pi-themes": "0.0.8"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@changesets/cli": "^2.31.0",
|
|
@@ -64,22 +64,22 @@
|
|
|
64
64
|
"optionalDependencies": {
|
|
65
65
|
"@spences10/pi-child-env": "0.1.8",
|
|
66
66
|
"@spences10/pi-confirm-destructive": "0.0.16",
|
|
67
|
-
"@spences10/pi-footer": "0.0.8",
|
|
68
67
|
"@spences10/pi-context": "0.1.3",
|
|
69
|
-
"@spences10/pi-
|
|
68
|
+
"@spences10/pi-footer": "0.0.8",
|
|
70
69
|
"@spences10/pi-coding-preferences": "0.0.11",
|
|
70
|
+
"@spences10/pi-git-ui": "0.0.12",
|
|
71
71
|
"@spences10/pi-lsp": "0.0.35",
|
|
72
|
+
"@spences10/pi-nopeek": "0.0.13",
|
|
72
73
|
"@spences10/pi-mcp": "0.0.43",
|
|
74
|
+
"@spences10/pi-observability": "0.0.13",
|
|
73
75
|
"@spences10/pi-omnisearch": "0.0.13",
|
|
74
|
-
"@spences10/pi-observability": "0.0.12",
|
|
75
|
-
"@spences10/pi-nopeek": "0.0.13",
|
|
76
76
|
"@spences10/pi-recall": "0.0.13",
|
|
77
77
|
"@spences10/pi-redact": "0.0.12",
|
|
78
78
|
"@spences10/pi-skill-importer": "0.0.8",
|
|
79
79
|
"@spences10/pi-skills": "0.0.29",
|
|
80
80
|
"@spences10/pi-sqlite-tools": "0.0.13",
|
|
81
81
|
"@spences10/pi-svelte-guardrails": "0.0.12",
|
|
82
|
-
"@spences10/pi-team-mode": "0.0.
|
|
82
|
+
"@spences10/pi-team-mode": "0.0.34",
|
|
83
83
|
"@spences10/pi-telemetry": "0.0.25"
|
|
84
84
|
},
|
|
85
85
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-registry-CYdEeqrp.js","names":[],"sources":["../src/extensions/builtin-registry.ts"],"sourcesContent":["import type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\n\nexport type BuiltinExtensionRuntimeMode =\n\t| 'interactive'\n\t| 'print'\n\t| 'json'\n\t| 'rpc';\n\ntype BuiltinExtensionLoader = () => Promise<ExtensionFactory>;\n\nexport interface BuiltinExtensionManifestEntry {\n\tkey: string;\n\tlabel: string;\n\tdocs_label: string;\n\tdescription: string;\n\tdefault_enabled: boolean;\n\toption_name: string;\n\tcli_arg: string;\n\tcli_flag: `--${string}`;\n\tcli_description: string;\n\taliases: readonly string[];\n\tmode_constraints?: {\n\t\tdisabled_in: readonly BuiltinExtensionRuntimeMode[];\n\t\treason: string;\n\t};\n\texternal_package_name?: string;\n\tload: BuiltinExtensionLoader;\n}\n\nexport const BUILTIN_EXTENSION_REGISTRY = [\n\t{\n\t\tkey: 'context-sidecar',\n\t\tlabel: 'Context sidecar',\n\t\tdocs_label: 'SQLite context sidecar',\n\t\tdescription: 'Local SQLite FTS sidecar for oversized tool output',\n\t\tdefault_enabled: true,\n\t\toption_name: 'context_sidecar',\n\t\tcli_arg: 'no-context-sidecar',\n\t\tcli_flag: '--no-context-sidecar',\n\t\tcli_description:\n\t\t\t'Disable SQLite context sidecar for large tool output',\n\t\taliases: ['context-sidecar', 'context', 'sidecar'],\n\t\texternal_package_name: '@spences10/pi-context',\n\t\tload: async () => (await import('@spences10/pi-context')).default,\n\t},\n\t{\n\t\tkey: 'mcp',\n\t\tlabel: 'MCP',\n\t\tdocs_label: 'MCP',\n\t\tdescription: 'MCP server integration and /mcp command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'mcp',\n\t\tcli_arg: 'no-mcp',\n\t\tcli_flag: '--no-mcp',\n\t\tcli_description: 'Disable built-in MCP extension',\n\t\taliases: ['mcp'],\n\t\texternal_package_name: '@spences10/pi-mcp',\n\t\tload: async () => (await import('@spences10/pi-mcp')).default,\n\t},\n\t{\n\t\tkey: 'openrouter-fusion-config',\n\t\tlabel: 'OpenRouter Fusion config',\n\t\tdocs_label: 'OpenRouter Fusion config guard',\n\t\tdescription:\n\t\t\t'Keeps OpenRouter Fusion off Anthropic by injecting a non-Anthropic panel and judge',\n\t\tdefault_enabled: true,\n\t\toption_name: 'openrouter_fusion_config',\n\t\tcli_arg: 'no-openrouter-fusion-config',\n\t\tcli_flag: '--no-openrouter-fusion-config',\n\t\tcli_description: 'Disable OpenRouter Fusion non-Anthropic config',\n\t\taliases: ['openrouter-fusion-config', 'fusion-budget'],\n\t\tload: async () =>\n\t\t\t(await import('./openrouter-fusion-config/index.js')).default,\n\t},\n\t{\n\t\tkey: 'footer',\n\t\tlabel: 'Footer',\n\t\tdocs_label: 'Footer',\n\t\tdescription: 'Configurable interactive footer/statusline',\n\t\tdefault_enabled: true,\n\t\toption_name: 'footer',\n\t\tcli_arg: 'no-footer',\n\t\tcli_flag: '--no-footer',\n\t\tcli_description: 'Disable custom footer/statusline',\n\t\taliases: ['footer', 'statusline', 'status-line'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Footer only renders in the interactive TUI',\n\t\t},\n\t\tload: async () => (await import('./footer/index.js')).default,\n\t},\n\t{\n\t\tkey: 'skills',\n\t\tlabel: 'Skills',\n\t\tdocs_label: 'Skills',\n\t\tdescription: 'Managed pi-native skills and /skills command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'skills',\n\t\tcli_arg: 'no-skills',\n\t\tcli_flag: '--no-skills',\n\t\tcli_description: 'Disable built-in skills extension',\n\t\taliases: ['skills', 'skill'],\n\t\texternal_package_name: '@spences10/pi-skills',\n\t\tload: async () => (await import('@spences10/pi-skills')).default,\n\t},\n\t{\n\t\tkey: 'skill-importer',\n\t\tlabel: 'Skill importer',\n\t\tdocs_label: 'Skill importer',\n\t\tdescription:\n\t\t\t'Import external Claude/plugin skills into Pi-native storage',\n\t\tdefault_enabled: true,\n\t\toption_name: 'skill_importer',\n\t\tcli_arg: 'no-skill-importer',\n\t\tcli_flag: '--no-skill-importer',\n\t\tcli_description: 'Disable external skill importer extension',\n\t\taliases: ['skill-importer', 'import-skills', 'skill-import'],\n\t\texternal_package_name: '@spences10/pi-skill-importer',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-skill-importer')).default,\n\t},\n\t{\n\t\tkey: 'filter-output',\n\t\tlabel: 'Secret redaction',\n\t\tdocs_label: 'Secret redaction',\n\t\tdescription:\n\t\t\t'Redacts secrets from tool output before the model sees them',\n\t\tdefault_enabled: true,\n\t\toption_name: 'filter_output',\n\t\tcli_arg: 'no-filter',\n\t\tcli_flag: '--no-filter',\n\t\tcli_description: 'Disable secret redaction in tool output',\n\t\taliases: [\n\t\t\t'filter-output',\n\t\t\t'filter_output',\n\t\t\t'filter',\n\t\t\t'redaction',\n\t\t\t'secret-redaction',\n\t\t\t'output-redaction',\n\t\t],\n\t\texternal_package_name: '@spences10/pi-redact',\n\t\tload: async () => (await import('@spences10/pi-redact')).default,\n\t},\n\t{\n\t\tkey: 'recall',\n\t\tlabel: 'Recall',\n\t\tdocs_label: 'Recall',\n\t\tdescription: 'pirecall reminder and background session sync',\n\t\tdefault_enabled: true,\n\t\toption_name: 'recall',\n\t\tcli_arg: 'no-recall',\n\t\tcli_flag: '--no-recall',\n\t\tcli_description: 'Disable recall extension',\n\t\taliases: ['recall', 'pirecall'],\n\t\texternal_package_name: '@spences10/pi-recall',\n\t\tload: async () => (await import('@spences10/pi-recall')).default,\n\t},\n\t{\n\t\tkey: 'nopeek',\n\t\tlabel: 'Nopeek',\n\t\tdocs_label: 'Nopeek',\n\t\tdescription:\n\t\t\t'nopeek reminder for secret-safe environment loading',\n\t\tdefault_enabled: true,\n\t\toption_name: 'nopeek',\n\t\tcli_arg: 'no-nopeek',\n\t\tcli_flag: '--no-nopeek',\n\t\tcli_description: 'Disable nopeek reminder extension',\n\t\taliases: ['nopeek', 'secrets', 'secret-loading'],\n\t\texternal_package_name: '@spences10/pi-nopeek',\n\t\tload: async () => (await import('@spences10/pi-nopeek')).default,\n\t},\n\t{\n\t\tkey: 'observability',\n\t\tlabel: 'Observability',\n\t\tdocs_label: 'Live observability',\n\t\tdescription:\n\t\t\t'Optional live event stream and local browser dashboard',\n\t\tdefault_enabled: true,\n\t\toption_name: 'observability',\n\t\tcli_arg: 'no-observability',\n\t\tcli_flag: '--no-observability',\n\t\tcli_description: 'Disable live observability extension',\n\t\taliases: ['observability', 'obs', 'live-events'],\n\t\texternal_package_name: '@spences10/pi-observability',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-observability')).default,\n\t},\n\t{\n\t\tkey: 'omnisearch',\n\t\tlabel: 'Omnisearch',\n\t\tdocs_label: 'Omnisearch',\n\t\tdescription: 'mcp-omnisearch reminder for verified web research',\n\t\tdefault_enabled: true,\n\t\toption_name: 'omnisearch',\n\t\tcli_arg: 'no-omnisearch',\n\t\tcli_flag: '--no-omnisearch',\n\t\tcli_description: 'Disable mcp-omnisearch reminder extension',\n\t\taliases: ['omnisearch', 'search', 'web-search', 'research'],\n\t\texternal_package_name: '@spences10/pi-omnisearch',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-omnisearch')).default,\n\t},\n\t{\n\t\tkey: 'sqlite-tools',\n\t\tlabel: 'SQLite tools',\n\t\tdocs_label: 'SQLite tools',\n\t\tdescription:\n\t\t\t'mcp-sqlite-tools reminder for safer SQLite database work',\n\t\tdefault_enabled: true,\n\t\toption_name: 'sqlite_tools',\n\t\tcli_arg: 'no-sqlite-tools',\n\t\tcli_flag: '--no-sqlite-tools',\n\t\tcli_description: 'Disable mcp-sqlite-tools reminder extension',\n\t\taliases: ['sqlite-tools', 'sqlite', 'mcp-sqlite-tools'],\n\t\texternal_package_name: '@spences10/pi-sqlite-tools',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-sqlite-tools')).default,\n\t},\n\t{\n\t\tkey: 'startup-screen',\n\t\tlabel: 'Startup screen',\n\t\tdocs_label: 'Startup screen',\n\t\tdescription:\n\t\t\t'Pixel-art gradient startup header for interactive sessions',\n\t\tdefault_enabled: true,\n\t\toption_name: 'startup_screen',\n\t\tcli_arg: 'no-startup-screen',\n\t\tcli_flag: '--no-startup-screen',\n\t\tcli_description: 'Disable the custom startup screen',\n\t\taliases: ['startup-screen', 'startup', 'header', 'splash'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Startup screen only renders in the interactive TUI',\n\t\t},\n\t\tload: async () =>\n\t\t\t(await import('./startup-screen/index.js')).default,\n\t},\n\t{\n\t\tkey: 'prompt-presets',\n\t\tlabel: 'Prompt presets',\n\t\tdocs_label: 'Prompt presets',\n\t\tdescription:\n\t\t\t'Runtime prompt preset selection and /prompt-preset command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'prompt_presets',\n\t\tcli_arg: 'no-prompt-presets',\n\t\tcli_flag: '--no-prompt-presets',\n\t\tcli_description: 'Disable prompt presets extension',\n\t\taliases: ['prompt-preset', 'preset', 'presets'],\n\t\tload: async () =>\n\t\t\t(await import('./prompt-presets/index.js')).default,\n\t},\n\t{\n\t\tkey: 'git-ui',\n\t\tlabel: 'Git UI',\n\t\tdocs_label: 'Git staging UI',\n\t\tdescription: 'Interactive source control staging panel',\n\t\tdefault_enabled: true,\n\t\toption_name: 'git_ui',\n\t\tcli_arg: 'no-git-ui',\n\t\tcli_flag: '--no-git-ui',\n\t\tcli_description: 'Disable built-in Git staging UI',\n\t\taliases: ['git-ui', 'git', 'source-control', 'scm'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason: 'Git UI is only useful in interactive mode',\n\t\t},\n\t\texternal_package_name: '@spences10/pi-git-ui',\n\t\tload: async () => (await import('@spences10/pi-git-ui')).default,\n\t},\n\t{\n\t\tkey: 'lsp',\n\t\tlabel: 'LSP',\n\t\tdocs_label: 'LSP',\n\t\tdescription:\n\t\t\t'Language Server Protocol tools (diagnostics, hover, definition, references)',\n\t\tdefault_enabled: true,\n\t\toption_name: 'lsp',\n\t\tcli_arg: 'no-lsp',\n\t\tcli_flag: '--no-lsp',\n\t\tcli_description: 'Disable LSP extension',\n\t\taliases: ['lsp', 'language-server'],\n\t\texternal_package_name: '@spences10/pi-lsp',\n\t\tload: async () => (await import('@spences10/pi-lsp')).default,\n\t},\n\t{\n\t\tkey: 'session-name',\n\t\tlabel: 'Session name',\n\t\tdocs_label: 'Session auto-naming',\n\t\tdescription:\n\t\t\t'AI-powered session auto-naming and /session-name command',\n\t\tdefault_enabled: true,\n\t\toption_name: 'session_name',\n\t\tcli_arg: 'no-session-name',\n\t\tcli_flag: '--no-session-name',\n\t\tcli_description: 'Disable session name extension',\n\t\taliases: ['session-name', 'session', 'auto-name'],\n\t\tmode_constraints: {\n\t\t\tdisabled_in: ['print', 'json', 'rpc'],\n\t\t\treason:\n\t\t\t\t'UI-only session naming is only useful in interactive mode',\n\t\t},\n\t\tload: async () =>\n\t\t\t(await import('./session-name/index.js')).default,\n\t},\n\t{\n\t\tkey: 'confirm-destructive',\n\t\tlabel: 'Confirm destructive',\n\t\tdocs_label: 'Destructive action confirmation',\n\t\tdescription:\n\t\t\t'Prompt before destructive tool calls like file deletes, overwrites, and hard resets',\n\t\tdefault_enabled: true,\n\t\toption_name: 'confirm_destructive',\n\t\tcli_arg: 'no-confirm-destructive',\n\t\tcli_flag: '--no-confirm-destructive',\n\t\tcli_description: 'Disable destructive action confirmations',\n\t\taliases: ['confirm-destructive', 'confirm'],\n\t\texternal_package_name: '@spences10/pi-confirm-destructive',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-confirm-destructive')).default,\n\t},\n\t{\n\t\tkey: 'hooks-resolution',\n\t\tlabel: 'Hooks resolution',\n\t\tdocs_label: 'Hooks resolution',\n\t\tdescription:\n\t\t\t'Claude Code style PreToolUse and PostToolUse hook compatibility from .claude, .rulesync, and .pi configs',\n\t\tdefault_enabled: true,\n\t\toption_name: 'hooks_resolution',\n\t\tcli_arg: 'no-hooks',\n\t\tcli_flag: '--no-hooks',\n\t\tcli_description: 'Disable Claude-style hook execution',\n\t\taliases: ['hooks-resolution', 'hooks'],\n\t\tload: async () =>\n\t\t\t(await import('./hooks-resolution/index.js')).default,\n\t},\n\t{\n\t\tkey: 'svelte-guardrails',\n\t\tlabel: 'Svelte guardrails',\n\t\tdocs_label: 'Svelte guardrails',\n\t\tdescription:\n\t\t\t'Blocks discouraged Svelte patterns like $effect before agents write them',\n\t\tdefault_enabled: true,\n\t\toption_name: 'svelte_guardrails',\n\t\tcli_arg: 'no-svelte-guardrails',\n\t\tcli_flag: '--no-svelte-guardrails',\n\t\tcli_description: 'Disable Svelte guardrails',\n\t\taliases: ['svelte-guardrails', 'svelte'],\n\t\texternal_package_name: '@spences10/pi-svelte-guardrails',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-svelte-guardrails')).default,\n\t},\n\t{\n\t\tkey: 'coding-preferences',\n\t\tlabel: 'Coding preferences',\n\t\tdocs_label: 'Coding preferences',\n\t\tdescription:\n\t\t\t'Blocks configured coding workflow anti-patterns from JSON preferences',\n\t\tdefault_enabled: true,\n\t\toption_name: 'coding_preferences',\n\t\tcli_arg: 'no-coding-preferences',\n\t\tcli_flag: '--no-coding-preferences',\n\t\tcli_description: 'Disable coding preferences guardrails',\n\t\taliases: ['coding-preferences', 'preferences', 'prefs'],\n\t\texternal_package_name: '@spences10/pi-coding-preferences',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-coding-preferences')).default,\n\t},\n\t{\n\t\tkey: 'handoff',\n\t\tlabel: 'Handoff',\n\t\tdocs_label: 'Handoff',\n\t\tdescription:\n\t\t\t'Help command for Pi continuation primitives like /fork, /tree, /export, /import, and /share',\n\t\tdefault_enabled: true,\n\t\toption_name: 'handoff',\n\t\tcli_arg: 'no-handoff',\n\t\tcli_flag: '--no-handoff',\n\t\tcli_description: 'Disable handoff helper command',\n\t\taliases: ['handoff', 'continuation'],\n\t\tload: async () => (await import('./handoff/index.js')).default,\n\t},\n\t{\n\t\tkey: 'team-mode',\n\t\tlabel: 'Team mode',\n\t\tdocs_label: 'Team mode',\n\t\tdescription:\n\t\t\t'Experimental orchestrator/team mode with RPC teammates, tasks, and mailboxes',\n\t\tdefault_enabled: true,\n\t\toption_name: 'team_mode',\n\t\tcli_arg: 'no-team-mode',\n\t\tcli_flag: '--no-team-mode',\n\t\tcli_description: 'Disable experimental team mode extension',\n\t\taliases: ['team-mode', 'team', 'teammates'],\n\t\texternal_package_name: '@spences10/pi-team-mode',\n\t\tload: async () =>\n\t\t\t(await import('@spences10/pi-team-mode')).default,\n\t},\n] as const satisfies readonly BuiltinExtensionManifestEntry[];\n\nexport type BuiltinExtensionKey =\n\t(typeof BUILTIN_EXTENSION_REGISTRY)[number]['key'];\n\nexport type BuiltinExtensionOptionName =\n\t(typeof BUILTIN_EXTENSION_REGISTRY)[number]['option_name'];\n\nexport type BuiltinExtensionInfo = Omit<\n\tBuiltinExtensionManifestEntry,\n\t'load'\n> & {\n\tkey: BuiltinExtensionKey;\n\toption_name: BuiltinExtensionOptionName;\n};\n\nexport const BUILTIN_EXTENSIONS: BuiltinExtensionInfo[] =\n\tBUILTIN_EXTENSION_REGISTRY.map(\n\t\t({ load: _load, ...extension }) => extension,\n\t);\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-name-arDf91uJ.js","names":[],"sources":["../src/extensions/session-name/index.ts"],"sourcesContent":["// Session name — AI-powered session naming\n// Adapted from Thomas Lopes' pi dotfiles\n\nimport { complete, type Message } from '@earendil-works/pi-ai';\nimport type {\n\tExtensionAPI,\n\tSessionEntry,\n} from '@earendil-works/pi-coding-agent';\nimport {\n\tBorderedLoader,\n\tconvertToLlm,\n\tserializeConversation,\n} from '@earendil-works/pi-coding-agent';\n\nconst SYSTEM_PROMPT = `You are a session naming assistant. Given a conversation history, generate a short, descriptive session name (2-5 words) that captures the main topic or task.\n\nGuidelines:\n- Be concise but specific\n- Use kebab-case only\n- Focus on the core task/question\n- Avoid generic names like \"discussion\" or \"conversation\"\n- No quotes, no punctuation at the end\n\nExamples:\n- \"fix auth bug\" -> \"fix-auth-bug\"\n- \"how do I deploy to vercel\" -> \"vercel-deployment\"\n- \"explain react hooks\" -> \"react-hooks-explanation\"\n- \"optimize database queries\" -> \"db-query-optimization\"\n\nOutput ONLY the session name, nothing else.`;\n\nconst AUTO_NAME_THRESHOLD = 1;\nconst MAX_CHARS = 4000;\nconst MAX_NAME_LEN = 50;\n\nfunction clean_name(value: string): string {\n\treturn value\n\t\t.replace(/^[\"']|[\"']$/g, '')\n\t\t.normalize('NFKD')\n\t\t.replace(/[\\u0300-\\u036f]/g, '')\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.slice(0, MAX_NAME_LEN)\n\t\t.replace(/-+$/g, '');\n}\n\nfunction truncate_conversation(value: string): string {\n\treturn value.length > MAX_CHARS\n\t\t? value.slice(0, MAX_CHARS) + '\\n...'\n\t\t: value;\n}\n\nasync function generate_session_name(\n\tctx: {\n\t\tmodelRegistry: {\n\t\t\tgetApiKeyAndHeaders: (\n\t\t\t\tmodel: NonNullable<\n\t\t\t\t\tParameters<\n\t\t\t\t\t\tParameters<ExtensionAPI['registerCommand']>[1]['handler']\n\t\t\t\t\t>[1]['model']\n\t\t\t\t>,\n\t\t\t) => Promise<any>;\n\t\t};\n\t},\n\tmodel: NonNullable<\n\t\tParameters<\n\t\t\tParameters<ExtensionAPI['registerCommand']>[1]['handler']\n\t\t>[1]['model']\n\t>,\n\tconversation_text: string,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);\n\tif (!auth.ok || !auth.apiKey) {\n\t\tthrow new Error(\n\t\t\tauth.ok ? `No API key for ${model.provider}` : auth.error,\n\t\t);\n\t}\n\n\tconst user_message: Message = {\n\t\trole: 'user',\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: 'text',\n\t\t\t\ttext: `## Conversation History\\n\\n${truncate_conversation(conversation_text)}\\n\\nGenerate a concise session name for this conversation.`,\n\t\t\t},\n\t\t],\n\t\ttimestamp: Date.now(),\n\t};\n\n\tconst response = await complete(\n\t\tmodel,\n\t\t{ systemPrompt: SYSTEM_PROMPT, messages: [user_message] },\n\t\t{ apiKey: auth.apiKey, headers: auth.headers, signal },\n\t);\n\n\tif (response.stopReason === 'aborted') {\n\t\treturn null;\n\t}\n\n\treturn clean_name(\n\t\tresponse.content\n\t\t\t.filter(\n\t\t\t\t(c): c is { type: 'text'; text: string } => c.type === 'text',\n\t\t\t)\n\t\t\t.map((c) => c.text.trim())\n\t\t\t.join(' '),\n\t);\n}\n\nexport default async function session_name(pi: ExtensionAPI) {\n\tlet auto_named_attempted = false;\n\n\tpi.on('agent_end', async (_event, ctx) => {\n\t\tif (!ctx.hasUI || !ctx.model) return;\n\t\tif (pi.getSessionName() || auto_named_attempted) return;\n\n\t\tconst branch = ctx.sessionManager.getBranch();\n\t\tconst user_messages = branch.filter(\n\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\tentry.type === 'message' && entry.message.role === 'user',\n\t\t);\n\t\tif (user_messages.length < AUTO_NAME_THRESHOLD) return;\n\n\t\tauto_named_attempted = true;\n\t\tconst messages = branch\n\t\t\t.filter(\n\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\tentry.type === 'message',\n\t\t\t)\n\t\t\t.map((entry) => entry.message);\n\t\tif (messages.length === 0) return;\n\n\t\tconst conversation_text = serializeConversation(\n\t\t\tconvertToLlm(messages),\n\t\t);\n\n\t\tgenerate_session_name(ctx, ctx.model, conversation_text)\n\t\t\t.then((name) => {\n\t\t\t\tif (!name) return;\n\t\t\t\tpi.setSessionName(name);\n\t\t\t\tctx.ui.notify(`Auto-named: ${name}`, 'info');\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t});\n\t});\n\n\tpi.on('session_start', async () => {\n\t\tauto_named_attempted = false;\n\t});\n\n\tpi.registerCommand('session-name', {\n\t\tdescription:\n\t\t\t'Set, show, or auto-generate the current session name',\n\t\thandler: async (args, ctx) => {\n\t\t\tconst trimmed = args.trim();\n\n\t\t\tif (!trimmed) {\n\t\t\t\tconst current = pi.getSessionName();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tcurrent ? `Session: ${current}` : 'No session name set',\n\t\t\t\t\t'info',\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (trimmed === '--auto' || trimmed === '-a') {\n\t\t\t\tif (!ctx.hasUI || !ctx.model) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t'Auto-naming requires interactive mode and a selected model',\n\t\t\t\t\t\t'error',\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst messages = branch\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(entry): entry is SessionEntry & { type: 'message' } =>\n\t\t\t\t\t\t\tentry.type === 'message',\n\t\t\t\t\t)\n\t\t\t\t\t.map((entry) => entry.message);\n\t\t\t\tif (messages.length === 0) {\n\t\t\t\t\tctx.ui.notify('No conversation to analyze', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst conversation_text = serializeConversation(\n\t\t\t\t\tconvertToLlm(messages),\n\t\t\t\t);\n\n\t\t\t\tconst result = await ctx.ui.custom<string | null>(\n\t\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\t\tconst loader = new BorderedLoader(\n\t\t\t\t\t\t\ttui,\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\t'Generating session name...',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tloader.onAbort = () => done(null);\n\n\t\t\t\t\t\tgenerate_session_name(\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\tctx.model!,\n\t\t\t\t\t\t\tconversation_text,\n\t\t\t\t\t\t\tloader.signal,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.then(done)\n\t\t\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\t\t\tconsole.error('Auto-naming failed:', err);\n\t\t\t\t\t\t\t\tdone(null);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn loader;\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (result === null) {\n\t\t\t\t\tctx.ui.notify('Auto-naming cancelled', 'info');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result) {\n\t\t\t\t\tctx.ui.notify('Failed to generate name', 'error');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tpi.setSessionName(result);\n\t\t\t\tctx.ui.notify(`Session named: ${result}`, 'info');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpi.setSessionName(clean_name(trimmed));\n\t\t\tctx.ui.notify(`Session named: ${clean_name(trimmed)}`, 'info');\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|