@ottocode/server 0.1.259 → 0.1.261
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 +4 -3
- package/src/index.ts +5 -4
- package/src/openapi/register.ts +92 -0
- package/src/openapi/route.ts +22 -0
- package/src/routes/ask.ts +210 -99
- package/src/routes/auth.ts +1701 -626
- package/src/routes/branch.ts +281 -90
- package/src/routes/config/agents.ts +79 -32
- package/src/routes/config/cwd.ts +46 -14
- package/src/routes/config/debug.ts +159 -30
- package/src/routes/config/defaults.ts +182 -64
- package/src/routes/config/main.ts +109 -73
- package/src/routes/config/models.ts +304 -137
- package/src/routes/config/providers.ts +462 -166
- package/src/routes/config/utils.ts +2 -2
- package/src/routes/doctor.ts +395 -161
- package/src/routes/files.ts +650 -260
- package/src/routes/git/branch.ts +143 -52
- package/src/routes/git/commit.ts +347 -141
- package/src/routes/git/diff.ts +239 -116
- package/src/routes/git/init.ts +103 -23
- package/src/routes/git/pull.ts +167 -65
- package/src/routes/git/push.ts +222 -117
- package/src/routes/git/remote.ts +401 -100
- package/src/routes/git/staging.ts +502 -141
- package/src/routes/git/status.ts +171 -78
- package/src/routes/mcp.ts +1129 -404
- package/src/routes/openapi.ts +27 -4
- package/src/routes/ottorouter.ts +1221 -389
- package/src/routes/provider-usage.ts +153 -36
- package/src/routes/research.ts +817 -370
- package/src/routes/root.ts +50 -6
- package/src/routes/session-approval.ts +228 -54
- package/src/routes/session-files.ts +265 -134
- package/src/routes/session-messages.ts +330 -150
- package/src/routes/session-stream.ts +83 -2
- package/src/routes/sessions.ts +1830 -780
- package/src/routes/skills.ts +849 -161
- package/src/routes/terminals.ts +469 -103
- package/src/routes/tunnel.ts +394 -118
- package/src/runtime/agent/runner-reasoning.ts +38 -3
- package/src/runtime/agent/runner.ts +1 -0
- package/src/runtime/ask/service.ts +1 -0
- package/src/runtime/message/compaction-limits.ts +3 -3
- package/src/runtime/provider/reasoning.ts +18 -7
- package/src/runtime/session/db-operations.ts +4 -3
- package/src/runtime/utils/token.ts +7 -2
- package/src/tools/adapter.ts +21 -0
- package/src/openapi/paths/ask.ts +0 -81
- package/src/openapi/paths/auth.ts +0 -687
- package/src/openapi/paths/branch.ts +0 -102
- package/src/openapi/paths/config.ts +0 -485
- package/src/openapi/paths/doctor.ts +0 -165
- package/src/openapi/paths/files.ts +0 -236
- package/src/openapi/paths/git.ts +0 -690
- package/src/openapi/paths/mcp.ts +0 -339
- package/src/openapi/paths/messages.ts +0 -103
- package/src/openapi/paths/ottorouter.ts +0 -594
- package/src/openapi/paths/provider-usage.ts +0 -59
- package/src/openapi/paths/research.ts +0 -227
- package/src/openapi/paths/session-approval.ts +0 -93
- package/src/openapi/paths/session-extras.ts +0 -336
- package/src/openapi/paths/session-files.ts +0 -91
- package/src/openapi/paths/sessions.ts +0 -210
- package/src/openapi/paths/skills.ts +0 -377
- package/src/openapi/paths/stream.ts +0 -26
- package/src/openapi/paths/terminals.ts +0 -226
- package/src/openapi/paths/tunnel.ts +0 -163
- package/src/openapi/spec.ts +0 -73
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
getProviderDefinition,
|
|
5
5
|
getModelNpmBinding,
|
|
6
6
|
getUnderlyingProviderKey,
|
|
7
|
+
isBuiltInProviderId,
|
|
7
8
|
modelSupportsReasoning,
|
|
8
9
|
type OttoConfig,
|
|
9
10
|
type ProviderId,
|
|
@@ -27,8 +28,9 @@ function normalizeReasoningLevel(
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
function toAnthropicEffort(
|
|
31
|
+
model: string,
|
|
30
32
|
level: ReasoningLevel | undefined,
|
|
31
|
-
): 'low' | 'medium' | 'high' | 'max' {
|
|
33
|
+
): 'low' | 'medium' | 'high' | 'xhigh' | 'max' {
|
|
32
34
|
switch (level) {
|
|
33
35
|
case 'minimal':
|
|
34
36
|
case 'low':
|
|
@@ -36,8 +38,9 @@ function toAnthropicEffort(
|
|
|
36
38
|
case 'medium':
|
|
37
39
|
return 'medium';
|
|
38
40
|
case 'max':
|
|
39
|
-
case 'xhigh':
|
|
40
41
|
return 'max';
|
|
42
|
+
case 'xhigh':
|
|
43
|
+
return isClaudeOpus47(model) ? 'xhigh' : 'max';
|
|
41
44
|
default:
|
|
42
45
|
return 'high';
|
|
43
46
|
}
|
|
@@ -116,7 +119,7 @@ function getOpenAICompatibleProviderOptionKeys(
|
|
|
116
119
|
cfg?: OttoConfig,
|
|
117
120
|
): string[] {
|
|
118
121
|
const definition = cfg ? getProviderDefinition(cfg, provider) : undefined;
|
|
119
|
-
const entry = catalog[provider];
|
|
122
|
+
const entry = isBuiltInProviderId(provider) ? catalog[provider] : undefined;
|
|
120
123
|
const keys = new Set<string>(['openaiCompatible', toCamelCaseKey(provider)]);
|
|
121
124
|
const label = definition?.label ?? entry?.label;
|
|
122
125
|
if (label) {
|
|
@@ -134,11 +137,15 @@ function buildSharedProviderOptions(
|
|
|
134
137
|
return Object.fromEntries(keys.map((key) => [key, options]));
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
function isClaudeOpus47(model: string): boolean {
|
|
141
|
+
const lower = model.toLowerCase();
|
|
142
|
+
return lower.includes('claude-opus-4-7') || lower.includes('claude-opus-4.7');
|
|
143
|
+
}
|
|
144
|
+
|
|
137
145
|
function usesAdaptiveAnthropicThinking(model: string): boolean {
|
|
138
146
|
const lower = model.toLowerCase();
|
|
139
147
|
return (
|
|
140
|
-
|
|
141
|
-
lower.includes('claude-opus-4.7') ||
|
|
148
|
+
isClaudeOpus47(model) ||
|
|
142
149
|
lower.includes('claude-opus-4-6') ||
|
|
143
150
|
lower.includes('claude-opus-4.6') ||
|
|
144
151
|
lower.includes('claude-sonnet-4-6') ||
|
|
@@ -238,11 +245,15 @@ export function buildReasoningConfig(args: {
|
|
|
238
245
|
const reasoningTarget = getReasoningProviderTarget(provider, model, cfg);
|
|
239
246
|
if (reasoningTarget === 'anthropic') {
|
|
240
247
|
if (usesAdaptiveAnthropicThinking(model)) {
|
|
248
|
+
const thinking = isClaudeOpus47(model)
|
|
249
|
+
? { type: 'adaptive', display: 'summarized' }
|
|
250
|
+
: { type: 'adaptive' };
|
|
251
|
+
|
|
241
252
|
return {
|
|
242
253
|
providerOptions: {
|
|
243
254
|
anthropic: {
|
|
244
|
-
thinking
|
|
245
|
-
effort: toAnthropicEffort(reasoningLevel),
|
|
255
|
+
thinking,
|
|
256
|
+
effort: toAnthropicEffort(model, reasoningLevel),
|
|
246
257
|
},
|
|
247
258
|
},
|
|
248
259
|
effectiveMaxOutputTokens: maxOutputTokens,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { getDb } from '@ottocode/database';
|
|
2
2
|
import { messages, messageParts, sessions } from '@ottocode/database/schema';
|
|
3
3
|
import { eq } from 'drizzle-orm';
|
|
4
|
-
import { catalog, type ProviderId } from '@ottocode/sdk';
|
|
4
|
+
import { catalog, isBuiltInProviderId, type ProviderId } from '@ottocode/sdk';
|
|
5
5
|
import type { RunOpts } from './queue.ts';
|
|
6
6
|
|
|
7
7
|
export type UsageData = {
|
|
@@ -77,10 +77,11 @@ export function resolveUsageProvider(
|
|
|
77
77
|
) {
|
|
78
78
|
return provider;
|
|
79
79
|
}
|
|
80
|
-
const entry = catalog[provider];
|
|
80
|
+
const entry = isBuiltInProviderId(provider) ? catalog[provider] : undefined;
|
|
81
81
|
const normalizedModel = model.includes('/') ? model.split('/').at(-1) : model;
|
|
82
82
|
const modelEntry = entry?.models.find(
|
|
83
|
-
(m
|
|
83
|
+
(m: { id?: string }) =>
|
|
84
|
+
m.id?.toLowerCase() === normalizedModel?.toLowerCase(),
|
|
84
85
|
);
|
|
85
86
|
const npm = modelEntry?.provider?.npm ?? '';
|
|
86
87
|
if (npm.includes('openai')) return 'openai';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { catalog } from '@ottocode/sdk';
|
|
1
|
+
import { catalog, isBuiltInProviderId } from '@ottocode/sdk';
|
|
2
2
|
import type { ProviderName } from '../provider/index.ts';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -13,11 +13,16 @@ export function getMaxOutputTokens(
|
|
|
13
13
|
return undefined;
|
|
14
14
|
}
|
|
15
15
|
try {
|
|
16
|
+
if (!isBuiltInProviderId(provider)) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
16
19
|
const providerCatalog = catalog[provider];
|
|
17
20
|
if (!providerCatalog) {
|
|
18
21
|
return undefined;
|
|
19
22
|
}
|
|
20
|
-
const modelInfo = providerCatalog.models.find(
|
|
23
|
+
const modelInfo = providerCatalog.models.find(
|
|
24
|
+
(m: { id: string }) => m.id === modelId,
|
|
25
|
+
);
|
|
21
26
|
if (!modelInfo) {
|
|
22
27
|
return undefined;
|
|
23
28
|
}
|
package/src/tools/adapter.ts
CHANGED
|
@@ -530,6 +530,27 @@ export function adaptTools(
|
|
|
530
530
|
streamedResult = (chunk as { result: unknown }).result;
|
|
531
531
|
continue;
|
|
532
532
|
}
|
|
533
|
+
if (
|
|
534
|
+
chunk &&
|
|
535
|
+
typeof chunk === 'object' &&
|
|
536
|
+
'terminalId' in chunk &&
|
|
537
|
+
typeof (chunk as { terminalId?: unknown }).terminalId ===
|
|
538
|
+
'string'
|
|
539
|
+
) {
|
|
540
|
+
publish({
|
|
541
|
+
type: 'tool.delta',
|
|
542
|
+
sessionId: ctx.sessionId,
|
|
543
|
+
payload: {
|
|
544
|
+
name,
|
|
545
|
+
channel: 'terminal',
|
|
546
|
+
delta: (chunk as { terminalId: string }).terminalId,
|
|
547
|
+
stepIndex: stepIndexForEvent,
|
|
548
|
+
callId: callIdFromQueue,
|
|
549
|
+
messageId: ctx.messageId,
|
|
550
|
+
},
|
|
551
|
+
});
|
|
552
|
+
continue;
|
|
553
|
+
}
|
|
533
554
|
const delta =
|
|
534
555
|
typeof chunk === 'string'
|
|
535
556
|
? chunk
|
package/src/openapi/paths/ask.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { errorResponse, projectQueryParam } from '../helpers';
|
|
2
|
-
|
|
3
|
-
export const askPaths = {
|
|
4
|
-
'/v1/ask': {
|
|
5
|
-
post: {
|
|
6
|
-
tags: ['ask'],
|
|
7
|
-
operationId: 'ask',
|
|
8
|
-
summary: 'Send a prompt using the ask service',
|
|
9
|
-
description:
|
|
10
|
-
'Streamlined endpoint used by the CLI to send prompts and receive assistant responses. Creates sessions as needed and reuses the last session when requested.',
|
|
11
|
-
parameters: [projectQueryParam()],
|
|
12
|
-
requestBody: {
|
|
13
|
-
required: true,
|
|
14
|
-
content: {
|
|
15
|
-
'application/json': {
|
|
16
|
-
schema: {
|
|
17
|
-
type: 'object',
|
|
18
|
-
required: ['prompt'],
|
|
19
|
-
properties: {
|
|
20
|
-
prompt: {
|
|
21
|
-
type: 'string',
|
|
22
|
-
description: 'User prompt to send to the assistant.',
|
|
23
|
-
},
|
|
24
|
-
agent: {
|
|
25
|
-
type: 'string',
|
|
26
|
-
description: 'Optional agent name to use for this request.',
|
|
27
|
-
},
|
|
28
|
-
provider: {
|
|
29
|
-
$ref: '#/components/schemas/Provider',
|
|
30
|
-
description:
|
|
31
|
-
'Optional provider override. When omitted the agent and config defaults apply.',
|
|
32
|
-
},
|
|
33
|
-
model: {
|
|
34
|
-
type: 'string',
|
|
35
|
-
description:
|
|
36
|
-
'Optional model override for the selected provider.',
|
|
37
|
-
},
|
|
38
|
-
reasoningText: {
|
|
39
|
-
type: 'boolean',
|
|
40
|
-
description:
|
|
41
|
-
'Enable extended thinking / reasoning for models that support it.',
|
|
42
|
-
},
|
|
43
|
-
reasoningLevel: {
|
|
44
|
-
type: 'string',
|
|
45
|
-
enum: ['minimal', 'low', 'medium', 'high', 'max', 'xhigh'],
|
|
46
|
-
description:
|
|
47
|
-
'Optional reasoning intensity override for supported providers/models.',
|
|
48
|
-
},
|
|
49
|
-
sessionId: {
|
|
50
|
-
type: 'string',
|
|
51
|
-
description: 'Send the prompt to a specific session.',
|
|
52
|
-
},
|
|
53
|
-
last: {
|
|
54
|
-
type: 'boolean',
|
|
55
|
-
description:
|
|
56
|
-
'If true, reuse the most recent session for the project.',
|
|
57
|
-
},
|
|
58
|
-
jsonMode: {
|
|
59
|
-
type: 'boolean',
|
|
60
|
-
description:
|
|
61
|
-
'Request structured JSON output when supported by the agent.',
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
responses: {
|
|
69
|
-
202: {
|
|
70
|
-
description: 'Accepted',
|
|
71
|
-
content: {
|
|
72
|
-
'application/json': {
|
|
73
|
-
schema: { $ref: '#/components/schemas/AskResponse' },
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
400: errorResponse(),
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
} as const;
|