@mono-agent/agent-app 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/adapter-send-tools.d.ts +7 -7
- package/dist/adapter-send-tools.d.ts.map +1 -1
- package/dist/adapter-send-tools.js +59 -50
- package/dist/adapter-send-tools.js.map +1 -1
- package/dist/app.js +8 -8
- package/dist/app.js.map +1 -1
- package/dist/channels.js +3 -3
- package/dist/channels.js.map +1 -1
- package/dist/cli.d.ts +28 -10
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +287 -164
- package/dist/cli.js.map +1 -1
- package/dist/config-reference.js +4 -4
- package/dist/config-reference.js.map +1 -1
- package/dist/consumer-contract.d.ts.map +1 -1
- package/dist/consumer-contract.js +5 -3
- package/dist/consumer-contract.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +131 -7
- package/dist/doctor.js.map +1 -1
- package/dist/init.d.ts +11 -22
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +25 -116
- package/dist/init.js.map +1 -1
- package/dist/interaction-bridge.d.ts +3 -3
- package/dist/interaction-bridge.d.ts.map +1 -1
- package/dist/memory-recall.d.ts +2 -2
- package/dist/memory-recall.d.ts.map +1 -1
- package/dist/memory-recall.js +3 -3
- package/dist/memory-recall.js.map +1 -1
- package/dist/modules/base.d.ts +25 -0
- package/dist/modules/base.d.ts.map +1 -0
- package/dist/{recipes → modules}/base.js +17 -11
- package/dist/modules/base.js.map +1 -0
- package/dist/modules/catalog.d.ts +12 -0
- package/dist/modules/catalog.d.ts.map +1 -0
- package/dist/modules/catalog.js +412 -0
- package/dist/modules/catalog.js.map +1 -0
- package/dist/modules/index.d.ts +8 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +5 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/known-tools.d.ts +44 -0
- package/dist/modules/known-tools.d.ts.map +1 -0
- package/dist/modules/known-tools.js +88 -0
- package/dist/modules/known-tools.js.map +1 -0
- package/dist/modules/types.d.ts +73 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/{recipes → modules}/types.js +3 -3
- package/dist/{recipes → modules}/types.js.map +1 -1
- package/dist/posted-message-index.d.ts +2 -2
- package/dist/posted-message-index.js +2 -2
- package/dist/provider-setup.d.ts +44 -0
- package/dist/provider-setup.d.ts.map +1 -0
- package/dist/provider-setup.js +174 -0
- package/dist/provider-setup.js.map +1 -0
- package/dist/wizard/answers.d.ts +87 -0
- package/dist/wizard/answers.d.ts.map +1 -0
- package/dist/wizard/answers.js +244 -0
- package/dist/wizard/answers.js.map +1 -0
- package/dist/wizard/from-flags.d.ts +27 -0
- package/dist/wizard/from-flags.d.ts.map +1 -0
- package/dist/wizard/from-flags.js +45 -0
- package/dist/wizard/from-flags.js.map +1 -0
- package/dist/wizard/index.d.ts +11 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +6 -0
- package/dist/wizard/index.js.map +1 -0
- package/dist/wizard/model-discovery.d.ts +35 -0
- package/dist/wizard/model-discovery.d.ts.map +1 -0
- package/dist/wizard/model-discovery.js +239 -0
- package/dist/wizard/model-discovery.js.map +1 -0
- package/dist/wizard/presets.d.ts +40 -0
- package/dist/wizard/presets.d.ts.map +1 -0
- package/dist/wizard/presets.js +85 -0
- package/dist/wizard/presets.js.map +1 -0
- package/dist/wizard/prompts.d.ts +55 -0
- package/dist/wizard/prompts.d.ts.map +1 -0
- package/dist/wizard/prompts.js +152 -0
- package/dist/wizard/prompts.js.map +1 -0
- package/dist/wizard/run.d.ts +20 -0
- package/dist/wizard/run.d.ts.map +1 -0
- package/dist/wizard/run.js +374 -0
- package/dist/wizard/run.js.map +1 -0
- package/package.json +17 -16
- package/schema/mono-agent.config.schema.json +5 -3
- package/skills/mono-agent-composer/SKILL.md +8 -8
- package/skills/mono-agent-composer/references/config-blueprint.md +7 -7
- package/skills/mono-agent-composer/references/discovery-questions.md +13 -10
- package/skills/mono-agent-composer/references/feature-coverage.md +12 -10
- package/skills/mono-agent-composer/references/package-map.md +7 -6
- package/skills/mono-agent-composer/references/playbooks.md +22 -22
- package/skills/mono-agent-composer/references/validation.md +3 -3
- package/dist/recipes/base.d.ts +0 -15
- package/dist/recipes/base.d.ts.map +0 -1
- package/dist/recipes/base.js.map +0 -1
- package/dist/recipes/catalog.d.ts +0 -4
- package/dist/recipes/catalog.d.ts.map +0 -1
- package/dist/recipes/catalog.js +0 -525
- package/dist/recipes/catalog.js.map +0 -1
- package/dist/recipes/index.d.ts +0 -11
- package/dist/recipes/index.d.ts.map +0 -1
- package/dist/recipes/index.js +0 -14
- package/dist/recipes/index.js.map +0 -1
- package/dist/recipes/types.d.ts +0 -70
- package/dist/recipes/types.d.ts.map +0 -1
- package/dist/setup.d.ts +0 -29
- package/dist/setup.d.ts.map +0 -1
- package/dist/setup.js +0 -97
- package/dist/setup.js.map +0 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { monoAgentConfigWithSchema } from "../config-reference.js";
|
|
2
|
+
import { ADAPTER_SEND_TOOL_NAMES, ALLOW_ALL_TOOLS, baseConfig, BUILTIN_TOOL_NAMES, DEFAULT_MODEL, DEFAULT_SAFE_TOOLS, findModule, resolveModuleInputs, } from "../modules/index.js";
|
|
3
|
+
/** Tools ordered canonically: built-ins first, then adapter send tools. */
|
|
4
|
+
const ORDERED_TOOL_NAMES = [...BUILTIN_TOOL_NAMES, ...ADAPTER_SEND_TOOL_NAMES];
|
|
5
|
+
const ZERO_TOOLS_WARNING = "Zero tools selected — the agent will be chat-only: it cannot read files, run commands, or send proactive messages.";
|
|
6
|
+
/**
|
|
7
|
+
* The module ids selected by these answers, in composer order: auto-derived
|
|
8
|
+
* providers first (from a `pi:ollama:*`/`pi:lmstudio:*` model), then channels (in
|
|
9
|
+
* answer order), then the memory tier, then sandbox, then observability.
|
|
10
|
+
*/
|
|
11
|
+
function selectedModuleIds(answers) {
|
|
12
|
+
const ids = [];
|
|
13
|
+
const modelRefs = [answers.model, ...answers.fallbackModels];
|
|
14
|
+
if (modelRefs.some((model) => /^pi:ollama:/u.test(model))) {
|
|
15
|
+
ids.push("provider:ollama");
|
|
16
|
+
}
|
|
17
|
+
if (modelRefs.some((model) => /^pi:lmstudio:/u.test(model))) {
|
|
18
|
+
ids.push("provider:lmstudio");
|
|
19
|
+
}
|
|
20
|
+
for (const channel of answers.channels) {
|
|
21
|
+
ids.push(channel);
|
|
22
|
+
}
|
|
23
|
+
if (answers.memory !== undefined) {
|
|
24
|
+
ids.push(answers.memory);
|
|
25
|
+
}
|
|
26
|
+
if (answers.sandbox) {
|
|
27
|
+
ids.push("sandbox");
|
|
28
|
+
}
|
|
29
|
+
if (answers.observability) {
|
|
30
|
+
ids.push("observability:phoenix");
|
|
31
|
+
}
|
|
32
|
+
return ids;
|
|
33
|
+
}
|
|
34
|
+
/** Resolve the selected module ids to modules, skipping unknown ids defensively. */
|
|
35
|
+
function selectedModules(answers) {
|
|
36
|
+
const modules = [];
|
|
37
|
+
for (const id of selectedModuleIds(answers)) {
|
|
38
|
+
const module = findModule(id);
|
|
39
|
+
if (module !== undefined) {
|
|
40
|
+
modules.push(module);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return modules;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The recommended `allowedTools` for these answers: the read-only safe defaults
|
|
47
|
+
* plus every selected module's `recommendedTools`, deduped and ordered by the
|
|
48
|
+
* canonical BUILTIN∪ADAPTER position. Deterministic — no Set-iteration reliance.
|
|
49
|
+
*/
|
|
50
|
+
export function recommendedToolSelection(answers) {
|
|
51
|
+
const union = new Set(DEFAULT_SAFE_TOOLS);
|
|
52
|
+
for (const module of selectedModules(answers)) {
|
|
53
|
+
for (const tool of module.recommendedTools ?? []) {
|
|
54
|
+
union.add(tool);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return ORDERED_TOOL_NAMES.filter((name) => union.has(name));
|
|
58
|
+
}
|
|
59
|
+
/** The read-only recall tool auto-provisioned from `memory.recallTool.enabled`. */
|
|
60
|
+
const MEMORY_RECALL_TOOL = "MemoryRecall";
|
|
61
|
+
/**
|
|
62
|
+
* True when the selected memory tier auto-provisions the read-only `MemoryRecall`
|
|
63
|
+
* tool (its fragment sets `memory.recallTool.enabled`). Derived from the catalog so
|
|
64
|
+
* it never drifts from the memory modules themselves — journal/bujo/supermemory do,
|
|
65
|
+
* lite does not.
|
|
66
|
+
*/
|
|
67
|
+
function memoryProvisionsRecall(memoryId) {
|
|
68
|
+
if (memoryId === undefined) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
const module = findModule(memoryId);
|
|
72
|
+
if (module?.kind !== "memory") {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
const fragment = module.configFragment({ model: DEFAULT_MODEL });
|
|
76
|
+
return fragment.memory?.recallTool?.enabled === true;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The tools this agent auto-provisions regardless of `tools.allowedTools` — the
|
|
80
|
+
* "always on" set the wizard surfaces so the operator understands they are NOT gated
|
|
81
|
+
* by the allow-list choice. Today that is `MemoryRecall` when the memory tier enables
|
|
82
|
+
* recall (journal/bujo/supermemory). `ReadSkill` (skills configured) and MCP-server
|
|
83
|
+
* tools are also always-on when present, but the basic wizard authors neither, so they
|
|
84
|
+
* never appear here.
|
|
85
|
+
*/
|
|
86
|
+
export function alwaysOnTools(answers) {
|
|
87
|
+
const tools = [];
|
|
88
|
+
if (memoryProvisionsRecall(answers.memory)) {
|
|
89
|
+
tools.push(MEMORY_RECALL_TOOL);
|
|
90
|
+
}
|
|
91
|
+
return tools;
|
|
92
|
+
}
|
|
93
|
+
const BASE_ANSWERS = {
|
|
94
|
+
model: DEFAULT_MODEL,
|
|
95
|
+
fallbackModels: [],
|
|
96
|
+
channels: ["channel:webhook"],
|
|
97
|
+
// `memory` is intentionally omitted (no memory section) — with
|
|
98
|
+
// exactOptionalPropertyTypes an optional key must be absent, not `undefined`.
|
|
99
|
+
sandbox: false,
|
|
100
|
+
observability: false,
|
|
101
|
+
allowedTools: [ALLOW_ALL_TOOLS],
|
|
102
|
+
moduleInputs: {},
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* The wizard's starting answers with `overrides` shallow-merged on top. Unless an
|
|
106
|
+
* explicit `allowedTools` override is supplied, `allowedTools` defaults to allow-all
|
|
107
|
+
* (`["*"]`) — the single choke point that flips the silent scaffold, every preset, and
|
|
108
|
+
* every non-interactive `--flag` path to allow-all. An explicit override is preserved
|
|
109
|
+
* verbatim: `["*"]`, a specific list, or `[]` (the chat-only case).
|
|
110
|
+
*/
|
|
111
|
+
export function defaultAnswers(overrides) {
|
|
112
|
+
const merged = { ...BASE_ANSWERS, ...overrides };
|
|
113
|
+
const allowedTools = overrides?.allowedTools ?? [ALLOW_ALL_TOOLS];
|
|
114
|
+
return { ...merged, allowedTools };
|
|
115
|
+
}
|
|
116
|
+
/** Overrides for one module: the shared model plus its non-secret input values. */
|
|
117
|
+
export function moduleOverrides(module, answers) {
|
|
118
|
+
const overrides = {
|
|
119
|
+
model: answers.model,
|
|
120
|
+
...(answers.moduleInputs[module.id] ?? {}),
|
|
121
|
+
};
|
|
122
|
+
// Defense in depth: a secret-declared value must never reach a fragment or the JSON.
|
|
123
|
+
for (const input of module.inputs) {
|
|
124
|
+
if (input.secret === true) {
|
|
125
|
+
delete overrides[input.id];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return overrides;
|
|
129
|
+
}
|
|
130
|
+
/** Merge a module fragment onto the working config, concatenating `channels.plugins`. */
|
|
131
|
+
function applyFragment(config, fragment) {
|
|
132
|
+
for (const [key, value] of Object.entries(fragment)) {
|
|
133
|
+
if (key === "channels") {
|
|
134
|
+
const existing = config.channels ?? {};
|
|
135
|
+
const incoming = value ?? {};
|
|
136
|
+
const existingPlugins = Array.isArray(existing.plugins) ? existing.plugins : [];
|
|
137
|
+
const incomingPlugins = Array.isArray(incoming.plugins) ? incoming.plugins : [];
|
|
138
|
+
const plugins = [...existingPlugins, ...incomingPlugins];
|
|
139
|
+
config.channels = {
|
|
140
|
+
...existing,
|
|
141
|
+
...incoming,
|
|
142
|
+
...(plugins.length > 0 ? { plugins } : {}),
|
|
143
|
+
};
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (key === "providers") {
|
|
147
|
+
const existing = config.providers ?? {};
|
|
148
|
+
const incoming = value ?? {};
|
|
149
|
+
const existingLocal = Array.isArray(existing.local) ? existing.local : [];
|
|
150
|
+
const incomingLocal = Array.isArray(incoming.local) ? incoming.local : [];
|
|
151
|
+
config.providers = {
|
|
152
|
+
...existing,
|
|
153
|
+
...incoming,
|
|
154
|
+
...(existingLocal.length > 0 || incomingLocal.length > 0 ? { local: [...existingLocal, ...incomingLocal] } : {}),
|
|
155
|
+
};
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
config[key] = value;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The single config-generation path: turn wizard answers into a complete
|
|
163
|
+
* `WizardPlan`. Fragments are composed onto the adapter-neutral base skeleton;
|
|
164
|
+
* secret inputs are stripped before any fragment runs, so a secret value can never
|
|
165
|
+
* reach the JSON. The composed default config is byte-equal to today's `init.ts`
|
|
166
|
+
* scaffold except `tools.allowedTools` (filled from the wizard's tools selection).
|
|
167
|
+
*/
|
|
168
|
+
export function composeWizardPlan(answers, ctx) {
|
|
169
|
+
const modules = selectedModules(answers);
|
|
170
|
+
const config = {
|
|
171
|
+
...baseConfig(ctx, answers.model, answers.fallbackModels, answers.effort),
|
|
172
|
+
};
|
|
173
|
+
const files = [];
|
|
174
|
+
const secrets = [];
|
|
175
|
+
const envLines = [];
|
|
176
|
+
const validateExpectations = [{ sectionId: "runtime", mustBe: "ok" }];
|
|
177
|
+
let providerOllamaSelected = false;
|
|
178
|
+
for (const module of modules) {
|
|
179
|
+
if (module.id === "provider:ollama") {
|
|
180
|
+
providerOllamaSelected = true;
|
|
181
|
+
}
|
|
182
|
+
const values = resolveModuleInputs(module, moduleOverrides(module, answers));
|
|
183
|
+
applyFragment(config, module.configFragment(values));
|
|
184
|
+
for (const line of module.envExampleLines?.(values) ?? []) {
|
|
185
|
+
envLines.push(line);
|
|
186
|
+
}
|
|
187
|
+
for (const file of module.files?.(values) ?? []) {
|
|
188
|
+
files.push(file);
|
|
189
|
+
}
|
|
190
|
+
for (const input of module.inputs) {
|
|
191
|
+
if (input.secret === true && input.envVar !== undefined) {
|
|
192
|
+
secrets.push({
|
|
193
|
+
moduleId: module.id,
|
|
194
|
+
label: input.label,
|
|
195
|
+
envVar: input.envVar,
|
|
196
|
+
description: input.description,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
for (const expectation of module.validateExpectations) {
|
|
201
|
+
validateExpectations.push(expectation);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
config.tools = {
|
|
205
|
+
...(config.tools ?? {}),
|
|
206
|
+
allowedTools: [...answers.allowedTools],
|
|
207
|
+
disallowedTools: [],
|
|
208
|
+
};
|
|
209
|
+
// The local-ollama endpoint mirrors the old recipe: only when the ollama
|
|
210
|
+
// provider is present AND memory embeddings actually target ollama.
|
|
211
|
+
const memory = config.memory;
|
|
212
|
+
if (providerOllamaSelected && memory?.embeddings !== undefined && memory.embeddings.provider === "ollama") {
|
|
213
|
+
config.memory = {
|
|
214
|
+
...memory,
|
|
215
|
+
embeddings: { ...memory.embeddings, endpoint: "http://localhost:11434" },
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const configJson = monoAgentConfigWithSchema(config);
|
|
219
|
+
const envExample = envLines.length > 0 ? `${envLines.join("\n")}\n` : undefined;
|
|
220
|
+
const warnings = answers.allowedTools.length === 0 ? [ZERO_TOOLS_WARNING] : [];
|
|
221
|
+
return {
|
|
222
|
+
configJson,
|
|
223
|
+
...(envExample === undefined ? {} : { envExample }),
|
|
224
|
+
files,
|
|
225
|
+
secrets,
|
|
226
|
+
selectedModules: modules,
|
|
227
|
+
validateExpectations: dedupeExpectations(validateExpectations),
|
|
228
|
+
warnings,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/** Dedupe validate expectations by `sectionId`, keeping the first occurrence. */
|
|
232
|
+
function dedupeExpectations(expectations) {
|
|
233
|
+
const seen = new Set();
|
|
234
|
+
const out = [];
|
|
235
|
+
for (const expectation of expectations) {
|
|
236
|
+
if (seen.has(expectation.sectionId)) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
seen.add(expectation.sectionId);
|
|
240
|
+
out.push(expectation);
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=answers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"answers.js","sourceRoot":"","sources":["../../src/wizard/answers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type WizardAnswers } from "./answers.js";
|
|
2
|
+
/** Channels `mono-agent init --with <csv>` can switch on, by their short flag name. */
|
|
3
|
+
export declare const WITH_CHANNELS: readonly ["telegram", "slack", "webhook", "openaiApi", "cron"];
|
|
4
|
+
export type WithChannel = (typeof WITH_CHANNELS)[number];
|
|
5
|
+
/** True when `value` is a `--with` channel flag name. */
|
|
6
|
+
export declare function isWithChannel(value: string): value is WithChannel;
|
|
7
|
+
/** The non-interactive `init`/preset flags, before they are mapped onto answers. */
|
|
8
|
+
export interface AnswersFromCliArgs {
|
|
9
|
+
readonly model?: string;
|
|
10
|
+
readonly fallbackModels?: readonly string[];
|
|
11
|
+
readonly effort?: string;
|
|
12
|
+
readonly memory?: "lite" | "journal" | "bujo";
|
|
13
|
+
/** Validated `--with` channel flag names (see {@link WithChannel}). */
|
|
14
|
+
readonly withChannels?: readonly string[];
|
|
15
|
+
/** Preset id whose answers seed the base selection (already validated by the caller). */
|
|
16
|
+
readonly presetId?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Map the non-interactive `init` flags (and an optional preset) onto full wizard
|
|
20
|
+
* answers, running once through the single {@link defaultAnswers} path so
|
|
21
|
+
* `allowedTools` is recomputed from the final capability selection. A preset seeds
|
|
22
|
+
* the base answers (its partial, so it never pins tools); each explicit flag
|
|
23
|
+
* overrides that; `--with` channels are unioned onto the preset/default channels.
|
|
24
|
+
* The caller resolves an unknown `presetId` and errors before calling this.
|
|
25
|
+
*/
|
|
26
|
+
export declare function answersFromCli(args: AnswersFromCliArgs): WizardAnswers;
|
|
27
|
+
//# sourceMappingURL=from-flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-flags.d.ts","sourceRoot":"","sources":["../../src/wizard/from-flags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlE,uFAAuF;AACvF,eAAO,MAAM,aAAa,gEAAiE,CAAC;AAC5F,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAEjE;AAWD,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAC9C,uEAAuE;IACvE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,aAAa,CAsBtE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { defaultAnswers } from "./answers.js";
|
|
2
|
+
import { findPreset } from "./presets.js";
|
|
3
|
+
/** Channels `mono-agent init --with <csv>` can switch on, by their short flag name. */
|
|
4
|
+
export const WITH_CHANNELS = ["telegram", "slack", "webhook", "openaiApi", "cron"];
|
|
5
|
+
/** True when `value` is a `--with` channel flag name. */
|
|
6
|
+
export function isWithChannel(value) {
|
|
7
|
+
return WITH_CHANNELS.includes(value);
|
|
8
|
+
}
|
|
9
|
+
/** `--with <channel>` flag → the capability-module id that enables it. */
|
|
10
|
+
const WITH_CHANNEL_MODULE_ID = {
|
|
11
|
+
telegram: "channel:telegram",
|
|
12
|
+
slack: "channel:slack",
|
|
13
|
+
webhook: "channel:webhook",
|
|
14
|
+
openaiApi: "channel:openai-api",
|
|
15
|
+
cron: "channel:cron",
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Map the non-interactive `init` flags (and an optional preset) onto full wizard
|
|
19
|
+
* answers, running once through the single {@link defaultAnswers} path so
|
|
20
|
+
* `allowedTools` is recomputed from the final capability selection. A preset seeds
|
|
21
|
+
* the base answers (its partial, so it never pins tools); each explicit flag
|
|
22
|
+
* overrides that; `--with` channels are unioned onto the preset/default channels.
|
|
23
|
+
* The caller resolves an unknown `presetId` and errors before calling this.
|
|
24
|
+
*/
|
|
25
|
+
export function answersFromCli(args) {
|
|
26
|
+
const basePartial = args.presetId === undefined
|
|
27
|
+
? {}
|
|
28
|
+
: findPreset(args.presetId)?.answers ?? {};
|
|
29
|
+
const channels = new Set(basePartial.channels ?? defaultAnswers().channels);
|
|
30
|
+
for (const channel of args.withChannels ?? []) {
|
|
31
|
+
if (isWithChannel(channel)) {
|
|
32
|
+
channels.add(WITH_CHANNEL_MODULE_ID[channel]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const memory = args.memory === undefined ? basePartial.memory : `memory:${args.memory}`;
|
|
36
|
+
return defaultAnswers({
|
|
37
|
+
...basePartial,
|
|
38
|
+
...(args.model === undefined ? {} : { model: args.model }),
|
|
39
|
+
...(args.fallbackModels === undefined ? {} : { fallbackModels: args.fallbackModels }),
|
|
40
|
+
...(args.effort === undefined ? {} : { effort: args.effort }),
|
|
41
|
+
channels: [...channels],
|
|
42
|
+
...(memory === undefined ? {} : { memory }),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=from-flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-flags.js","sourceRoot":"","sources":["../../src/wizard/from-flags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAsB,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,uFAAuF;AACvF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAU,CAAC;AAG5F,yDAAyD;AACzD,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAQ,aAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,0EAA0E;AAC1E,MAAM,sBAAsB,GAAgC;IAC1D,QAAQ,EAAE,kBAAkB;IAC5B,KAAK,EAAE,eAAe;IACtB,OAAO,EAAE,iBAAiB;IAC1B,SAAS,EAAE,oBAAoB;IAC/B,IAAI,EAAE,cAAc;CACrB,CAAC;AAcF;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,MAAM,WAAW,GAA2B,IAAI,CAAC,QAAQ,KAAK,SAAS;QACrE,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC;IAE7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,WAAW,CAAC,QAAQ,IAAI,cAAc,EAAE,CAAC,QAAQ,CAAC,CAAC;IACpF,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QAC9C,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC,GAAG,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;IAExF,OAAO,cAAc,CAAC;QACpB,GAAG,WAAW;QACd,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;QACrF,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7D,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC;QACvB,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;KAC5C,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { ComposeContext, SecretChecklistItem, WizardAnswers, WizardPlan, } from "./answers.js";
|
|
2
|
+
export { alwaysOnTools, composeWizardPlan, defaultAnswers, recommendedToolSelection } from "./answers.js";
|
|
3
|
+
export type { WizardPreset } from "./presets.js";
|
|
4
|
+
export { findPreset, PRESET_CATALOG, presetAnswers, presetIds, RECIPE_TO_PRESET } from "./presets.js";
|
|
5
|
+
export type { AnswersFromCliArgs, WithChannel } from "./from-flags.js";
|
|
6
|
+
export { answersFromCli, isWithChannel, WITH_CHANNELS } from "./from-flags.js";
|
|
7
|
+
export type { WizardSelectOption } from "./prompts.js";
|
|
8
|
+
export { channelSelectOptions, guard, memorySelectOptions, modelSelectOptions, presetSelectOptions, toolMultiselectOptions, WizardCancelled, } from "./prompts.js";
|
|
9
|
+
export type { WizardOutcome } from "./run.js";
|
|
10
|
+
export { runInitWizard } from "./run.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/wizard/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE1G,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEtG,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE/E,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,KAAK,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,GAChB,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { alwaysOnTools, composeWizardPlan, defaultAnswers, recommendedToolSelection } from "./answers.js";
|
|
2
|
+
export { findPreset, PRESET_CATALOG, presetAnswers, presetIds, RECIPE_TO_PRESET } from "./presets.js";
|
|
3
|
+
export { answersFromCli, isWithChannel, WITH_CHANNELS } from "./from-flags.js";
|
|
4
|
+
export { channelSelectOptions, guard, memorySelectOptions, modelSelectOptions, presetSelectOptions, toolMultiselectOptions, WizardCancelled, } from "./prompts.js";
|
|
5
|
+
export { runInitWizard } from "./run.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/wizard/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAG1G,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGtG,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG/E,OAAO,EACL,oBAAoB,EACpB,KAAK,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,GAChB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type WizardModelSource = "claude" | "pi" | "codex" | "opencode" | "ollama" | "lmstudio" | "custom";
|
|
2
|
+
export interface WizardModelCandidate {
|
|
3
|
+
readonly value: string;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly hint?: string;
|
|
6
|
+
readonly source: WizardModelSource;
|
|
7
|
+
readonly discovered?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ModelDiscoveryStatus {
|
|
10
|
+
readonly provider: "Pi" | "OpenCode" | "Ollama" | "LM Studio";
|
|
11
|
+
readonly status: "detected" | "unavailable";
|
|
12
|
+
readonly detail: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ModelDiscoveryResult {
|
|
15
|
+
readonly candidates: readonly WizardModelCandidate[];
|
|
16
|
+
readonly statuses: readonly ModelDiscoveryStatus[];
|
|
17
|
+
}
|
|
18
|
+
interface ExecResult {
|
|
19
|
+
readonly stdout: string;
|
|
20
|
+
}
|
|
21
|
+
export interface DiscoverWizardModelsOptions {
|
|
22
|
+
readonly execFile?: (file: string, args: readonly string[], opts: {
|
|
23
|
+
readonly timeout: number;
|
|
24
|
+
}) => Promise<ExecResult>;
|
|
25
|
+
readonly fetch?: typeof fetch;
|
|
26
|
+
readonly readFile?: (path: string, encoding: "utf8") => Promise<string>;
|
|
27
|
+
readonly piAuthPath?: string;
|
|
28
|
+
readonly timeoutMs?: number;
|
|
29
|
+
}
|
|
30
|
+
export declare const STATIC_MODEL_CANDIDATES: readonly WizardModelCandidate[];
|
|
31
|
+
export declare function discoverWizardModelCandidates(opts?: DiscoverWizardModelsOptions): Promise<ModelDiscoveryResult>;
|
|
32
|
+
export declare function rankWizardModelCandidates(candidates: readonly WizardModelCandidate[]): WizardModelCandidate[];
|
|
33
|
+
export declare function formatModelDiscoveryStatus(statuses: readonly ModelDiscoveryStatus[]): string;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=model-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-discovery.d.ts","sourceRoot":"","sources":["../../src/wizard/model-discovery.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE1G,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,IAAI,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACpD;AAED,UAAU,UAAU;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACvH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAMD,eAAO,MAAM,uBAAuB,EAAE,SAAS,oBAAoB,EAIlE,CAAC;AAEF,wBAAsB,6BAA6B,CACjD,IAAI,GAAE,2BAAgC,GACrC,OAAO,CAAC,oBAAoB,CAAC,CAmB/B;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,SAAS,oBAAoB,EAAE,GAC1C,oBAAoB,EAAE,CAOxB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,CAE5F"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { execFile as execFileCallback } from "node:child_process";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
const execFile = promisify(execFileCallback);
|
|
7
|
+
const DEFAULT_DISCOVERY_TIMEOUT_MS = 1200;
|
|
8
|
+
const PI_OPENAI_CODEX = "pi:openai-codex:gpt-5.5";
|
|
9
|
+
const DIRECT_CODEX = "codex:gpt-5.5";
|
|
10
|
+
export const STATIC_MODEL_CANDIDATES = [
|
|
11
|
+
{ value: "claude:claude-sonnet-4-6", label: "Claude Sonnet 4.6", hint: "default", source: "claude" },
|
|
12
|
+
{ value: DIRECT_CODEX, label: "Codex GPT-5.5", source: "codex" },
|
|
13
|
+
{ value: "pi:ollama:llama3.1:8b", label: "Ollama llama3.1:8b", hint: "fully local", source: "ollama" },
|
|
14
|
+
];
|
|
15
|
+
export async function discoverWizardModelCandidates(opts = {}) {
|
|
16
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_DISCOVERY_TIMEOUT_MS;
|
|
17
|
+
const [pi, opencode, ollama, lmstudio] = await Promise.all([
|
|
18
|
+
discoverPiOpenAiCodex({ ...opts, timeoutMs }),
|
|
19
|
+
discoverOpenCodeModels({ ...opts, timeoutMs }),
|
|
20
|
+
discoverOllamaModels({ ...opts, timeoutMs }),
|
|
21
|
+
discoverLmStudioModels({ ...opts, timeoutMs }),
|
|
22
|
+
]);
|
|
23
|
+
return {
|
|
24
|
+
candidates: rankWizardModelCandidates([
|
|
25
|
+
...STATIC_MODEL_CANDIDATES,
|
|
26
|
+
...pi.candidates,
|
|
27
|
+
...opencode.candidates,
|
|
28
|
+
...ollama.candidates,
|
|
29
|
+
...lmstudio.candidates,
|
|
30
|
+
]),
|
|
31
|
+
statuses: [pi.status, opencode.status, ollama.status, lmstudio.status],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function rankWizardModelCandidates(candidates) {
|
|
35
|
+
const byValue = new Map();
|
|
36
|
+
for (const candidate of candidates) {
|
|
37
|
+
const existing = byValue.get(candidate.value);
|
|
38
|
+
byValue.set(candidate.value, existing === undefined ? candidate : mergeCandidate(existing, candidate));
|
|
39
|
+
}
|
|
40
|
+
return [...byValue.values()].sort((a, b) => rank(a) - rank(b) || a.label.localeCompare(b.label));
|
|
41
|
+
}
|
|
42
|
+
export function formatModelDiscoveryStatus(statuses) {
|
|
43
|
+
return statuses.map((status) => `${status.provider}: ${status.detail}`).join("\n");
|
|
44
|
+
}
|
|
45
|
+
async function discoverPiOpenAiCodex(opts) {
|
|
46
|
+
const read = opts.readFile ?? readFile;
|
|
47
|
+
const authPath = opts.piAuthPath ?? join(homedir(), ".pi", "agent", "auth.json");
|
|
48
|
+
try {
|
|
49
|
+
const auth = parseJsonObject(await read(authPath, "utf8"));
|
|
50
|
+
const providers = readPiAuthProviderMap(auth);
|
|
51
|
+
if (providers["openai-codex"] !== undefined) {
|
|
52
|
+
return {
|
|
53
|
+
candidates: [
|
|
54
|
+
{
|
|
55
|
+
value: PI_OPENAI_CODEX,
|
|
56
|
+
label: "Pi OpenAI-Codex GPT-5.5",
|
|
57
|
+
hint: "recommended when Pi auth is configured",
|
|
58
|
+
source: "pi",
|
|
59
|
+
discovered: true,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
status: { provider: "Pi", status: "detected", detail: "OpenAI-Codex credentials found" },
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return { candidates: [], status: { provider: "Pi", status: "unavailable", detail: "OpenAI-Codex credentials not found" } };
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return { candidates: [], status: { provider: "Pi", status: "unavailable", detail: "auth store not found" } };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function readPiAuthProviderMap(auth) {
|
|
72
|
+
const nestedProviders = parseJsonObject(auth.providers);
|
|
73
|
+
return { ...nestedProviders, ...auth };
|
|
74
|
+
}
|
|
75
|
+
async function discoverOpenCodeModels(opts) {
|
|
76
|
+
const run = opts.execFile ?? execFile;
|
|
77
|
+
try {
|
|
78
|
+
const { stdout } = await run("opencode", ["models", "--json"], { timeout: opts.timeoutMs });
|
|
79
|
+
const models = parseModelNames(stdout);
|
|
80
|
+
return {
|
|
81
|
+
candidates: models.map((model) => ({
|
|
82
|
+
value: model.startsWith("pi:") ? model : `pi:opencode-go:${model}`,
|
|
83
|
+
label: `OpenCode ${displayModelName(model)}`,
|
|
84
|
+
hint: "discovered from opencode",
|
|
85
|
+
source: "opencode",
|
|
86
|
+
discovered: true,
|
|
87
|
+
})),
|
|
88
|
+
status: models.length > 0
|
|
89
|
+
? { provider: "OpenCode", status: "detected", detail: `${models.length} model(s) found` }
|
|
90
|
+
: { provider: "OpenCode", status: "unavailable", detail: "no models returned" },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return { candidates: [], status: { provider: "OpenCode", status: "unavailable", detail: "`opencode models --json` unavailable" } };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function discoverOllamaModels(opts) {
|
|
98
|
+
const run = opts.execFile ?? execFile;
|
|
99
|
+
try {
|
|
100
|
+
const { stdout } = await run("ollama", ["list"], { timeout: opts.timeoutMs });
|
|
101
|
+
const models = parseOllamaList(stdout);
|
|
102
|
+
return {
|
|
103
|
+
candidates: models.map((model) => ({
|
|
104
|
+
value: `pi:ollama:${model}`,
|
|
105
|
+
label: `Ollama ${model}`,
|
|
106
|
+
hint: "discovered locally",
|
|
107
|
+
source: "ollama",
|
|
108
|
+
discovered: true,
|
|
109
|
+
})),
|
|
110
|
+
status: models.length > 0
|
|
111
|
+
? { provider: "Ollama", status: "detected", detail: `${models.length} model(s) found` }
|
|
112
|
+
: { provider: "Ollama", status: "unavailable", detail: "no local models returned" },
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return { candidates: [], status: { provider: "Ollama", status: "unavailable", detail: "`ollama list` unavailable" } };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async function discoverLmStudioModels(opts) {
|
|
120
|
+
const fetchImpl = opts.fetch ?? fetch;
|
|
121
|
+
const controller = new AbortController();
|
|
122
|
+
const timer = setTimeout(() => controller.abort(), opts.timeoutMs);
|
|
123
|
+
try {
|
|
124
|
+
const response = await fetchImpl("http://localhost:1234/v1/models", { signal: controller.signal });
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
return { candidates: [], status: { provider: "LM Studio", status: "unavailable", detail: "server did not return models" } };
|
|
127
|
+
}
|
|
128
|
+
const body = await response.json();
|
|
129
|
+
const models = parseOpenAiModelsBody(body);
|
|
130
|
+
return {
|
|
131
|
+
candidates: models.map((model) => ({
|
|
132
|
+
value: `pi:lmstudio:${model}`,
|
|
133
|
+
label: `LM Studio ${model}`,
|
|
134
|
+
hint: "discovered locally",
|
|
135
|
+
source: "lmstudio",
|
|
136
|
+
discovered: true,
|
|
137
|
+
})),
|
|
138
|
+
status: models.length > 0
|
|
139
|
+
? { provider: "LM Studio", status: "detected", detail: `${models.length} model(s) found` }
|
|
140
|
+
: { provider: "LM Studio", status: "unavailable", detail: "no models returned" },
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return { candidates: [], status: { provider: "LM Studio", status: "unavailable", detail: "local server unavailable" } };
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
clearTimeout(timer);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function mergeCandidate(left, right) {
|
|
151
|
+
const hint = right.discovered === true ? right.hint ?? left.hint : left.hint ?? right.hint;
|
|
152
|
+
return {
|
|
153
|
+
...left,
|
|
154
|
+
...right,
|
|
155
|
+
...(hint === undefined ? {} : { hint }),
|
|
156
|
+
discovered: left.discovered === true || right.discovered === true,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function rank(candidate) {
|
|
160
|
+
if (candidate.value === "claude:claude-sonnet-4-6") {
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
if (candidate.value === PI_OPENAI_CODEX) {
|
|
164
|
+
return 10;
|
|
165
|
+
}
|
|
166
|
+
if (candidate.value === DIRECT_CODEX) {
|
|
167
|
+
return 20;
|
|
168
|
+
}
|
|
169
|
+
if (candidate.source === "opencode") {
|
|
170
|
+
return 30;
|
|
171
|
+
}
|
|
172
|
+
if (candidate.source === "ollama") {
|
|
173
|
+
return candidate.discovered === true ? 40 : 45;
|
|
174
|
+
}
|
|
175
|
+
if (candidate.source === "lmstudio") {
|
|
176
|
+
return 50;
|
|
177
|
+
}
|
|
178
|
+
return 90;
|
|
179
|
+
}
|
|
180
|
+
function parseOllamaList(stdout) {
|
|
181
|
+
const lines = stdout.trim().split(/\r?\n/u).filter(Boolean);
|
|
182
|
+
if (lines.length === 0) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
return lines
|
|
186
|
+
.slice(lines[0]?.toLowerCase().startsWith("name") ? 1 : 0)
|
|
187
|
+
.map((line) => line.trim().split(/\s+/u)[0])
|
|
188
|
+
.filter((name) => name !== undefined && name.length > 0);
|
|
189
|
+
}
|
|
190
|
+
function parseModelNames(stdout) {
|
|
191
|
+
try {
|
|
192
|
+
const parsed = JSON.parse(stdout);
|
|
193
|
+
if (Array.isArray(parsed)) {
|
|
194
|
+
return parsed.map(modelNameFromUnknown).filter(isNonEmptyString);
|
|
195
|
+
}
|
|
196
|
+
if (isRecord(parsed)) {
|
|
197
|
+
for (const key of ["models", "data"]) {
|
|
198
|
+
const value = parsed[key];
|
|
199
|
+
if (Array.isArray(value)) {
|
|
200
|
+
return value.map(modelNameFromUnknown).filter(isNonEmptyString);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// Fall through to tolerant line parsing.
|
|
207
|
+
}
|
|
208
|
+
return stdout.split(/\r?\n/u).map((line) => line.trim().split(/\s+/u)[0]).filter(isNonEmptyString);
|
|
209
|
+
}
|
|
210
|
+
function parseOpenAiModelsBody(body) {
|
|
211
|
+
if (!isRecord(body) || !Array.isArray(body.data)) {
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
return body.data.map(modelNameFromUnknown).filter(isNonEmptyString);
|
|
215
|
+
}
|
|
216
|
+
function modelNameFromUnknown(value) {
|
|
217
|
+
if (typeof value === "string") {
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
if (!isRecord(value)) {
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
const raw = value.id ?? value.name ?? value.model;
|
|
224
|
+
return typeof raw === "string" ? raw : undefined;
|
|
225
|
+
}
|
|
226
|
+
function displayModelName(model) {
|
|
227
|
+
return model.startsWith("pi:") ? model.split(":").slice(2).join(":") : model;
|
|
228
|
+
}
|
|
229
|
+
function parseJsonObject(value) {
|
|
230
|
+
const parsed = typeof value === "string" ? JSON.parse(value) : value;
|
|
231
|
+
return isRecord(parsed) ? parsed : {};
|
|
232
|
+
}
|
|
233
|
+
function isRecord(value) {
|
|
234
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
235
|
+
}
|
|
236
|
+
function isNonEmptyString(value) {
|
|
237
|
+
return value !== undefined && value.length > 0;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=model-discovery.js.map
|