daemora 1.0.8 → 1.0.10
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/SOUL.md +40 -52
- package/daemora-ui/dist/assets/index-D7W1-PNQ.js +92 -0
- package/daemora-ui/dist/assets/index-DzMLJeoL.css +1 -0
- package/daemora-ui/dist/index.html +2 -2
- package/package.json +1 -1
- package/skills/coding.md +23 -4
- package/src/agents/systemPrompt.js +114 -91
- package/src/cli.js +7 -1
- package/src/config/models.js +72 -0
- package/src/index.js +49 -13
- package/src/mcp/MCPAgentRunner.js +1 -1
- package/src/setup/wizard.js +58 -88
- package/daemora-ui/dist/assets/index-BiMfB4bx.js +0 -90
- package/daemora-ui/dist/assets/index-DP95eMOr.css +0 -1
package/src/setup/wizard.js
CHANGED
|
@@ -87,104 +87,74 @@ export async function runSetupWizard() {
|
|
|
87
87
|
],
|
|
88
88
|
}));
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
]
|
|
108
|
-
|
|
109
|
-
} else if (provider === "anthropic") {
|
|
110
|
-
const key = guard(await p.password({ message: "Anthropic API key (sk-ant-...)", validate: (v) => !v ? "Required" : undefined }));
|
|
111
|
-
envConfig.ANTHROPIC_API_KEY = key;
|
|
112
|
-
envConfig.DEFAULT_MODEL = guard(await p.select({
|
|
113
|
-
message: "Claude model",
|
|
114
|
-
options: [
|
|
115
|
-
{ value: "anthropic:claude-sonnet-4-6", label: "claude-sonnet-4-6", hint: "Best speed/intelligence \u2014 coding & agents [NEW]" },
|
|
116
|
-
{ value: "anthropic:claude-opus-4-6", label: "claude-opus-4-6", hint: "Most intelligent \u2014 extended thinking [NEW]" },
|
|
117
|
-
{ value: "anthropic:claude-haiku-4-5", label: "claude-haiku-4-5", hint: "Fastest \u2014 high-volume tasks" },
|
|
118
|
-
{ value: "anthropic:claude-sonnet-4-5-20250929", label: "claude-sonnet-4-5-20250929", hint: "Sonnet 4.5 \u2014 coding & agentic (200K ctx)" },
|
|
119
|
-
{ value: "anthropic:claude-3-5-sonnet-latest", label: "claude-3-5-sonnet-latest", hint: "3.5 Sonnet \u2014 widely used previous gen" },
|
|
120
|
-
],
|
|
121
|
-
}));
|
|
122
|
-
} else if (provider === "google") {
|
|
123
|
-
const key = guard(await p.password({ message: "Google AI API key", validate: (v) => !v ? "Required" : undefined }));
|
|
124
|
-
envConfig.GOOGLE_AI_API_KEY = key;
|
|
125
|
-
envConfig.DEFAULT_MODEL = guard(await p.select({
|
|
126
|
-
message: "Gemini model",
|
|
127
|
-
options: [
|
|
128
|
-
{ value: "google:gemini-2.5-flash", label: "gemini-2.5-flash", hint: "Fast & cost-effective \u2014 recommended" },
|
|
129
|
-
{ value: "google:gemini-3.1-pro-preview", label: "gemini-3.1-pro-preview", hint: "Latest \u2014 complex tasks [NEW]" },
|
|
130
|
-
{ value: "google:gemini-3.1-flash-lite-preview", label: "gemini-3.1-flash-lite-preview", hint: "Latest lite \u2014 cost-efficient [NEW]" },
|
|
131
|
-
{ value: "google:gemini-2.5-pro", label: "gemini-2.5-pro", hint: "Complex reasoning & coding (1M ctx)" },
|
|
132
|
-
{ value: "google:gemini-2.5-flash-lite", label: "gemini-2.5-flash-lite", hint: "Speed-optimised high-throughput" },
|
|
133
|
-
{ value: "google:gemini-2.0-flash", label: "gemini-2.0-flash", hint: "Previous gen flash" },
|
|
134
|
-
],
|
|
135
|
-
}));
|
|
136
|
-
} else if (provider === "xai") {
|
|
137
|
-
const key = guard(await p.password({ message: "xAI API key", validate: (v) => !v ? "Required" : undefined }));
|
|
138
|
-
envConfig.XAI_API_KEY = key;
|
|
139
|
-
envConfig.DEFAULT_MODEL = guard(await p.select({
|
|
140
|
-
message: "Grok model",
|
|
141
|
-
options: [
|
|
142
|
-
{ value: "xai:grok-4", label: "grok-4", hint: "Latest & most capable (Jul 2025) [NEW]" },
|
|
143
|
-
{ value: "xai:grok-3-beta", label: "grok-3-beta", hint: "Grok 3 Beta \u2014 131K ctx" },
|
|
144
|
-
{ value: "xai:grok-3-mini-beta", label: "grok-3-mini-beta", hint: "Grok 3 Mini \u2014 fast, 131K ctx" },
|
|
145
|
-
],
|
|
146
|
-
}));
|
|
147
|
-
} else if (provider === "deepseek") {
|
|
148
|
-
const key = guard(await p.password({ message: "DeepSeek API key (sk-...)", validate: (v) => !v ? "Required" : undefined }));
|
|
149
|
-
envConfig.DEEPSEEK_API_KEY = key;
|
|
150
|
-
envConfig.DEFAULT_MODEL = guard(await p.select({
|
|
151
|
-
message: "DeepSeek model",
|
|
152
|
-
options: [
|
|
153
|
-
{ value: "deepseek:deepseek-chat", label: "deepseek-chat", hint: "V3 \u2014 excellent coder (128K ctx, recommended)" },
|
|
154
|
-
{ value: "deepseek:deepseek-reasoner", label: "deepseek-reasoner", hint: "R1 \u2014 chain-of-thought reasoning" },
|
|
155
|
-
],
|
|
156
|
-
}));
|
|
157
|
-
} else if (provider === "mistral") {
|
|
158
|
-
const key = guard(await p.password({ message: "Mistral API key", validate: (v) => !v ? "Required" : undefined }));
|
|
159
|
-
envConfig.MISTRAL_API_KEY = key;
|
|
160
|
-
envConfig.DEFAULT_MODEL = guard(await p.select({
|
|
161
|
-
message: "Mistral model",
|
|
162
|
-
options: [
|
|
163
|
-
{ value: "mistral:mistral-large-2512", label: "mistral-large-2512", hint: "Flagship \u2014 best quality (Dec 2025) [NEW]" },
|
|
164
|
-
{ value: "mistral:mistral-medium-3", label: "mistral-medium-3", hint: "Balanced capability & speed" },
|
|
165
|
-
{ value: "mistral:codestral-2508", label: "codestral-2508", hint: "Code specialist (Aug 2025)" },
|
|
166
|
-
{ value: "mistral:mistral-small-3.2-24b", label: "mistral-small-3.2-24b", hint: "Lightweight, runs locally (24B)" },
|
|
167
|
-
],
|
|
168
|
-
}));
|
|
169
|
-
} else if (provider === "ollama") {
|
|
90
|
+
// Load model registry dynamically
|
|
91
|
+
const { models: modelRegistry } = await import("../config/models.js");
|
|
92
|
+
|
|
93
|
+
// Provider config: API key prompt + env var name
|
|
94
|
+
const providerKeys = {
|
|
95
|
+
openai: { env: "OPENAI_API_KEY", prompt: "OpenAI API key (sk-...)" },
|
|
96
|
+
anthropic: { env: "ANTHROPIC_API_KEY", prompt: "Anthropic API key (sk-ant-...)" },
|
|
97
|
+
google: { env: "GOOGLE_AI_API_KEY", prompt: "Google AI API key" },
|
|
98
|
+
xai: { env: "XAI_API_KEY", prompt: "xAI API key" },
|
|
99
|
+
deepseek: { env: "DEEPSEEK_API_KEY", prompt: "DeepSeek API key (sk-...)" },
|
|
100
|
+
mistral: { env: "MISTRAL_API_KEY", prompt: "Mistral API key" },
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if (provider === "ollama") {
|
|
104
|
+
// Ollama: list known local models from registry + free text input
|
|
105
|
+
const ollamaModels = Object.entries(modelRegistry)
|
|
106
|
+
.filter(([, m]) => m.provider === "ollama")
|
|
107
|
+
.map(([, m]) => m.model);
|
|
108
|
+
const ollamaHint = ollamaModels.length ? ollamaModels.join(", ") : "llama3.1, qwen2.5-coder";
|
|
170
109
|
p.note(
|
|
171
110
|
[
|
|
172
111
|
"Make sure Ollama is running: ollama serve",
|
|
173
|
-
"Pull a model first: ollama pull
|
|
174
|
-
|
|
175
|
-
"
|
|
176
|
-
" llama4-scout \u2014 Llama 4, 17B MoE, 10M ctx",
|
|
177
|
-
" llama3.3 \u2014 best 70B open model",
|
|
178
|
-
" qwen2.5 \u2014 strong coder",
|
|
112
|
+
"Pull a model first: ollama pull <model>",
|
|
113
|
+
`Known models: ${ollamaHint}`,
|
|
114
|
+
"You can use any model available in your Ollama installation.",
|
|
179
115
|
].join("\n"),
|
|
180
116
|
"Ollama (local models)",
|
|
181
117
|
);
|
|
182
118
|
const model = guard(await p.text({
|
|
183
119
|
message: "Ollama model name",
|
|
184
|
-
initialValue: "
|
|
185
|
-
placeholder:
|
|
120
|
+
initialValue: ollamaModels[0] || "llama3.1",
|
|
121
|
+
placeholder: `e.g. ${ollamaHint}`,
|
|
186
122
|
}));
|
|
187
123
|
envConfig.DEFAULT_MODEL = `ollama:${model}`;
|
|
124
|
+
} else {
|
|
125
|
+
// Cloud provider: ask for API key, then show models from registry
|
|
126
|
+
const keyInfo = providerKeys[provider];
|
|
127
|
+
if (keyInfo) {
|
|
128
|
+
const key = guard(await p.password({ message: keyInfo.prompt, validate: (v) => !v ? "Required" : undefined }));
|
|
129
|
+
envConfig[keyInfo.env] = key;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Build model options from registry for this provider
|
|
133
|
+
const providerModels = Object.entries(modelRegistry)
|
|
134
|
+
.filter(([, m]) => m.provider === provider)
|
|
135
|
+
.map(([id, m]) => {
|
|
136
|
+
const ctx = m.contextWindow >= 1_000_000
|
|
137
|
+
? `${(m.contextWindow / 1_000_000).toFixed(0)}M ctx`
|
|
138
|
+
: `${(m.contextWindow / 1_000).toFixed(0)}K ctx`;
|
|
139
|
+
const caps = (m.capabilities || []).filter(c => c !== "text" && c !== "tools").join(", ");
|
|
140
|
+
const price = m.costPer1kInput > 0 ? `$${m.costPer1kInput}/1k in` : "free";
|
|
141
|
+
const parts = [ctx, m.tier, caps, price].filter(Boolean);
|
|
142
|
+
return { value: id, label: m.model, hint: parts.join(" \u00b7 ") };
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
if (providerModels.length > 0) {
|
|
146
|
+
envConfig.DEFAULT_MODEL = guard(await p.select({
|
|
147
|
+
message: `${provider.charAt(0).toUpperCase() + provider.slice(1)} model`,
|
|
148
|
+
options: providerModels,
|
|
149
|
+
}));
|
|
150
|
+
} else {
|
|
151
|
+
// Provider not in registry — free text input
|
|
152
|
+
const model = guard(await p.text({
|
|
153
|
+
message: `${provider} model name (e.g. ${provider}:model-name)`,
|
|
154
|
+
validate: (v) => !v ? "Required" : undefined,
|
|
155
|
+
}));
|
|
156
|
+
envConfig.DEFAULT_MODEL = model.includes(":") ? model : `${provider}:${model}`;
|
|
157
|
+
}
|
|
188
158
|
}
|
|
189
159
|
|
|
190
160
|
p.log.success(`Provider: ${t.bold(provider)} Model: ${t.bold(envConfig.DEFAULT_MODEL)}`);
|