@ottocode/server 0.1.265 → 0.1.266
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 +3 -3
- package/src/routes/auth/copilot.ts +699 -0
- package/src/routes/auth/oauth.ts +578 -0
- package/src/routes/auth/onboarding.ts +45 -0
- package/src/routes/auth/providers.ts +189 -0
- package/src/routes/auth/service.ts +167 -0
- package/src/routes/auth/state.ts +23 -0
- package/src/routes/auth/status.ts +203 -0
- package/src/routes/auth/wallet.ts +229 -0
- package/src/routes/auth.ts +12 -2080
- package/src/routes/config/models-service.ts +411 -0
- package/src/routes/config/models.ts +6 -426
- package/src/routes/config/providers-service.ts +237 -0
- package/src/routes/config/providers.ts +10 -242
- package/src/routes/files/handlers.ts +297 -0
- package/src/routes/files/service.ts +313 -0
- package/src/routes/files.ts +12 -608
- package/src/routes/git/commit-service.ts +207 -0
- package/src/routes/git/commit.ts +6 -220
- package/src/routes/git/remote-service.ts +116 -0
- package/src/routes/git/remote.ts +8 -115
- package/src/routes/git/staging-service.ts +111 -0
- package/src/routes/git/staging.ts +10 -205
- package/src/routes/mcp/auth.ts +338 -0
- package/src/routes/mcp/lifecycle.ts +263 -0
- package/src/routes/mcp/servers.ts +212 -0
- package/src/routes/mcp/service.ts +664 -0
- package/src/routes/mcp/state.ts +13 -0
- package/src/routes/mcp.ts +6 -1233
- package/src/routes/ottorouter/billing.ts +593 -0
- package/src/routes/ottorouter/service.ts +92 -0
- package/src/routes/ottorouter/topup.ts +301 -0
- package/src/routes/ottorouter/wallet.ts +370 -0
- package/src/routes/ottorouter.ts +6 -1319
- package/src/routes/research/service.ts +339 -0
- package/src/routes/research.ts +12 -390
- package/src/routes/sessions/crud.ts +563 -0
- package/src/routes/sessions/queue.ts +242 -0
- package/src/routes/sessions/retry.ts +121 -0
- package/src/routes/sessions/service.ts +768 -0
- package/src/routes/sessions/share.ts +434 -0
- package/src/routes/sessions.ts +8 -1977
- package/src/routes/skills/service.ts +221 -0
- package/src/routes/skills/spec.ts +309 -0
- package/src/routes/skills.ts +31 -909
- package/src/routes/terminals/service.ts +326 -0
- package/src/routes/terminals.ts +19 -295
- package/src/routes/tunnel/service.ts +217 -0
- package/src/routes/tunnel.ts +29 -219
- package/src/runtime/agent/registry-prompts.ts +147 -0
- package/src/runtime/agent/registry.ts +6 -124
- package/src/runtime/agent/runner-errors.ts +116 -0
- package/src/runtime/agent/runner-reminders.ts +45 -0
- package/src/runtime/agent/runner-setup-model.ts +75 -0
- package/src/runtime/agent/runner-setup-prompt.ts +185 -0
- package/src/runtime/agent/runner-setup-tools.ts +103 -0
- package/src/runtime/agent/runner-setup-utils.ts +21 -0
- package/src/runtime/agent/runner-setup.ts +54 -288
- package/src/runtime/agent/runner-telemetry.ts +112 -0
- package/src/runtime/agent/runner-text.ts +108 -0
- package/src/runtime/agent/runner-tool-observer.ts +86 -0
- package/src/runtime/agent/runner.ts +79 -378
- package/src/runtime/provider/custom.ts +73 -0
- package/src/runtime/provider/index.ts +2 -85
- package/src/runtime/provider/reasoning-builders.ts +280 -0
- package/src/runtime/provider/reasoning.ts +67 -264
- package/src/tools/adapter/events.ts +116 -0
- package/src/tools/adapter/execution.ts +160 -0
- package/src/tools/adapter/pending.ts +37 -0
- package/src/tools/adapter/persistence.ts +166 -0
- package/src/tools/adapter/results.ts +97 -0
- package/src/tools/adapter.ts +124 -451
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { messageParts, sessions } from '@ottocode/database/schema';
|
|
2
|
+
import { eq } from 'drizzle-orm';
|
|
3
|
+
import type { ToolAdapterContext } from '../../runtime/tools/context.ts';
|
|
4
|
+
import { publishToolResult, type ToolResultContent } from './events.ts';
|
|
5
|
+
|
|
6
|
+
export type ToolTiming = {
|
|
7
|
+
endTs: number;
|
|
8
|
+
durationMs: number | null;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function computeToolTiming(startTs?: number): ToolTiming {
|
|
12
|
+
const endTs = Date.now();
|
|
13
|
+
return {
|
|
14
|
+
endTs,
|
|
15
|
+
durationMs:
|
|
16
|
+
typeof startTs === 'number' ? Math.max(0, endTs - startTs) : null,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function persistToolCall(
|
|
21
|
+
ctx: ToolAdapterContext,
|
|
22
|
+
args: {
|
|
23
|
+
partId: string;
|
|
24
|
+
name: string;
|
|
25
|
+
input: unknown;
|
|
26
|
+
callId: string;
|
|
27
|
+
startTs?: number;
|
|
28
|
+
stepIndex?: number;
|
|
29
|
+
},
|
|
30
|
+
): Promise<void> {
|
|
31
|
+
const index = await ctx.nextIndex();
|
|
32
|
+
await ctx.db.insert(messageParts).values({
|
|
33
|
+
id: args.partId,
|
|
34
|
+
messageId: ctx.messageId,
|
|
35
|
+
index,
|
|
36
|
+
stepIndex: args.stepIndex,
|
|
37
|
+
type: 'tool_call',
|
|
38
|
+
content: JSON.stringify({
|
|
39
|
+
name: args.name,
|
|
40
|
+
args: args.input,
|
|
41
|
+
callId: args.callId,
|
|
42
|
+
}),
|
|
43
|
+
agent: ctx.agent,
|
|
44
|
+
provider: ctx.provider,
|
|
45
|
+
model: ctx.model,
|
|
46
|
+
startedAt: args.startTs,
|
|
47
|
+
toolName: args.name,
|
|
48
|
+
toolCallId: args.callId,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function persistToolResultWithIndex(
|
|
53
|
+
ctx: ToolAdapterContext,
|
|
54
|
+
args: {
|
|
55
|
+
partId: string;
|
|
56
|
+
index: number;
|
|
57
|
+
name: string;
|
|
58
|
+
content: ToolResultContent;
|
|
59
|
+
startTs?: number;
|
|
60
|
+
callId?: string;
|
|
61
|
+
stepIndex?: number;
|
|
62
|
+
endTs: number;
|
|
63
|
+
durationMs: number | null;
|
|
64
|
+
},
|
|
65
|
+
): Promise<void> {
|
|
66
|
+
await ctx.db.insert(messageParts).values({
|
|
67
|
+
id: args.partId,
|
|
68
|
+
messageId: ctx.messageId,
|
|
69
|
+
index: args.index,
|
|
70
|
+
stepIndex: args.stepIndex,
|
|
71
|
+
type: 'tool_result',
|
|
72
|
+
content: JSON.stringify(args.content),
|
|
73
|
+
agent: ctx.agent,
|
|
74
|
+
provider: ctx.provider,
|
|
75
|
+
model: ctx.model,
|
|
76
|
+
startedAt: args.startTs,
|
|
77
|
+
completedAt: args.endTs,
|
|
78
|
+
toolName: args.name,
|
|
79
|
+
toolCallId: args.callId,
|
|
80
|
+
toolDurationMs: args.durationMs ?? undefined,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export async function persistToolResult(
|
|
85
|
+
ctx: ToolAdapterContext,
|
|
86
|
+
args: {
|
|
87
|
+
partId: string;
|
|
88
|
+
name: string;
|
|
89
|
+
content: ToolResultContent;
|
|
90
|
+
startTs?: number;
|
|
91
|
+
callId?: string;
|
|
92
|
+
stepIndex?: number;
|
|
93
|
+
endTs: number;
|
|
94
|
+
durationMs: number | null;
|
|
95
|
+
},
|
|
96
|
+
): Promise<void> {
|
|
97
|
+
const index = await ctx.nextIndex();
|
|
98
|
+
await persistToolResultWithIndex(ctx, { ...args, index });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function persistToolErrorResult(
|
|
102
|
+
ctx: ToolAdapterContext,
|
|
103
|
+
args: {
|
|
104
|
+
name: string;
|
|
105
|
+
errorResult: unknown;
|
|
106
|
+
callId?: string;
|
|
107
|
+
startTs?: number;
|
|
108
|
+
stepIndexForEvent?: number;
|
|
109
|
+
input?: unknown;
|
|
110
|
+
},
|
|
111
|
+
): Promise<void> {
|
|
112
|
+
const resultPartId = crypto.randomUUID();
|
|
113
|
+
const { endTs, durationMs } = computeToolTiming(args.startTs);
|
|
114
|
+
const effectiveStepIndex = args.stepIndexForEvent ?? ctx.stepIndex;
|
|
115
|
+
const content: ToolResultContent = {
|
|
116
|
+
name: args.name,
|
|
117
|
+
result: args.errorResult,
|
|
118
|
+
callId: args.callId,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (args.input !== undefined) {
|
|
122
|
+
content.args = args.input;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await persistToolResult(ctx, {
|
|
126
|
+
partId: resultPartId,
|
|
127
|
+
name: args.name,
|
|
128
|
+
content,
|
|
129
|
+
startTs: args.startTs,
|
|
130
|
+
callId: args.callId,
|
|
131
|
+
stepIndex: effectiveStepIndex,
|
|
132
|
+
endTs,
|
|
133
|
+
durationMs,
|
|
134
|
+
});
|
|
135
|
+
publishToolResult(ctx, content, effectiveStepIndex);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export async function updateToolSessionStats(
|
|
139
|
+
ctx: ToolAdapterContext,
|
|
140
|
+
args: { name: string; durationMs: number | null; endTs: number },
|
|
141
|
+
): Promise<void> {
|
|
142
|
+
try {
|
|
143
|
+
const sessRows = await ctx.db
|
|
144
|
+
.select()
|
|
145
|
+
.from(sessions)
|
|
146
|
+
.where(eq(sessions.id, ctx.sessionId));
|
|
147
|
+
if (sessRows.length) {
|
|
148
|
+
const row = sessRows[0] as typeof sessions.$inferSelect;
|
|
149
|
+
const totalToolTimeMs =
|
|
150
|
+
Number(row.totalToolTimeMs || 0) + (args.durationMs ?? 0);
|
|
151
|
+
let counts: Record<string, number> = {};
|
|
152
|
+
try {
|
|
153
|
+
counts = row.toolCountsJson ? JSON.parse(row.toolCountsJson) : {};
|
|
154
|
+
} catch {}
|
|
155
|
+
counts[args.name] = (counts[args.name] || 0) + 1;
|
|
156
|
+
await ctx.db
|
|
157
|
+
.update(sessions)
|
|
158
|
+
.set({
|
|
159
|
+
totalToolTimeMs,
|
|
160
|
+
toolCountsJson: JSON.stringify(counts),
|
|
161
|
+
lastActiveAt: args.endTs,
|
|
162
|
+
})
|
|
163
|
+
.where(eq(sessions.id, ctx.sessionId));
|
|
164
|
+
}
|
|
165
|
+
} catch {}
|
|
166
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { ToolResultContent } from './events.ts';
|
|
2
|
+
|
|
3
|
+
export type ToolFailureState = {
|
|
4
|
+
active: boolean;
|
|
5
|
+
toolName?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function createBlockedToolResult(reason: string | undefined): {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: string;
|
|
11
|
+
details: { reason: 'safety_guard' };
|
|
12
|
+
} {
|
|
13
|
+
return {
|
|
14
|
+
ok: false,
|
|
15
|
+
error: `Blocked: ${reason}`,
|
|
16
|
+
details: { reason: 'safety_guard' },
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createRejectedToolResult(): {
|
|
21
|
+
ok: false;
|
|
22
|
+
error: string;
|
|
23
|
+
details: { reason: 'user_rejected' };
|
|
24
|
+
} {
|
|
25
|
+
return {
|
|
26
|
+
ok: false,
|
|
27
|
+
error: 'Tool execution rejected by user',
|
|
28
|
+
details: { reason: 'user_rejected' },
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createToolExceptionResult(error: unknown): unknown {
|
|
33
|
+
if (error && typeof error === 'object' && 'ok' in error) return error;
|
|
34
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
35
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
36
|
+
return {
|
|
37
|
+
ok: false,
|
|
38
|
+
error: errorMessage,
|
|
39
|
+
stack: errorStack,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function buildToolResultContent(args: {
|
|
44
|
+
name: string;
|
|
45
|
+
result: unknown;
|
|
46
|
+
callId?: string;
|
|
47
|
+
input?: unknown;
|
|
48
|
+
}): ToolResultContent {
|
|
49
|
+
const content: ToolResultContent = {
|
|
50
|
+
name: args.name,
|
|
51
|
+
result: args.result,
|
|
52
|
+
callId: args.callId,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
if (args.input !== undefined) {
|
|
56
|
+
content.args = args.input;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (
|
|
60
|
+
args.result &&
|
|
61
|
+
typeof args.result === 'object' &&
|
|
62
|
+
'artifact' in args.result
|
|
63
|
+
) {
|
|
64
|
+
try {
|
|
65
|
+
const maybeArtifact = (args.result as { artifact?: unknown }).artifact;
|
|
66
|
+
if (maybeArtifact !== undefined) {
|
|
67
|
+
content.artifact = maybeArtifact;
|
|
68
|
+
}
|
|
69
|
+
} catch {}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return content;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function markToolFailed(
|
|
76
|
+
stepState: { failed: boolean; failedToolName?: string },
|
|
77
|
+
failureState: ToolFailureState,
|
|
78
|
+
name: string,
|
|
79
|
+
): void {
|
|
80
|
+
stepState.failed = true;
|
|
81
|
+
stepState.failedToolName = name;
|
|
82
|
+
failureState.active = true;
|
|
83
|
+
failureState.toolName = name;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function markToolSucceeded(
|
|
87
|
+
stepState: { failed: boolean; failedToolName?: string },
|
|
88
|
+
failureState: ToolFailureState,
|
|
89
|
+
name: string,
|
|
90
|
+
): void {
|
|
91
|
+
stepState.failed = false;
|
|
92
|
+
stepState.failedToolName = undefined;
|
|
93
|
+
if (failureState.active && failureState.toolName === name) {
|
|
94
|
+
failureState.active = false;
|
|
95
|
+
failureState.toolName = undefined;
|
|
96
|
+
}
|
|
97
|
+
}
|