@akon-labs/nexus-cli 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -5316
- package/README.md +30 -26
- package/dist/cli.js +90 -62
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +18 -63
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/extensions/gitnexus/gateway.d.ts +2 -0
- package/dist/extensions/gitnexus/gateway.d.ts.map +1 -1
- package/dist/extensions/gitnexus/gateway.js +22 -4
- package/dist/extensions/gitnexus/gateway.js.map +1 -1
- package/dist/extensions/gitnexus/index.d.ts.map +1 -1
- package/dist/extensions/gitnexus/index.js +21 -3
- package/dist/extensions/gitnexus/index.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +1 -1
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/web-access.d.ts +8 -1
- package/dist/extensions/web-access.d.ts.map +1 -1
- package/dist/extensions/web-access.js +48 -2
- package/dist/extensions/web-access.js.map +1 -1
- package/dist/index.js +93 -65
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +2 -2
- package/dist/migrations.js.map +1 -1
- package/dist/rpc-entry.js +90 -62
- package/dist/vendor/agent-core.js +6805 -0
- package/dist/vendor/ai.js +12407 -0
- package/dist/vendor/tui.js +11645 -0
- package/dist/vendor/web-access.js +93103 -0
- package/docs/compaction.md +14 -14
- package/docs/containerization.md +1 -1
- package/docs/custom-provider.md +17 -17
- package/docs/development.md +2 -2
- package/docs/environment-variables.md +1 -1
- package/docs/extensions.md +44 -44
- package/docs/index.md +5 -11
- package/docs/json.md +4 -4
- package/docs/llama-cpp.md +2 -2
- package/docs/models.md +3 -3
- package/docs/packages.md +6 -6
- package/docs/providers.md +13 -13
- package/docs/quickstart.md +19 -13
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +28 -28
- package/docs/security.md +1 -1
- package/docs/session-format.md +6 -6
- package/docs/settings.md +1 -1
- package/docs/termux.md +1 -1
- package/docs/themes.md +2 -2
- package/docs/tui.md +20 -20
- package/docs/usage.md +5 -4
- package/examples/extensions/README.md +2 -2
- package/examples/extensions/auto-commit-on-exit.ts +1 -1
- package/examples/extensions/bash-spawn-hook.ts +2 -2
- package/examples/extensions/bookmark.ts +1 -1
- package/examples/extensions/border-status-editor.ts +3 -3
- package/examples/extensions/built-in-tool-renderer.ts +3 -3
- package/examples/extensions/claude-rules.ts +1 -1
- package/examples/extensions/commands.ts +1 -1
- package/examples/extensions/confirm-destructive.ts +1 -1
- package/examples/extensions/custom-compaction.ts +3 -3
- package/examples/extensions/custom-footer.ts +3 -3
- package/examples/extensions/custom-header.ts +2 -2
- package/examples/extensions/custom-provider-anthropic/index.ts +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
- package/examples/extensions/dirty-repo-guard.ts +1 -1
- package/examples/extensions/doom-overlay/doom-component.ts +2 -2
- package/examples/extensions/doom-overlay/doom-keys.ts +1 -1
- package/examples/extensions/doom-overlay/index.ts +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/dynamic-resources/index.ts +1 -1
- package/examples/extensions/dynamic-tools.ts +1 -1
- package/examples/extensions/entry-renderer.ts +2 -2
- package/examples/extensions/event-bus.ts +1 -1
- package/examples/extensions/file-trigger.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +1 -1
- package/examples/extensions/git-merge-and-resolve.ts +1 -1
- package/examples/extensions/github-issue-autocomplete.ts +2 -2
- package/examples/extensions/gondolin/index.ts +2 -2
- package/examples/extensions/handoff.ts +4 -4
- package/examples/extensions/hello.ts +2 -2
- package/examples/extensions/hidden-thinking-label.ts +1 -1
- package/examples/extensions/inline-bash.ts +1 -1
- package/examples/extensions/input-transform-streaming.ts +1 -1
- package/examples/extensions/input-transform.ts +1 -1
- package/examples/extensions/interactive-shell.ts +1 -1
- package/examples/extensions/kimi-deferred-tools.ts +1 -1
- package/examples/extensions/mac-system-theme.ts +1 -1
- package/examples/extensions/message-renderer.ts +2 -2
- package/examples/extensions/minimal-mode.ts +3 -3
- package/examples/extensions/modal-editor.ts +2 -2
- package/examples/extensions/model-status.ts +1 -1
- package/examples/extensions/notify.ts +1 -1
- package/examples/extensions/overlay-qa-tests.ts +5 -5
- package/examples/extensions/overlay-test.ts +2 -2
- package/examples/extensions/permission-gate.ts +1 -1
- package/examples/extensions/pirate.ts +1 -1
- package/examples/extensions/plan-mode/index.ts +4 -4
- package/examples/extensions/preset.ts +4 -4
- package/examples/extensions/project-trust.ts +1 -1
- package/examples/extensions/prompt-customizer.ts +1 -1
- package/examples/extensions/protected-paths.ts +1 -1
- package/examples/extensions/provider-payload.ts +1 -1
- package/examples/extensions/qna.ts +3 -3
- package/examples/extensions/question.ts +2 -2
- package/examples/extensions/questionnaire.ts +2 -2
- package/examples/extensions/rainbow-editor.ts +1 -1
- package/examples/extensions/reload-runtime.ts +1 -1
- package/examples/extensions/rpc-demo.ts +1 -1
- package/examples/extensions/sandbox/index.ts +2 -2
- package/examples/extensions/send-user-message.ts +1 -1
- package/examples/extensions/session-name.ts +1 -1
- package/examples/extensions/shutdown-command.ts +1 -1
- package/examples/extensions/snake.ts +2 -2
- package/examples/extensions/space-invaders.ts +2 -2
- package/examples/extensions/ssh.ts +2 -2
- package/examples/extensions/status-line.ts +1 -1
- package/examples/extensions/structured-output.ts +2 -2
- package/examples/extensions/subagent/agents.ts +1 -1
- package/examples/extensions/subagent/index.ts +5 -5
- package/examples/extensions/summarize.ts +4 -4
- package/examples/extensions/system-prompt-header.ts +1 -1
- package/examples/extensions/tic-tac-toe.ts +3 -3
- package/examples/extensions/timed-confirm.ts +1 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/todo.ts +3 -3
- package/examples/extensions/tool-override.ts +2 -2
- package/examples/extensions/tools.ts +3 -3
- package/examples/extensions/trigger-compact.ts +1 -1
- package/examples/extensions/truncated-tool.ts +3 -3
- package/examples/extensions/widget-placement.ts +1 -1
- package/examples/extensions/with-deps/index.ts +1 -1
- package/examples/extensions/working-indicator.ts +1 -1
- package/examples/extensions/working-message-test.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/02-custom-model.ts +1 -1
- package/examples/sdk/03-custom-prompt.ts +1 -6
- package/examples/sdk/04-skills.ts +1 -1
- package/examples/sdk/05-tools.ts +1 -1
- package/examples/sdk/06-extensions.ts +2 -7
- package/examples/sdk/07-context-files.ts +1 -6
- package/examples/sdk/08-prompt-templates.ts +1 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
- package/examples/sdk/10-settings.ts +1 -1
- package/examples/sdk/11-sessions.ts +1 -1
- package/examples/sdk/12-full-control.ts +2 -2
- package/examples/sdk/13-session-runtime.ts +1 -1
- package/examples/sdk/README.md +2 -2
- package/npm-shrinkwrap.json +2 -26
- package/package.json +10 -25
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/llama/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gCAAgC,CAAC;AAyC5F,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA0L7D","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { formatBytes, LlamaClient, type LlamaModelInfo, normalizeLlamaServerUrl } from \"./client.ts\";\nimport { findHuggingFaceToken, HuggingFaceClient } from \"./huggingface.ts\";\nimport { createLlamaProvider, LLAMA_PROVIDER_ID } from \"./provider.ts\";\nimport { type LlamaUi, runWithProgress, showLlamaUi } from \"./ui.ts\";\n\nfunction modelIsLoaded(model: LlamaModelInfo): boolean {\n\treturn model.status.value === \"loaded\" || model.status.value === \"sleeping\";\n}\n\nfunction isConnectionError(error: unknown): boolean {\n\tif (!(error instanceof Error)) return false;\n\tconst message = `${error.name} ${error.message}`.toLowerCase();\n\treturn message.includes(\"fetch failed\") || message.includes(\"timeout\") || message.includes(\"network\");\n}\n\nfunction connectionErrorMessage(error: unknown): string {\n\tif (isConnectionError(error)) return \"Could not connect to the server.\";\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction parseHuggingFaceModel(value: string): { repository: string; quantization?: string } {\n\tconst colon = value.indexOf(\":\", value.indexOf(\"/\") + 1);\n\treturn colon < 0\n\t\t? { repository: value }\n\t\t: { repository: value.slice(0, colon), quantization: value.slice(colon + 1) };\n}\n\nasync function configuredClient(ctx: ExtensionCommandContext): Promise<LlamaClient | undefined> {\n\tconst result = await ctx.modelRegistry.getProviderAuth(LLAMA_PROVIDER_ID);\n\tif (!result) {\n\t\tctx.ui.notify(`Configure llama.cpp with /
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/llama/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gCAAgC,CAAC;AAyC5F,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA0L7D","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { formatBytes, LlamaClient, type LlamaModelInfo, normalizeLlamaServerUrl } from \"./client.ts\";\nimport { findHuggingFaceToken, HuggingFaceClient } from \"./huggingface.ts\";\nimport { createLlamaProvider, LLAMA_PROVIDER_ID } from \"./provider.ts\";\nimport { type LlamaUi, runWithProgress, showLlamaUi } from \"./ui.ts\";\n\nfunction modelIsLoaded(model: LlamaModelInfo): boolean {\n\treturn model.status.value === \"loaded\" || model.status.value === \"sleeping\";\n}\n\nfunction isConnectionError(error: unknown): boolean {\n\tif (!(error instanceof Error)) return false;\n\tconst message = `${error.name} ${error.message}`.toLowerCase();\n\treturn message.includes(\"fetch failed\") || message.includes(\"timeout\") || message.includes(\"network\");\n}\n\nfunction connectionErrorMessage(error: unknown): string {\n\tif (isConnectionError(error)) return \"Could not connect to the server.\";\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction parseHuggingFaceModel(value: string): { repository: string; quantization?: string } {\n\tconst colon = value.indexOf(\":\", value.indexOf(\"/\") + 1);\n\treturn colon < 0\n\t\t? { repository: value }\n\t\t: { repository: value.slice(0, colon), quantization: value.slice(colon + 1) };\n}\n\nasync function configuredClient(ctx: ExtensionCommandContext): Promise<LlamaClient | undefined> {\n\tconst result = await ctx.modelRegistry.getProviderAuth(LLAMA_PROVIDER_ID);\n\tif (!result) {\n\t\tctx.ui.notify(`Configure llama.cpp with /byok ${LLAMA_PROVIDER_ID}`, \"warning\");\n\t\treturn undefined;\n\t}\n\tconst configuredUrl = result.env?.LLAMA_BASE_URL;\n\tconst serverUrl = normalizeLlamaServerUrl(\n\t\ttypeof configuredUrl === \"string\" && configuredUrl ? configuredUrl : (result.auth.baseUrl ?? \"\"),\n\t);\n\treturn new LlamaClient(serverUrl, result.auth.apiKey);\n}\n\nexport default function llamaExtension(pi: ExtensionAPI): void {\n\tconst provider = createLlamaProvider();\n\tpi.registerProvider(provider.provider);\n\n\tconst syncCatalog = async (\n\t\tctx: ExtensionCommandContext,\n\t\tclient: LlamaClient,\n\t\tcatalog?: LlamaModelInfo[],\n\t): Promise<LlamaModelInfo[]> => {\n\t\tconst signal = AbortSignal.timeout(15_000);\n\t\tconst current = catalog ?? (await client.list({ signal }));\n\t\tprovider.setCatalog(current, client.serverUrl);\n\t\tconst result = await ctx.modelRegistry.refresh({\n\t\t\tproviders: [LLAMA_PROVIDER_ID],\n\t\t\tsignal,\n\t\t});\n\t\tif (result.aborted) throw new Error(\"Model catalog refresh timed out.\");\n\t\tconst refreshError = result.errors.get(LLAMA_PROVIDER_ID);\n\t\tif (refreshError) throw refreshError;\n\t\treturn current;\n\t};\n\n\tconst loadModel = async (\n\t\tctx: ExtensionCommandContext,\n\t\tui: LlamaUi,\n\t\tclient: LlamaClient,\n\t\tcatalog: LlamaModelInfo[],\n\t\ttarget: LlamaModelInfo,\n\t): Promise<void> => {\n\t\tconst loaded = catalog.filter((model) => model.id !== target.id && modelIsLoaded(model));\n\t\tlet replace = false;\n\t\tif (loaded.length > 0) {\n\t\t\tconst choice = await ui.select(`${loaded.length} model${loaded.length === 1 ? \" is\" : \"s are\"} loaded`, [\n\t\t\t\t\"Unload all and load\",\n\t\t\t\t\"Keep loaded and load\",\n\t\t\t\t\"Cancel\",\n\t\t\t]);\n\t\t\tif (!choice || choice === \"Cancel\") return;\n\t\t\treplace = choice === \"Unload all and load\";\n\t\t}\n\n\t\tconst restoreLoaded = async (): Promise<void> => {\n\t\t\tctx.ui.notify(\"Restoring previously loaded models\");\n\t\t\tfor (const model of loaded) await client.loadAndWait(model.id, () => {});\n\t\t\tawait syncCatalog(ctx, client);\n\t\t};\n\t\tif (replace) {\n\t\t\tfor (const model of loaded) await client.unloadAndWait(model.id);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await runWithProgress(ui, {\n\t\t\t\ttitle: \"Loading model\",\n\t\t\t\tmodel: target.id,\n\t\t\t\tinitialMessage: \"Starting…\",\n\t\t\t\tcancelTitle: \"Stop loading?\",\n\t\t\t\tcancelMessage: target.id,\n\t\t\t\trun: (signal, update) => client.loadAndWait(target.id, update, signal),\n\t\t\t\tcancel: () => client.unload(target.id),\n\t\t\t});\n\t\t\tif (result.cancelled) {\n\t\t\t\tif (replace) await restoreLoaded();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst refreshed = await syncCatalog(ctx, client);\n\t\t\tconst loadedModel = refreshed.find((model) => model.id === target.id);\n\t\t\tctx.ui.notify(\n\t\t\t\tloadedModel?.status.value === \"loaded\" ? `Loaded ${target.id}` : `Load started for ${target.id}`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (replace) {\n\t\t\t\ttry {\n\t\t\t\t\tawait restoreLoaded();\n\t\t\t\t} catch {\n\t\t\t\t\t// Preserve the original load error.\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t};\n\n\tconst unloadModel = async (\n\t\tctx: ExtensionCommandContext,\n\t\tui: LlamaUi,\n\t\tclient: LlamaClient,\n\t\tmodel: LlamaModelInfo,\n\t): Promise<void> => {\n\t\tif (!(await ui.confirm(\"Unload model?\", model.id))) return;\n\t\tawait client.unloadAndWait(model.id);\n\t\tawait syncCatalog(ctx, client);\n\t\tctx.ui.notify(`Unloaded ${model.id}`);\n\t};\n\n\tconst downloadModel = async (ctx: ExtensionCommandContext, ui: LlamaUi, client: LlamaClient): Promise<void> => {\n\t\tconst huggingFace = new HuggingFaceClient(await findHuggingFaceToken());\n\t\tconst selected = await ui.searchModels((query, signal) => huggingFace.search(query, signal));\n\t\tif (!selected) return;\n\t\tconst parsed = parseHuggingFaceModel(selected);\n\t\tui.showStatus(\"Loading model details\", parsed.repository);\n\t\tconst details = await huggingFace.details(parsed.repository);\n\t\tif (details.gated) {\n\t\t\tconst approval = details.gated === \"manual\" ? \"Manual approval is required\" : \"Accept the access terms\";\n\t\t\tconst choice = await ui.select(\n\t\t\t\t`Hugging Face access required\\n${details.id}\\n\\n${approval} at:\\nhttps://huggingface.co/${details.id}\\n\\nThe llama.cpp server needs HF_TOKEN with access.`,\n\t\t\t\t[\"Continue\", \"Back\"],\n\t\t\t);\n\t\t\tif (choice !== \"Continue\") return;\n\t\t}\n\t\tlet quantization = parsed.quantization;\n\t\tif (!quantization && details.quantizations.length > 0) {\n\t\t\tconst options = details.quantizations.map((entry) => {\n\t\t\t\tconst detail = [\n\t\t\t\t\tentry.size === undefined ? undefined : formatBytes(entry.size),\n\t\t\t\t\tentry.name === \"Q4_K_M\" ? \"recommended\" : undefined,\n\t\t\t\t]\n\t\t\t\t\t.filter((value): value is string => Boolean(value))\n\t\t\t\t\t.join(\" · \");\n\t\t\t\treturn detail ? `${entry.name} · ${detail}` : entry.name;\n\t\t\t});\n\t\t\tconst choice = await ui.select(`Select quantization\\n${details.id}`, options);\n\t\t\tif (!choice) return;\n\t\t\tquantization = details.quantizations[options.indexOf(choice)]?.name;\n\t\t\tif (!quantization) return;\n\t\t}\n\t\tconst model = quantization ? `${details.id}:${quantization}` : details.id;\n\t\tconst result = await runWithProgress(ui, {\n\t\t\ttitle: \"Downloading model\",\n\t\t\tmodel,\n\t\t\tinitialMessage: \"Starting…\",\n\t\t\tcancelTitle: \"Stop download?\",\n\t\t\tcancelMessage: model,\n\t\t\trun: (signal, update) => client.downloadAndWait(model, update, signal),\n\t\t\tcancel: () => client.unload(model),\n\t\t});\n\t\tif (result.cancelled) return;\n\t\tawait syncCatalog(ctx, client, result.value);\n\t\tctx.ui.notify(`Downloaded ${model}`);\n\t};\n\n\tpi.registerCommand(\"llama\", {\n\t\tdescription: \"Manage llama.cpp router models\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\tctx.ui.notify(\"/llama is available in interactive mode\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst client = await configuredClient(ctx);\n\t\t\tif (!client) return;\n\t\t\tawait showLlamaUi(ctx, async (ui) => {\n\t\t\t\tconst readCatalog = async (): Promise<LlamaModelInfo[] | undefined> => {\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn await syncCatalog(ctx, client);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif ((await ui.connectionError(client.serverUrl, connectionErrorMessage(error))) === \"close\") {\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tlet catalog = await readCatalog();\n\t\t\t\tif (!catalog) return;\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst action = await ui.showModels(client.serverUrl, catalog);\n\t\t\t\t\tif (action.type === \"close\") return;\n\t\t\t\t\tlet actionError: unknown;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (action.type === \"download\") await downloadModel(ctx, ui, client);\n\t\t\t\t\t\telse if (modelIsLoaded(action.model)) await unloadModel(ctx, ui, client, action.model);\n\t\t\t\t\t\telse if (action.model.status.value === \"unloaded\")\n\t\t\t\t\t\t\tawait loadModel(ctx, ui, client, catalog, action.model);\n\t\t\t\t\t\telse ctx.ui.notify(`${action.model.id} is ${action.model.status.value}`, \"warning\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tactionError = error;\n\t\t\t\t\t}\n\t\t\t\t\tconst refreshed = await readCatalog();\n\t\t\t\t\tif (!refreshed) return;\n\t\t\t\t\tcatalog = refreshed;\n\t\t\t\t\tif (actionError && !isConnectionError(actionError)) {\n\t\t\t\t\t\tctx.ui.notify(actionError instanceof Error ? actionError.message : String(actionError), \"error\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t});\n}\n"]}
|
|
@@ -25,7 +25,7 @@ function parseHuggingFaceModel(value) {
|
|
|
25
25
|
async function configuredClient(ctx) {
|
|
26
26
|
const result = await ctx.modelRegistry.getProviderAuth(LLAMA_PROVIDER_ID);
|
|
27
27
|
if (!result) {
|
|
28
|
-
ctx.ui.notify(`Configure llama.cpp with /
|
|
28
|
+
ctx.ui.notify(`Configure llama.cpp with /byok ${LLAMA_PROVIDER_ID}`, "warning");
|
|
29
29
|
return undefined;
|
|
30
30
|
}
|
|
31
31
|
const configuredUrl = result.env?.LLAMA_BASE_URL;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/llama/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { formatBytes, LlamaClient, type LlamaModelInfo, normalizeLlamaServerUrl } from \"./client.ts\";\nimport { findHuggingFaceToken, HuggingFaceClient } from \"./huggingface.ts\";\nimport { createLlamaProvider, LLAMA_PROVIDER_ID } from \"./provider.ts\";\nimport { type LlamaUi, runWithProgress, showLlamaUi } from \"./ui.ts\";\n\nfunction modelIsLoaded(model: LlamaModelInfo): boolean {\n\treturn model.status.value === \"loaded\" || model.status.value === \"sleeping\";\n}\n\nfunction isConnectionError(error: unknown): boolean {\n\tif (!(error instanceof Error)) return false;\n\tconst message = `${error.name} ${error.message}`.toLowerCase();\n\treturn message.includes(\"fetch failed\") || message.includes(\"timeout\") || message.includes(\"network\");\n}\n\nfunction connectionErrorMessage(error: unknown): string {\n\tif (isConnectionError(error)) return \"Could not connect to the server.\";\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction parseHuggingFaceModel(value: string): { repository: string; quantization?: string } {\n\tconst colon = value.indexOf(\":\", value.indexOf(\"/\") + 1);\n\treturn colon < 0\n\t\t? { repository: value }\n\t\t: { repository: value.slice(0, colon), quantization: value.slice(colon + 1) };\n}\n\nasync function configuredClient(ctx: ExtensionCommandContext): Promise<LlamaClient | undefined> {\n\tconst result = await ctx.modelRegistry.getProviderAuth(LLAMA_PROVIDER_ID);\n\tif (!result) {\n\t\tctx.ui.notify(`Configure llama.cpp with /login ${LLAMA_PROVIDER_ID}`, \"warning\");\n\t\treturn undefined;\n\t}\n\tconst configuredUrl = result.env?.LLAMA_BASE_URL;\n\tconst serverUrl = normalizeLlamaServerUrl(\n\t\ttypeof configuredUrl === \"string\" && configuredUrl ? configuredUrl : (result.auth.baseUrl ?? \"\"),\n\t);\n\treturn new LlamaClient(serverUrl, result.auth.apiKey);\n}\n\nexport default function llamaExtension(pi: ExtensionAPI): void {\n\tconst provider = createLlamaProvider();\n\tpi.registerProvider(provider.provider);\n\n\tconst syncCatalog = async (\n\t\tctx: ExtensionCommandContext,\n\t\tclient: LlamaClient,\n\t\tcatalog?: LlamaModelInfo[],\n\t): Promise<LlamaModelInfo[]> => {\n\t\tconst signal = AbortSignal.timeout(15_000);\n\t\tconst current = catalog ?? (await client.list({ signal }));\n\t\tprovider.setCatalog(current, client.serverUrl);\n\t\tconst result = await ctx.modelRegistry.refresh({\n\t\t\tproviders: [LLAMA_PROVIDER_ID],\n\t\t\tsignal,\n\t\t});\n\t\tif (result.aborted) throw new Error(\"Model catalog refresh timed out.\");\n\t\tconst refreshError = result.errors.get(LLAMA_PROVIDER_ID);\n\t\tif (refreshError) throw refreshError;\n\t\treturn current;\n\t};\n\n\tconst loadModel = async (\n\t\tctx: ExtensionCommandContext,\n\t\tui: LlamaUi,\n\t\tclient: LlamaClient,\n\t\tcatalog: LlamaModelInfo[],\n\t\ttarget: LlamaModelInfo,\n\t): Promise<void> => {\n\t\tconst loaded = catalog.filter((model) => model.id !== target.id && modelIsLoaded(model));\n\t\tlet replace = false;\n\t\tif (loaded.length > 0) {\n\t\t\tconst choice = await ui.select(`${loaded.length} model${loaded.length === 1 ? \" is\" : \"s are\"} loaded`, [\n\t\t\t\t\"Unload all and load\",\n\t\t\t\t\"Keep loaded and load\",\n\t\t\t\t\"Cancel\",\n\t\t\t]);\n\t\t\tif (!choice || choice === \"Cancel\") return;\n\t\t\treplace = choice === \"Unload all and load\";\n\t\t}\n\n\t\tconst restoreLoaded = async (): Promise<void> => {\n\t\t\tctx.ui.notify(\"Restoring previously loaded models\");\n\t\t\tfor (const model of loaded) await client.loadAndWait(model.id, () => {});\n\t\t\tawait syncCatalog(ctx, client);\n\t\t};\n\t\tif (replace) {\n\t\t\tfor (const model of loaded) await client.unloadAndWait(model.id);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await runWithProgress(ui, {\n\t\t\t\ttitle: \"Loading model\",\n\t\t\t\tmodel: target.id,\n\t\t\t\tinitialMessage: \"Starting…\",\n\t\t\t\tcancelTitle: \"Stop loading?\",\n\t\t\t\tcancelMessage: target.id,\n\t\t\t\trun: (signal, update) => client.loadAndWait(target.id, update, signal),\n\t\t\t\tcancel: () => client.unload(target.id),\n\t\t\t});\n\t\t\tif (result.cancelled) {\n\t\t\t\tif (replace) await restoreLoaded();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst refreshed = await syncCatalog(ctx, client);\n\t\t\tconst loadedModel = refreshed.find((model) => model.id === target.id);\n\t\t\tctx.ui.notify(\n\t\t\t\tloadedModel?.status.value === \"loaded\" ? `Loaded ${target.id}` : `Load started for ${target.id}`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (replace) {\n\t\t\t\ttry {\n\t\t\t\t\tawait restoreLoaded();\n\t\t\t\t} catch {\n\t\t\t\t\t// Preserve the original load error.\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t};\n\n\tconst unloadModel = async (\n\t\tctx: ExtensionCommandContext,\n\t\tui: LlamaUi,\n\t\tclient: LlamaClient,\n\t\tmodel: LlamaModelInfo,\n\t): Promise<void> => {\n\t\tif (!(await ui.confirm(\"Unload model?\", model.id))) return;\n\t\tawait client.unloadAndWait(model.id);\n\t\tawait syncCatalog(ctx, client);\n\t\tctx.ui.notify(`Unloaded ${model.id}`);\n\t};\n\n\tconst downloadModel = async (ctx: ExtensionCommandContext, ui: LlamaUi, client: LlamaClient): Promise<void> => {\n\t\tconst huggingFace = new HuggingFaceClient(await findHuggingFaceToken());\n\t\tconst selected = await ui.searchModels((query, signal) => huggingFace.search(query, signal));\n\t\tif (!selected) return;\n\t\tconst parsed = parseHuggingFaceModel(selected);\n\t\tui.showStatus(\"Loading model details\", parsed.repository);\n\t\tconst details = await huggingFace.details(parsed.repository);\n\t\tif (details.gated) {\n\t\t\tconst approval = details.gated === \"manual\" ? \"Manual approval is required\" : \"Accept the access terms\";\n\t\t\tconst choice = await ui.select(\n\t\t\t\t`Hugging Face access required\\n${details.id}\\n\\n${approval} at:\\nhttps://huggingface.co/${details.id}\\n\\nThe llama.cpp server needs HF_TOKEN with access.`,\n\t\t\t\t[\"Continue\", \"Back\"],\n\t\t\t);\n\t\t\tif (choice !== \"Continue\") return;\n\t\t}\n\t\tlet quantization = parsed.quantization;\n\t\tif (!quantization && details.quantizations.length > 0) {\n\t\t\tconst options = details.quantizations.map((entry) => {\n\t\t\t\tconst detail = [\n\t\t\t\t\tentry.size === undefined ? undefined : formatBytes(entry.size),\n\t\t\t\t\tentry.name === \"Q4_K_M\" ? \"recommended\" : undefined,\n\t\t\t\t]\n\t\t\t\t\t.filter((value): value is string => Boolean(value))\n\t\t\t\t\t.join(\" · \");\n\t\t\t\treturn detail ? `${entry.name} · ${detail}` : entry.name;\n\t\t\t});\n\t\t\tconst choice = await ui.select(`Select quantization\\n${details.id}`, options);\n\t\t\tif (!choice) return;\n\t\t\tquantization = details.quantizations[options.indexOf(choice)]?.name;\n\t\t\tif (!quantization) return;\n\t\t}\n\t\tconst model = quantization ? `${details.id}:${quantization}` : details.id;\n\t\tconst result = await runWithProgress(ui, {\n\t\t\ttitle: \"Downloading model\",\n\t\t\tmodel,\n\t\t\tinitialMessage: \"Starting…\",\n\t\t\tcancelTitle: \"Stop download?\",\n\t\t\tcancelMessage: model,\n\t\t\trun: (signal, update) => client.downloadAndWait(model, update, signal),\n\t\t\tcancel: () => client.unload(model),\n\t\t});\n\t\tif (result.cancelled) return;\n\t\tawait syncCatalog(ctx, client, result.value);\n\t\tctx.ui.notify(`Downloaded ${model}`);\n\t};\n\n\tpi.registerCommand(\"llama\", {\n\t\tdescription: \"Manage llama.cpp router models\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\tctx.ui.notify(\"/llama is available in interactive mode\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst client = await configuredClient(ctx);\n\t\t\tif (!client) return;\n\t\t\tawait showLlamaUi(ctx, async (ui) => {\n\t\t\t\tconst readCatalog = async (): Promise<LlamaModelInfo[] | undefined> => {\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn await syncCatalog(ctx, client);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif ((await ui.connectionError(client.serverUrl, connectionErrorMessage(error))) === \"close\") {\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tlet catalog = await readCatalog();\n\t\t\t\tif (!catalog) return;\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst action = await ui.showModels(client.serverUrl, catalog);\n\t\t\t\t\tif (action.type === \"close\") return;\n\t\t\t\t\tlet actionError: unknown;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (action.type === \"download\") await downloadModel(ctx, ui, client);\n\t\t\t\t\t\telse if (modelIsLoaded(action.model)) await unloadModel(ctx, ui, client, action.model);\n\t\t\t\t\t\telse if (action.model.status.value === \"unloaded\")\n\t\t\t\t\t\t\tawait loadModel(ctx, ui, client, catalog, action.model);\n\t\t\t\t\t\telse ctx.ui.notify(`${action.model.id} is ${action.model.status.value}`, \"warning\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tactionError = error;\n\t\t\t\t\t}\n\t\t\t\t\tconst refreshed = await readCatalog();\n\t\t\t\t\tif (!refreshed) return;\n\t\t\t\t\tcatalog = refreshed;\n\t\t\t\t\tif (actionError && !isConnectionError(actionError)) {\n\t\t\t\t\t\tctx.ui.notify(actionError instanceof Error ? actionError.message : String(actionError), \"error\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/llama/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { formatBytes, LlamaClient, type LlamaModelInfo, normalizeLlamaServerUrl } from \"./client.ts\";\nimport { findHuggingFaceToken, HuggingFaceClient } from \"./huggingface.ts\";\nimport { createLlamaProvider, LLAMA_PROVIDER_ID } from \"./provider.ts\";\nimport { type LlamaUi, runWithProgress, showLlamaUi } from \"./ui.ts\";\n\nfunction modelIsLoaded(model: LlamaModelInfo): boolean {\n\treturn model.status.value === \"loaded\" || model.status.value === \"sleeping\";\n}\n\nfunction isConnectionError(error: unknown): boolean {\n\tif (!(error instanceof Error)) return false;\n\tconst message = `${error.name} ${error.message}`.toLowerCase();\n\treturn message.includes(\"fetch failed\") || message.includes(\"timeout\") || message.includes(\"network\");\n}\n\nfunction connectionErrorMessage(error: unknown): string {\n\tif (isConnectionError(error)) return \"Could not connect to the server.\";\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction parseHuggingFaceModel(value: string): { repository: string; quantization?: string } {\n\tconst colon = value.indexOf(\":\", value.indexOf(\"/\") + 1);\n\treturn colon < 0\n\t\t? { repository: value }\n\t\t: { repository: value.slice(0, colon), quantization: value.slice(colon + 1) };\n}\n\nasync function configuredClient(ctx: ExtensionCommandContext): Promise<LlamaClient | undefined> {\n\tconst result = await ctx.modelRegistry.getProviderAuth(LLAMA_PROVIDER_ID);\n\tif (!result) {\n\t\tctx.ui.notify(`Configure llama.cpp with /byok ${LLAMA_PROVIDER_ID}`, \"warning\");\n\t\treturn undefined;\n\t}\n\tconst configuredUrl = result.env?.LLAMA_BASE_URL;\n\tconst serverUrl = normalizeLlamaServerUrl(\n\t\ttypeof configuredUrl === \"string\" && configuredUrl ? configuredUrl : (result.auth.baseUrl ?? \"\"),\n\t);\n\treturn new LlamaClient(serverUrl, result.auth.apiKey);\n}\n\nexport default function llamaExtension(pi: ExtensionAPI): void {\n\tconst provider = createLlamaProvider();\n\tpi.registerProvider(provider.provider);\n\n\tconst syncCatalog = async (\n\t\tctx: ExtensionCommandContext,\n\t\tclient: LlamaClient,\n\t\tcatalog?: LlamaModelInfo[],\n\t): Promise<LlamaModelInfo[]> => {\n\t\tconst signal = AbortSignal.timeout(15_000);\n\t\tconst current = catalog ?? (await client.list({ signal }));\n\t\tprovider.setCatalog(current, client.serverUrl);\n\t\tconst result = await ctx.modelRegistry.refresh({\n\t\t\tproviders: [LLAMA_PROVIDER_ID],\n\t\t\tsignal,\n\t\t});\n\t\tif (result.aborted) throw new Error(\"Model catalog refresh timed out.\");\n\t\tconst refreshError = result.errors.get(LLAMA_PROVIDER_ID);\n\t\tif (refreshError) throw refreshError;\n\t\treturn current;\n\t};\n\n\tconst loadModel = async (\n\t\tctx: ExtensionCommandContext,\n\t\tui: LlamaUi,\n\t\tclient: LlamaClient,\n\t\tcatalog: LlamaModelInfo[],\n\t\ttarget: LlamaModelInfo,\n\t): Promise<void> => {\n\t\tconst loaded = catalog.filter((model) => model.id !== target.id && modelIsLoaded(model));\n\t\tlet replace = false;\n\t\tif (loaded.length > 0) {\n\t\t\tconst choice = await ui.select(`${loaded.length} model${loaded.length === 1 ? \" is\" : \"s are\"} loaded`, [\n\t\t\t\t\"Unload all and load\",\n\t\t\t\t\"Keep loaded and load\",\n\t\t\t\t\"Cancel\",\n\t\t\t]);\n\t\t\tif (!choice || choice === \"Cancel\") return;\n\t\t\treplace = choice === \"Unload all and load\";\n\t\t}\n\n\t\tconst restoreLoaded = async (): Promise<void> => {\n\t\t\tctx.ui.notify(\"Restoring previously loaded models\");\n\t\t\tfor (const model of loaded) await client.loadAndWait(model.id, () => {});\n\t\t\tawait syncCatalog(ctx, client);\n\t\t};\n\t\tif (replace) {\n\t\t\tfor (const model of loaded) await client.unloadAndWait(model.id);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await runWithProgress(ui, {\n\t\t\t\ttitle: \"Loading model\",\n\t\t\t\tmodel: target.id,\n\t\t\t\tinitialMessage: \"Starting…\",\n\t\t\t\tcancelTitle: \"Stop loading?\",\n\t\t\t\tcancelMessage: target.id,\n\t\t\t\trun: (signal, update) => client.loadAndWait(target.id, update, signal),\n\t\t\t\tcancel: () => client.unload(target.id),\n\t\t\t});\n\t\t\tif (result.cancelled) {\n\t\t\t\tif (replace) await restoreLoaded();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst refreshed = await syncCatalog(ctx, client);\n\t\t\tconst loadedModel = refreshed.find((model) => model.id === target.id);\n\t\t\tctx.ui.notify(\n\t\t\t\tloadedModel?.status.value === \"loaded\" ? `Loaded ${target.id}` : `Load started for ${target.id}`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (replace) {\n\t\t\t\ttry {\n\t\t\t\t\tawait restoreLoaded();\n\t\t\t\t} catch {\n\t\t\t\t\t// Preserve the original load error.\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t};\n\n\tconst unloadModel = async (\n\t\tctx: ExtensionCommandContext,\n\t\tui: LlamaUi,\n\t\tclient: LlamaClient,\n\t\tmodel: LlamaModelInfo,\n\t): Promise<void> => {\n\t\tif (!(await ui.confirm(\"Unload model?\", model.id))) return;\n\t\tawait client.unloadAndWait(model.id);\n\t\tawait syncCatalog(ctx, client);\n\t\tctx.ui.notify(`Unloaded ${model.id}`);\n\t};\n\n\tconst downloadModel = async (ctx: ExtensionCommandContext, ui: LlamaUi, client: LlamaClient): Promise<void> => {\n\t\tconst huggingFace = new HuggingFaceClient(await findHuggingFaceToken());\n\t\tconst selected = await ui.searchModels((query, signal) => huggingFace.search(query, signal));\n\t\tif (!selected) return;\n\t\tconst parsed = parseHuggingFaceModel(selected);\n\t\tui.showStatus(\"Loading model details\", parsed.repository);\n\t\tconst details = await huggingFace.details(parsed.repository);\n\t\tif (details.gated) {\n\t\t\tconst approval = details.gated === \"manual\" ? \"Manual approval is required\" : \"Accept the access terms\";\n\t\t\tconst choice = await ui.select(\n\t\t\t\t`Hugging Face access required\\n${details.id}\\n\\n${approval} at:\\nhttps://huggingface.co/${details.id}\\n\\nThe llama.cpp server needs HF_TOKEN with access.`,\n\t\t\t\t[\"Continue\", \"Back\"],\n\t\t\t);\n\t\t\tif (choice !== \"Continue\") return;\n\t\t}\n\t\tlet quantization = parsed.quantization;\n\t\tif (!quantization && details.quantizations.length > 0) {\n\t\t\tconst options = details.quantizations.map((entry) => {\n\t\t\t\tconst detail = [\n\t\t\t\t\tentry.size === undefined ? undefined : formatBytes(entry.size),\n\t\t\t\t\tentry.name === \"Q4_K_M\" ? \"recommended\" : undefined,\n\t\t\t\t]\n\t\t\t\t\t.filter((value): value is string => Boolean(value))\n\t\t\t\t\t.join(\" · \");\n\t\t\t\treturn detail ? `${entry.name} · ${detail}` : entry.name;\n\t\t\t});\n\t\t\tconst choice = await ui.select(`Select quantization\\n${details.id}`, options);\n\t\t\tif (!choice) return;\n\t\t\tquantization = details.quantizations[options.indexOf(choice)]?.name;\n\t\t\tif (!quantization) return;\n\t\t}\n\t\tconst model = quantization ? `${details.id}:${quantization}` : details.id;\n\t\tconst result = await runWithProgress(ui, {\n\t\t\ttitle: \"Downloading model\",\n\t\t\tmodel,\n\t\t\tinitialMessage: \"Starting…\",\n\t\t\tcancelTitle: \"Stop download?\",\n\t\t\tcancelMessage: model,\n\t\t\trun: (signal, update) => client.downloadAndWait(model, update, signal),\n\t\t\tcancel: () => client.unload(model),\n\t\t});\n\t\tif (result.cancelled) return;\n\t\tawait syncCatalog(ctx, client, result.value);\n\t\tctx.ui.notify(`Downloaded ${model}`);\n\t};\n\n\tpi.registerCommand(\"llama\", {\n\t\tdescription: \"Manage llama.cpp router models\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\tctx.ui.notify(\"/llama is available in interactive mode\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst client = await configuredClient(ctx);\n\t\t\tif (!client) return;\n\t\t\tawait showLlamaUi(ctx, async (ui) => {\n\t\t\t\tconst readCatalog = async (): Promise<LlamaModelInfo[] | undefined> => {\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn await syncCatalog(ctx, client);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif ((await ui.connectionError(client.serverUrl, connectionErrorMessage(error))) === \"close\") {\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tlet catalog = await readCatalog();\n\t\t\t\tif (!catalog) return;\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst action = await ui.showModels(client.serverUrl, catalog);\n\t\t\t\t\tif (action.type === \"close\") return;\n\t\t\t\t\tlet actionError: unknown;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (action.type === \"download\") await downloadModel(ctx, ui, client);\n\t\t\t\t\t\telse if (modelIsLoaded(action.model)) await unloadModel(ctx, ui, client, action.model);\n\t\t\t\t\t\telse if (action.model.status.value === \"unloaded\")\n\t\t\t\t\t\t\tawait loadModel(ctx, ui, client, catalog, action.model);\n\t\t\t\t\t\telse ctx.ui.notify(`${action.model.id} is ${action.model.status.value}`, \"warning\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tactionError = error;\n\t\t\t\t\t}\n\t\t\t\t\tconst refreshed = await readCatalog();\n\t\t\t\t\tif (!refreshed) return;\n\t\t\t\t\tcatalog = refreshed;\n\t\t\t\t\tif (actionError && !isConnectionError(actionError)) {\n\t\t\t\t\t\tctx.ui.notify(actionError instanceof Error ? actionError.message : String(actionError), \"error\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t});\n}\n"]}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Registry fallback for the default web access extension. Only used when no
|
|
3
|
+
* vendored copy is available (e.g. a source checkout before `npm install`):
|
|
4
|
+
* the published package must never install this at runtime, both because the
|
|
5
|
+
* install is slow/flaky and because the package name is not ours to surface.
|
|
6
|
+
*/
|
|
7
|
+
export declare const WEB_ACCESS_NPM_FALLBACK_SOURCE = "npm:pi-web-access@0.22.0";
|
|
8
|
+
export declare const WEB_ACCESS_EXTENSION_SOURCE: string;
|
|
2
9
|
export declare const WEB_ACCESS_CONFIG_FILENAME = "web-search.json";
|
|
3
10
|
/**
|
|
4
11
|
* Point Pi ecosystem extensions at Nexus's config directory and add Nexus-safe
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-access.d.ts","sourceRoot":"","sources":["../../src/extensions/web-access.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"web-access.d.ts","sourceRoot":"","sources":["../../src/extensions/web-access.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,6BAA6B,CAAC;AA4BzE,eAAO,MAAM,2BAA2B,QAAoC,CAAC;AAC7E,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAgC5D;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAmE/F;AAED,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQpF;AAED,0EAA0E;AAC1E,wBAAgB,6BAA6B,CAC5C,sBAAsB,EAAE,MAAM,EAAE,GAAG,SAAS,EAC5C,oBAAoB,EAAE,OAAO,GAC3B,MAAM,EAAE,GAAG,SAAS,CAStB","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getPackageDir, setAppEnv } from \"../config.ts\";\n\n/**\n * Registry fallback for the default web access extension. Only used when no\n * vendored copy is available (e.g. a source checkout before `npm install`):\n * the published package must never install this at runtime, both because the\n * install is slow/flaky and because the package name is not ours to surface.\n */\nexport const WEB_ACCESS_NPM_FALLBACK_SOURCE = \"npm:pi-web-access@0.22.0\";\n\nfunction resolveWebAccessExtensionSource(): string {\n\tconst packageDir = getPackageDir();\n\t// Source checkout: the extension is a root devDependency, so its TypeScript\n\t// loads directly (tsconfig paths then map its pi imports to the workspace\n\t// sources) instead of npm-installing at runtime or using a stale bundle.\n\tconst sourceCandidates = [\n\t\tjoin(packageDir, \"node_modules\", \"pi-web-access\", \"index.ts\"),\n\t\tjoin(packageDir, \"..\", \"..\", \"node_modules\", \"pi-web-access\", \"index.ts\"),\n\t];\n\t// Published npm build: bundled by scripts/bundle-coding-agent.mjs. Compiled\n\t// binary: assets sit next to the executable, which is what getPackageDir()\n\t// points at there.\n\tconst bundledCandidates = [\n\t\tjoin(packageDir, \"dist\", \"vendor\", \"web-access.js\"),\n\t\tjoin(packageDir, \"vendor\", \"web-access.js\"),\n\t];\n\tconst isTypeScriptSourceRuntime = import.meta.url.endsWith(\".ts\");\n\tconst candidates = isTypeScriptSourceRuntime\n\t\t? [...sourceCandidates, ...bundledCandidates]\n\t\t: [...bundledCandidates, ...sourceCandidates];\n\tfor (const candidate of candidates) {\n\t\tif (existsSync(candidate)) return candidate;\n\t}\n\treturn WEB_ACCESS_NPM_FALLBACK_SOURCE;\n}\n\nexport const WEB_ACCESS_EXTENSION_SOURCE = resolveWebAccessExtensionSource();\nexport const WEB_ACCESS_CONFIG_FILENAME = \"web-search.json\";\n\nconst DEFAULT_WORKFLOW = \"none\";\nconst DEFAULT_WEB_SEARCH_TOOL_NAME = \"websearch\";\nconst DEFAULT_SEARCH_ROUTING = {\n\tproviders: [\n\t\t\"searxng\",\n\t\t\"openai\",\n\t\t\"exa\",\n\t\t\"brave\",\n\t\t\"parallel\",\n\t\t\"tinyfish\",\n\t\t\"search1api\",\n\t\t\"searchinfinity\",\n\t\t\"querit\",\n\t\t\"tavily\",\n\t\t\"jina\",\n\t\t\"serpdive\",\n\t\t\"kagi\",\n\t\t\"bocha\",\n\t\t\"ollama\",\n\t\t\"perplexity\",\n\t\t\"gemini\",\n\t\t\"duckduckgo\",\n\t],\n\tfallbackOn: [\"quota\", \"transient\", \"network\", \"invalid-response\"],\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Point Pi ecosystem extensions at Nexus's config directory and add Nexus-safe\n * defaults without replacing user-selected web access settings.\n */\nexport function prepareWebAccessConfig(agentDir: string): { changed: boolean; warning?: string } {\n\tsetAppEnv(\"CODING_AGENT_DIR\", agentDir);\n\tconst configPath = join(agentDir, WEB_ACCESS_CONFIG_FILENAME);\n\n\tlet config: Record<string, unknown> = {};\n\tif (existsSync(configPath)) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\t\tif (!isRecord(parsed)) {\n\t\t\t\treturn { changed: false };\n\t\t\t}\n\t\t\tconfig = parsed;\n\t\t} catch {\n\t\t\t// pi-web-access reports malformed config with its own path-aware diagnostic.\n\t\t\treturn { changed: false };\n\t\t}\n\t}\n\n\tlet changed = false;\n\tif (config.workflow === undefined) {\n\t\tconfig.workflow = DEFAULT_WORKFLOW;\n\t\tchanged = true;\n\t}\n\n\tif (config.toolNames === undefined) {\n\t\tconfig.toolNames = { webSearch: DEFAULT_WEB_SEARCH_TOOL_NAME };\n\t\tchanged = true;\n\t} else if (isRecord(config.toolNames) && config.toolNames.webSearch === undefined) {\n\t\tconfig.toolNames.webSearch = DEFAULT_WEB_SEARCH_TOOL_NAME;\n\t\tchanged = true;\n\t}\n\n\tconst hasExplicitProvider = config.provider !== undefined || config.searchProvider !== undefined;\n\tif (!hasExplicitProvider && config.searchRouting === undefined) {\n\t\tconfig.searchRouting = DEFAULT_SEARCH_ROUTING;\n\t\tchanged = true;\n\t}\n\n\t// The extension's slash commands (/websearch, /curator, /search,\n\t// /google-account) are operator utilities around the agent-facing tools;\n\t// they don't belong in Nexus's command list. Default them off — a dev can\n\t// re-enable per command with `commands.<name>.enabled: true`.\n\tif (config.commands === undefined) {\n\t\tconfig.commands = {\n\t\t\twebsearch: { enabled: false },\n\t\t\tcurator: { enabled: false },\n\t\t\tsearch: { enabled: false },\n\t\t\t\"google-account\": { enabled: false },\n\t\t};\n\t\tchanged = true;\n\t}\n\n\tif (!changed) {\n\t\treturn { changed: false };\n\t}\n\n\ttry {\n\t\tmkdirSync(agentDir, { recursive: true });\n\t\twriteFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\treturn { changed: true };\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\treturn { changed: false, warning: `Could not write web access defaults to ${configPath}: ${message}` };\n\t}\n}\n\nexport function readConfiguredWebSearchToolName(agentDir: string): string | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(readFileSync(join(agentDir, WEB_ACCESS_CONFIG_FILENAME), \"utf-8\"));\n\t\tif (!isRecord(parsed) || !isRecord(parsed.toolNames)) return undefined;\n\t\treturn typeof parsed.toolNames.webSearch === \"string\" ? parsed.toolNames.webSearch : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Omit Nexus's default package without suppressing explicit -e paths. */\nexport function withDefaultWebAccessExtension(\n\texplicitExtensionPaths: string[] | undefined,\n\tomitDefaultExtension: boolean,\n): string[] | undefined {\n\tif (omitDefaultExtension) {\n\t\treturn explicitExtensionPaths;\n\t}\n\n\treturn [\n\t\tWEB_ACCESS_EXTENSION_SOURCE,\n\t\t...(explicitExtensionPaths ?? []).filter((source) => source !== WEB_ACCESS_EXTENSION_SOURCE),\n\t];\n}\n"]}
|
|
@@ -1,7 +1,40 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { setAppEnv } from "../config.js";
|
|
4
|
-
|
|
3
|
+
import { getPackageDir, setAppEnv } from "../config.js";
|
|
4
|
+
/**
|
|
5
|
+
* Registry fallback for the default web access extension. Only used when no
|
|
6
|
+
* vendored copy is available (e.g. a source checkout before `npm install`):
|
|
7
|
+
* the published package must never install this at runtime, both because the
|
|
8
|
+
* install is slow/flaky and because the package name is not ours to surface.
|
|
9
|
+
*/
|
|
10
|
+
export const WEB_ACCESS_NPM_FALLBACK_SOURCE = "npm:pi-web-access@0.22.0";
|
|
11
|
+
function resolveWebAccessExtensionSource() {
|
|
12
|
+
const packageDir = getPackageDir();
|
|
13
|
+
// Source checkout: the extension is a root devDependency, so its TypeScript
|
|
14
|
+
// loads directly (tsconfig paths then map its pi imports to the workspace
|
|
15
|
+
// sources) instead of npm-installing at runtime or using a stale bundle.
|
|
16
|
+
const sourceCandidates = [
|
|
17
|
+
join(packageDir, "node_modules", "pi-web-access", "index.ts"),
|
|
18
|
+
join(packageDir, "..", "..", "node_modules", "pi-web-access", "index.ts"),
|
|
19
|
+
];
|
|
20
|
+
// Published npm build: bundled by scripts/bundle-coding-agent.mjs. Compiled
|
|
21
|
+
// binary: assets sit next to the executable, which is what getPackageDir()
|
|
22
|
+
// points at there.
|
|
23
|
+
const bundledCandidates = [
|
|
24
|
+
join(packageDir, "dist", "vendor", "web-access.js"),
|
|
25
|
+
join(packageDir, "vendor", "web-access.js"),
|
|
26
|
+
];
|
|
27
|
+
const isTypeScriptSourceRuntime = import.meta.url.endsWith(".ts");
|
|
28
|
+
const candidates = isTypeScriptSourceRuntime
|
|
29
|
+
? [...sourceCandidates, ...bundledCandidates]
|
|
30
|
+
: [...bundledCandidates, ...sourceCandidates];
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
if (existsSync(candidate))
|
|
33
|
+
return candidate;
|
|
34
|
+
}
|
|
35
|
+
return WEB_ACCESS_NPM_FALLBACK_SOURCE;
|
|
36
|
+
}
|
|
37
|
+
export const WEB_ACCESS_EXTENSION_SOURCE = resolveWebAccessExtensionSource();
|
|
5
38
|
export const WEB_ACCESS_CONFIG_FILENAME = "web-search.json";
|
|
6
39
|
const DEFAULT_WORKFLOW = "none";
|
|
7
40
|
const DEFAULT_WEB_SEARCH_TOOL_NAME = "websearch";
|
|
@@ -70,6 +103,19 @@ export function prepareWebAccessConfig(agentDir) {
|
|
|
70
103
|
config.searchRouting = DEFAULT_SEARCH_ROUTING;
|
|
71
104
|
changed = true;
|
|
72
105
|
}
|
|
106
|
+
// The extension's slash commands (/websearch, /curator, /search,
|
|
107
|
+
// /google-account) are operator utilities around the agent-facing tools;
|
|
108
|
+
// they don't belong in Nexus's command list. Default them off — a dev can
|
|
109
|
+
// re-enable per command with `commands.<name>.enabled: true`.
|
|
110
|
+
if (config.commands === undefined) {
|
|
111
|
+
config.commands = {
|
|
112
|
+
websearch: { enabled: false },
|
|
113
|
+
curator: { enabled: false },
|
|
114
|
+
search: { enabled: false },
|
|
115
|
+
"google-account": { enabled: false },
|
|
116
|
+
};
|
|
117
|
+
changed = true;
|
|
118
|
+
}
|
|
73
119
|
if (!changed) {
|
|
74
120
|
return { changed: false };
|
|
75
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-access.js","sourceRoot":"","sources":["../../src/extensions/web-access.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { setAppEnv } from \"../config.ts\";\n\nexport const WEB_ACCESS_EXTENSION_SOURCE = \"npm:pi-web-access@0.22.0\";\nexport const WEB_ACCESS_CONFIG_FILENAME = \"web-search.json\";\n\nconst DEFAULT_WORKFLOW = \"none\";\nconst DEFAULT_WEB_SEARCH_TOOL_NAME = \"websearch\";\nconst DEFAULT_SEARCH_ROUTING = {\n\tproviders: [\n\t\t\"searxng\",\n\t\t\"openai\",\n\t\t\"exa\",\n\t\t\"brave\",\n\t\t\"parallel\",\n\t\t\"tinyfish\",\n\t\t\"search1api\",\n\t\t\"searchinfinity\",\n\t\t\"querit\",\n\t\t\"tavily\",\n\t\t\"jina\",\n\t\t\"serpdive\",\n\t\t\"kagi\",\n\t\t\"bocha\",\n\t\t\"ollama\",\n\t\t\"perplexity\",\n\t\t\"gemini\",\n\t\t\"duckduckgo\",\n\t],\n\tfallbackOn: [\"quota\", \"transient\", \"network\", \"invalid-response\"],\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Point Pi ecosystem extensions at Nexus's config directory and add Nexus-safe\n * defaults without replacing user-selected web access settings.\n */\nexport function prepareWebAccessConfig(agentDir: string): { changed: boolean; warning?: string } {\n\tsetAppEnv(\"CODING_AGENT_DIR\", agentDir);\n\tconst configPath = join(agentDir, WEB_ACCESS_CONFIG_FILENAME);\n\n\tlet config: Record<string, unknown> = {};\n\tif (existsSync(configPath)) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\t\tif (!isRecord(parsed)) {\n\t\t\t\treturn { changed: false };\n\t\t\t}\n\t\t\tconfig = parsed;\n\t\t} catch {\n\t\t\t// pi-web-access reports malformed config with its own path-aware diagnostic.\n\t\t\treturn { changed: false };\n\t\t}\n\t}\n\n\tlet changed = false;\n\tif (config.workflow === undefined) {\n\t\tconfig.workflow = DEFAULT_WORKFLOW;\n\t\tchanged = true;\n\t}\n\n\tif (config.toolNames === undefined) {\n\t\tconfig.toolNames = { webSearch: DEFAULT_WEB_SEARCH_TOOL_NAME };\n\t\tchanged = true;\n\t} else if (isRecord(config.toolNames) && config.toolNames.webSearch === undefined) {\n\t\tconfig.toolNames.webSearch = DEFAULT_WEB_SEARCH_TOOL_NAME;\n\t\tchanged = true;\n\t}\n\n\tconst hasExplicitProvider = config.provider !== undefined || config.searchProvider !== undefined;\n\tif (!hasExplicitProvider && config.searchRouting === undefined) {\n\t\tconfig.searchRouting = DEFAULT_SEARCH_ROUTING;\n\t\tchanged = true;\n\t}\n\n\tif (!changed) {\n\t\treturn { changed: false };\n\t}\n\n\ttry {\n\t\tmkdirSync(agentDir, { recursive: true });\n\t\twriteFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\treturn { changed: true };\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\treturn { changed: false, warning: `Could not write web access defaults to ${configPath}: ${message}` };\n\t}\n}\n\nexport function readConfiguredWebSearchToolName(agentDir: string): string | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(readFileSync(join(agentDir, WEB_ACCESS_CONFIG_FILENAME), \"utf-8\"));\n\t\tif (!isRecord(parsed) || !isRecord(parsed.toolNames)) return undefined;\n\t\treturn typeof parsed.toolNames.webSearch === \"string\" ? parsed.toolNames.webSearch : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Omit Nexus's default package without suppressing explicit -e paths. */\nexport function withDefaultWebAccessExtension(\n\texplicitExtensionPaths: string[] | undefined,\n\tomitDefaultExtension: boolean,\n): string[] | undefined {\n\tif (omitDefaultExtension) {\n\t\treturn explicitExtensionPaths;\n\t}\n\n\treturn [\n\t\tWEB_ACCESS_EXTENSION_SOURCE,\n\t\t...(explicitExtensionPaths ?? []).filter((source) => source !== WEB_ACCESS_EXTENSION_SOURCE),\n\t];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"web-access.js","sourceRoot":"","sources":["../../src/extensions/web-access.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getPackageDir, setAppEnv } from \"../config.ts\";\n\n/**\n * Registry fallback for the default web access extension. Only used when no\n * vendored copy is available (e.g. a source checkout before `npm install`):\n * the published package must never install this at runtime, both because the\n * install is slow/flaky and because the package name is not ours to surface.\n */\nexport const WEB_ACCESS_NPM_FALLBACK_SOURCE = \"npm:pi-web-access@0.22.0\";\n\nfunction resolveWebAccessExtensionSource(): string {\n\tconst packageDir = getPackageDir();\n\t// Source checkout: the extension is a root devDependency, so its TypeScript\n\t// loads directly (tsconfig paths then map its pi imports to the workspace\n\t// sources) instead of npm-installing at runtime or using a stale bundle.\n\tconst sourceCandidates = [\n\t\tjoin(packageDir, \"node_modules\", \"pi-web-access\", \"index.ts\"),\n\t\tjoin(packageDir, \"..\", \"..\", \"node_modules\", \"pi-web-access\", \"index.ts\"),\n\t];\n\t// Published npm build: bundled by scripts/bundle-coding-agent.mjs. Compiled\n\t// binary: assets sit next to the executable, which is what getPackageDir()\n\t// points at there.\n\tconst bundledCandidates = [\n\t\tjoin(packageDir, \"dist\", \"vendor\", \"web-access.js\"),\n\t\tjoin(packageDir, \"vendor\", \"web-access.js\"),\n\t];\n\tconst isTypeScriptSourceRuntime = import.meta.url.endsWith(\".ts\");\n\tconst candidates = isTypeScriptSourceRuntime\n\t\t? [...sourceCandidates, ...bundledCandidates]\n\t\t: [...bundledCandidates, ...sourceCandidates];\n\tfor (const candidate of candidates) {\n\t\tif (existsSync(candidate)) return candidate;\n\t}\n\treturn WEB_ACCESS_NPM_FALLBACK_SOURCE;\n}\n\nexport const WEB_ACCESS_EXTENSION_SOURCE = resolveWebAccessExtensionSource();\nexport const WEB_ACCESS_CONFIG_FILENAME = \"web-search.json\";\n\nconst DEFAULT_WORKFLOW = \"none\";\nconst DEFAULT_WEB_SEARCH_TOOL_NAME = \"websearch\";\nconst DEFAULT_SEARCH_ROUTING = {\n\tproviders: [\n\t\t\"searxng\",\n\t\t\"openai\",\n\t\t\"exa\",\n\t\t\"brave\",\n\t\t\"parallel\",\n\t\t\"tinyfish\",\n\t\t\"search1api\",\n\t\t\"searchinfinity\",\n\t\t\"querit\",\n\t\t\"tavily\",\n\t\t\"jina\",\n\t\t\"serpdive\",\n\t\t\"kagi\",\n\t\t\"bocha\",\n\t\t\"ollama\",\n\t\t\"perplexity\",\n\t\t\"gemini\",\n\t\t\"duckduckgo\",\n\t],\n\tfallbackOn: [\"quota\", \"transient\", \"network\", \"invalid-response\"],\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Point Pi ecosystem extensions at Nexus's config directory and add Nexus-safe\n * defaults without replacing user-selected web access settings.\n */\nexport function prepareWebAccessConfig(agentDir: string): { changed: boolean; warning?: string } {\n\tsetAppEnv(\"CODING_AGENT_DIR\", agentDir);\n\tconst configPath = join(agentDir, WEB_ACCESS_CONFIG_FILENAME);\n\n\tlet config: Record<string, unknown> = {};\n\tif (existsSync(configPath)) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\t\tif (!isRecord(parsed)) {\n\t\t\t\treturn { changed: false };\n\t\t\t}\n\t\t\tconfig = parsed;\n\t\t} catch {\n\t\t\t// pi-web-access reports malformed config with its own path-aware diagnostic.\n\t\t\treturn { changed: false };\n\t\t}\n\t}\n\n\tlet changed = false;\n\tif (config.workflow === undefined) {\n\t\tconfig.workflow = DEFAULT_WORKFLOW;\n\t\tchanged = true;\n\t}\n\n\tif (config.toolNames === undefined) {\n\t\tconfig.toolNames = { webSearch: DEFAULT_WEB_SEARCH_TOOL_NAME };\n\t\tchanged = true;\n\t} else if (isRecord(config.toolNames) && config.toolNames.webSearch === undefined) {\n\t\tconfig.toolNames.webSearch = DEFAULT_WEB_SEARCH_TOOL_NAME;\n\t\tchanged = true;\n\t}\n\n\tconst hasExplicitProvider = config.provider !== undefined || config.searchProvider !== undefined;\n\tif (!hasExplicitProvider && config.searchRouting === undefined) {\n\t\tconfig.searchRouting = DEFAULT_SEARCH_ROUTING;\n\t\tchanged = true;\n\t}\n\n\t// The extension's slash commands (/websearch, /curator, /search,\n\t// /google-account) are operator utilities around the agent-facing tools;\n\t// they don't belong in Nexus's command list. Default them off — a dev can\n\t// re-enable per command with `commands.<name>.enabled: true`.\n\tif (config.commands === undefined) {\n\t\tconfig.commands = {\n\t\t\twebsearch: { enabled: false },\n\t\t\tcurator: { enabled: false },\n\t\t\tsearch: { enabled: false },\n\t\t\t\"google-account\": { enabled: false },\n\t\t};\n\t\tchanged = true;\n\t}\n\n\tif (!changed) {\n\t\treturn { changed: false };\n\t}\n\n\ttry {\n\t\tmkdirSync(agentDir, { recursive: true });\n\t\twriteFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\treturn { changed: true };\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\treturn { changed: false, warning: `Could not write web access defaults to ${configPath}: ${message}` };\n\t}\n}\n\nexport function readConfiguredWebSearchToolName(agentDir: string): string | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(readFileSync(join(agentDir, WEB_ACCESS_CONFIG_FILENAME), \"utf-8\"));\n\t\tif (!isRecord(parsed) || !isRecord(parsed.toolNames)) return undefined;\n\t\treturn typeof parsed.toolNames.webSearch === \"string\" ? parsed.toolNames.webSearch : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Omit Nexus's default package without suppressing explicit -e paths. */\nexport function withDefaultWebAccessExtension(\n\texplicitExtensionPaths: string[] | undefined,\n\tomitDefaultExtension: boolean,\n): string[] | undefined {\n\tif (omitDefaultExtension) {\n\t\treturn explicitExtensionPaths;\n\t}\n\n\treturn [\n\t\tWEB_ACCESS_EXTENSION_SOURCE,\n\t\t...(explicitExtensionPaths ?? []).filter((source) => source !== WEB_ACCESS_EXTENSION_SOURCE),\n\t];\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -9283,7 +9283,7 @@ try {
|
|
|
9283
9283
|
throw e;
|
|
9284
9284
|
}
|
|
9285
9285
|
var piConfigName = pkg.piConfig?.name;
|
|
9286
|
-
var PACKAGE_NAME = pkg.name || "@
|
|
9286
|
+
var PACKAGE_NAME = pkg.name || "@akon-labs/nexus-cli";
|
|
9287
9287
|
var APP_NAME = piConfigName || "nexus";
|
|
9288
9288
|
var APP_TITLE = piConfigName ? APP_NAME : "Nexus";
|
|
9289
9289
|
var CONFIG_DIR_NAME = pkg.piConfig?.configDir || ".nexus";
|
|
@@ -29683,7 +29683,6 @@ function createToolHtmlRenderer(deps) {
|
|
|
29683
29683
|
|
|
29684
29684
|
// dist/core/extensions/loader.js
|
|
29685
29685
|
import * as fs5 from "node:fs";
|
|
29686
|
-
import { createRequire as createRequire4 } from "node:module";
|
|
29687
29686
|
import * as path7 from "node:path";
|
|
29688
29687
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
29689
29688
|
|
|
@@ -35972,6 +35971,14 @@ var VIRTUAL_MODULES = {
|
|
|
35972
35971
|
"@earendil-works/pi-ai/oauth": oauth_exports,
|
|
35973
35972
|
"@earendil-works/pi-ai/providers/all": all_exports,
|
|
35974
35973
|
"@earendil-works/pi-coding-agent": index_exports,
|
|
35974
|
+
// The fork's own SDK names: without these mappings, an extension importing
|
|
35975
|
+
// them would resolve the installed package from disk and load a second copy
|
|
35976
|
+
// instead of sharing the host's instances. These are also the only names
|
|
35977
|
+
// the public docs/examples use for the pi ecosystem packages.
|
|
35978
|
+
"@akon-labs/nexus-cli": index_exports,
|
|
35979
|
+
"@akon-labs/nexus-cli/agent-core": src_exports2,
|
|
35980
|
+
"@akon-labs/nexus-cli/tui": src_exports,
|
|
35981
|
+
"@akon-labs/nexus-cli/ai": compat_exports,
|
|
35975
35982
|
"@mariozechner/pi-agent-core": src_exports2,
|
|
35976
35983
|
"@mariozechner/pi-tui": src_exports,
|
|
35977
35984
|
"@mariozechner/pi-ai": compat_exports,
|
|
@@ -35980,55 +35987,7 @@ var VIRTUAL_MODULES = {
|
|
|
35980
35987
|
"@mariozechner/pi-ai/providers/all": all_exports,
|
|
35981
35988
|
"@mariozechner/pi-coding-agent": index_exports
|
|
35982
35989
|
};
|
|
35983
|
-
var require3 = createRequire4(import.meta.url);
|
|
35984
35990
|
var isTypeScriptSourceRuntime = !isBunBinary && path7.extname(fileURLToPath6(import.meta.url)) === ".ts";
|
|
35985
|
-
var _aliases = null;
|
|
35986
|
-
function getAliases() {
|
|
35987
|
-
if (_aliases)
|
|
35988
|
-
return _aliases;
|
|
35989
|
-
const __dirname2 = path7.dirname(fileURLToPath6(import.meta.url));
|
|
35990
|
-
const packageIndex = path7.resolve(__dirname2, "../..", "index.js");
|
|
35991
|
-
const typeboxEntry = require3.resolve("typebox");
|
|
35992
|
-
const typeboxCompileEntry = require3.resolve("typebox/compile");
|
|
35993
|
-
const typeboxValueEntry = require3.resolve("typebox/value");
|
|
35994
|
-
const packagesRoot = path7.resolve(__dirname2, "../../../../");
|
|
35995
|
-
const resolveWorkspaceOrImport = (workspaceRelativePath, specifier) => {
|
|
35996
|
-
const workspacePath = path7.join(packagesRoot, workspaceRelativePath);
|
|
35997
|
-
if (fs5.existsSync(workspacePath)) {
|
|
35998
|
-
return workspacePath;
|
|
35999
|
-
}
|
|
36000
|
-
return fileURLToPath6(import.meta.resolve(specifier));
|
|
36001
|
-
};
|
|
36002
|
-
const piCodingAgentEntry = packageIndex;
|
|
36003
|
-
const piAgentCoreEntry = resolveWorkspaceOrImport("agent/dist/index.js", "@earendil-works/pi-agent-core");
|
|
36004
|
-
const piTuiEntry = resolveWorkspaceOrImport("tui/dist/index.js", "@earendil-works/pi-tui");
|
|
36005
|
-
const piAiCompatEntry = resolveWorkspaceOrImport("ai/dist/compat.js", "@earendil-works/pi-ai/compat");
|
|
36006
|
-
const piAiOauthEntry = resolveWorkspaceOrImport("ai/dist/oauth.js", "@earendil-works/pi-ai/oauth");
|
|
36007
|
-
const piAiProvidersEntry = resolveWorkspaceOrImport("ai/dist/providers/all.js", "@earendil-works/pi-ai/providers/all");
|
|
36008
|
-
_aliases = {
|
|
36009
|
-
"@earendil-works/pi-coding-agent": piCodingAgentEntry,
|
|
36010
|
-
"@earendil-works/pi-agent-core": piAgentCoreEntry,
|
|
36011
|
-
"@earendil-works/pi-tui": piTuiEntry,
|
|
36012
|
-
"@earendil-works/pi-ai/providers/all": piAiProvidersEntry,
|
|
36013
|
-
"@earendil-works/pi-ai/compat": piAiCompatEntry,
|
|
36014
|
-
"@earendil-works/pi-ai/oauth": piAiOauthEntry,
|
|
36015
|
-
"@earendil-works/pi-ai": piAiCompatEntry,
|
|
36016
|
-
"@mariozechner/pi-coding-agent": piCodingAgentEntry,
|
|
36017
|
-
"@mariozechner/pi-agent-core": piAgentCoreEntry,
|
|
36018
|
-
"@mariozechner/pi-tui": piTuiEntry,
|
|
36019
|
-
"@mariozechner/pi-ai/providers/all": piAiProvidersEntry,
|
|
36020
|
-
"@mariozechner/pi-ai/compat": piAiCompatEntry,
|
|
36021
|
-
"@mariozechner/pi-ai/oauth": piAiOauthEntry,
|
|
36022
|
-
"@mariozechner/pi-ai": piAiCompatEntry,
|
|
36023
|
-
typebox: typeboxEntry,
|
|
36024
|
-
"typebox/compile": typeboxCompileEntry,
|
|
36025
|
-
"typebox/value": typeboxValueEntry,
|
|
36026
|
-
"@sinclair/typebox": typeboxEntry,
|
|
36027
|
-
"@sinclair/typebox/compile": typeboxCompileEntry,
|
|
36028
|
-
"@sinclair/typebox/value": typeboxValueEntry
|
|
36029
|
-
};
|
|
36030
|
-
return _aliases;
|
|
36031
|
-
}
|
|
36032
35991
|
var extensionCacheCwd;
|
|
36033
35992
|
var extensionCacheGeneration = 0;
|
|
36034
35993
|
var extensionCache = /* @__PURE__ */ new Map();
|
|
@@ -36264,9 +36223,14 @@ async function loadExtensionModule(extensionPath, cacheToken) {
|
|
|
36264
36223
|
}
|
|
36265
36224
|
const jiti = createJiti(import.meta.url, {
|
|
36266
36225
|
moduleCache: false,
|
|
36267
|
-
//
|
|
36268
|
-
//
|
|
36269
|
-
|
|
36226
|
+
// All modes serve extensions the statically imported module instances via
|
|
36227
|
+
// virtualModules. This is required for Bun (modules are embedded in the
|
|
36228
|
+
// executable) and for the published npm build (the vendored workspace
|
|
36229
|
+
// packages are inlined into dist/cli.js and exist nowhere on disk), and it
|
|
36230
|
+
// guarantees extensions share the host's module instances rather than
|
|
36231
|
+
// loading a second copy. Source TypeScript additionally resolves through
|
|
36232
|
+
// the root tsconfig paths.
|
|
36233
|
+
...isTypeScriptSourceRuntime && !isBunBinary ? { virtualModules: VIRTUAL_MODULES, tsconfigPaths: true } : { virtualModules: VIRTUAL_MODULES, tryNative: false }
|
|
36270
36234
|
});
|
|
36271
36235
|
const module = await jiti.import(extensionPath, { default: true });
|
|
36272
36236
|
const factory = module;
|
|
@@ -54131,6 +54095,24 @@ import { existsSync as existsSync23, mkdirSync as mkdirSync11, readFileSync as r
|
|
|
54131
54095
|
import { dirname as dirname20, join as join32 } from "node:path";
|
|
54132
54096
|
var AUTO_PROVIDER_ID = "gitnexus";
|
|
54133
54097
|
var AUTO_MODEL_ID = "auto";
|
|
54098
|
+
function parseUsage2(value) {
|
|
54099
|
+
if (!value || typeof value !== "object")
|
|
54100
|
+
return void 0;
|
|
54101
|
+
const usage = value;
|
|
54102
|
+
if (typeof usage.used !== "number" || typeof usage.limit !== "number")
|
|
54103
|
+
return void 0;
|
|
54104
|
+
return {
|
|
54105
|
+
used: usage.used,
|
|
54106
|
+
limit: usage.limit,
|
|
54107
|
+
...typeof usage.remaining === "number" ? { remaining: usage.remaining } : {}
|
|
54108
|
+
};
|
|
54109
|
+
}
|
|
54110
|
+
function formatCreditBalance(policy) {
|
|
54111
|
+
if (!policy?.usage)
|
|
54112
|
+
return void 0;
|
|
54113
|
+
const remaining = policy.usage.remaining ?? Math.max(0, policy.usage.limit - policy.usage.used);
|
|
54114
|
+
return `Nexus Credits: ${remaining.toLocaleString()} / ${policy.usage.limit.toLocaleString()}`;
|
|
54115
|
+
}
|
|
54134
54116
|
function gatewayCachePath() {
|
|
54135
54117
|
return join32(dirname20(gitNexusConfigPath()), "gateway.json");
|
|
54136
54118
|
}
|
|
@@ -54143,7 +54125,7 @@ function readGatewayCache(path11 = gatewayCachePath()) {
|
|
|
54143
54125
|
configured: parsed.configured === true,
|
|
54144
54126
|
contextWindow: parsed.contextWindow,
|
|
54145
54127
|
maxTokens: parsed.maxTokens,
|
|
54146
|
-
usage: parsed.usage
|
|
54128
|
+
usage: parseUsage2(parsed.usage)
|
|
54147
54129
|
};
|
|
54148
54130
|
} catch {
|
|
54149
54131
|
return void 0;
|
|
@@ -54180,7 +54162,7 @@ async function refreshGatewayPolicy(config, options = {}) {
|
|
|
54180
54162
|
configured: body.configured === true,
|
|
54181
54163
|
contextWindow: body.contextWindow,
|
|
54182
54164
|
maxTokens: body.maxTokens,
|
|
54183
|
-
usage: body.usage
|
|
54165
|
+
usage: parseUsage2(body.usage)
|
|
54184
54166
|
};
|
|
54185
54167
|
if (!existsSync23(dirname20(cachePath)))
|
|
54186
54168
|
mkdirSync11(dirname20(cachePath), { recursive: true, mode: 448 });
|
|
@@ -54213,8 +54195,8 @@ function registerAutoProvider(pi, config, policy) {
|
|
|
54213
54195
|
// so none are offered.
|
|
54214
54196
|
reasoning: false,
|
|
54215
54197
|
input: ["text", "image"],
|
|
54216
|
-
// Spend is metered hub-side against
|
|
54217
|
-
// per-token price to show.
|
|
54198
|
+
// Spend is metered hub-side against Nexus Credits; there is no
|
|
54199
|
+
// per-token or dollar price to show.
|
|
54218
54200
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
54219
54201
|
contextWindow: policy.contextWindow,
|
|
54220
54202
|
maxTokens: policy.maxTokens
|
|
@@ -55144,7 +55126,11 @@ function gitnexusExtension(pi) {
|
|
|
55144
55126
|
let startupNotice;
|
|
55145
55127
|
let loginRequired = false;
|
|
55146
55128
|
const cwd = process.cwd();
|
|
55147
|
-
|
|
55129
|
+
let gatewayPolicy = readGatewayCache();
|
|
55130
|
+
registerAutoProvider(pi, resolveGitNexusConfig(), gatewayPolicy);
|
|
55131
|
+
function updateCreditStatus(ctx) {
|
|
55132
|
+
ctx.ui.setStatus("nexus-credits", formatCreditBalance(gatewayPolicy));
|
|
55133
|
+
}
|
|
55148
55134
|
registerAugmentedGrep(pi, cwd, () => activeClient, () => current?.name);
|
|
55149
55135
|
registerChangeTracking(pi, cwd);
|
|
55150
55136
|
async function connect2() {
|
|
@@ -55197,9 +55183,18 @@ function gitnexusExtension(pi) {
|
|
|
55197
55183
|
}
|
|
55198
55184
|
pi.on("session_start", async (_event, ctx) => {
|
|
55199
55185
|
await connect2();
|
|
55186
|
+
updateCreditStatus(ctx);
|
|
55200
55187
|
if (startupNotice)
|
|
55201
55188
|
ctx.ui.notify(startupNotice, inventory ? "info" : "warning");
|
|
55202
55189
|
});
|
|
55190
|
+
pi.on("agent_settled", async (_event, ctx) => {
|
|
55191
|
+
if (!gatewayPolicy || ctx.model?.provider !== "gitnexus")
|
|
55192
|
+
return;
|
|
55193
|
+
const config = resolveGitNexusConfig();
|
|
55194
|
+
if (config)
|
|
55195
|
+
gatewayPolicy = await refreshGatewayPolicy(config);
|
|
55196
|
+
updateCreditStatus(ctx);
|
|
55197
|
+
});
|
|
55203
55198
|
pi.on("resources_discover", (event) => {
|
|
55204
55199
|
const hasOwnGitnexusSkills = existsSync24(join34(event.cwd, ".agents", "skills", "gitnexus")) || existsSync24(join34(homedir11(), ".agents", "skills", "gitnexus-debugging"));
|
|
55205
55200
|
if (hasOwnGitnexusSkills)
|
|
@@ -55255,13 +55250,18 @@ ${buildGitNexusPrompt(inventory, current)}` };
|
|
|
55255
55250
|
pi.registerCommand("gitnexus-status", {
|
|
55256
55251
|
description: "Show GitNexus connection status",
|
|
55257
55252
|
handler: async (_args, ctx) => {
|
|
55253
|
+
const config = resolveGitNexusConfig();
|
|
55254
|
+
if (config)
|
|
55255
|
+
gatewayPolicy = await refreshGatewayPolicy(config);
|
|
55256
|
+
updateCreditStatus(ctx);
|
|
55258
55257
|
if (!inventory) {
|
|
55259
55258
|
const message = loginRequired ? "GitNexus session expired. Run /login to sign in again." : startupNotice ?? "GitNexus: not signed in. Run /login.";
|
|
55260
55259
|
ctx.ui.notify(message, "warning");
|
|
55261
55260
|
return;
|
|
55262
55261
|
}
|
|
55263
55262
|
const repoLine = current ? `current repo: ${current.name}` : "current repo: not indexed";
|
|
55264
|
-
|
|
55263
|
+
const creditLine = formatCreditBalance(gatewayPolicy);
|
|
55264
|
+
ctx.ui.notify(`GitNexus: connected \u2014 ${inventory.repos.length} repos, ${repoLine}${creditLine ? `, ${creditLine}` : ""}`, "info");
|
|
55265
55265
|
}
|
|
55266
55266
|
});
|
|
55267
55267
|
}
|
|
@@ -55661,7 +55661,26 @@ function mcpExtension(pi) {
|
|
|
55661
55661
|
// dist/extensions/web-access.js
|
|
55662
55662
|
import { existsSync as existsSync25, mkdirSync as mkdirSync12, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "node:fs";
|
|
55663
55663
|
import { join as join36 } from "node:path";
|
|
55664
|
-
var
|
|
55664
|
+
var WEB_ACCESS_NPM_FALLBACK_SOURCE = "npm:pi-web-access@0.22.0";
|
|
55665
|
+
function resolveWebAccessExtensionSource() {
|
|
55666
|
+
const packageDir = getPackageDir();
|
|
55667
|
+
const sourceCandidates = [
|
|
55668
|
+
join36(packageDir, "node_modules", "pi-web-access", "index.ts"),
|
|
55669
|
+
join36(packageDir, "..", "..", "node_modules", "pi-web-access", "index.ts")
|
|
55670
|
+
];
|
|
55671
|
+
const bundledCandidates = [
|
|
55672
|
+
join36(packageDir, "dist", "vendor", "web-access.js"),
|
|
55673
|
+
join36(packageDir, "vendor", "web-access.js")
|
|
55674
|
+
];
|
|
55675
|
+
const isTypeScriptSourceRuntime2 = import.meta.url.endsWith(".ts");
|
|
55676
|
+
const candidates = isTypeScriptSourceRuntime2 ? [...sourceCandidates, ...bundledCandidates] : [...bundledCandidates, ...sourceCandidates];
|
|
55677
|
+
for (const candidate of candidates) {
|
|
55678
|
+
if (existsSync25(candidate))
|
|
55679
|
+
return candidate;
|
|
55680
|
+
}
|
|
55681
|
+
return WEB_ACCESS_NPM_FALLBACK_SOURCE;
|
|
55682
|
+
}
|
|
55683
|
+
var WEB_ACCESS_EXTENSION_SOURCE = resolveWebAccessExtensionSource();
|
|
55665
55684
|
var WEB_ACCESS_CONFIG_FILENAME = "web-search.json";
|
|
55666
55685
|
var DEFAULT_WORKFLOW = "none";
|
|
55667
55686
|
var DEFAULT_WEB_SEARCH_TOOL_NAME = "websearch";
|
|
@@ -55723,6 +55742,15 @@ function prepareWebAccessConfig(agentDir) {
|
|
|
55723
55742
|
config.searchRouting = DEFAULT_SEARCH_ROUTING;
|
|
55724
55743
|
changed = true;
|
|
55725
55744
|
}
|
|
55745
|
+
if (config.commands === void 0) {
|
|
55746
|
+
config.commands = {
|
|
55747
|
+
websearch: { enabled: false },
|
|
55748
|
+
curator: { enabled: false },
|
|
55749
|
+
search: { enabled: false },
|
|
55750
|
+
"google-account": { enabled: false }
|
|
55751
|
+
};
|
|
55752
|
+
changed = true;
|
|
55753
|
+
}
|
|
55726
55754
|
if (!changed) {
|
|
55727
55755
|
return { changed: false };
|
|
55728
55756
|
}
|
|
@@ -55862,8 +55890,8 @@ var builtInExtensions = [
|
|
|
55862
55890
|
import chalk9 from "chalk";
|
|
55863
55891
|
import { existsSync as existsSync26, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as readFileSync20, renameSync as renameSync2, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
|
|
55864
55892
|
import { dirname as dirname21, join as join37 } from "path";
|
|
55865
|
-
var MIGRATION_GUIDE_URL = "https://github.com/
|
|
55866
|
-
var EXTENSIONS_DOC_URL = "https://github.com/
|
|
55893
|
+
var MIGRATION_GUIDE_URL = "https://github.com/Akon-Labs/nexus-cli/blob/main/packages/coding-agent/CHANGELOG.upstream.md#extensions-migration";
|
|
55894
|
+
var EXTENSIONS_DOC_URL = "https://github.com/Akon-Labs/nexus-cli/blob/main/packages/coding-agent/docs/extensions.md";
|
|
55867
55895
|
function migrateAuthToAuthJson() {
|
|
55868
55896
|
const agentDir = getAgentDir();
|
|
55869
55897
|
const authPath = join37(agentDir, "auth.json");
|
|
@@ -56195,11 +56223,11 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
56195
56223
|
import { join as join39 } from "path";
|
|
56196
56224
|
|
|
56197
56225
|
// dist/utils/clipboard-native.js
|
|
56198
|
-
import { createRequire as
|
|
56226
|
+
import { createRequire as createRequire4 } from "module";
|
|
56199
56227
|
import { dirname as dirname22, join as join38 } from "path";
|
|
56200
56228
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
56201
|
-
var moduleRequire =
|
|
56202
|
-
var executableDirRequire =
|
|
56229
|
+
var moduleRequire = createRequire4(import.meta.url);
|
|
56230
|
+
var executableDirRequire = createRequire4(pathToFileURL3(join38(dirname22(process.execPath), "package.json")).href);
|
|
56203
56231
|
var hasDisplay = process.platform !== "linux" || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
|
|
56204
56232
|
function loadClipboardNative(requires = [moduleRequire, executableDirRequire]) {
|
|
56205
56233
|
for (const requireClipboard of requires) {
|