@agi-cli/server 0.1.119 → 0.1.121

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 (70) hide show
  1. package/package.json +3 -3
  2. package/src/index.ts +9 -5
  3. package/src/openapi/paths/git.ts +4 -0
  4. package/src/routes/ask.ts +13 -14
  5. package/src/routes/branch.ts +106 -0
  6. package/src/routes/config/agents.ts +1 -1
  7. package/src/routes/config/cwd.ts +1 -1
  8. package/src/routes/config/main.ts +1 -1
  9. package/src/routes/config/models.ts +32 -4
  10. package/src/routes/config/providers.ts +1 -1
  11. package/src/routes/config/utils.ts +14 -1
  12. package/src/routes/files.ts +1 -1
  13. package/src/routes/git/commit.ts +23 -6
  14. package/src/routes/git/schemas.ts +1 -0
  15. package/src/routes/session-files.ts +1 -1
  16. package/src/routes/session-messages.ts +2 -2
  17. package/src/routes/sessions.ts +8 -6
  18. package/src/runtime/agent/registry.ts +333 -0
  19. package/src/runtime/agent/runner-reasoning.ts +108 -0
  20. package/src/runtime/agent/runner-setup.ts +265 -0
  21. package/src/runtime/agent/runner.ts +356 -0
  22. package/src/runtime/agent-registry.ts +6 -333
  23. package/src/runtime/{ask-service.ts → ask/service.ts} +5 -5
  24. package/src/runtime/{debug.ts → debug/index.ts} +1 -1
  25. package/src/runtime/{api-error.ts → errors/api-error.ts} +2 -2
  26. package/src/runtime/message/compaction-auto.ts +137 -0
  27. package/src/runtime/message/compaction-context.ts +64 -0
  28. package/src/runtime/message/compaction-detect.ts +19 -0
  29. package/src/runtime/message/compaction-limits.ts +58 -0
  30. package/src/runtime/message/compaction-mark.ts +115 -0
  31. package/src/runtime/message/compaction-prune.ts +75 -0
  32. package/src/runtime/message/compaction.ts +23 -0
  33. package/src/runtime/{history-builder.ts → message/history-builder.ts} +2 -2
  34. package/src/runtime/{message-service.ts → message/service.ts} +8 -14
  35. package/src/runtime/{history → message}/tool-history-tracker.ts +1 -1
  36. package/src/runtime/{prompt.ts → prompt/builder.ts} +1 -1
  37. package/src/runtime/{provider.ts → provider/anthropic.ts} +4 -219
  38. package/src/runtime/provider/google.ts +12 -0
  39. package/src/runtime/provider/index.ts +44 -0
  40. package/src/runtime/provider/openai.ts +26 -0
  41. package/src/runtime/provider/opencode.ts +61 -0
  42. package/src/runtime/provider/openrouter.ts +11 -0
  43. package/src/runtime/provider/solforge.ts +22 -0
  44. package/src/runtime/provider/zai.ts +53 -0
  45. package/src/runtime/session/branch.ts +277 -0
  46. package/src/runtime/{db-operations.ts → session/db-operations.ts} +1 -1
  47. package/src/runtime/{session-manager.ts → session/manager.ts} +1 -1
  48. package/src/runtime/{session-queue.ts → session/queue.ts} +2 -2
  49. package/src/runtime/stream/abort-handler.ts +65 -0
  50. package/src/runtime/stream/error-handler.ts +200 -0
  51. package/src/runtime/stream/finish-handler.ts +123 -0
  52. package/src/runtime/stream/handlers.ts +5 -0
  53. package/src/runtime/stream/step-finish.ts +93 -0
  54. package/src/runtime/stream/types.ts +17 -0
  55. package/src/runtime/{tool-context.ts → tools/context.ts} +1 -1
  56. package/src/runtime/{tool-context-setup.ts → tools/setup.ts} +3 -3
  57. package/src/runtime/{token-utils.ts → utils/token.ts} +2 -2
  58. package/src/tools/adapter.ts +4 -4
  59. package/src/runtime/compaction.ts +0 -536
  60. package/src/runtime/runner.ts +0 -654
  61. package/src/runtime/stream-handlers.ts +0 -508
  62. /package/src/runtime/{cache-optimizer.ts → context/cache-optimizer.ts} +0 -0
  63. /package/src/runtime/{environment.ts → context/environment.ts} +0 -0
  64. /package/src/runtime/{context-optimizer.ts → context/optimizer.ts} +0 -0
  65. /package/src/runtime/{debug-state.ts → debug/state.ts} +0 -0
  66. /package/src/runtime/{error-handling.ts → errors/handling.ts} +0 -0
  67. /package/src/runtime/{history-truncator.ts → message/history-truncator.ts} +0 -0
  68. /package/src/runtime/{provider-selection.ts → provider/selection.ts} +0 -0
  69. /package/src/runtime/{tool-mapping.ts → tools/mapping.ts} +0 -0
  70. /package/src/runtime/{cwd.ts → utils/cwd.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agi-cli/server",
3
- "version": "0.1.119",
3
+ "version": "0.1.121",
4
4
  "description": "HTTP API server for AGI CLI",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -29,8 +29,8 @@
29
29
  "typecheck": "tsc --noEmit"
30
30
  },
31
31
  "dependencies": {
32
- "@agi-cli/sdk": "0.1.119",
33
- "@agi-cli/database": "0.1.119",
32
+ "@agi-cli/sdk": "0.1.121",
33
+ "@agi-cli/database": "0.1.121",
34
34
  "drizzle-orm": "^0.44.5",
35
35
  "hono": "^4.9.9",
36
36
  "zod": "^4.1.8"
package/src/index.ts CHANGED
@@ -14,7 +14,8 @@ import { registerFilesRoutes } from './routes/files.ts';
14
14
  import { registerGitRoutes } from './routes/git/index.ts';
15
15
  import { registerTerminalsRoutes } from './routes/terminals.ts';
16
16
  import { registerSessionFilesRoutes } from './routes/session-files.ts';
17
- import type { AgentConfigEntry } from './runtime/agent-registry.ts';
17
+ import { registerBranchRoutes } from './routes/branch.ts';
18
+ import type { AgentConfigEntry } from './runtime/agent/registry.ts';
18
19
 
19
20
  const globalTerminalManager = new TerminalManager();
20
21
  setTerminalManager(globalTerminalManager);
@@ -64,6 +65,7 @@ function initApp() {
64
65
  registerGitRoutes(app);
65
66
  registerTerminalsRoutes(app, globalTerminalManager);
66
67
  registerSessionFilesRoutes(app);
68
+ registerBranchRoutes(app);
67
69
 
68
70
  return app;
69
71
  }
@@ -130,6 +132,7 @@ export function createStandaloneApp(_config?: StandaloneAppConfig) {
130
132
  registerGitRoutes(honoApp);
131
133
  registerTerminalsRoutes(honoApp, globalTerminalManager);
132
134
  registerSessionFilesRoutes(honoApp);
135
+ registerBranchRoutes(honoApp);
133
136
 
134
137
  return honoApp;
135
138
  }
@@ -224,6 +227,7 @@ export function createEmbeddedApp(config: EmbeddedAppConfig = {}) {
224
227
  registerGitRoutes(honoApp);
225
228
  registerTerminalsRoutes(honoApp, globalTerminalManager);
226
229
  registerSessionFilesRoutes(honoApp);
230
+ registerBranchRoutes(honoApp);
227
231
 
228
232
  return honoApp;
229
233
  }
@@ -231,17 +235,17 @@ export function createEmbeddedApp(config: EmbeddedAppConfig = {}) {
231
235
  export {
232
236
  resolveAgentConfig,
233
237
  defaultToolsForAgent,
234
- } from './runtime/agent-registry.ts';
238
+ } from './runtime/agent/registry.ts';
235
239
  export {
236
240
  composeSystemPrompt,
237
241
  type ComposedSystemPrompt,
238
- } from './runtime/prompt.ts';
242
+ } from './runtime/prompt/builder.ts';
239
243
  export {
240
244
  AskServiceError,
241
245
  handleAskRequest,
242
246
  deriveStatusFromMessage,
243
247
  inferStatus,
244
- } from './runtime/ask-service.ts';
248
+ } from './runtime/ask/service.ts';
245
249
  export { registerSessionsRoutes } from './routes/sessions.ts';
246
250
  export { registerAskRoutes } from './routes/ask.ts';
247
251
  export {
@@ -257,5 +261,5 @@ export {
257
261
  isDebugEnabled,
258
262
  setTraceEnabled,
259
263
  isTraceEnabled,
260
- } from './runtime/debug-state.ts';
264
+ } from './runtime/debug/state.ts';
261
265
  export { logger } from '@agi-cli/sdk';
@@ -268,6 +268,10 @@ export const gitPaths = {
268
268
  type: 'object',
269
269
  properties: {
270
270
  project: { type: 'string' },
271
+ sessionId: {
272
+ type: 'string',
273
+ description: 'Session ID to use session provider',
274
+ },
271
275
  },
272
276
  },
273
277
  },
package/src/routes/ask.ts CHANGED
@@ -3,11 +3,11 @@ import type {
3
3
  AskServerRequest,
4
4
  InjectableConfig,
5
5
  InjectableCredentials,
6
- } from '../runtime/ask-service.ts';
7
- import { handleAskRequest } from '../runtime/ask-service.ts';
8
- import type { EmbeddedAppConfig } from '../index.ts';
9
- import { serializeError } from '../runtime/api-error.ts';
6
+ } from '../runtime/ask/service.ts';
7
+ import { handleAskRequest } from '../runtime/ask/service.ts';
8
+ import { serializeError } from '../runtime/errors/api-error.ts';
10
9
  import { logger } from '@agi-cli/sdk';
10
+ import type { EmbeddedAppConfig } from '../index.ts';
11
11
 
12
12
  export function registerAskRoutes(app: Hono) {
13
13
  app.post('/v1/ask', async (c) => {
@@ -32,19 +32,18 @@ export function registerAskRoutes(app: Hono) {
32
32
 
33
33
  if (embeddedConfig && Object.keys(embeddedConfig).length > 0) {
34
34
  // Has embedded config - build injectable config from it
35
+ const defaults = embeddedConfig.defaults;
35
36
  const hasDefaults =
36
- embeddedConfig.defaults ||
37
+ defaults ||
37
38
  embeddedConfig.provider ||
38
39
  embeddedConfig.model ||
39
40
  embeddedConfig.agent;
40
41
 
41
42
  if (hasDefaults) {
42
43
  injectableConfig = {
43
- defaults: embeddedConfig.defaults || {
44
- agent: embeddedConfig.agent,
45
- provider: embeddedConfig.provider,
46
- model: embeddedConfig.model,
47
- },
44
+ provider: defaults?.provider ?? embeddedConfig.provider,
45
+ model: defaults?.model ?? embeddedConfig.model,
46
+ agent: defaults?.agent ?? embeddedConfig.agent,
48
47
  };
49
48
  }
50
49
 
@@ -52,12 +51,12 @@ export function registerAskRoutes(app: Hono) {
52
51
  const hasAuth = embeddedConfig.auth || embeddedConfig.apiKey;
53
52
  if (hasAuth) {
54
53
  if (embeddedConfig.auth) {
55
- injectableCredentials = {};
54
+ injectableCredentials = {} as InjectableCredentials;
56
55
  for (const [provider, auth] of Object.entries(embeddedConfig.auth)) {
57
56
  if ('apiKey' in auth) {
58
- injectableCredentials[provider] = { apiKey: auth.apiKey };
59
- } else {
60
- injectableCredentials[provider] = auth;
57
+ (injectableCredentials as Record<string, { apiKey: string }>)[
58
+ provider
59
+ ] = { apiKey: auth.apiKey };
61
60
  }
62
61
  }
63
62
  } else if (embeddedConfig.apiKey && embeddedConfig.provider) {
@@ -0,0 +1,106 @@
1
+ import type { Hono } from 'hono';
2
+ import { loadConfig } from '@agi-cli/sdk';
3
+ import { getDb } from '@agi-cli/database';
4
+ import { isProviderId, logger } from '@agi-cli/sdk';
5
+ import {
6
+ createBranch,
7
+ listBranches,
8
+ getParentSession,
9
+ } from '../runtime/session/branch.ts';
10
+ import { serializeError } from '../runtime/errors/api-error.ts';
11
+
12
+ export function registerBranchRoutes(app: Hono) {
13
+ app.post('/v1/sessions/:sessionId/branch', async (c) => {
14
+ try {
15
+ const sessionId = c.req.param('sessionId');
16
+ const projectRoot = c.req.query('project') || process.cwd();
17
+ const cfg = await loadConfig(projectRoot);
18
+ const db = await getDb(cfg.projectRoot);
19
+
20
+ const body = (await c.req.json().catch(() => ({}))) as Record<
21
+ string,
22
+ unknown
23
+ >;
24
+
25
+ const fromMessageId = body.fromMessageId;
26
+ if (typeof fromMessageId !== 'string' || !fromMessageId.trim()) {
27
+ return c.json({ error: 'fromMessageId is required' }, 400);
28
+ }
29
+
30
+ const provider =
31
+ typeof body.provider === 'string' && isProviderId(body.provider)
32
+ ? body.provider
33
+ : undefined;
34
+
35
+ const model =
36
+ typeof body.model === 'string' && body.model.trim()
37
+ ? body.model.trim()
38
+ : undefined;
39
+
40
+ const agent =
41
+ typeof body.agent === 'string' && body.agent.trim()
42
+ ? body.agent.trim()
43
+ : undefined;
44
+
45
+ const title =
46
+ typeof body.title === 'string' && body.title.trim()
47
+ ? body.title.trim()
48
+ : undefined;
49
+
50
+ const result = await createBranch({
51
+ db,
52
+ parentSessionId: sessionId,
53
+ fromMessageId: fromMessageId.trim(),
54
+ provider,
55
+ model,
56
+ agent,
57
+ title,
58
+ projectPath: cfg.projectRoot,
59
+ });
60
+
61
+ return c.json(result, 201);
62
+ } catch (err) {
63
+ logger.error('Failed to create branch', err);
64
+ const errorResponse = serializeError(err);
65
+ return c.json(errorResponse, errorResponse.error.status || 400);
66
+ }
67
+ });
68
+
69
+ app.get('/v1/sessions/:sessionId/branches', async (c) => {
70
+ try {
71
+ const sessionId = c.req.param('sessionId');
72
+ const projectRoot = c.req.query('project') || process.cwd();
73
+ const cfg = await loadConfig(projectRoot);
74
+ const db = await getDb(cfg.projectRoot);
75
+
76
+ const branches = await listBranches(db, sessionId, cfg.projectRoot);
77
+
78
+ return c.json({ branches });
79
+ } catch (err) {
80
+ logger.error('Failed to list branches', err);
81
+ const errorResponse = serializeError(err);
82
+ return c.json(errorResponse, errorResponse.error.status || 500);
83
+ }
84
+ });
85
+
86
+ app.get('/v1/sessions/:sessionId/parent', async (c) => {
87
+ try {
88
+ const sessionId = c.req.param('sessionId');
89
+ const projectRoot = c.req.query('project') || process.cwd();
90
+ const cfg = await loadConfig(projectRoot);
91
+ const db = await getDb(cfg.projectRoot);
92
+
93
+ const parent = await getParentSession(db, sessionId, cfg.projectRoot);
94
+
95
+ if (!parent) {
96
+ return c.json({ parent: null });
97
+ }
98
+
99
+ return c.json({ parent });
100
+ } catch (err) {
101
+ logger.error('Failed to get parent session', err);
102
+ const errorResponse = serializeError(err);
103
+ return c.json(errorResponse, errorResponse.error.status || 500);
104
+ }
105
+ });
106
+ }
@@ -2,7 +2,7 @@ import type { Hono } from 'hono';
2
2
  import { loadConfig } from '@agi-cli/sdk';
3
3
  import type { EmbeddedAppConfig } from '../../index.ts';
4
4
  import { logger } from '@agi-cli/sdk';
5
- import { serializeError } from '../../runtime/api-error.ts';
5
+ import { serializeError } from '../../runtime/errors/api-error.ts';
6
6
  import { discoverAllAgents, getDefault } from './utils.ts';
7
7
 
8
8
  export function registerAgentsRoute(app: Hono) {
@@ -1,7 +1,7 @@
1
1
  import type { Hono } from 'hono';
2
2
  import { basename } from 'node:path';
3
3
  import { logger } from '@agi-cli/sdk';
4
- import { serializeError } from '../../runtime/api-error.ts';
4
+ import { serializeError } from '../../runtime/errors/api-error.ts';
5
5
 
6
6
  export function registerCwdRoute(app: Hono) {
7
7
  app.get('/v1/config/cwd', (c) => {
@@ -2,7 +2,7 @@ import type { Hono } from 'hono';
2
2
  import { loadConfig } from '@agi-cli/sdk';
3
3
  import type { EmbeddedAppConfig } from '../../index.ts';
4
4
  import { logger } from '@agi-cli/sdk';
5
- import { serializeError } from '../../runtime/api-error.ts';
5
+ import { serializeError } from '../../runtime/errors/api-error.ts';
6
6
  import {
7
7
  discoverAllAgents,
8
8
  getAuthorizedProviders,
@@ -1,12 +1,18 @@
1
1
  import type { Hono } from 'hono';
2
- import { loadConfig, catalog, type ProviderId } from '@agi-cli/sdk';
2
+ import {
3
+ loadConfig,
4
+ catalog,
5
+ type ProviderId,
6
+ filterModelsForAuthType,
7
+ } from '@agi-cli/sdk';
3
8
  import type { EmbeddedAppConfig } from '../../index.ts';
4
9
  import { logger } from '@agi-cli/sdk';
5
- import { serializeError } from '../../runtime/api-error.ts';
10
+ import { serializeError } from '../../runtime/errors/api-error.ts';
6
11
  import {
7
12
  isProviderAuthorizedHybrid,
8
13
  getAuthorizedProviders,
9
14
  getDefault,
15
+ getAuthTypeForProvider,
10
16
  } from './utils.ts';
11
17
 
12
18
  export function registerModelsRoutes(app: Hono) {
@@ -37,8 +43,19 @@ export function registerModelsRoutes(app: Hono) {
37
43
  return c.json({ error: 'Provider not found' }, 404);
38
44
  }
39
45
 
46
+ const authType = await getAuthTypeForProvider(
47
+ embeddedConfig,
48
+ provider,
49
+ projectRoot,
50
+ );
51
+ const filteredModels = filterModelsForAuthType(
52
+ provider,
53
+ providerCatalog.models,
54
+ authType,
55
+ );
56
+
40
57
  return c.json({
41
- models: providerCatalog.models.map((m) => ({
58
+ models: filteredModels.map((m) => ({
42
59
  id: m.id,
43
60
  label: m.label || m.id,
44
61
  toolCall: m.toolCall,
@@ -88,9 +105,20 @@ export function registerModelsRoutes(app: Hono) {
88
105
  for (const provider of authorizedProviders) {
89
106
  const providerCatalog = catalog[provider];
90
107
  if (providerCatalog) {
108
+ const authType = await getAuthTypeForProvider(
109
+ embeddedConfig,
110
+ provider,
111
+ projectRoot,
112
+ );
113
+ const filteredModels = filterModelsForAuthType(
114
+ provider,
115
+ providerCatalog.models,
116
+ authType,
117
+ );
91
118
  modelsMap[provider] = {
92
119
  label: providerCatalog.label || provider,
93
- models: providerCatalog.models.map((m) => ({
120
+ authType,
121
+ models: filteredModels.map((m) => ({
94
122
  id: m.id,
95
123
  label: m.label || m.id,
96
124
  toolCall: m.toolCall,
@@ -3,7 +3,7 @@ import { loadConfig } from '@agi-cli/sdk';
3
3
  import type { ProviderId } from '@agi-cli/sdk';
4
4
  import type { EmbeddedAppConfig } from '../../index.ts';
5
5
  import { logger } from '@agi-cli/sdk';
6
- import { serializeError } from '../../runtime/api-error.ts';
6
+ import { serializeError } from '../../runtime/errors/api-error.ts';
7
7
  import { getAuthorizedProviders, getDefault } from './utils.ts';
8
8
 
9
9
  export function registerProvidersRoute(app: Hono) {
@@ -3,13 +3,14 @@ import {
3
3
  type ProviderId,
4
4
  isProviderAuthorized,
5
5
  getGlobalAgentsDir,
6
+ getAuth,
6
7
  } from '@agi-cli/sdk';
7
8
  import { readdir } from 'node:fs/promises';
8
9
  import { join } from 'node:path';
9
10
  import type { EmbeddedAppConfig } from '../../index.ts';
10
11
  import type { AGIConfig } from '@agi-cli/sdk';
11
12
  import { logger } from '@agi-cli/sdk';
12
- import { loadAgentsConfig } from '../../runtime/agent-registry.ts';
13
+ import { loadAgentsConfig } from '../../runtime/agent/registry.ts';
13
14
 
14
15
  export async function isProviderAuthorizedHybrid(
15
16
  embeddedConfig: EmbeddedAppConfig | undefined,
@@ -56,6 +57,18 @@ export function getDefault<T>(
56
57
  return embeddedValue ?? embeddedDefaultValue ?? fileValue;
57
58
  }
58
59
 
60
+ export async function getAuthTypeForProvider(
61
+ embeddedConfig: EmbeddedAppConfig | undefined,
62
+ provider: ProviderId,
63
+ projectRoot: string,
64
+ ): Promise<'api' | 'oauth' | 'wallet' | undefined> {
65
+ if (embeddedConfig?.auth?.[provider]) {
66
+ return embeddedConfig.auth[provider].type as 'api' | 'oauth' | 'wallet';
67
+ }
68
+ const auth = await getAuth(provider, projectRoot);
69
+ return auth?.type as 'api' | 'oauth' | 'wallet' | undefined;
70
+ }
71
+
59
72
  export async function discoverAllAgents(
60
73
  projectRoot: string,
61
74
  ): Promise<string[]> {
@@ -3,7 +3,7 @@ import { readdir, readFile } from 'node:fs/promises';
3
3
  import { join, relative } from 'node:path';
4
4
  import { exec } from 'node:child_process';
5
5
  import { promisify } from 'node:util';
6
- import { serializeError } from '../runtime/api-error.ts';
6
+ import { serializeError } from '../runtime/errors/api-error.ts';
7
7
  import { logger } from '@agi-cli/sdk';
8
8
 
9
9
  const execAsync = promisify(exec);
@@ -2,12 +2,15 @@ import type { Hono } from 'hono';
2
2
  import { execFile } from 'node:child_process';
3
3
  import { promisify } from 'node:util';
4
4
  import { generateText } from 'ai';
5
+ import { eq } from 'drizzle-orm';
5
6
  import type { ProviderId } from '@agi-cli/sdk';
6
- import { loadConfig, getAuth } from '@agi-cli/sdk';
7
+ import { loadConfig, getAuth, getFastModelForAuth } from '@agi-cli/sdk';
8
+ import { getDb } from '@agi-cli/database';
9
+ import { sessions } from '@agi-cli/database/schema';
7
10
  import { gitCommitSchema, gitGenerateCommitMessageSchema } from './schemas.ts';
8
11
  import { validateAndGetGitRoot, parseGitStatus } from './utils.ts';
9
- import { resolveModel } from '../../runtime/provider.ts';
10
- import { getProviderSpoofPrompt } from '../../runtime/prompt.ts';
12
+ import { resolveModel } from '../../runtime/provider/index.ts';
13
+ import { getProviderSpoofPrompt } from '../../runtime/prompt/builder.ts';
11
14
 
12
15
  const execFileAsync = promisify(execFile);
13
16
 
@@ -53,7 +56,7 @@ export function registerCommitRoutes(app: Hono) {
53
56
  app.post('/v1/git/generate-commit-message', async (c) => {
54
57
  try {
55
58
  const body = await c.req.json();
56
- const { project } = gitGenerateCommitMessageSchema.parse(body);
59
+ const { project, sessionId } = gitGenerateCommitMessageSchema.parse(body);
57
60
 
58
61
  const requestedPath = project || process.cwd();
59
62
 
@@ -95,8 +98,18 @@ export function registerCommitRoutes(app: Hono) {
95
98
 
96
99
  const config = await loadConfig();
97
100
 
98
- const provider = (config.defaults?.provider || 'anthropic') as ProviderId;
99
- const modelId = config.defaults?.model || 'claude-3-5-sonnet-20241022';
101
+ let provider = (config.defaults?.provider || 'anthropic') as ProviderId;
102
+
103
+ if (sessionId) {
104
+ const db = getDb();
105
+ const [session] = await db
106
+ .select({ provider: sessions.provider })
107
+ .from(sessions)
108
+ .where(eq(sessions.id, sessionId));
109
+ if (session?.provider) {
110
+ provider = session.provider as ProviderId;
111
+ }
112
+ }
100
113
 
101
114
  const auth = await getAuth(provider, config.projectRoot);
102
115
  const needsSpoof = auth?.type === 'oauth';
@@ -104,6 +117,10 @@ export function registerCommitRoutes(app: Hono) {
104
117
  ? getProviderSpoofPrompt(provider)
105
118
  : undefined;
106
119
 
120
+ const modelId =
121
+ getFastModelForAuth(provider, auth?.type) ??
122
+ config.defaults?.model ??
123
+ 'claude-3-5-sonnet-20241022';
107
124
  const model = await resolveModel(provider, modelId, config);
108
125
 
109
126
  const userPrompt = `Generate a concise, conventional commit message for these git changes.
@@ -40,6 +40,7 @@ export const gitCommitSchema = z.object({
40
40
 
41
41
  export const gitGenerateCommitMessageSchema = z.object({
42
42
  project: z.string().optional(),
43
+ sessionId: z.string().optional(),
43
44
  });
44
45
 
45
46
  export const gitPushSchema = z.object({
@@ -3,7 +3,7 @@ import { loadConfig } from '@agi-cli/sdk';
3
3
  import { getDb } from '@agi-cli/database';
4
4
  import { messages, messageParts, sessions } from '@agi-cli/database/schema';
5
5
  import { eq, and, inArray } from 'drizzle-orm';
6
- import { serializeError } from '../runtime/api-error.ts';
6
+ import { serializeError } from '../runtime/errors/api-error.ts';
7
7
  import { logger } from '@agi-cli/sdk';
8
8
 
9
9
  const FILE_EDIT_TOOLS = [
@@ -8,9 +8,9 @@ import {
8
8
  isProviderAuthorized,
9
9
  ensureProviderEnv,
10
10
  } from '@agi-cli/sdk';
11
- import { dispatchAssistantMessage } from '../runtime/message-service.ts';
11
+ import { dispatchAssistantMessage } from '../runtime/message/service.ts';
12
12
  import { logger } from '@agi-cli/sdk';
13
- import { serializeError } from '../runtime/api-error.ts';
13
+ import { serializeError } from '../runtime/errors/api-error.ts';
14
14
 
15
15
  type MessagePartRow = typeof messageParts.$inferSelect;
16
16
  type SessionRow = typeof sessions.$inferSelect;
@@ -5,9 +5,9 @@ import { sessions, messages, messageParts } from '@agi-cli/database/schema';
5
5
  import { desc, eq, and, inArray } from 'drizzle-orm';
6
6
  import type { ProviderId } from '@agi-cli/sdk';
7
7
  import { isProviderId, catalog } from '@agi-cli/sdk';
8
- import { resolveAgentConfig } from '../runtime/agent-registry.ts';
9
- import { createSession as createSessionRow } from '../runtime/session-manager.ts';
10
- import { serializeError } from '../runtime/api-error.ts';
8
+ import { resolveAgentConfig } from '../runtime/agent/registry.ts';
9
+ import { createSession as createSessionRow } from '../runtime/session/manager.ts';
10
+ import { serializeError } from '../runtime/errors/api-error.ts';
11
11
  import { logger } from '@agi-cli/sdk';
12
12
 
13
13
  export function registerSessionsRoutes(app: Hono) {
@@ -202,7 +202,9 @@ export function registerSessionsRoutes(app: Hono) {
202
202
  typeof body.messageId === 'string' ? body.messageId : undefined;
203
203
  const clearQueue = body.clearQueue === true;
204
204
 
205
- const { abortSession, abortMessage } = await import('../runtime/runner.ts');
205
+ const { abortSession, abortMessage } = await import(
206
+ '../runtime/agent/runner.ts'
207
+ );
206
208
 
207
209
  if (messageId) {
208
210
  const result = abortMessage(sessionId, messageId);
@@ -220,7 +222,7 @@ export function registerSessionsRoutes(app: Hono) {
220
222
  // Get queue state for a session
221
223
  app.get('/v1/sessions/:sessionId/queue', async (c) => {
222
224
  const sessionId = c.req.param('sessionId');
223
- const { getQueueState } = await import('../runtime/session-queue.ts');
225
+ const { getQueueState } = await import('../runtime/session/queue.ts');
224
226
  const state = getQueueState(sessionId);
225
227
  return c.json(
226
228
  state ?? {
@@ -239,7 +241,7 @@ export function registerSessionsRoutes(app: Hono) {
239
241
  const cfg = await loadConfig(projectRoot);
240
242
  const db = await getDb(cfg.projectRoot);
241
243
  const { removeFromQueue, abortMessage } = await import(
242
- '../runtime/session-queue.ts'
244
+ '../runtime/session/queue.ts'
243
245
  );
244
246
 
245
247
  // First try to remove from queue (queued messages)