@ottocode/server 0.1.257 → 0.1.258
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ottocode/server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.258",
|
|
4
4
|
"description": "HTTP API server for ottocode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"typecheck": "tsc --noEmit"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@ottocode/database": "0.1.
|
|
65
|
-
"@ottocode/sdk": "0.1.
|
|
64
|
+
"@ottocode/database": "0.1.258",
|
|
65
|
+
"@ottocode/sdk": "0.1.258",
|
|
66
66
|
"ai-sdk-ollama": "^3.8.3",
|
|
67
67
|
"drizzle-orm": "^0.44.5",
|
|
68
68
|
"hono": "^4.9.9",
|
|
@@ -6,14 +6,11 @@ import {
|
|
|
6
6
|
getProviderSettings,
|
|
7
7
|
type ProviderId,
|
|
8
8
|
isProviderAuthorized,
|
|
9
|
-
getGlobalAgentsDir,
|
|
10
9
|
getAuth,
|
|
11
10
|
} from '@ottocode/sdk';
|
|
12
|
-
import { readdir } from 'node:fs/promises';
|
|
13
|
-
import { join } from 'node:path';
|
|
14
11
|
import type { EmbeddedAppConfig } from '../../index.ts';
|
|
15
12
|
import type { OttoConfig } from '@ottocode/sdk';
|
|
16
|
-
|
|
13
|
+
export { discoverAllAgents } from '../../runtime/agent/registry.ts';
|
|
17
14
|
|
|
18
15
|
export type ProviderDetail = {
|
|
19
16
|
id: string;
|
|
@@ -138,47 +135,3 @@ export async function getAuthTypeForProvider(
|
|
|
138
135
|
const auth = await getAuth(provider, projectRoot);
|
|
139
136
|
return auth?.type as 'api' | 'oauth' | 'wallet' | undefined;
|
|
140
137
|
}
|
|
141
|
-
|
|
142
|
-
export async function discoverAllAgents(
|
|
143
|
-
projectRoot: string,
|
|
144
|
-
): Promise<string[]> {
|
|
145
|
-
const builtInAgents = ['general', 'build', 'plan', 'init'];
|
|
146
|
-
const agentSet = new Set<string>(builtInAgents);
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
const agentsJson = await loadAgentsConfig(projectRoot);
|
|
150
|
-
for (const agentName of Object.keys(agentsJson)) {
|
|
151
|
-
if (agentName.trim()) {
|
|
152
|
-
agentSet.add(agentName);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
} catch {}
|
|
156
|
-
|
|
157
|
-
try {
|
|
158
|
-
const localAgentsPath = join(projectRoot, '.otto', 'agents');
|
|
159
|
-
const localFiles = await readdir(localAgentsPath).catch(() => []);
|
|
160
|
-
for (const file of localFiles) {
|
|
161
|
-
if (file.endsWith('.txt') || file.endsWith('.md')) {
|
|
162
|
-
const agentName = file.replace(/\.(txt|md)$/, '');
|
|
163
|
-
if (agentName.trim()) {
|
|
164
|
-
agentSet.add(agentName);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
} catch {}
|
|
169
|
-
|
|
170
|
-
try {
|
|
171
|
-
const globalAgentsPath = getGlobalAgentsDir();
|
|
172
|
-
const globalFiles = await readdir(globalAgentsPath).catch(() => []);
|
|
173
|
-
for (const file of globalFiles) {
|
|
174
|
-
if (file.endsWith('.txt') || file.endsWith('.md')) {
|
|
175
|
-
const agentName = file.replace(/\.(txt|md)$/, '');
|
|
176
|
-
if (agentName.trim()) {
|
|
177
|
-
agentSet.add(agentName);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
} catch {}
|
|
182
|
-
|
|
183
|
-
return Array.from(agentSet).sort();
|
|
184
|
-
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getGlobalAgentsJsonPath, getGlobalAgentsDir } from '@ottocode/sdk';
|
|
2
2
|
import type { ProviderName } from '@ottocode/sdk';
|
|
3
3
|
import { catalog } from '@ottocode/sdk';
|
|
4
|
+
import { readdir } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
4
6
|
// Embed default agent prompts; only user overrides read from disk.
|
|
5
7
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
6
8
|
import AGENT_BUILD from '@ottocode/sdk/prompts/agents/build.txt' with {
|
|
@@ -40,6 +42,8 @@ export type AgentConfigEntry = {
|
|
|
40
42
|
|
|
41
43
|
type AgentsJson = Record<string, AgentConfigEntry>;
|
|
42
44
|
|
|
45
|
+
const BUILTIN_AGENT_NAMES = ['build', 'plan', 'general', 'init', 'research'];
|
|
46
|
+
|
|
43
47
|
function normalizeStringList(value: unknown): string[] {
|
|
44
48
|
if (!Array.isArray(value)) return [];
|
|
45
49
|
const seen = new Set<string>();
|
|
@@ -221,6 +225,49 @@ export async function loadAgentsConfig(
|
|
|
221
225
|
return merged;
|
|
222
226
|
}
|
|
223
227
|
|
|
228
|
+
export async function discoverAllAgents(
|
|
229
|
+
projectRoot: string,
|
|
230
|
+
): Promise<string[]> {
|
|
231
|
+
const agentSet = new Set<string>(BUILTIN_AGENT_NAMES);
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
const agentsJson = await loadAgentsConfig(projectRoot);
|
|
235
|
+
for (const agentName of Object.keys(agentsJson)) {
|
|
236
|
+
if (agentName.trim()) {
|
|
237
|
+
agentSet.add(agentName);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
} catch {}
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
const localAgentsPath = join(projectRoot, '.otto', 'agents');
|
|
244
|
+
const localFiles = await readdir(localAgentsPath).catch(() => []);
|
|
245
|
+
for (const file of localFiles) {
|
|
246
|
+
if (file.endsWith('.txt') || file.endsWith('.md')) {
|
|
247
|
+
const agentName = file.replace(/\.(txt|md)$/, '');
|
|
248
|
+
if (agentName.trim()) {
|
|
249
|
+
agentSet.add(agentName);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
} catch {}
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
const globalAgentsPath = getGlobalAgentsDir();
|
|
257
|
+
const globalFiles = await readdir(globalAgentsPath).catch(() => []);
|
|
258
|
+
for (const file of globalFiles) {
|
|
259
|
+
if (file.endsWith('.txt') || file.endsWith('.md')) {
|
|
260
|
+
const agentName = file.replace(/\.(txt|md)$/, '');
|
|
261
|
+
if (agentName.trim()) {
|
|
262
|
+
agentSet.add(agentName);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
} catch {}
|
|
267
|
+
|
|
268
|
+
return Array.from(agentSet).sort();
|
|
269
|
+
}
|
|
270
|
+
|
|
224
271
|
export async function resolveAgentConfig(
|
|
225
272
|
projectRoot: string,
|
|
226
273
|
name: string,
|
|
@@ -73,6 +73,7 @@ export type AskServerRequest = {
|
|
|
73
73
|
credentials?: InjectableCredentials;
|
|
74
74
|
agentPrompt?: string;
|
|
75
75
|
tools?: string[];
|
|
76
|
+
images?: Array<{ data: string; mediaType: string }>;
|
|
76
77
|
};
|
|
77
78
|
|
|
78
79
|
export type AskServerResponse = {
|
|
@@ -305,7 +306,9 @@ async function processAskRequest(
|
|
|
305
306
|
} as SessionRow;
|
|
306
307
|
}
|
|
307
308
|
|
|
308
|
-
validateProviderModel(providerForMessage, modelForMessage, cfg
|
|
309
|
+
validateProviderModel(providerForMessage, modelForMessage, cfg, {
|
|
310
|
+
wantsVision: Boolean(request.images?.length),
|
|
311
|
+
});
|
|
309
312
|
|
|
310
313
|
if (!request.skipFileConfig && !request.config && !request.credentials) {
|
|
311
314
|
await ensureProviderEnv(cfg, providerForMessage);
|
|
@@ -327,6 +330,7 @@ async function processAskRequest(
|
|
|
327
330
|
oneShot: !request.sessionId && !request.last,
|
|
328
331
|
reasoningText,
|
|
329
332
|
reasoningLevel,
|
|
333
|
+
images: request.images,
|
|
330
334
|
});
|
|
331
335
|
|
|
332
336
|
const headerAgent = session.agent ?? agentName;
|