@voybio/ace-swarm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +109 -0
- package/LICENSE +186 -0
- package/README.md +229 -0
- package/assets/.agents/ACE/ACE-Init/AGENTS.md +210 -0
- package/assets/.agents/ACE/ACE-Init/instructions.md +118 -0
- package/assets/.agents/ACE/ACE_coders/AGENTS.md +154 -0
- package/assets/.agents/ACE/ACE_coders/INSTRUCTIONS.md +216 -0
- package/assets/.agents/ACE/AGENT_REGISTRY.md +70 -0
- package/assets/.agents/ACE/AGENT_REGISTRY_7.md +9 -0
- package/assets/.agents/ACE/DIRECTIVE_KERNEL.md +234 -0
- package/assets/.agents/ACE/UI/AGENTS.md +115 -0
- package/assets/.agents/ACE/UI/instructions.md +178 -0
- package/assets/.agents/ACE/VOS/ACE_VOS_MISSING_INFO_MATRIX.md +42 -0
- package/assets/.agents/ACE/VOS/AGENTS.md +72 -0
- package/assets/.agents/ACE/VOS/instructions.md +211 -0
- package/assets/.agents/ACE/agent-astgrep/AGENTS.md +123 -0
- package/assets/.agents/ACE/agent-astgrep/instructions.md +91 -0
- package/assets/.agents/ACE/agent-builder/AGENTS.md +172 -0
- package/assets/.agents/ACE/agent-builder/instructions.md +137 -0
- package/assets/.agents/ACE/agent-docs/AGENTS.md +159 -0
- package/assets/.agents/ACE/agent-docs/instructions.md +133 -0
- package/assets/.agents/ACE/agent-eval/AGENTS.md +46 -0
- package/assets/.agents/ACE/agent-eval/instructions.md +56 -0
- package/assets/.agents/ACE/agent-memory/AGENTS.md +49 -0
- package/assets/.agents/ACE/agent-memory/instructions.md +50 -0
- package/assets/.agents/ACE/agent-observability/AGENTS.md +46 -0
- package/assets/.agents/ACE/agent-observability/instructions.md +50 -0
- package/assets/.agents/ACE/agent-ops/AGENTS.md +201 -0
- package/assets/.agents/ACE/agent-ops/instructions.md +136 -0
- package/assets/.agents/ACE/agent-qa/AGENTS.md +189 -0
- package/assets/.agents/ACE/agent-qa/instructions.md +121 -0
- package/assets/.agents/ACE/agent-release/AGENTS.md +48 -0
- package/assets/.agents/ACE/agent-release/instructions.md +49 -0
- package/assets/.agents/ACE/agent-research/AGENTS.md +160 -0
- package/assets/.agents/ACE/agent-research/instructions.md +118 -0
- package/assets/.agents/ACE/agent-security/AGENTS.md +48 -0
- package/assets/.agents/ACE/agent-security/instructions.md +50 -0
- package/assets/.agents/ACE/agent-skeptic/AGENTS.md +178 -0
- package/assets/.agents/ACE/agent-skeptic/instructions.md +196 -0
- package/assets/.agents/ACE/agent-spec/AGENTS.md +169 -0
- package/assets/.agents/ACE/agent-spec/instructions.md +116 -0
- package/assets/.agents/ACE/orchestrator/AGENTS.md +365 -0
- package/assets/.agents/ACE/orchestrator/instructions.md +231 -0
- package/assets/.agents/skills/ace-orchestrator/SKILL.md +63 -0
- package/assets/.agents/skills/ace-orchestrator/references/engineering-bootstrap-playbook.md +360 -0
- package/assets/.agents/skills/astgrep-index/SKILL.md +58 -0
- package/assets/.agents/skills/codemunch/SKILL.md +65 -0
- package/assets/.agents/skills/codemunch/references/ast-driven-protocol.md +543 -0
- package/assets/.agents/skills/codesnipe/SKILL.md +64 -0
- package/assets/.agents/skills/codesnipe/references/dual-codebase-playbook.md +671 -0
- package/assets/.agents/skills/eval-harness/SKILL.md +203 -0
- package/assets/.agents/skills/handoff-lint/SKILL.md +164 -0
- package/assets/.agents/skills/incident-commander/SKILL.md +174 -0
- package/assets/.agents/skills/landing-review-watcher/SKILL.md +68 -0
- package/assets/.agents/skills/memory-curator/SKILL.md +179 -0
- package/assets/.agents/skills/problem-triage/SKILL.md +57 -0
- package/assets/.agents/skills/problem-triage/agents/openai.yaml +3 -0
- package/assets/.agents/skills/release-sentry/SKILL.md +189 -0
- package/assets/.agents/skills/risk-quant/SKILL.md +190 -0
- package/assets/.agents/skills/schema-forge/SKILL.md +174 -0
- package/assets/.agents/skills/skill-auditor/SKILL.md +52 -0
- package/assets/.agents/skills/state-auditor/SKILL.md +182 -0
- package/assets/.github/hooks/ace-copilot.json +68 -0
- package/assets/agent-state/ACE_WORKFLOW.md +131 -0
- package/assets/agent-state/ARTIFACT_MANIFEST.json +5 -0
- package/assets/agent-state/AST_GREP_COMMANDS.md +121 -0
- package/assets/agent-state/AST_GREP_INDEX.json +13 -0
- package/assets/agent-state/AST_GREP_INDEX.md +15 -0
- package/assets/agent-state/DECISIONS.md +7 -0
- package/assets/agent-state/EVIDENCE_LOG.md +7 -0
- package/assets/agent-state/HANDOFF.json +24 -0
- package/assets/agent-state/INTERFACE_REGISTRY.md +75 -0
- package/assets/agent-state/MODULES/gates/gate-autonomy.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-completeness.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-correctness.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-evaluation.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-operability.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-security.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-typescript-public-surface.json +7 -0
- package/assets/agent-state/MODULES/registry.json +41 -0
- package/assets/agent-state/MODULES/roles/capability-astgrep.json +49 -0
- package/assets/agent-state/MODULES/roles/capability-build.json +39 -0
- package/assets/agent-state/MODULES/roles/capability-docs.json +38 -0
- package/assets/agent-state/MODULES/roles/capability-eval.json +20 -0
- package/assets/agent-state/MODULES/roles/capability-memory.json +20 -0
- package/assets/agent-state/MODULES/roles/capability-observability.json +20 -0
- package/assets/agent-state/MODULES/roles/capability-ops.json +45 -0
- package/assets/agent-state/MODULES/roles/capability-qa.json +40 -0
- package/assets/agent-state/MODULES/roles/capability-release.json +21 -0
- package/assets/agent-state/MODULES/roles/capability-research.json +44 -0
- package/assets/agent-state/MODULES/roles/capability-security.json +21 -0
- package/assets/agent-state/MODULES/roles/capability-skeptic.json +48 -0
- package/assets/agent-state/MODULES/roles/capability-spec.json +42 -0
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +289 -0
- package/assets/agent-state/MODULES/schemas/ARTIFACT_MANIFEST.schema.json +185 -0
- package/assets/agent-state/MODULES/schemas/HANDOFF.agent-state.schema.json +124 -0
- package/assets/agent-state/MODULES/schemas/HANDOFF.schema.json +55 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +290 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +144 -0
- package/assets/agent-state/MODULES/schemas/STATUS_EVENT.schema.json +84 -0
- package/assets/agent-state/MODULES/schemas/SWARM_HANDOFF.schema.json +138 -0
- package/assets/agent-state/MODULES/schemas/TRACKER_SNAPSHOT.schema.json +134 -0
- package/assets/agent-state/MODULES/schemas/VERICIFY_BRIDGE_SNAPSHOT.schema.json +157 -0
- package/assets/agent-state/MODULES/schemas/VERICIFY_PROCESS_POST_LOG.schema.json +93 -0
- package/assets/agent-state/MODULES/schemas/WORKSPACE_SESSION_REGISTRY.schema.json +133 -0
- package/assets/agent-state/PROVENANCE_LOG.md +28 -0
- package/assets/agent-state/QUALITY_GATES.md +15 -0
- package/assets/agent-state/RISKS.md +8 -0
- package/assets/agent-state/SCOPE.md +20 -0
- package/assets/agent-state/SKILL_CATALOG.md +48 -0
- package/assets/agent-state/STATUS.md +8 -0
- package/assets/agent-state/STATUS_EVENTS.ndjson +1 -0
- package/assets/agent-state/TASK.md +18 -0
- package/assets/agent-state/TEAL_CONFIG.md +117 -0
- package/assets/agent-state/handoff-registry.json +5 -0
- package/assets/agent-state/index-fingerprints.json +7 -0
- package/assets/agent-state/index.json +32 -0
- package/assets/agent-state/run-ledger.json +5 -0
- package/assets/agent-state/runtime-executor-sessions.json +5 -0
- package/assets/agent-state/runtime-tool-specs.json +5 -0
- package/assets/agent-state/runtime-workspaces.json +5 -0
- package/assets/agent-state/todo-state.json +7 -0
- package/assets/agent-state/tracker-snapshot.json +7 -0
- package/assets/agent-state/vericify/ace-bridge.json +60 -0
- package/assets/agent-state/vericify/process-posts.json +5 -0
- package/assets/instructions/ACE.instructions.md +187 -0
- package/assets/instructions/ACE_Coder.instructions.md +146 -0
- package/assets/instructions/ACE_UI.instructions.md +178 -0
- package/assets/instructions/ACE_VOS.instructions.md +211 -0
- package/assets/scripts/ace-hook-dispatch.mjs +538 -0
- package/assets/scripts/bootstrap-workspace.sh +27 -0
- package/assets/scripts/copilot-hook-dispatch.mjs +3 -0
- package/assets/scripts/eval-harness.sh +68 -0
- package/assets/scripts/render-mcp-configs.sh +396 -0
- package/assets/tasks/README.md +48 -0
- package/assets/tasks/SWARM_HANDOFF.example.json +53 -0
- package/assets/tasks/SWARM_HANDOFF.example_ui_to_coders.json +55 -0
- package/assets/tasks/SWARM_HANDOFF.example_vos_to_ui.json +55 -0
- package/assets/tasks/SWARM_HANDOFF.template.json +52 -0
- package/assets/tasks/cli_work_split.md +22 -0
- package/assets/tasks/lessons.md +17 -0
- package/assets/tasks/role_tasks.md +206 -0
- package/assets/tasks/todo.md +23 -0
- package/dist/ace-autonomy.d.ts +137 -0
- package/dist/ace-autonomy.js +472 -0
- package/dist/ace-context.d.ts +29 -0
- package/dist/ace-context.js +240 -0
- package/dist/ace-internal-tools.d.ts +8 -0
- package/dist/ace-internal-tools.js +76 -0
- package/dist/ace-server-instructions.d.ts +12 -0
- package/dist/ace-server-instructions.js +324 -0
- package/dist/agent-runtime/role-adapters.d.ts +29 -0
- package/dist/agent-runtime/role-adapters.js +573 -0
- package/dist/astgrep-index.d.ts +24 -0
- package/dist/astgrep-index.js +476 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +591 -0
- package/dist/git-ops.d.ts +53 -0
- package/dist/git-ops.js +238 -0
- package/dist/handoff-registry.d.ts +71 -0
- package/dist/handoff-registry.js +422 -0
- package/dist/helpers.d.ts +126 -0
- package/dist/helpers.js +1687 -0
- package/dist/index-store.d.ts +51 -0
- package/dist/index-store.js +328 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -0
- package/dist/internal-tool-runtime.d.ts +21 -0
- package/dist/internal-tool-runtime.js +136 -0
- package/dist/job-scheduler.d.ts +175 -0
- package/dist/job-scheduler.js +1217 -0
- package/dist/kanban.d.ts +27 -0
- package/dist/kanban.js +339 -0
- package/dist/local-model-runtime.d.ts +40 -0
- package/dist/local-model-runtime.js +174 -0
- package/dist/model-bridge.d.ts +54 -0
- package/dist/model-bridge.js +587 -0
- package/dist/orchestrator-supervisor.d.ts +100 -0
- package/dist/orchestrator-supervisor.js +399 -0
- package/dist/problem-triage.d.ts +23 -0
- package/dist/problem-triage.js +448 -0
- package/dist/prompts.d.ts +7 -0
- package/dist/prompts.js +628 -0
- package/dist/public-surface.d.ts +30 -0
- package/dist/public-surface.js +316 -0
- package/dist/resources.d.ts +7 -0
- package/dist/resources.js +545 -0
- package/dist/run-ledger.d.ts +36 -0
- package/dist/run-ledger.js +257 -0
- package/dist/runtime-command.d.ts +18 -0
- package/dist/runtime-command.js +76 -0
- package/dist/runtime-executor.d.ts +104 -0
- package/dist/runtime-executor.js +985 -0
- package/dist/runtime-profile.d.ts +116 -0
- package/dist/runtime-profile.js +532 -0
- package/dist/runtime-tool-specs.d.ts +68 -0
- package/dist/runtime-tool-specs.js +527 -0
- package/dist/safe-edit.d.ts +52 -0
- package/dist/safe-edit.js +255 -0
- package/dist/schemas.d.ts +44 -0
- package/dist/schemas.js +830 -0
- package/dist/semantic-cache.d.ts +147 -0
- package/dist/semantic-cache.js +552 -0
- package/dist/semantic-hash.d.ts +83 -0
- package/dist/semantic-hash.js +346 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +46 -0
- package/dist/shared.d.ts +136 -0
- package/dist/shared.js +269 -0
- package/dist/skill-auditor.d.ts +26 -0
- package/dist/skill-auditor.js +184 -0
- package/dist/skill-catalog.d.ts +60 -0
- package/dist/skill-catalog.js +305 -0
- package/dist/status-events.d.ts +40 -0
- package/dist/status-events.js +269 -0
- package/dist/store/ace-packed-store.d.ts +69 -0
- package/dist/store/ace-packed-store.js +434 -0
- package/dist/store/bootstrap-store.d.ts +46 -0
- package/dist/store/bootstrap-store.js +242 -0
- package/dist/store/catalog-builder.d.ts +21 -0
- package/dist/store/catalog-builder.js +68 -0
- package/dist/store/importer.d.ts +19 -0
- package/dist/store/importer.js +157 -0
- package/dist/store/knowledge-bake.d.ts +59 -0
- package/dist/store/knowledge-bake.js +339 -0
- package/dist/store/materializers/hook-context-materializer.d.ts +25 -0
- package/dist/store/materializers/hook-context-materializer.js +100 -0
- package/dist/store/materializers/host-file-materializer.d.ts +37 -0
- package/dist/store/materializers/host-file-materializer.js +271 -0
- package/dist/store/materializers/todo-syncer.d.ts +30 -0
- package/dist/store/materializers/todo-syncer.js +140 -0
- package/dist/store/materializers/vericify-projector.d.ts +38 -0
- package/dist/store/materializers/vericify-projector.js +239 -0
- package/dist/store/repositories/discovery-repository.d.ts +24 -0
- package/dist/store/repositories/discovery-repository.js +58 -0
- package/dist/store/repositories/handoff-repository.d.ts +31 -0
- package/dist/store/repositories/handoff-repository.js +67 -0
- package/dist/store/repositories/ledger-repository.d.ts +26 -0
- package/dist/store/repositories/ledger-repository.js +49 -0
- package/dist/store/repositories/runtime-kv-repository.d.ts +16 -0
- package/dist/store/repositories/runtime-kv-repository.js +36 -0
- package/dist/store/repositories/scheduler-repository.d.ts +50 -0
- package/dist/store/repositories/scheduler-repository.js +123 -0
- package/dist/store/repositories/session-repository.d.ts +33 -0
- package/dist/store/repositories/session-repository.js +82 -0
- package/dist/store/repositories/todo-repository.d.ts +31 -0
- package/dist/store/repositories/todo-repository.js +77 -0
- package/dist/store/repositories/tracker-repository.d.ts +25 -0
- package/dist/store/repositories/tracker-repository.js +43 -0
- package/dist/store/repositories/vericify-repository.d.ts +32 -0
- package/dist/store/repositories/vericify-repository.js +58 -0
- package/dist/store/skills-install.d.ts +28 -0
- package/dist/store/skills-install.js +86 -0
- package/dist/store/state-reader.d.ts +49 -0
- package/dist/store/state-reader.js +111 -0
- package/dist/store/store-artifacts.d.ts +12 -0
- package/dist/store/store-artifacts.js +138 -0
- package/dist/store/store-snapshot.d.ts +19 -0
- package/dist/store/store-snapshot.js +140 -0
- package/dist/store/topology-bake.d.ts +15 -0
- package/dist/store/topology-bake.js +215 -0
- package/dist/store/types.d.ts +155 -0
- package/dist/store/types.js +35 -0
- package/dist/store/workspace-snapshot.d.ts +26 -0
- package/dist/store/workspace-snapshot.js +107 -0
- package/dist/store/write-queue.d.ts +7 -0
- package/dist/store/write-queue.js +26 -0
- package/dist/todo-state.d.ts +41 -0
- package/dist/todo-state.js +399 -0
- package/dist/tools-agent.d.ts +7 -0
- package/dist/tools-agent.js +1542 -0
- package/dist/tools-discovery.d.ts +6 -0
- package/dist/tools-discovery.js +178 -0
- package/dist/tools-drift.d.ts +13 -0
- package/dist/tools-drift.js +357 -0
- package/dist/tools-files.d.ts +6 -0
- package/dist/tools-files.js +679 -0
- package/dist/tools-framework.d.ts +7 -0
- package/dist/tools-framework.js +1414 -0
- package/dist/tools-git.d.ts +6 -0
- package/dist/tools-git.js +183 -0
- package/dist/tools-handoff.d.ts +32 -0
- package/dist/tools-handoff.js +489 -0
- package/dist/tools-lifecycle.d.ts +6 -0
- package/dist/tools-lifecycle.js +205 -0
- package/dist/tools-memory.d.ts +6 -0
- package/dist/tools-memory.js +260 -0
- package/dist/tools-scheduler.d.ts +6 -0
- package/dist/tools-scheduler.js +228 -0
- package/dist/tools-skills.d.ts +3 -0
- package/dist/tools-skills.js +104 -0
- package/dist/tools-todo.d.ts +6 -0
- package/dist/tools-todo.js +154 -0
- package/dist/tools.d.ts +9 -0
- package/dist/tools.js +33 -0
- package/dist/tracker-adapters.d.ts +74 -0
- package/dist/tracker-adapters.js +776 -0
- package/dist/tracker-sync.d.ts +10 -0
- package/dist/tracker-sync.js +84 -0
- package/dist/tui/agent-runner.d.ts +137 -0
- package/dist/tui/agent-runner.js +466 -0
- package/dist/tui/agent-worker.d.ts +10 -0
- package/dist/tui/agent-worker.js +347 -0
- package/dist/tui/chat.d.ts +84 -0
- package/dist/tui/chat.js +368 -0
- package/dist/tui/commands.d.ts +57 -0
- package/dist/tui/commands.js +432 -0
- package/dist/tui/dashboard.d.ts +24 -0
- package/dist/tui/dashboard.js +110 -0
- package/dist/tui/index.d.ts +114 -0
- package/dist/tui/index.js +1059 -0
- package/dist/tui/input.d.ts +49 -0
- package/dist/tui/input.js +336 -0
- package/dist/tui/layout.d.ts +116 -0
- package/dist/tui/layout.js +367 -0
- package/dist/tui/ollama.d.ts +116 -0
- package/dist/tui/ollama.js +192 -0
- package/dist/tui/openai-compatible.d.ts +63 -0
- package/dist/tui/openai-compatible.js +370 -0
- package/dist/tui/provider-discovery.d.ts +59 -0
- package/dist/tui/provider-discovery.js +530 -0
- package/dist/tui/renderer.d.ts +166 -0
- package/dist/tui/renderer.js +304 -0
- package/dist/tui/tabs.d.ts +70 -0
- package/dist/tui/tabs.js +208 -0
- package/dist/tui/telemetry.d.ts +56 -0
- package/dist/tui/telemetry.js +106 -0
- package/dist/vericify-bridge.d.ts +146 -0
- package/dist/vericify-bridge.js +571 -0
- package/dist/vericify-context.d.ts +10 -0
- package/dist/vericify-context.js +72 -0
- package/dist/workspace-manager.d.ts +107 -0
- package/dist/workspace-manager.js +636 -0
- package/package.json +83 -0
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACE-TUI Provider Discovery
|
|
3
|
+
*
|
|
4
|
+
* Resolves provider/model defaults without mutating system files.
|
|
5
|
+
* Sources:
|
|
6
|
+
* - CLI hints
|
|
7
|
+
* - workspace .ace/llm-profile.json
|
|
8
|
+
* - workspace .vscode/settings.json
|
|
9
|
+
* - VS Code user settings.json (platform defaults)
|
|
10
|
+
* - environment overrides
|
|
11
|
+
*
|
|
12
|
+
* Async runtime scanning is exposed separately so `ace doctor --scan` can probe
|
|
13
|
+
* common local endpoints instead of assuming a hardcoded Ollama host.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { join, resolve } from "node:path";
|
|
18
|
+
import { readStoreJsonSync } from "../store/store-snapshot.js";
|
|
19
|
+
export const DEFAULT_OLLAMA_MODEL = "llama3.1:8b";
|
|
20
|
+
export const DEFAULT_LLAMA_CPP_MODEL = "local-model";
|
|
21
|
+
const LOCAL_RUNTIME_PROVIDER_PREFERENCE = ["ollama", "llama.cpp"];
|
|
22
|
+
const PROVIDER_PREFERENCE = [
|
|
23
|
+
...LOCAL_RUNTIME_PROVIDER_PREFERENCE,
|
|
24
|
+
"codex",
|
|
25
|
+
"gemini",
|
|
26
|
+
"claude",
|
|
27
|
+
"copilot",
|
|
28
|
+
];
|
|
29
|
+
const DEFAULT_LOCAL_SCAN_TARGETS = {
|
|
30
|
+
ollama: ["http://127.0.0.1:11434", "http://localhost:11434"],
|
|
31
|
+
"llama.cpp": ["http://127.0.0.1:8080", "http://localhost:8080"],
|
|
32
|
+
};
|
|
33
|
+
export function normalizeProvider(input) {
|
|
34
|
+
if (!input)
|
|
35
|
+
return undefined;
|
|
36
|
+
const normalized = input.trim().toLowerCase();
|
|
37
|
+
if (!normalized)
|
|
38
|
+
return undefined;
|
|
39
|
+
if (normalized === "openai")
|
|
40
|
+
return "codex";
|
|
41
|
+
if (normalized === "anthropic")
|
|
42
|
+
return "claude";
|
|
43
|
+
if (normalized === "google")
|
|
44
|
+
return "gemini";
|
|
45
|
+
if (["llamacpp", "llama-cpp", "llama.cpp"].includes(normalized))
|
|
46
|
+
return "llama.cpp";
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
export function normalizeLocalBaseUrl(url) {
|
|
50
|
+
if (!url)
|
|
51
|
+
return undefined;
|
|
52
|
+
const trimmed = url.trim();
|
|
53
|
+
if (!trimmed)
|
|
54
|
+
return undefined;
|
|
55
|
+
const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `http://${trimmed}`;
|
|
56
|
+
return withScheme.endsWith("/") ? withScheme.slice(0, -1) : withScheme;
|
|
57
|
+
}
|
|
58
|
+
export function buildOpenAiCompatibleBaseUrl(baseUrl) {
|
|
59
|
+
const normalized = normalizeLocalBaseUrl(baseUrl) ?? baseUrl.trim();
|
|
60
|
+
return normalized.endsWith("/v1") ? normalized : `${normalized}/v1`;
|
|
61
|
+
}
|
|
62
|
+
export function inferProviderFromModel(model) {
|
|
63
|
+
if (!model)
|
|
64
|
+
return undefined;
|
|
65
|
+
const value = model.trim().toLowerCase();
|
|
66
|
+
if (!value)
|
|
67
|
+
return undefined;
|
|
68
|
+
if (value.startsWith("llama.cpp/") || value.startsWith("llamacpp/")) {
|
|
69
|
+
return "llama.cpp";
|
|
70
|
+
}
|
|
71
|
+
if (value.startsWith("ollama/") ||
|
|
72
|
+
value.includes("llama") ||
|
|
73
|
+
value.includes("qwen") ||
|
|
74
|
+
value.includes("mistral") ||
|
|
75
|
+
value.includes("deepseek") ||
|
|
76
|
+
value.includes("phi") ||
|
|
77
|
+
value.includes(":") ||
|
|
78
|
+
value.includes("mixtral")) {
|
|
79
|
+
return "ollama";
|
|
80
|
+
}
|
|
81
|
+
if (value.startsWith("copilot/")) {
|
|
82
|
+
return "copilot";
|
|
83
|
+
}
|
|
84
|
+
if (value.includes("claude"))
|
|
85
|
+
return "claude";
|
|
86
|
+
if (value.includes("gemini"))
|
|
87
|
+
return "gemini";
|
|
88
|
+
if (value.includes("gpt") ||
|
|
89
|
+
value.includes("codex") ||
|
|
90
|
+
value.startsWith("o1") ||
|
|
91
|
+
value.startsWith("o3") ||
|
|
92
|
+
value.startsWith("o4") ||
|
|
93
|
+
value.startsWith("o5")) {
|
|
94
|
+
return "codex";
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
function defaultModelForProvider(provider) {
|
|
99
|
+
if (provider === "ollama")
|
|
100
|
+
return DEFAULT_OLLAMA_MODEL;
|
|
101
|
+
if (provider === "llama.cpp")
|
|
102
|
+
return DEFAULT_LLAMA_CPP_MODEL;
|
|
103
|
+
return `${provider}/default`;
|
|
104
|
+
}
|
|
105
|
+
function looksLikeModel(value) {
|
|
106
|
+
const v = value.trim().toLowerCase();
|
|
107
|
+
if (!v)
|
|
108
|
+
return false;
|
|
109
|
+
return (v.includes("gpt") ||
|
|
110
|
+
v.includes("claude") ||
|
|
111
|
+
v.includes("gemini") ||
|
|
112
|
+
v.includes("llama") ||
|
|
113
|
+
v.includes("qwen") ||
|
|
114
|
+
v.includes("mistral") ||
|
|
115
|
+
v.includes("deepseek") ||
|
|
116
|
+
v.includes("codex") ||
|
|
117
|
+
v.startsWith("copilot/") ||
|
|
118
|
+
v.includes(":"));
|
|
119
|
+
}
|
|
120
|
+
export function parseJsoncLoose(raw) {
|
|
121
|
+
let out = "";
|
|
122
|
+
let inString = false;
|
|
123
|
+
let escape = false;
|
|
124
|
+
let inLineComment = false;
|
|
125
|
+
let inBlockComment = false;
|
|
126
|
+
for (let i = 0; i < raw.length; i += 1) {
|
|
127
|
+
const ch = raw[i];
|
|
128
|
+
const next = raw[i + 1] ?? "";
|
|
129
|
+
if (inLineComment) {
|
|
130
|
+
if (ch === "\n") {
|
|
131
|
+
inLineComment = false;
|
|
132
|
+
out += ch;
|
|
133
|
+
}
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (inBlockComment) {
|
|
137
|
+
if (ch === "*" && next === "/") {
|
|
138
|
+
inBlockComment = false;
|
|
139
|
+
i += 1;
|
|
140
|
+
}
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (inString) {
|
|
144
|
+
out += ch;
|
|
145
|
+
if (escape) {
|
|
146
|
+
escape = false;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (ch === "\\") {
|
|
150
|
+
escape = true;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (ch === "\"") {
|
|
154
|
+
inString = false;
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (ch === "\"") {
|
|
159
|
+
inString = true;
|
|
160
|
+
out += ch;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (ch === "/" && next === "/") {
|
|
164
|
+
inLineComment = true;
|
|
165
|
+
i += 1;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (ch === "/" && next === "*") {
|
|
169
|
+
inBlockComment = true;
|
|
170
|
+
i += 1;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
out += ch;
|
|
174
|
+
}
|
|
175
|
+
return JSON.parse(out.replace(/,\s*([}\]])/g, "$1"));
|
|
176
|
+
}
|
|
177
|
+
function readJsoncFile(path) {
|
|
178
|
+
const raw = readFileSync(path, "utf-8");
|
|
179
|
+
return parseJsoncLoose(raw);
|
|
180
|
+
}
|
|
181
|
+
function readProfile(workspaceRoot) {
|
|
182
|
+
const storeProfile = readStoreJsonSync(workspaceRoot, "state/runtime/llm_profile") ??
|
|
183
|
+
readStoreJsonSync(workspaceRoot, "state/runtime/llm-profile");
|
|
184
|
+
if (storeProfile && typeof storeProfile === "object") {
|
|
185
|
+
return storeProfile;
|
|
186
|
+
}
|
|
187
|
+
const canonicalProfilePath = resolve(workspaceRoot, ".agents", "ACE", ".ace", "llm-profile.json");
|
|
188
|
+
const legacyProfilePath = resolve(workspaceRoot, ".ace", "llm-profile.json");
|
|
189
|
+
const profilePath = existsSync(canonicalProfilePath) ? canonicalProfilePath : legacyProfilePath;
|
|
190
|
+
if (!existsSync(profilePath))
|
|
191
|
+
return undefined;
|
|
192
|
+
try {
|
|
193
|
+
const raw = readFileSync(profilePath, "utf-8");
|
|
194
|
+
const parsed = JSON.parse(raw);
|
|
195
|
+
return parsed && typeof parsed === "object" ? parsed : undefined;
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function defaultVsCodeUserSettingsPaths() {
|
|
202
|
+
const home = homedir();
|
|
203
|
+
return [
|
|
204
|
+
join(home, "Library", "Application Support", "Code", "User", "settings.json"),
|
|
205
|
+
join(home, ".config", "Code", "User", "settings.json"),
|
|
206
|
+
join(home, "AppData", "Roaming", "Code", "User", "settings.json"),
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
function collectHintsFromSettings(value, source) {
|
|
210
|
+
const found = [];
|
|
211
|
+
const visit = (node, keyHint = "") => {
|
|
212
|
+
if (typeof node === "string") {
|
|
213
|
+
const provider = normalizeProvider(node);
|
|
214
|
+
if (provider &&
|
|
215
|
+
[
|
|
216
|
+
"ollama",
|
|
217
|
+
"llama.cpp",
|
|
218
|
+
"copilot",
|
|
219
|
+
"codex",
|
|
220
|
+
"claude",
|
|
221
|
+
"gemini",
|
|
222
|
+
"openai",
|
|
223
|
+
"anthropic",
|
|
224
|
+
"google",
|
|
225
|
+
].includes(provider)) {
|
|
226
|
+
found.push({ source, provider });
|
|
227
|
+
}
|
|
228
|
+
if (looksLikeModel(node)) {
|
|
229
|
+
found.push({ source, model: node, provider: inferProviderFromModel(node) });
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (Array.isArray(node)) {
|
|
234
|
+
for (const item of node) {
|
|
235
|
+
if (typeof item === "string") {
|
|
236
|
+
if (looksLikeModel(item) || keyHint.toLowerCase().includes("model")) {
|
|
237
|
+
found.push({ source, model: item, provider: inferProviderFromModel(item) });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
visit(item, keyHint);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (!node || typeof node !== "object")
|
|
247
|
+
return;
|
|
248
|
+
for (const [key, child] of Object.entries(node)) {
|
|
249
|
+
const lowerKey = key.toLowerCase();
|
|
250
|
+
if (lowerKey.includes("provider") && typeof child === "string") {
|
|
251
|
+
found.push({ source, provider: normalizeProvider(child) });
|
|
252
|
+
}
|
|
253
|
+
if (lowerKey.includes("model") || lowerKey.includes("allowedmodels")) {
|
|
254
|
+
if (typeof child === "string" && looksLikeModel(child)) {
|
|
255
|
+
found.push({ source, model: child, provider: inferProviderFromModel(child) });
|
|
256
|
+
}
|
|
257
|
+
if (Array.isArray(child)) {
|
|
258
|
+
for (const item of child) {
|
|
259
|
+
if (typeof item === "string" && looksLikeModel(item)) {
|
|
260
|
+
found.push({ source, model: item, provider: inferProviderFromModel(item) });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
visit(child, lowerKey);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
visit(value);
|
|
269
|
+
return found;
|
|
270
|
+
}
|
|
271
|
+
function sortProviders(providers) {
|
|
272
|
+
const unique = [...new Set(providers.map((p) => p.trim().toLowerCase()).filter(Boolean))];
|
|
273
|
+
return unique.sort((a, b) => {
|
|
274
|
+
const ia = PROVIDER_PREFERENCE.indexOf(a);
|
|
275
|
+
const ib = PROVIDER_PREFERENCE.indexOf(b);
|
|
276
|
+
const sa = ia === -1 ? Number.MAX_SAFE_INTEGER : ia;
|
|
277
|
+
const sb = ib === -1 ? Number.MAX_SAFE_INTEGER : ib;
|
|
278
|
+
if (sa !== sb)
|
|
279
|
+
return sa - sb;
|
|
280
|
+
return a.localeCompare(b);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
function addModel(modelsByProvider, provider, model) {
|
|
284
|
+
const trimmedModel = model?.trim();
|
|
285
|
+
if (!trimmedModel)
|
|
286
|
+
return;
|
|
287
|
+
const resolvedProvider = normalizeProvider(provider) ?? inferProviderFromModel(trimmedModel) ?? "ollama";
|
|
288
|
+
if (!modelsByProvider.has(resolvedProvider)) {
|
|
289
|
+
modelsByProvider.set(resolvedProvider, new Set());
|
|
290
|
+
}
|
|
291
|
+
modelsByProvider.get(resolvedProvider)?.add(trimmedModel);
|
|
292
|
+
}
|
|
293
|
+
function readSettingsCandidates(workspaceRoot) {
|
|
294
|
+
const candidates = [];
|
|
295
|
+
const paths = [resolve(workspaceRoot, ".vscode", "settings.json"), ...defaultVsCodeUserSettingsPaths()];
|
|
296
|
+
for (const path of paths) {
|
|
297
|
+
if (!existsSync(path))
|
|
298
|
+
continue;
|
|
299
|
+
try {
|
|
300
|
+
candidates.push(...collectHintsFromSettings(readJsoncFile(path), path));
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
// Ignore malformed or locked settings files.
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return candidates;
|
|
307
|
+
}
|
|
308
|
+
function setProviderBaseUrl(target, provider, baseUrl) {
|
|
309
|
+
const normalizedProvider = normalizeProvider(provider);
|
|
310
|
+
const normalizedBaseUrl = normalizeLocalBaseUrl(baseUrl);
|
|
311
|
+
if (!normalizedProvider || !normalizedBaseUrl)
|
|
312
|
+
return;
|
|
313
|
+
target.set(normalizedProvider, normalizedBaseUrl);
|
|
314
|
+
}
|
|
315
|
+
export function discoverProviderContext(options) {
|
|
316
|
+
const notes = [];
|
|
317
|
+
const modelsByProvider = new Map();
|
|
318
|
+
const providerBaseUrls = new Map();
|
|
319
|
+
const profile = readProfile(options.workspaceRoot);
|
|
320
|
+
const profileProvider = normalizeProvider(profile?.provider);
|
|
321
|
+
const profileModel = profile?.model?.trim() || undefined;
|
|
322
|
+
const profileBaseUrl = normalizeLocalBaseUrl(profile?.base_url);
|
|
323
|
+
const envProvider = normalizeProvider(process.env.ACE_TUI_PROVIDER ?? process.env.ACE_LLM_PROVIDER ?? process.env.LLM_PROVIDER);
|
|
324
|
+
const envModel = process.env.ACE_TUI_MODEL?.trim() ||
|
|
325
|
+
process.env.ACE_MODEL?.trim() ||
|
|
326
|
+
process.env.LLM_MODEL?.trim() ||
|
|
327
|
+
undefined;
|
|
328
|
+
const envGenericBaseUrl = normalizeLocalBaseUrl(process.env.ACE_TUI_BASE_URL ?? process.env.ACE_LLM_BASE_URL ?? process.env.LLM_BASE_URL);
|
|
329
|
+
const cliProvider = normalizeProvider(options.cliProvider);
|
|
330
|
+
const cliModel = options.cliModel?.trim() || undefined;
|
|
331
|
+
const cliBaseUrl = normalizeLocalBaseUrl(options.cliBaseUrl ?? options.cliOllamaUrl);
|
|
332
|
+
setProviderBaseUrl(providerBaseUrls, "ollama", options.cliOllamaUrl ?? process.env.ACE_TUI_OLLAMA_URL ?? process.env.OLLAMA_HOST);
|
|
333
|
+
setProviderBaseUrl(providerBaseUrls, "llama.cpp", process.env.LLAMA_CPP_BASE_URL ?? process.env.LLAMACPP_BASE_URL);
|
|
334
|
+
addModel(modelsByProvider, profileProvider, profileModel);
|
|
335
|
+
addModel(modelsByProvider, envProvider, envModel);
|
|
336
|
+
addModel(modelsByProvider, cliProvider, cliModel);
|
|
337
|
+
const settingHints = readSettingsCandidates(options.workspaceRoot);
|
|
338
|
+
for (const hint of settingHints) {
|
|
339
|
+
if (hint.model)
|
|
340
|
+
addModel(modelsByProvider, hint.provider, hint.model);
|
|
341
|
+
}
|
|
342
|
+
const providerHints = [
|
|
343
|
+
...settingHints
|
|
344
|
+
.map((hint) => normalizeProvider(hint.provider))
|
|
345
|
+
.filter(Boolean),
|
|
346
|
+
profileProvider,
|
|
347
|
+
envProvider,
|
|
348
|
+
cliProvider,
|
|
349
|
+
].filter(Boolean);
|
|
350
|
+
let provider = cliProvider ?? envProvider ?? profileProvider;
|
|
351
|
+
if (!provider) {
|
|
352
|
+
provider =
|
|
353
|
+
inferProviderFromModel(cliModel) ??
|
|
354
|
+
inferProviderFromModel(envModel) ??
|
|
355
|
+
inferProviderFromModel(profileModel);
|
|
356
|
+
}
|
|
357
|
+
if (!provider) {
|
|
358
|
+
provider = "ollama";
|
|
359
|
+
if (settingHints.length > 0) {
|
|
360
|
+
notes.push("runtime_default=ollama (VS Code model hints are discovery-only)");
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
setProviderBaseUrl(providerBaseUrls, profileProvider, profileBaseUrl);
|
|
364
|
+
setProviderBaseUrl(providerBaseUrls, envProvider, envGenericBaseUrl);
|
|
365
|
+
setProviderBaseUrl(providerBaseUrls, cliProvider, cliBaseUrl);
|
|
366
|
+
if (!providerBaseUrls.has(provider) && cliBaseUrl) {
|
|
367
|
+
providerBaseUrls.set(provider, cliBaseUrl);
|
|
368
|
+
}
|
|
369
|
+
if (!providerBaseUrls.has(provider) && envGenericBaseUrl) {
|
|
370
|
+
providerBaseUrls.set(provider, envGenericBaseUrl);
|
|
371
|
+
}
|
|
372
|
+
if (!providerBaseUrls.has(provider) && profileBaseUrl && profileProvider === provider) {
|
|
373
|
+
providerBaseUrls.set(provider, profileBaseUrl);
|
|
374
|
+
}
|
|
375
|
+
if (!modelsByProvider.has(provider)) {
|
|
376
|
+
modelsByProvider.set(provider, new Set());
|
|
377
|
+
}
|
|
378
|
+
let model = cliModel ?? envModel ?? profileModel;
|
|
379
|
+
if (!model) {
|
|
380
|
+
const providerModels = [...(modelsByProvider.get(provider) ?? [])];
|
|
381
|
+
if (providerModels.length > 0) {
|
|
382
|
+
model = providerModels[0];
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (!model) {
|
|
386
|
+
model = defaultModelForProvider(provider);
|
|
387
|
+
}
|
|
388
|
+
addModel(modelsByProvider, provider, model);
|
|
389
|
+
const allProviders = sortProviders([
|
|
390
|
+
...modelsByProvider.keys(),
|
|
391
|
+
...providerHints,
|
|
392
|
+
...providerBaseUrls.keys(),
|
|
393
|
+
provider,
|
|
394
|
+
]);
|
|
395
|
+
const modelsByProviderObj = {};
|
|
396
|
+
for (const candidateProvider of allProviders) {
|
|
397
|
+
modelsByProviderObj[candidateProvider] = [...(modelsByProvider.get(candidateProvider) ?? [])].sort((a, b) => a.localeCompare(b));
|
|
398
|
+
}
|
|
399
|
+
const baseUrl = providerBaseUrls.get(provider);
|
|
400
|
+
const ollamaUrl = providerBaseUrls.get("ollama");
|
|
401
|
+
notes.push(`provider=${provider}`);
|
|
402
|
+
notes.push(`model=${model}`);
|
|
403
|
+
notes.push(`providers_detected=${allProviders.join(",")}`);
|
|
404
|
+
notes.push(`base_url=${baseUrl ?? "unconfigured"}`);
|
|
405
|
+
return {
|
|
406
|
+
provider,
|
|
407
|
+
model,
|
|
408
|
+
baseUrl,
|
|
409
|
+
ollamaUrl,
|
|
410
|
+
providerBaseUrls: Object.fromEntries(providerBaseUrls.entries()),
|
|
411
|
+
providers: allProviders,
|
|
412
|
+
modelsByProvider: modelsByProviderObj,
|
|
413
|
+
notes,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
async function fetchJson(url, timeoutMs) {
|
|
417
|
+
const controller = new AbortController();
|
|
418
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
419
|
+
try {
|
|
420
|
+
const response = await fetch(url, {
|
|
421
|
+
method: "GET",
|
|
422
|
+
headers: { Accept: "application/json" },
|
|
423
|
+
signal: controller.signal,
|
|
424
|
+
});
|
|
425
|
+
if (!response.ok) {
|
|
426
|
+
throw new Error(`${response.status} ${response.statusText}`);
|
|
427
|
+
}
|
|
428
|
+
return await response.json();
|
|
429
|
+
}
|
|
430
|
+
finally {
|
|
431
|
+
clearTimeout(timeout);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
async function probeOllama(baseUrl, timeoutMs) {
|
|
435
|
+
const payload = (await fetchJson(`${baseUrl}/api/tags`, timeoutMs));
|
|
436
|
+
const models = Array.isArray(payload.models)
|
|
437
|
+
? payload.models
|
|
438
|
+
.map((entry) => entry?.name?.trim())
|
|
439
|
+
.filter((name) => Boolean(name))
|
|
440
|
+
: [];
|
|
441
|
+
return {
|
|
442
|
+
provider: "ollama",
|
|
443
|
+
baseUrl,
|
|
444
|
+
apiBaseUrl: buildOpenAiCompatibleBaseUrl(baseUrl),
|
|
445
|
+
models,
|
|
446
|
+
source: "probe",
|
|
447
|
+
notes: [`ollama_models=${models.length}`],
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
async function probeLlamaCpp(baseUrl, timeoutMs) {
|
|
451
|
+
const apiBaseUrl = buildOpenAiCompatibleBaseUrl(baseUrl);
|
|
452
|
+
const payload = (await fetchJson(`${apiBaseUrl}/models`, timeoutMs));
|
|
453
|
+
const models = Array.isArray(payload.data)
|
|
454
|
+
? payload.data
|
|
455
|
+
.map((entry) => entry?.id?.trim())
|
|
456
|
+
.filter((name) => Boolean(name))
|
|
457
|
+
: [];
|
|
458
|
+
return {
|
|
459
|
+
provider: "llama.cpp",
|
|
460
|
+
baseUrl,
|
|
461
|
+
apiBaseUrl,
|
|
462
|
+
models,
|
|
463
|
+
source: "probe",
|
|
464
|
+
notes: [`llama_cpp_models=${models.length}`],
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
function buildScanAttempts(options) {
|
|
468
|
+
const attempts = [];
|
|
469
|
+
const seen = new Set();
|
|
470
|
+
const preferredProvider = normalizeProvider(options.preferredProvider);
|
|
471
|
+
const profile = options.workspaceRoot ? readProfile(options.workspaceRoot) : undefined;
|
|
472
|
+
const profileProvider = normalizeProvider(profile?.provider);
|
|
473
|
+
const profileBaseUrl = normalizeLocalBaseUrl(profile?.base_url);
|
|
474
|
+
const addAttempt = (provider, baseUrl, source) => {
|
|
475
|
+
const normalizedProvider = normalizeProvider(provider);
|
|
476
|
+
const normalizedBaseUrl = normalizeLocalBaseUrl(baseUrl);
|
|
477
|
+
if (!normalizedProvider || !normalizedBaseUrl)
|
|
478
|
+
return;
|
|
479
|
+
const key = `${normalizedProvider}:${normalizedBaseUrl}`;
|
|
480
|
+
if (seen.has(key))
|
|
481
|
+
return;
|
|
482
|
+
seen.add(key);
|
|
483
|
+
attempts.push({ provider: normalizedProvider, baseUrl: normalizedBaseUrl, source });
|
|
484
|
+
};
|
|
485
|
+
const explicitBaseUrl = normalizeLocalBaseUrl(options.explicitBaseUrl);
|
|
486
|
+
if (explicitBaseUrl) {
|
|
487
|
+
const providers = preferredProvider ? [preferredProvider] : [...LOCAL_RUNTIME_PROVIDER_PREFERENCE];
|
|
488
|
+
for (const provider of providers) {
|
|
489
|
+
addAttempt(provider, explicitBaseUrl, "explicit_base_url");
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
addAttempt(profileProvider ?? preferredProvider ?? undefined, profileBaseUrl, "workspace_profile");
|
|
493
|
+
addAttempt("ollama", process.env.ACE_TUI_OLLAMA_URL, "ACE_TUI_OLLAMA_URL");
|
|
494
|
+
addAttempt("ollama", process.env.OLLAMA_HOST, "OLLAMA_HOST");
|
|
495
|
+
addAttempt("llama.cpp", process.env.LLAMA_CPP_BASE_URL, "LLAMA_CPP_BASE_URL");
|
|
496
|
+
addAttempt("llama.cpp", process.env.LLAMACPP_BASE_URL, "LLAMACPP_BASE_URL");
|
|
497
|
+
const providers = preferredProvider && LOCAL_RUNTIME_PROVIDER_PREFERENCE.includes(preferredProvider)
|
|
498
|
+
? [preferredProvider]
|
|
499
|
+
: [...LOCAL_RUNTIME_PROVIDER_PREFERENCE];
|
|
500
|
+
for (const provider of providers) {
|
|
501
|
+
for (const baseUrl of DEFAULT_LOCAL_SCAN_TARGETS[provider]) {
|
|
502
|
+
addAttempt(provider, baseUrl, "default_scan_target");
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return attempts;
|
|
506
|
+
}
|
|
507
|
+
export async function scanLocalModelRuntimes(options = {}) {
|
|
508
|
+
const timeoutMs = options.timeoutMs ?? 1500;
|
|
509
|
+
const notes = [];
|
|
510
|
+
const candidates = [];
|
|
511
|
+
for (const attempt of buildScanAttempts(options)) {
|
|
512
|
+
try {
|
|
513
|
+
const candidate = attempt.provider === "ollama"
|
|
514
|
+
? await probeOllama(attempt.baseUrl, timeoutMs)
|
|
515
|
+
: await probeLlamaCpp(attempt.baseUrl, timeoutMs);
|
|
516
|
+
if (!candidate)
|
|
517
|
+
continue;
|
|
518
|
+
candidates.push({
|
|
519
|
+
...candidate,
|
|
520
|
+
source: attempt.source,
|
|
521
|
+
});
|
|
522
|
+
notes.push(`scan_hit:${attempt.provider}:${attempt.baseUrl}`);
|
|
523
|
+
}
|
|
524
|
+
catch (error) {
|
|
525
|
+
notes.push(`scan_miss:${attempt.provider}:${attempt.baseUrl}:${error instanceof Error ? error.message : String(error)}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return { candidates, notes };
|
|
529
|
+
}
|
|
530
|
+
//# sourceMappingURL=provider-discovery.js.map
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACE-TUI ANSI Renderer
|
|
3
|
+
*
|
|
4
|
+
* Direct terminal rendering via ANSI escape sequences.
|
|
5
|
+
* Zero dependencies — uses process.stdout.write() exclusively.
|
|
6
|
+
* Inspired by arttime's rendering approach.
|
|
7
|
+
*/
|
|
8
|
+
/** Cursor movement */
|
|
9
|
+
export declare const cursor: {
|
|
10
|
+
readonly to: (x: number, y: number) => string;
|
|
11
|
+
readonly up: (n?: number) => string;
|
|
12
|
+
readonly down: (n?: number) => string;
|
|
13
|
+
readonly right: (n?: number) => string;
|
|
14
|
+
readonly left: (n?: number) => string;
|
|
15
|
+
readonly hide: "\u001B[?25l";
|
|
16
|
+
readonly show: "\u001B[?25h";
|
|
17
|
+
readonly save: "\u001B7";
|
|
18
|
+
readonly restore: "\u001B8";
|
|
19
|
+
readonly home: "\u001B[H";
|
|
20
|
+
};
|
|
21
|
+
/** Screen operations */
|
|
22
|
+
export declare const screen: {
|
|
23
|
+
readonly clear: "\u001B[2J";
|
|
24
|
+
readonly clearLine: "\u001B[2K";
|
|
25
|
+
readonly clearDown: "\u001B[J";
|
|
26
|
+
readonly clearRight: "\u001B[K";
|
|
27
|
+
readonly altBuffer: "\u001B[?1049h";
|
|
28
|
+
readonly mainBuffer: "\u001B[?1049l";
|
|
29
|
+
readonly enableMouse: "\u001B[?1003h\u001B[?1006h";
|
|
30
|
+
readonly disableMouse: "\u001B[?1003l\u001B[?1006l";
|
|
31
|
+
};
|
|
32
|
+
/** Style codes */
|
|
33
|
+
export declare const style: {
|
|
34
|
+
readonly reset: "\u001B[0m";
|
|
35
|
+
readonly bold: "\u001B[1m";
|
|
36
|
+
readonly dim: "\u001B[2m";
|
|
37
|
+
readonly italic: "\u001B[3m";
|
|
38
|
+
readonly underline: "\u001B[4m";
|
|
39
|
+
readonly inverse: "\u001B[7m";
|
|
40
|
+
readonly strikethrough: "\u001B[9m";
|
|
41
|
+
};
|
|
42
|
+
export type ColorLevel = "none" | "basic" | "256" | "truecolor";
|
|
43
|
+
export declare function detectColorLevel(): ColorLevel;
|
|
44
|
+
/** 16-color CGA foreground */
|
|
45
|
+
export declare const fg: {
|
|
46
|
+
readonly black: "\u001B[30m";
|
|
47
|
+
readonly red: "\u001B[31m";
|
|
48
|
+
readonly green: "\u001B[32m";
|
|
49
|
+
readonly yellow: "\u001B[33m";
|
|
50
|
+
readonly blue: "\u001B[34m";
|
|
51
|
+
readonly magenta: "\u001B[35m";
|
|
52
|
+
readonly cyan: "\u001B[36m";
|
|
53
|
+
readonly white: "\u001B[37m";
|
|
54
|
+
readonly gray: "\u001B[90m";
|
|
55
|
+
readonly brightRed: "\u001B[91m";
|
|
56
|
+
readonly brightGreen: "\u001B[92m";
|
|
57
|
+
readonly brightYellow: "\u001B[93m";
|
|
58
|
+
readonly brightBlue: "\u001B[94m";
|
|
59
|
+
readonly brightMagenta: "\u001B[95m";
|
|
60
|
+
readonly brightCyan: "\u001B[96m";
|
|
61
|
+
readonly brightWhite: "\u001B[97m";
|
|
62
|
+
};
|
|
63
|
+
/** 16-color CGA background */
|
|
64
|
+
export declare const bg: {
|
|
65
|
+
readonly black: "\u001B[40m";
|
|
66
|
+
readonly red: "\u001B[41m";
|
|
67
|
+
readonly green: "\u001B[42m";
|
|
68
|
+
readonly yellow: "\u001B[43m";
|
|
69
|
+
readonly blue: "\u001B[44m";
|
|
70
|
+
readonly magenta: "\u001B[45m";
|
|
71
|
+
readonly cyan: "\u001B[46m";
|
|
72
|
+
readonly white: "\u001B[47m";
|
|
73
|
+
readonly gray: "\u001B[100m";
|
|
74
|
+
readonly brightBlue: "\u001B[104m";
|
|
75
|
+
readonly brightCyan: "\u001B[106m";
|
|
76
|
+
};
|
|
77
|
+
/** 256-color codes */
|
|
78
|
+
export declare function fg256(n: number): string;
|
|
79
|
+
export declare function bg256(n: number): string;
|
|
80
|
+
/** 24-bit RGB colors */
|
|
81
|
+
export declare function fgRgb(r: number, g: number, b: number): string;
|
|
82
|
+
export declare function bgRgb(r: number, g: number, b: number): string;
|
|
83
|
+
export declare const box: {
|
|
84
|
+
readonly topLeft: "┌";
|
|
85
|
+
readonly topRight: "┐";
|
|
86
|
+
readonly bottomLeft: "└";
|
|
87
|
+
readonly bottomRight: "┘";
|
|
88
|
+
readonly horizontal: "─";
|
|
89
|
+
readonly vertical: "│";
|
|
90
|
+
readonly teeRight: "├";
|
|
91
|
+
readonly teeLeft: "┤";
|
|
92
|
+
readonly teeDown: "┬";
|
|
93
|
+
readonly teeUp: "┴";
|
|
94
|
+
readonly cross: "┼";
|
|
95
|
+
readonly heavyHorizontal: "━";
|
|
96
|
+
readonly heavyVertical: "┃";
|
|
97
|
+
readonly roundTopLeft: "╭";
|
|
98
|
+
readonly roundTopRight: "╮";
|
|
99
|
+
readonly roundBottomLeft: "╰";
|
|
100
|
+
readonly roundBottomRight: "╯";
|
|
101
|
+
};
|
|
102
|
+
export declare const symbols: {
|
|
103
|
+
readonly check: "✓";
|
|
104
|
+
readonly cross: "✗";
|
|
105
|
+
readonly bullet: "●";
|
|
106
|
+
readonly hollowBullet: "○";
|
|
107
|
+
readonly arrow: "→";
|
|
108
|
+
readonly arrowLeft: "←";
|
|
109
|
+
readonly arrowUp: "↑";
|
|
110
|
+
readonly arrowDown: "↓";
|
|
111
|
+
readonly spinner: readonly ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
112
|
+
readonly progress: {
|
|
113
|
+
readonly filled: "█";
|
|
114
|
+
readonly partial: "▓";
|
|
115
|
+
readonly empty: "░";
|
|
116
|
+
};
|
|
117
|
+
readonly tab: "▎";
|
|
118
|
+
readonly activeTab: "▌";
|
|
119
|
+
};
|
|
120
|
+
/** Strip ANSI escape codes from a string (arttime: sed -e 's/\x1b\[[0-9;]*m//g') */
|
|
121
|
+
export declare function stripAnsi(text: string): string;
|
|
122
|
+
/** Get visible width of a string (ANSI-aware) */
|
|
123
|
+
export declare function visibleWidth(text: string): number;
|
|
124
|
+
/** Truncate text to fit width, add ellipsis if needed */
|
|
125
|
+
export declare function truncate(text: string, maxWidth: number): string;
|
|
126
|
+
/** Pad text to exact width (ANSI-aware) */
|
|
127
|
+
export declare function padRight(text: string, width: number): string;
|
|
128
|
+
/** Center text in width (ANSI-aware, arttime centering math) */
|
|
129
|
+
export declare function center(text: string, width: number): string;
|
|
130
|
+
/** Write raw string to stdout */
|
|
131
|
+
export declare function write(s: string): void;
|
|
132
|
+
/** Write at specific position */
|
|
133
|
+
export declare function writeAt(x: number, y: number, text: string): void;
|
|
134
|
+
/** Draw a horizontal line */
|
|
135
|
+
export declare function hline(x: number, y: number, width: number, char?: "─"): void;
|
|
136
|
+
/** Draw a vertical line */
|
|
137
|
+
export declare function vline(x: number, y: number, height: number, char?: "│"): void;
|
|
138
|
+
/** Draw a box with optional title */
|
|
139
|
+
export declare function drawBox(x: number, y: number, width: number, height: number, opts?: {
|
|
140
|
+
title?: string;
|
|
141
|
+
titleColor?: string;
|
|
142
|
+
borderColor?: string;
|
|
143
|
+
rounded?: boolean;
|
|
144
|
+
}): void;
|
|
145
|
+
/** Fill a rectangular region with spaces (clear region) */
|
|
146
|
+
export declare function clearRegion(x: number, y: number, width: number, height: number): void;
|
|
147
|
+
/** Draw a progress bar (arttime-inspired) */
|
|
148
|
+
export declare function progressBar(x: number, y: number, width: number, ratio: number, opts?: {
|
|
149
|
+
filledColor?: string;
|
|
150
|
+
emptyColor?: string;
|
|
151
|
+
showPercent?: boolean;
|
|
152
|
+
}): void;
|
|
153
|
+
/** Draw a spinner frame */
|
|
154
|
+
export declare function spinnerFrame(frame: number): string;
|
|
155
|
+
/** Get terminal dimensions */
|
|
156
|
+
export declare function getTermSize(): {
|
|
157
|
+
cols: number;
|
|
158
|
+
rows: number;
|
|
159
|
+
};
|
|
160
|
+
/** Format elapsed time (arttime contextual time display) */
|
|
161
|
+
export declare function formatElapsed(ms: number): string;
|
|
162
|
+
/** Format timestamp as HH:MM:SS */
|
|
163
|
+
export declare function formatTime(date?: Date): string;
|
|
164
|
+
/** Format a number with commas */
|
|
165
|
+
export declare function formatNumber(n: number): string;
|
|
166
|
+
//# sourceMappingURL=renderer.d.ts.map
|