@ottocode/server 0.1.260 → 0.1.262

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.
Files changed (67) hide show
  1. package/package.json +4 -3
  2. package/src/index.ts +5 -4
  3. package/src/openapi/register.ts +92 -0
  4. package/src/openapi/route.ts +22 -0
  5. package/src/routes/ask.ts +210 -99
  6. package/src/routes/auth.ts +1701 -626
  7. package/src/routes/branch.ts +281 -90
  8. package/src/routes/config/agents.ts +79 -32
  9. package/src/routes/config/cwd.ts +46 -14
  10. package/src/routes/config/debug.ts +159 -30
  11. package/src/routes/config/defaults.ts +182 -64
  12. package/src/routes/config/main.ts +109 -73
  13. package/src/routes/config/models.ts +304 -137
  14. package/src/routes/config/providers.ts +462 -166
  15. package/src/routes/config/utils.ts +2 -2
  16. package/src/routes/doctor.ts +395 -161
  17. package/src/routes/files.ts +650 -260
  18. package/src/routes/git/branch.ts +143 -52
  19. package/src/routes/git/commit.ts +347 -141
  20. package/src/routes/git/diff.ts +239 -116
  21. package/src/routes/git/init.ts +103 -23
  22. package/src/routes/git/pull.ts +167 -65
  23. package/src/routes/git/push.ts +222 -117
  24. package/src/routes/git/remote.ts +401 -100
  25. package/src/routes/git/staging.ts +502 -141
  26. package/src/routes/git/status.ts +171 -78
  27. package/src/routes/mcp.ts +1129 -404
  28. package/src/routes/openapi.ts +27 -4
  29. package/src/routes/ottorouter.ts +1221 -389
  30. package/src/routes/provider-usage.ts +153 -36
  31. package/src/routes/research.ts +817 -370
  32. package/src/routes/root.ts +50 -6
  33. package/src/routes/session-approval.ts +228 -54
  34. package/src/routes/session-files.ts +265 -134
  35. package/src/routes/session-messages.ts +330 -150
  36. package/src/routes/session-stream.ts +83 -2
  37. package/src/routes/sessions.ts +1830 -780
  38. package/src/routes/skills.ts +849 -161
  39. package/src/routes/terminals.ts +469 -103
  40. package/src/routes/tunnel.ts +394 -118
  41. package/src/runtime/ask/service.ts +1 -0
  42. package/src/runtime/message/compaction-limits.ts +3 -3
  43. package/src/runtime/provider/reasoning.ts +2 -1
  44. package/src/runtime/session/db-operations.ts +4 -3
  45. package/src/runtime/utils/token.ts +7 -2
  46. package/src/tools/adapter.ts +21 -0
  47. package/src/openapi/paths/ask.ts +0 -81
  48. package/src/openapi/paths/auth.ts +0 -687
  49. package/src/openapi/paths/branch.ts +0 -102
  50. package/src/openapi/paths/config.ts +0 -485
  51. package/src/openapi/paths/doctor.ts +0 -165
  52. package/src/openapi/paths/files.ts +0 -236
  53. package/src/openapi/paths/git.ts +0 -690
  54. package/src/openapi/paths/mcp.ts +0 -339
  55. package/src/openapi/paths/messages.ts +0 -103
  56. package/src/openapi/paths/ottorouter.ts +0 -594
  57. package/src/openapi/paths/provider-usage.ts +0 -59
  58. package/src/openapi/paths/research.ts +0 -227
  59. package/src/openapi/paths/session-approval.ts +0 -93
  60. package/src/openapi/paths/session-extras.ts +0 -336
  61. package/src/openapi/paths/session-files.ts +0 -91
  62. package/src/openapi/paths/sessions.ts +0 -210
  63. package/src/openapi/paths/skills.ts +0 -377
  64. package/src/openapi/paths/stream.ts +0 -26
  65. package/src/openapi/paths/terminals.ts +0 -226
  66. package/src/openapi/paths/tunnel.ts +0 -163
  67. package/src/openapi/spec.ts +0 -73
@@ -1,39 +1,168 @@
1
1
  import type { Hono } from 'hono';
2
2
  import { logger, readDebugConfig, writeDebugConfig } from '@ottocode/sdk';
3
3
  import { serializeError } from '../../runtime/errors/api-error.ts';
4
+ import { openApiRoute } from '../../openapi/route.ts';
4
5
 
5
6
  export function registerDebugConfigRoute(app: Hono) {
6
- app.get('/v1/config/debug', async (c) => {
7
- try {
8
- const debug = await readDebugConfig();
9
- return c.json(debug);
10
- } catch (error) {
11
- logger.error('Failed to load debug config', error);
12
- const errorResponse = serializeError(error);
13
- return c.json(errorResponse, errorResponse.error.status || 500);
14
- }
15
- });
7
+ openApiRoute(
8
+ app,
9
+ {
10
+ method: 'get',
11
+ path: '/v1/config/debug',
12
+ tags: ['config'],
13
+ operationId: 'getDebugConfig',
14
+ summary: 'Get debug configuration',
15
+ responses: {
16
+ '200': {
17
+ description: 'OK',
18
+ content: {
19
+ 'application/json': {
20
+ schema: {
21
+ type: 'object',
22
+ properties: {
23
+ enabled: {
24
+ type: 'boolean',
25
+ },
26
+ scopes: {
27
+ type: 'array',
28
+ items: {
29
+ type: 'string',
30
+ },
31
+ },
32
+ logPath: {
33
+ type: 'string',
34
+ },
35
+ sessionsDir: {
36
+ type: 'string',
37
+ },
38
+ debugDir: {
39
+ type: 'string',
40
+ },
41
+ },
42
+ required: [
43
+ 'enabled',
44
+ 'scopes',
45
+ 'logPath',
46
+ 'sessionsDir',
47
+ 'debugDir',
48
+ ],
49
+ },
50
+ },
51
+ },
52
+ },
53
+ },
54
+ },
55
+ async (c) => {
56
+ try {
57
+ const debug = await readDebugConfig();
58
+ return c.json(debug);
59
+ } catch (error) {
60
+ logger.error('Failed to load debug config', error);
61
+ const errorResponse = serializeError(error);
62
+ return c.json(errorResponse, errorResponse.error.status || 500);
63
+ }
64
+ },
65
+ );
16
66
 
17
- app.patch('/v1/config/debug', async (c) => {
18
- try {
19
- const body = await c.req.json<{
20
- enabled?: boolean;
21
- scopes?: string[];
22
- }>();
67
+ openApiRoute(
68
+ app,
69
+ {
70
+ method: 'patch',
71
+ path: '/v1/config/debug',
72
+ tags: ['config'],
73
+ operationId: 'updateDebugConfig',
74
+ summary: 'Update debug configuration',
75
+ requestBody: {
76
+ required: true,
77
+ content: {
78
+ 'application/json': {
79
+ schema: {
80
+ type: 'object',
81
+ properties: {
82
+ enabled: {
83
+ type: 'boolean',
84
+ },
85
+ scopes: {
86
+ type: 'array',
87
+ items: {
88
+ type: 'string',
89
+ },
90
+ },
91
+ },
92
+ },
93
+ },
94
+ },
95
+ },
96
+ responses: {
97
+ '200': {
98
+ description: 'OK',
99
+ content: {
100
+ 'application/json': {
101
+ schema: {
102
+ type: 'object',
103
+ properties: {
104
+ success: {
105
+ type: 'boolean',
106
+ },
107
+ debug: {
108
+ type: 'object',
109
+ properties: {
110
+ enabled: {
111
+ type: 'boolean',
112
+ },
113
+ scopes: {
114
+ type: 'array',
115
+ items: {
116
+ type: 'string',
117
+ },
118
+ },
119
+ logPath: {
120
+ type: 'string',
121
+ },
122
+ sessionsDir: {
123
+ type: 'string',
124
+ },
125
+ debugDir: {
126
+ type: 'string',
127
+ },
128
+ },
129
+ required: [
130
+ 'enabled',
131
+ 'scopes',
132
+ 'logPath',
133
+ 'sessionsDir',
134
+ 'debugDir',
135
+ ],
136
+ },
137
+ },
138
+ required: ['success', 'debug'],
139
+ },
140
+ },
141
+ },
142
+ },
143
+ },
144
+ },
145
+ async (c) => {
146
+ try {
147
+ const body = await c.req.json<{
148
+ enabled?: boolean;
149
+ scopes?: string[];
150
+ }>();
23
151
 
24
- await writeDebugConfig({
25
- enabled: body.enabled,
26
- scopes: Array.isArray(body.scopes)
27
- ? body.scopes.map((scope) => scope.trim()).filter(Boolean)
28
- : body.scopes,
29
- });
152
+ await writeDebugConfig({
153
+ enabled: body.enabled,
154
+ scopes: Array.isArray(body.scopes)
155
+ ? body.scopes.map((scope) => scope.trim()).filter(Boolean)
156
+ : body.scopes,
157
+ });
30
158
 
31
- const debug = await readDebugConfig();
32
- return c.json({ success: true, debug });
33
- } catch (error) {
34
- logger.error('Failed to update debug config', error);
35
- const errorResponse = serializeError(error);
36
- return c.json(errorResponse, errorResponse.error.status || 500);
37
- }
38
- });
159
+ const debug = await readDebugConfig();
160
+ return c.json({ success: true, debug });
161
+ } catch (error) {
162
+ logger.error('Failed to update debug config', error);
163
+ const errorResponse = serializeError(error);
164
+ return c.json(errorResponse, errorResponse.error.status || 500);
165
+ }
166
+ },
167
+ );
39
168
  }
@@ -8,77 +8,195 @@ import {
8
8
  } from '@ottocode/sdk';
9
9
  import { logger } from '@ottocode/sdk';
10
10
  import { serializeError } from '../../runtime/errors/api-error.ts';
11
+ import { openApiRoute } from '../../openapi/route.ts';
11
12
 
12
13
  export function registerDefaultsRoute(app: Hono) {
13
- app.patch('/v1/config/defaults', async (c) => {
14
- try {
15
- const projectRoot = c.req.query('project') || process.cwd();
16
- const cfg = await loadConfig(projectRoot);
17
- const body = await c.req.json<{
18
- agent?: string;
19
- provider?: string;
20
- model?: string;
21
- toolApproval?: 'auto' | 'dangerous' | 'all' | 'yolo';
22
- guidedMode?: boolean;
23
- reasoningText?: boolean;
24
- reasoningLevel?: ReasoningLevel;
25
- theme?: string;
26
- fullWidthContent?: boolean;
27
- autoCompactThresholdTokens?: number | null;
28
- scope?: 'global' | 'local';
29
- }>();
14
+ openApiRoute(
15
+ app,
16
+ {
17
+ method: 'patch',
18
+ path: '/v1/config/defaults',
19
+ tags: ['config'],
20
+ operationId: 'updateDefaults',
21
+ summary: 'Update default configuration',
22
+ description: 'Update the default agent, provider, and/or model',
23
+ parameters: [
24
+ {
25
+ in: 'query',
26
+ name: 'project',
27
+ required: false,
28
+ schema: {
29
+ type: 'string',
30
+ },
31
+ description:
32
+ 'Project root override (defaults to current working directory).',
33
+ },
34
+ ],
35
+ requestBody: {
36
+ required: true,
37
+ content: {
38
+ 'application/json': {
39
+ schema: {
40
+ type: 'object',
41
+ properties: {
42
+ agent: {
43
+ type: 'string',
44
+ },
45
+ provider: {
46
+ type: 'string',
47
+ },
48
+ model: {
49
+ type: 'string',
50
+ },
51
+ fullWidthContent: {
52
+ type: 'boolean',
53
+ },
54
+ autoCompactThresholdTokens: {
55
+ type: 'integer',
56
+ nullable: true,
57
+ },
58
+ reasoningText: {
59
+ type: 'boolean',
60
+ },
61
+ reasoningLevel: {
62
+ type: 'string',
63
+ enum: ['minimal', 'low', 'medium', 'high', 'max', 'xhigh'],
64
+ },
65
+ scope: {
66
+ type: 'string',
67
+ enum: ['global', 'local'],
68
+ default: 'local',
69
+ },
70
+ },
71
+ },
72
+ },
73
+ },
74
+ },
75
+ responses: {
76
+ '200': {
77
+ description: 'OK',
78
+ content: {
79
+ 'application/json': {
80
+ schema: {
81
+ type: 'object',
82
+ properties: {
83
+ success: {
84
+ type: 'boolean',
85
+ },
86
+ defaults: {
87
+ type: 'object',
88
+ properties: {
89
+ agent: {
90
+ type: 'string',
91
+ },
92
+ provider: {
93
+ type: 'string',
94
+ },
95
+ model: {
96
+ type: 'string',
97
+ },
98
+ fullWidthContent: {
99
+ type: 'boolean',
100
+ },
101
+ autoCompactThresholdTokens: {
102
+ type: 'integer',
103
+ nullable: true,
104
+ },
105
+ reasoningText: {
106
+ type: 'boolean',
107
+ },
108
+ reasoningLevel: {
109
+ type: 'string',
110
+ enum: [
111
+ 'minimal',
112
+ 'low',
113
+ 'medium',
114
+ 'high',
115
+ 'max',
116
+ 'xhigh',
117
+ ],
118
+ },
119
+ },
120
+ required: ['agent', 'provider', 'model'],
121
+ },
122
+ },
123
+ required: ['success', 'defaults'],
124
+ },
125
+ },
126
+ },
127
+ },
128
+ },
129
+ },
130
+ async (c) => {
131
+ try {
132
+ const projectRoot = c.req.query('project') || process.cwd();
133
+ const cfg = await loadConfig(projectRoot);
134
+ const body = await c.req.json<{
135
+ agent?: string;
136
+ provider?: string;
137
+ model?: string;
138
+ toolApproval?: 'auto' | 'dangerous' | 'all' | 'yolo';
139
+ guidedMode?: boolean;
140
+ reasoningText?: boolean;
141
+ reasoningLevel?: ReasoningLevel;
142
+ theme?: string;
143
+ fullWidthContent?: boolean;
144
+ autoCompactThresholdTokens?: number | null;
145
+ scope?: 'global' | 'local';
146
+ }>();
30
147
 
31
- const scope = body.scope || 'global';
32
- const updates: Partial<{
33
- agent: string;
34
- provider: ProviderId;
35
- model: string;
36
- toolApproval: 'auto' | 'dangerous' | 'all' | 'yolo';
37
- guidedMode: boolean;
38
- reasoningText: boolean;
39
- reasoningLevel: ReasoningLevel;
40
- theme: string;
41
- fullWidthContent: boolean;
42
- autoCompactThresholdTokens: number | null;
43
- }> = {};
148
+ const scope = body.scope || 'global';
149
+ const updates: Partial<{
150
+ agent: string;
151
+ provider: ProviderId;
152
+ model: string;
153
+ toolApproval: 'auto' | 'dangerous' | 'all' | 'yolo';
154
+ guidedMode: boolean;
155
+ reasoningText: boolean;
156
+ reasoningLevel: ReasoningLevel;
157
+ theme: string;
158
+ fullWidthContent: boolean;
159
+ autoCompactThresholdTokens: number | null;
160
+ }> = {};
44
161
 
45
- if (body.agent) updates.agent = body.agent;
46
- if (body.provider) {
47
- if (!hasConfiguredProvider(cfg, body.provider)) {
48
- return c.json({ error: `Invalid provider: ${body.provider}` }, 400);
162
+ if (body.agent) updates.agent = body.agent;
163
+ if (body.provider) {
164
+ if (!hasConfiguredProvider(cfg, body.provider)) {
165
+ return c.json({ error: `Invalid provider: ${body.provider}` }, 400);
166
+ }
167
+ updates.provider = body.provider as ProviderId;
49
168
  }
50
- updates.provider = body.provider as ProviderId;
51
- }
52
- if (body.model) updates.model = body.model;
53
- if (body.toolApproval) updates.toolApproval = body.toolApproval;
54
- if (body.guidedMode !== undefined) updates.guidedMode = body.guidedMode;
55
- if (body.reasoningText !== undefined)
56
- updates.reasoningText = body.reasoningText;
57
- if (body.reasoningLevel) updates.reasoningLevel = body.reasoningLevel;
58
- if (body.theme) updates.theme = body.theme;
59
- if (body.fullWidthContent !== undefined)
60
- updates.fullWidthContent = body.fullWidthContent;
61
- if (body.autoCompactThresholdTokens !== undefined) {
62
- const threshold = body.autoCompactThresholdTokens;
63
- if (threshold === null) {
64
- updates.autoCompactThresholdTokens = null;
65
- } else if (Number.isFinite(threshold) && threshold > 0) {
66
- updates.autoCompactThresholdTokens = Math.floor(threshold);
169
+ if (body.model) updates.model = body.model;
170
+ if (body.toolApproval) updates.toolApproval = body.toolApproval;
171
+ if (body.guidedMode !== undefined) updates.guidedMode = body.guidedMode;
172
+ if (body.reasoningText !== undefined)
173
+ updates.reasoningText = body.reasoningText;
174
+ if (body.reasoningLevel) updates.reasoningLevel = body.reasoningLevel;
175
+ if (body.theme) updates.theme = body.theme;
176
+ if (body.fullWidthContent !== undefined)
177
+ updates.fullWidthContent = body.fullWidthContent;
178
+ if (body.autoCompactThresholdTokens !== undefined) {
179
+ const threshold = body.autoCompactThresholdTokens;
180
+ if (threshold === null) {
181
+ updates.autoCompactThresholdTokens = null;
182
+ } else if (Number.isFinite(threshold) && threshold > 0) {
183
+ updates.autoCompactThresholdTokens = Math.floor(threshold);
184
+ }
67
185
  }
68
- }
69
186
 
70
- await setConfig(scope, updates, projectRoot);
187
+ await setConfig(scope, updates, projectRoot);
71
188
 
72
- const nextCfg = await loadConfig(projectRoot);
189
+ const nextCfg = await loadConfig(projectRoot);
73
190
 
74
- return c.json({
75
- success: true,
76
- defaults: nextCfg.defaults,
77
- });
78
- } catch (error) {
79
- logger.error('Failed to update defaults', error);
80
- const errorResponse = serializeError(error);
81
- return c.json(errorResponse, errorResponse.error.status || 500);
82
- }
83
- });
191
+ return c.json({
192
+ success: true,
193
+ defaults: nextCfg.defaults,
194
+ });
195
+ } catch (error) {
196
+ logger.error('Failed to update defaults', error);
197
+ const errorResponse = serializeError(error);
198
+ return c.json(errorResponse, errorResponse.error.status || 500);
199
+ }
200
+ },
201
+ );
84
202
  }
@@ -9,86 +9,122 @@ import {
9
9
  getDefault,
10
10
  getProviderDetails,
11
11
  } from './utils.ts';
12
+ import { openApiRoute } from '../../openapi/route.ts';
12
13
 
13
14
  export function registerMainConfigRoute(app: Hono) {
14
- app.get('/v1/config', async (c) => {
15
- try {
16
- const projectRoot = c.req.query('project') || process.cwd();
17
- const embeddedConfig = (
18
- c as unknown as {
19
- get: (key: 'embeddedConfig') => EmbeddedAppConfig | undefined;
20
- }
21
- ).get('embeddedConfig');
15
+ openApiRoute(
16
+ app,
17
+ {
18
+ method: 'get',
19
+ path: '/v1/config',
20
+ tags: ['config'],
21
+ operationId: 'getConfig',
22
+ summary: 'Get full configuration',
23
+ description: 'Returns agents, authorized providers, models, and defaults',
24
+ parameters: [
25
+ {
26
+ in: 'query',
27
+ name: 'project',
28
+ required: false,
29
+ schema: {
30
+ type: 'string',
31
+ },
32
+ description:
33
+ 'Project root override (defaults to current working directory).',
34
+ },
35
+ ],
36
+ responses: {
37
+ '200': {
38
+ description: 'OK',
39
+ content: {
40
+ 'application/json': {
41
+ schema: {
42
+ $ref: '#/components/schemas/Config',
43
+ },
44
+ },
45
+ },
46
+ },
47
+ },
48
+ },
49
+ async (c) => {
50
+ try {
51
+ const projectRoot = c.req.query('project') || process.cwd();
52
+ const embeddedConfig = (
53
+ c as unknown as {
54
+ get: (key: 'embeddedConfig') => EmbeddedAppConfig | undefined;
55
+ }
56
+ ).get('embeddedConfig');
22
57
 
23
- const cfg = await loadConfig(projectRoot);
58
+ const cfg = await loadConfig(projectRoot);
24
59
 
25
- let allAgents: string[];
60
+ let allAgents: string[];
26
61
 
27
- if (embeddedConfig?.agents) {
28
- const embeddedAgents = Object.keys(embeddedConfig.agents);
29
- const fileAgents = await discoverAllAgents(cfg.projectRoot);
30
- allAgents = Array.from(
31
- new Set([...embeddedAgents, ...fileAgents]),
32
- ).sort();
33
- } else {
34
- allAgents = await discoverAllAgents(cfg.projectRoot);
35
- }
62
+ if (embeddedConfig?.agents) {
63
+ const embeddedAgents = Object.keys(embeddedConfig.agents);
64
+ const fileAgents = await discoverAllAgents(cfg.projectRoot);
65
+ allAgents = Array.from(
66
+ new Set([...embeddedAgents, ...fileAgents]),
67
+ ).sort();
68
+ } else {
69
+ allAgents = await discoverAllAgents(cfg.projectRoot);
70
+ }
36
71
 
37
- const authorizedProviders = await getAuthorizedProviders(
38
- embeddedConfig,
39
- cfg,
40
- );
41
- const providerDetails = await getProviderDetails(embeddedConfig, cfg);
72
+ const authorizedProviders = await getAuthorizedProviders(
73
+ embeddedConfig,
74
+ cfg,
75
+ );
76
+ const providerDetails = await getProviderDetails(embeddedConfig, cfg);
42
77
 
43
- const defaults = {
44
- agent: getDefault(
45
- embeddedConfig?.agent,
46
- embeddedConfig?.defaults?.agent,
47
- cfg.defaults.agent,
48
- ),
49
- provider: getDefault(
50
- embeddedConfig?.provider,
51
- embeddedConfig?.defaults?.provider,
52
- cfg.defaults.provider,
53
- ),
54
- model: getDefault(
55
- embeddedConfig?.model,
56
- embeddedConfig?.defaults?.model,
57
- cfg.defaults.model,
58
- ),
59
- toolApproval: getDefault(
60
- undefined,
61
- embeddedConfig?.defaults?.toolApproval,
62
- cfg.defaults.toolApproval,
63
- ) as 'auto' | 'dangerous' | 'all' | 'yolo',
64
- guidedMode: cfg.defaults.guidedMode ?? false,
65
- reasoningText: cfg.defaults.reasoningText ?? true,
66
- reasoningLevel: cfg.defaults.reasoningLevel ?? 'high',
67
- theme: cfg.defaults.theme,
68
- fullWidthContent:
69
- getDefault(
78
+ const defaults = {
79
+ agent: getDefault(
80
+ embeddedConfig?.agent,
81
+ embeddedConfig?.defaults?.agent,
82
+ cfg.defaults.agent,
83
+ ),
84
+ provider: getDefault(
85
+ embeddedConfig?.provider,
86
+ embeddedConfig?.defaults?.provider,
87
+ cfg.defaults.provider,
88
+ ),
89
+ model: getDefault(
90
+ embeddedConfig?.model,
91
+ embeddedConfig?.defaults?.model,
92
+ cfg.defaults.model,
93
+ ),
94
+ toolApproval: getDefault(
70
95
  undefined,
71
- embeddedConfig?.defaults?.fullWidthContent,
72
- cfg.defaults.fullWidthContent,
73
- ) ?? false,
74
- autoCompactThresholdTokens:
75
- getDefault(
76
- undefined,
77
- embeddedConfig?.defaults?.autoCompactThresholdTokens,
78
- cfg.defaults.autoCompactThresholdTokens,
79
- ) ?? null,
80
- };
96
+ embeddedConfig?.defaults?.toolApproval,
97
+ cfg.defaults.toolApproval,
98
+ ) as 'auto' | 'dangerous' | 'all' | 'yolo',
99
+ guidedMode: cfg.defaults.guidedMode ?? false,
100
+ reasoningText: cfg.defaults.reasoningText ?? true,
101
+ reasoningLevel: cfg.defaults.reasoningLevel ?? 'high',
102
+ theme: cfg.defaults.theme,
103
+ fullWidthContent:
104
+ getDefault(
105
+ undefined,
106
+ embeddedConfig?.defaults?.fullWidthContent,
107
+ cfg.defaults.fullWidthContent,
108
+ ) ?? false,
109
+ autoCompactThresholdTokens:
110
+ getDefault(
111
+ undefined,
112
+ embeddedConfig?.defaults?.autoCompactThresholdTokens,
113
+ cfg.defaults.autoCompactThresholdTokens,
114
+ ) ?? null,
115
+ };
81
116
 
82
- return c.json({
83
- agents: allAgents,
84
- providers: authorizedProviders,
85
- providerDetails,
86
- defaults,
87
- });
88
- } catch (error) {
89
- logger.error('Failed to load config', error);
90
- const errorResponse = serializeError(error);
91
- return c.json(errorResponse, errorResponse.error.status || 500);
92
- }
93
- });
117
+ return c.json({
118
+ agents: allAgents,
119
+ providers: authorizedProviders,
120
+ providerDetails,
121
+ defaults,
122
+ });
123
+ } catch (error) {
124
+ logger.error('Failed to load config', error);
125
+ const errorResponse = serializeError(error);
126
+ return c.json(errorResponse, errorResponse.error.status || 500);
127
+ }
128
+ },
129
+ );
94
130
  }