nexus-agents 2.77.13 → 2.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{child-mcp-config-MJMUF7TL.js → child-mcp-config-CTO2MBRM.js} +3 -4
- package/dist/{child-mcp-config-MJMUF7TL.js.map → child-mcp-config-CTO2MBRM.js.map} +1 -1
- package/dist/{chunk-YJ2IGAD2.js → chunk-2UYTFLMO.js} +2 -2
- package/dist/{chunk-6AY5DK4E.js → chunk-2YPG6PDG.js} +3 -3
- package/dist/{chunk-3VWMM6UF.js → chunk-3NIPH6UP.js} +2 -2
- package/dist/{chunk-GFKGL2GQ.js → chunk-3ULMVOIF.js} +171 -83
- package/dist/chunk-3ULMVOIF.js.map +1 -0
- package/dist/{chunk-JN6UWGHH.js → chunk-5O6XLBPP.js} +2 -2
- package/dist/{chunk-ERWXGXV2.js → chunk-6TFTVW77.js} +3 -3
- package/dist/{chunk-GOT7OAL5.js → chunk-7BMOZJYS.js} +29 -5
- package/dist/chunk-7BMOZJYS.js.map +1 -0
- package/dist/{chunk-C2LLQ6TW.js → chunk-7XCUZI4G.js} +4 -4
- package/dist/chunk-7XCUZI4G.js.map +1 -0
- package/dist/{chunk-TDV5ALHY.js → chunk-D6TM2VHX.js} +3 -3
- package/dist/{chunk-PWTJGGKB.js → chunk-DLXT23AC.js} +2 -2
- package/dist/chunk-DNO2INX5.js +276 -0
- package/dist/chunk-DNO2INX5.js.map +1 -0
- package/dist/{chunk-G2CSKBY5.js → chunk-FJWWSVWB.js} +29 -6
- package/dist/chunk-FJWWSVWB.js.map +1 -0
- package/dist/{chunk-DSQ5XM4O.js → chunk-FVPYP5DD.js} +4 -4
- package/dist/{chunk-MGLWPN2I.js → chunk-GONMG4NM.js} +2 -2
- package/dist/{chunk-YQMQSJQK.js → chunk-HYU4GZY6.js} +2 -2
- package/dist/{chunk-3DH5SLFH.js → chunk-K2QILJG4.js} +6 -6
- package/dist/{chunk-5WHWKY32.js → chunk-KT5FIBWS.js} +2 -2
- package/dist/{chunk-DIB6V67T.js → chunk-L6SCKLGO.js} +3 -3
- package/dist/{chunk-IPWCD22D.js → chunk-PLX6FCFC.js} +2 -2
- package/dist/chunk-PQHVC4BD.js +639 -0
- package/dist/chunk-PQHVC4BD.js.map +1 -0
- package/dist/chunk-Q5CFPIJ5.js +5581 -0
- package/dist/chunk-Q5CFPIJ5.js.map +1 -0
- package/dist/{chunk-G6ZPVADX.js → chunk-SD76JZBG.js} +2 -2
- package/dist/{chunk-Y2CP4Z5B.js → chunk-SWFJU3W2.js} +220 -4580
- package/dist/chunk-SWFJU3W2.js.map +1 -0
- package/dist/{chunk-3MRM53T4.js → chunk-WDYCIJWN.js} +640 -470
- package/dist/chunk-WDYCIJWN.js.map +1 -0
- package/dist/{chunk-RBZ4CDMY.js → chunk-YMMYYAZT.js} +5 -5
- package/dist/{chunk-CM3TORGV.js → chunk-YXWGEIQR.js} +2 -2
- package/dist/{chunk-JX6OI4FS.js → chunk-ZI6G7U7Y.js} +125 -33
- package/dist/chunk-ZI6G7U7Y.js.map +1 -0
- package/dist/{chunk-7NK7BTWP.js → chunk-ZVCED4Z4.js} +2 -2
- package/dist/cli-circuit-breaker-I74ZQ44Q.js +13 -0
- package/dist/cli.js +109 -58
- package/dist/cli.js.map +1 -1
- package/dist/{composite-router-S6E26BCI.js → composite-router-V3OC57IE.js} +3 -4
- package/dist/consensus-vote-ESFPGEJE.js +30 -0
- package/dist/context-retriever-MB3D7KS6.js +18 -0
- package/dist/dist-NIXVXYIH.js +42 -0
- package/dist/doctor-deep-KQ765XZA.js +12 -0
- package/dist/expert-bridge-JKLC57IC.js +10 -0
- package/dist/factory-BUUXNGIB.js +14 -0
- package/dist/{factory-X3VKIGKP.js → factory-LHHYDVZX.js} +5 -6
- package/dist/index.d.ts +72 -8
- package/dist/index.js +208 -316
- package/dist/index.js.map +1 -1
- package/dist/{init-opencode-CFE7M6XA.js → init-opencode-GXZN2W5S.js} +6 -7
- package/dist/{init-opencode-CFE7M6XA.js.map → init-opencode-GXZN2W5S.js.map} +1 -1
- package/dist/issue-triage-RMXPDZ2K.js +15 -0
- package/dist/{learning-persistence-N6ILD2HX.js → learning-persistence-Q3HTOGTU.js} +2 -3
- package/dist/outcome-store-adapter-QRFJJIKB.js +57 -0
- package/dist/outcome-store-adapter-QRFJJIKB.js.map +1 -0
- package/dist/{registry-command-RPPC7N2K.js → registry-command-6E4YKAMT.js} +3 -4
- package/dist/{registry-command-RPPC7N2K.js.map → registry-command-6E4YKAMT.js.map} +1 -1
- package/dist/{repo-security-plan-7ZCDVH5O.js → repo-security-plan-AGRU72DL.js} +4 -5
- package/dist/research-helpers-synthesize-K2UCJQQG.js +13 -0
- package/dist/{routing-memory-5VTX7LQX.js → routing-memory-3B6DDZ76.js} +3 -4
- package/dist/{session-memory-7XBV6BMY.js → session-memory-L7EQIY2O.js} +4 -5
- package/dist/{setup-command-W6UKPODL.js → setup-command-R4BOEMLZ.js} +11 -12
- package/dist/setup-config-EQT24DD4.js +10 -0
- package/dist/{setup-custom-api-WM5W5AY5.js → setup-custom-api-IBDV654K.js} +5 -6
- package/dist/{setup-custom-api-WM5W5AY5.js.map → setup-custom-api-IBDV654K.js.map} +1 -1
- package/dist/tool-memory-6HCHQLAN.js +19 -0
- package/dist/{weather-report-YJMVKJGA.js → weather-report-ER3WUZ7S.js} +3 -4
- package/package.json +3 -2
- package/dist/adaptive-memory-EI564K4C.js +0 -16
- package/dist/chunk-3MRM53T4.js.map +0 -1
- package/dist/chunk-BJ2OMC7P.js +0 -944
- package/dist/chunk-BJ2OMC7P.js.map +0 -1
- package/dist/chunk-C2LLQ6TW.js.map +0 -1
- package/dist/chunk-G2CSKBY5.js.map +0 -1
- package/dist/chunk-GFKGL2GQ.js.map +0 -1
- package/dist/chunk-GOT7OAL5.js.map +0 -1
- package/dist/chunk-I7ORMAO7.js +0 -32
- package/dist/chunk-I7ORMAO7.js.map +0 -1
- package/dist/chunk-JX6OI4FS.js.map +0 -1
- package/dist/chunk-Y2CP4Z5B.js.map +0 -1
- package/dist/cli-circuit-breaker-YX4BWZD5.js +0 -14
- package/dist/consensus-vote-MUQ4HPIF.js +0 -30
- package/dist/doctor-deep-BRU5ZUJI.js +0 -13
- package/dist/expert-bridge-ZPNVLJVN.js +0 -11
- package/dist/factory-A7DTCCUY.js +0 -15
- package/dist/issue-triage-6XD6CVPB.js +0 -16
- package/dist/mobimem-CG2MNS7V.js +0 -14
- package/dist/nexus-data-dir-77UO7N6J.js +0 -12
- package/dist/research-helpers-synthesize-36TUTUUA.js +0 -14
- package/dist/setup-config-EI5KROA3.js +0 -11
- /package/dist/{chunk-YJ2IGAD2.js.map → chunk-2UYTFLMO.js.map} +0 -0
- /package/dist/{chunk-6AY5DK4E.js.map → chunk-2YPG6PDG.js.map} +0 -0
- /package/dist/{chunk-3VWMM6UF.js.map → chunk-3NIPH6UP.js.map} +0 -0
- /package/dist/{chunk-JN6UWGHH.js.map → chunk-5O6XLBPP.js.map} +0 -0
- /package/dist/{chunk-ERWXGXV2.js.map → chunk-6TFTVW77.js.map} +0 -0
- /package/dist/{chunk-TDV5ALHY.js.map → chunk-D6TM2VHX.js.map} +0 -0
- /package/dist/{chunk-PWTJGGKB.js.map → chunk-DLXT23AC.js.map} +0 -0
- /package/dist/{chunk-DSQ5XM4O.js.map → chunk-FVPYP5DD.js.map} +0 -0
- /package/dist/{chunk-MGLWPN2I.js.map → chunk-GONMG4NM.js.map} +0 -0
- /package/dist/{chunk-YQMQSJQK.js.map → chunk-HYU4GZY6.js.map} +0 -0
- /package/dist/{chunk-3DH5SLFH.js.map → chunk-K2QILJG4.js.map} +0 -0
- /package/dist/{chunk-5WHWKY32.js.map → chunk-KT5FIBWS.js.map} +0 -0
- /package/dist/{chunk-DIB6V67T.js.map → chunk-L6SCKLGO.js.map} +0 -0
- /package/dist/{chunk-IPWCD22D.js.map → chunk-PLX6FCFC.js.map} +0 -0
- /package/dist/{chunk-G6ZPVADX.js.map → chunk-SD76JZBG.js.map} +0 -0
- /package/dist/{chunk-RBZ4CDMY.js.map → chunk-YMMYYAZT.js.map} +0 -0
- /package/dist/{chunk-CM3TORGV.js.map → chunk-YXWGEIQR.js.map} +0 -0
- /package/dist/{chunk-7NK7BTWP.js.map → chunk-ZVCED4Z4.js.map} +0 -0
- /package/dist/{adaptive-memory-EI564K4C.js.map → cli-circuit-breaker-I74ZQ44Q.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-YX4BWZD5.js.map → composite-router-V3OC57IE.js.map} +0 -0
- /package/dist/{composite-router-S6E26BCI.js.map → consensus-vote-ESFPGEJE.js.map} +0 -0
- /package/dist/{consensus-vote-MUQ4HPIF.js.map → context-retriever-MB3D7KS6.js.map} +0 -0
- /package/dist/{doctor-deep-BRU5ZUJI.js.map → dist-NIXVXYIH.js.map} +0 -0
- /package/dist/{expert-bridge-ZPNVLJVN.js.map → doctor-deep-KQ765XZA.js.map} +0 -0
- /package/dist/{factory-A7DTCCUY.js.map → expert-bridge-JKLC57IC.js.map} +0 -0
- /package/dist/{factory-X3VKIGKP.js.map → factory-BUUXNGIB.js.map} +0 -0
- /package/dist/{issue-triage-6XD6CVPB.js.map → factory-LHHYDVZX.js.map} +0 -0
- /package/dist/{learning-persistence-N6ILD2HX.js.map → issue-triage-RMXPDZ2K.js.map} +0 -0
- /package/dist/{mobimem-CG2MNS7V.js.map → learning-persistence-Q3HTOGTU.js.map} +0 -0
- /package/dist/{nexus-data-dir-77UO7N6J.js.map → repo-security-plan-AGRU72DL.js.map} +0 -0
- /package/dist/{repo-security-plan-7ZCDVH5O.js.map → research-helpers-synthesize-K2UCJQQG.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-36TUTUUA.js.map → routing-memory-3B6DDZ76.js.map} +0 -0
- /package/dist/{routing-memory-5VTX7LQX.js.map → session-memory-L7EQIY2O.js.map} +0 -0
- /package/dist/{session-memory-7XBV6BMY.js.map → setup-command-R4BOEMLZ.js.map} +0 -0
- /package/dist/{setup-command-W6UKPODL.js.map → setup-config-EQT24DD4.js.map} +0 -0
- /package/dist/{setup-config-EI5KROA3.js.map → tool-memory-6HCHQLAN.js.map} +0 -0
- /package/dist/{weather-report-YJMVKJGA.js.map → weather-report-ER3WUZ7S.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/setup-custom-api.ts"],"sourcesContent":["/**\n * Interactive setup for a custom OpenAI-compatible gateway (#2124).\n *\n * Closes the last child of epic #2119. The runtime adapter (#2125) is\n * already live — this module is the ergonomics layer: a single command\n * that validates the URL, probes connectivity, and tells the user\n * exactly what env vars to set for their shell.\n *\n * Writes nothing by default (dry-run is the safe behavior for a CLI\n * that touches shell state). Prints the shell fragment; user copies\n * it into ~/.bashrc / ~/.zshrc / ~/.config/fish/config.fish. Rationale:\n * harness-neutral — we don't know which shell the user runs or where\n * their nexus-agents.yaml lives.\n *\n * @module cli/setup-custom-api\n */\n\nimport { createInterface } from 'node:readline';\nimport { validateCustomApiBaseUrl } from '../adapters/sdk/custom-api-validation.js';\nimport { CUSTOM_API_BASE_URL_ENV, CUSTOM_API_ALLOW_PRIVATE_ENV } from '../adapters/sdk/types.js';\nimport { CUSTOM_API_DEFAULT_MODEL as DEFAULT_MODEL } from '../config/defaults.js';\nimport { ok, err, type Result } from '../core/index.js';\n\n/** Inputs to `configureCustomApi`. */\nexport interface CustomApiSetupInput {\n /** Gateway base URL (required). SSRF guard from adapters/sdk is applied. */\n readonly baseUrl: string;\n /** API key. If absent, `configureCustomApi` will prompt (or fail non-interactively). */\n readonly apiKey?: string;\n /** Model id to default to. Omitted → documented fallback \"gpt-4o\". */\n readonly model?: string;\n /** Skip the TTY prompt for the API key — useful for CI and scripting. */\n readonly nonInteractive?: boolean;\n /** Omit HTTP probe — useful for dry-run / offline verify. */\n readonly skipProbe?: boolean;\n /** Allow private / loopback base URLs (overrides the SSRF guard). */\n readonly allowPrivate?: boolean;\n /** Stream for prompts/output. Defaults to process.stdout / stdin. */\n readonly stream?: { readonly output: NodeJS.WritableStream };\n /**\n * Pluggable HTTP fetcher for tests. Defaults to global fetch.\n * Called as `fetch(url, { headers })`; should return `{ status, body }`.\n */\n readonly fetcher?: HttpFetcher;\n}\n\n/** Minimal HTTP fetcher shape — lets tests inject a mock without network. */\nexport type HttpFetcher = (\n url: string,\n init: { readonly headers: Readonly<Record<string, string>> }\n) => Promise<{ readonly status: number; readonly body: string }>;\n\n/** Outcome of `configureCustomApi`. */\nexport interface CustomApiSetupResult {\n /** Validated base URL (may differ trivially from input — e.g. canonical form). */\n readonly baseUrl: string;\n /** Resolved model id. */\n readonly model: string;\n /** Whether the /v1/models probe succeeded (always true unless skipped). */\n readonly probeSucceeded: boolean;\n /**\n * Shell fragment the user should add to their shell rc so nexus-agents\n * picks up the gateway on subsequent invocations. Already-set env\n * equivalents of these lines are all that's needed at runtime.\n */\n readonly shellFragment: string;\n}\n\n/**\n * Configures a custom OpenAI-compatible gateway.\n *\n * Steps:\n * 1. Validate base URL via the SSRF guard (same as the runtime adapter).\n * 2. Resolve the API key (from input, env, or TTY prompt).\n * 3. Probe `GET {baseUrl}/models` with Bearer auth to confirm connectivity.\n * 4. Emit the shell-fragment the user adds to their shell rc.\n *\n * Returns an `ok` Result on success, or a `ConfigError`-bearing `err`\n * Result on any failure (invalid URL, missing API key in non-interactive,\n * probe failure). Never throws.\n */\nexport async function configureCustomApi(\n input: CustomApiSetupInput\n): Promise<Result<CustomApiSetupResult, Error>> {\n const urlValidation = validateCustomApiBaseUrl(input.baseUrl, {\n ...(input.allowPrivate === true ? { allowPrivate: true } : {}),\n });\n if (!urlValidation.ok) return err(urlValidation.error);\n const baseUrl = urlValidation.value.toString();\n\n const apiKeyResult = await resolveApiKey(input);\n if (!apiKeyResult.ok) return err(apiKeyResult.error);\n const apiKey = apiKeyResult.value;\n\n const probeSucceeded = input.skipProbe === true ? false : await runProbe(baseUrl, apiKey, input);\n if (input.skipProbe !== true && !probeSucceeded) {\n return err(\n new Error(\n `Gateway probe failed: GET ${stripTrailingSlash(baseUrl)}/models did not return 2xx. ` +\n `Check that the URL is the chat-completions base (typically ends with /v1) and the API key has /models read scope.`\n )\n );\n }\n\n const model = input.model ?? DEFAULT_MODEL;\n return ok({\n baseUrl,\n model,\n probeSucceeded,\n shellFragment: buildShellFragment({ baseUrl, apiKey, model, allowPrivate: input.allowPrivate }),\n });\n}\n\nfunction stripTrailingSlash(s: string): string {\n return s.endsWith('/') ? s.slice(0, -1) : s;\n}\n\n/**\n * Performs the /v1/models probe. Returns true on any 2xx response.\n * Swallows errors into `false` — the caller reports the failure.\n */\nasync function runProbe(\n baseUrl: string,\n apiKey: string,\n input: CustomApiSetupInput\n): Promise<boolean> {\n const url = `${stripTrailingSlash(baseUrl)}/models`;\n const fetcher = input.fetcher ?? defaultFetcher;\n try {\n const res = await fetcher(url, {\n headers: { Authorization: `Bearer ${apiKey}`, Accept: 'application/json' },\n });\n return res.status >= 200 && res.status < 300;\n } catch {\n return false;\n }\n}\n\nconst defaultFetcher: HttpFetcher = async (url, init) => {\n const res = await fetch(url, { headers: init.headers });\n const body = await res.text();\n return { status: res.status, body };\n};\n\n/**\n * Resolves the API key in priority order: input → env var → TTY prompt\n * (unless non-interactive, in which case the absence is a fail).\n */\nasync function resolveApiKey(input: CustomApiSetupInput): Promise<Result<string, Error>> {\n if (input.apiKey !== undefined && input.apiKey !== '') return ok(input.apiKey);\n const envKey = process.env['NEXUS_CUSTOM_API_KEY'];\n if (envKey !== undefined && envKey !== '') return ok(envKey);\n if (input.nonInteractive === true) {\n return err(\n new Error(\n 'Custom API key required but not provided. Pass --custom-api-key or set NEXUS_CUSTOM_API_KEY.'\n )\n );\n }\n const prompted = await promptForApiKey(input.stream?.output ?? process.stdout);\n if (prompted === '') {\n return err(new Error('No API key entered; aborting.'));\n }\n return ok(prompted);\n}\n\nasync function promptForApiKey(out: NodeJS.WritableStream): Promise<string> {\n out.write('Enter the API key for your custom gateway: ');\n const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: true });\n try {\n return await new Promise<string>((resolve) => {\n rl.question('', (answer) => {\n resolve(answer.trim());\n });\n });\n } finally {\n rl.close();\n }\n}\n\n/**\n * Formats the shell fragment the user should paste into their shell rc.\n * Designed to be POSIX-portable; fish users can adapt `export` to `set -gx`.\n */\nfunction buildShellFragment(params: {\n readonly baseUrl: string;\n readonly apiKey: string;\n readonly model: string;\n readonly allowPrivate: boolean | undefined;\n}): string {\n const { baseUrl, apiKey, model, allowPrivate } = params;\n const lines: string[] = [\n '# nexus-agents custom-openai gateway (nexus-agents setup --custom-api)',\n `export ${CUSTOM_API_BASE_URL_ENV}=\"${baseUrl}\"`,\n `export NEXUS_CUSTOM_API_KEY=\"${apiKey}\"`,\n `export NEXUS_CUSTOM_MODEL=\"${model}\"`,\n ];\n if (allowPrivate === true) {\n lines.push(`export ${CUSTOM_API_ALLOW_PRIVATE_ENV}=1 # SSRF-guard bypass`);\n }\n return lines.join('\\n') + '\\n';\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/setup-custom-api.ts"],"sourcesContent":["/**\n * Interactive setup for a custom OpenAI-compatible gateway (#2124).\n *\n * Closes the last child of epic #2119. The runtime adapter (#2125) is\n * already live — this module is the ergonomics layer: a single command\n * that validates the URL, probes connectivity, and tells the user\n * exactly what env vars to set for their shell.\n *\n * Writes nothing by default (dry-run is the safe behavior for a CLI\n * that touches shell state). Prints the shell fragment; user copies\n * it into ~/.bashrc / ~/.zshrc / ~/.config/fish/config.fish. Rationale:\n * harness-neutral — we don't know which shell the user runs or where\n * their nexus-agents.yaml lives.\n *\n * @module cli/setup-custom-api\n */\n\nimport { createInterface } from 'node:readline';\nimport { validateCustomApiBaseUrl } from '../adapters/sdk/custom-api-validation.js';\nimport { CUSTOM_API_BASE_URL_ENV, CUSTOM_API_ALLOW_PRIVATE_ENV } from '../adapters/sdk/types.js';\nimport { CUSTOM_API_DEFAULT_MODEL as DEFAULT_MODEL } from '../config/defaults.js';\nimport { ok, err, type Result } from '../core/index.js';\n\n/** Inputs to `configureCustomApi`. */\nexport interface CustomApiSetupInput {\n /** Gateway base URL (required). SSRF guard from adapters/sdk is applied. */\n readonly baseUrl: string;\n /** API key. If absent, `configureCustomApi` will prompt (or fail non-interactively). */\n readonly apiKey?: string;\n /** Model id to default to. Omitted → documented fallback \"gpt-4o\". */\n readonly model?: string;\n /** Skip the TTY prompt for the API key — useful for CI and scripting. */\n readonly nonInteractive?: boolean;\n /** Omit HTTP probe — useful for dry-run / offline verify. */\n readonly skipProbe?: boolean;\n /** Allow private / loopback base URLs (overrides the SSRF guard). */\n readonly allowPrivate?: boolean;\n /** Stream for prompts/output. Defaults to process.stdout / stdin. */\n readonly stream?: { readonly output: NodeJS.WritableStream };\n /**\n * Pluggable HTTP fetcher for tests. Defaults to global fetch.\n * Called as `fetch(url, { headers })`; should return `{ status, body }`.\n */\n readonly fetcher?: HttpFetcher;\n}\n\n/** Minimal HTTP fetcher shape — lets tests inject a mock without network. */\nexport type HttpFetcher = (\n url: string,\n init: { readonly headers: Readonly<Record<string, string>> }\n) => Promise<{ readonly status: number; readonly body: string }>;\n\n/** Outcome of `configureCustomApi`. */\nexport interface CustomApiSetupResult {\n /** Validated base URL (may differ trivially from input — e.g. canonical form). */\n readonly baseUrl: string;\n /** Resolved model id. */\n readonly model: string;\n /** Whether the /v1/models probe succeeded (always true unless skipped). */\n readonly probeSucceeded: boolean;\n /**\n * Shell fragment the user should add to their shell rc so nexus-agents\n * picks up the gateway on subsequent invocations. Already-set env\n * equivalents of these lines are all that's needed at runtime.\n */\n readonly shellFragment: string;\n}\n\n/**\n * Configures a custom OpenAI-compatible gateway.\n *\n * Steps:\n * 1. Validate base URL via the SSRF guard (same as the runtime adapter).\n * 2. Resolve the API key (from input, env, or TTY prompt).\n * 3. Probe `GET {baseUrl}/models` with Bearer auth to confirm connectivity.\n * 4. Emit the shell-fragment the user adds to their shell rc.\n *\n * Returns an `ok` Result on success, or a `ConfigError`-bearing `err`\n * Result on any failure (invalid URL, missing API key in non-interactive,\n * probe failure). Never throws.\n */\nexport async function configureCustomApi(\n input: CustomApiSetupInput\n): Promise<Result<CustomApiSetupResult, Error>> {\n const urlValidation = validateCustomApiBaseUrl(input.baseUrl, {\n ...(input.allowPrivate === true ? { allowPrivate: true } : {}),\n });\n if (!urlValidation.ok) return err(urlValidation.error);\n const baseUrl = urlValidation.value.toString();\n\n const apiKeyResult = await resolveApiKey(input);\n if (!apiKeyResult.ok) return err(apiKeyResult.error);\n const apiKey = apiKeyResult.value;\n\n const probeSucceeded = input.skipProbe === true ? false : await runProbe(baseUrl, apiKey, input);\n if (input.skipProbe !== true && !probeSucceeded) {\n return err(\n new Error(\n `Gateway probe failed: GET ${stripTrailingSlash(baseUrl)}/models did not return 2xx. ` +\n `Check that the URL is the chat-completions base (typically ends with /v1) and the API key has /models read scope.`\n )\n );\n }\n\n const model = input.model ?? DEFAULT_MODEL;\n return ok({\n baseUrl,\n model,\n probeSucceeded,\n shellFragment: buildShellFragment({ baseUrl, apiKey, model, allowPrivate: input.allowPrivate }),\n });\n}\n\nfunction stripTrailingSlash(s: string): string {\n return s.endsWith('/') ? s.slice(0, -1) : s;\n}\n\n/**\n * Performs the /v1/models probe. Returns true on any 2xx response.\n * Swallows errors into `false` — the caller reports the failure.\n */\nasync function runProbe(\n baseUrl: string,\n apiKey: string,\n input: CustomApiSetupInput\n): Promise<boolean> {\n const url = `${stripTrailingSlash(baseUrl)}/models`;\n const fetcher = input.fetcher ?? defaultFetcher;\n try {\n const res = await fetcher(url, {\n headers: { Authorization: `Bearer ${apiKey}`, Accept: 'application/json' },\n });\n return res.status >= 200 && res.status < 300;\n } catch {\n return false;\n }\n}\n\nconst defaultFetcher: HttpFetcher = async (url, init) => {\n const res = await fetch(url, { headers: init.headers });\n const body = await res.text();\n return { status: res.status, body };\n};\n\n/**\n * Resolves the API key in priority order: input → env var → TTY prompt\n * (unless non-interactive, in which case the absence is a fail).\n */\nasync function resolveApiKey(input: CustomApiSetupInput): Promise<Result<string, Error>> {\n if (input.apiKey !== undefined && input.apiKey !== '') return ok(input.apiKey);\n const envKey = process.env['NEXUS_CUSTOM_API_KEY'];\n if (envKey !== undefined && envKey !== '') return ok(envKey);\n if (input.nonInteractive === true) {\n return err(\n new Error(\n 'Custom API key required but not provided. Pass --custom-api-key or set NEXUS_CUSTOM_API_KEY.'\n )\n );\n }\n const prompted = await promptForApiKey(input.stream?.output ?? process.stdout);\n if (prompted === '') {\n return err(new Error('No API key entered; aborting.'));\n }\n return ok(prompted);\n}\n\nasync function promptForApiKey(out: NodeJS.WritableStream): Promise<string> {\n out.write('Enter the API key for your custom gateway: ');\n const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: true });\n try {\n return await new Promise<string>((resolve) => {\n rl.question('', (answer) => {\n resolve(answer.trim());\n });\n });\n } finally {\n rl.close();\n }\n}\n\n/**\n * Formats the shell fragment the user should paste into their shell rc.\n * Designed to be POSIX-portable; fish users can adapt `export` to `set -gx`.\n */\nfunction buildShellFragment(params: {\n readonly baseUrl: string;\n readonly apiKey: string;\n readonly model: string;\n readonly allowPrivate: boolean | undefined;\n}): string {\n const { baseUrl, apiKey, model, allowPrivate } = params;\n const lines: string[] = [\n '# nexus-agents custom-openai gateway (nexus-agents setup --custom-api)',\n `export ${CUSTOM_API_BASE_URL_ENV}=\"${baseUrl}\"`,\n `export NEXUS_CUSTOM_API_KEY=\"${apiKey}\"`,\n `export NEXUS_CUSTOM_MODEL=\"${model}\"`,\n ];\n if (allowPrivate === true) {\n lines.push(`export ${CUSTOM_API_ALLOW_PRIVATE_ENV}=1 # SSRF-guard bypass`);\n }\n return lines.join('\\n') + '\\n';\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ToolMemoryManager,
|
|
3
|
+
getToolMemory,
|
|
4
|
+
reinitializeMemoryBackends,
|
|
5
|
+
shutdownToolMemory
|
|
6
|
+
} from "./chunk-Q5CFPIJ5.js";
|
|
7
|
+
import "./chunk-633WH2ML.js";
|
|
8
|
+
import "./chunk-PQHVC4BD.js";
|
|
9
|
+
import "./chunk-3NIPH6UP.js";
|
|
10
|
+
import "./chunk-WDYCIJWN.js";
|
|
11
|
+
import "./chunk-7BMOZJYS.js";
|
|
12
|
+
import "./chunk-UP2VWCW5.js";
|
|
13
|
+
export {
|
|
14
|
+
ToolMemoryManager,
|
|
15
|
+
getToolMemory,
|
|
16
|
+
reinitializeMemoryBackends,
|
|
17
|
+
shutdownToolMemory
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=tool-memory-6HCHQLAN.js.map
|
|
@@ -3,9 +3,8 @@ import {
|
|
|
3
3
|
getAdaptiveBonus,
|
|
4
4
|
queryWithLookback,
|
|
5
5
|
shouldExplore
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-GOT7OAL5.js";
|
|
6
|
+
} from "./chunk-WDYCIJWN.js";
|
|
7
|
+
import "./chunk-7BMOZJYS.js";
|
|
9
8
|
import "./chunk-UP2VWCW5.js";
|
|
10
9
|
export {
|
|
11
10
|
generateWeatherReport,
|
|
@@ -13,4 +12,4 @@ export {
|
|
|
13
12
|
queryWithLookback,
|
|
14
13
|
shouldExplore
|
|
15
14
|
};
|
|
16
|
-
//# sourceMappingURL=weather-report-
|
|
15
|
+
//# sourceMappingURL=weather-report-ER3WUZ7S.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexus-agents",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.79.0",
|
|
4
4
|
"description": "Intelligent orchestration platform for AI coding tools — routes tasks to the best model, learns from outcomes, and enforces quality through multi-model consensus",
|
|
5
5
|
"mcpName": "io.github.williamzujkowski/nexus-agents",
|
|
6
6
|
"license": "MIT",
|
|
@@ -77,7 +77,8 @@
|
|
|
77
77
|
"fast-check": "^4.7.0",
|
|
78
78
|
"tsup": "^8.5.1",
|
|
79
79
|
"typedoc": "0.28.19",
|
|
80
|
-
"vitest": "4.1.5"
|
|
80
|
+
"vitest": "4.1.5",
|
|
81
|
+
"nexus-memory": "0.1.0"
|
|
81
82
|
},
|
|
82
83
|
"peerDependencies": {
|
|
83
84
|
"@ai-sdk/anthropic": "^3.0.0",
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AdaptiveMemoryBackend,
|
|
3
|
-
DEFAULT_SCORING_CONFIG,
|
|
4
|
-
createAdaptiveMemory
|
|
5
|
-
} from "./chunk-BJ2OMC7P.js";
|
|
6
|
-
import "./chunk-633WH2ML.js";
|
|
7
|
-
import "./chunk-3MRM53T4.js";
|
|
8
|
-
import "./chunk-I7ORMAO7.js";
|
|
9
|
-
import "./chunk-GOT7OAL5.js";
|
|
10
|
-
import "./chunk-UP2VWCW5.js";
|
|
11
|
-
export {
|
|
12
|
-
AdaptiveMemoryBackend,
|
|
13
|
-
DEFAULT_SCORING_CONFIG,
|
|
14
|
-
createAdaptiveMemory
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=adaptive-memory-EI564K4C.js.map
|