vibeman 0.0.1 → 0.0.3

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 (102) hide show
  1. package/dist/index.js +5 -7
  2. package/dist/runtime/api/.tsbuildinfo +1 -1
  3. package/dist/runtime/api/agent/agent-service.d.ts +18 -19
  4. package/dist/runtime/api/agent/agent-service.js +61 -58
  5. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +2 -2
  6. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +25 -36
  7. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +2 -0
  8. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +109 -43
  9. package/dist/runtime/api/agent/ai-providers/types.d.ts +2 -0
  10. package/dist/runtime/api/agent/codex-cli-provider.test.js +83 -1
  11. package/dist/runtime/api/agent/parsers.d.ts +1 -0
  12. package/dist/runtime/api/agent/parsers.js +75 -8
  13. package/dist/runtime/api/agent/prompt-service.d.ts +14 -1
  14. package/dist/runtime/api/agent/prompt-service.js +123 -14
  15. package/dist/runtime/api/agent/prompt-service.test.js +230 -0
  16. package/dist/runtime/api/agent/routing-policy.d.ts +25 -42
  17. package/dist/runtime/api/agent/routing-policy.js +82 -132
  18. package/dist/runtime/api/agent/routing-policy.test.js +63 -0
  19. package/dist/runtime/api/api/routers/ai.d.ts +19 -7
  20. package/dist/runtime/api/api/routers/ai.js +9 -23
  21. package/dist/runtime/api/api/routers/executions.d.ts +4 -4
  22. package/dist/runtime/api/api/routers/executions.js +12 -21
  23. package/dist/runtime/api/api/routers/provider-config.d.ts +165 -0
  24. package/dist/runtime/api/api/routers/provider-config.js +252 -0
  25. package/dist/runtime/api/api/routers/tasks.d.ts +9 -9
  26. package/dist/runtime/api/api/routers/workflows.d.ts +23 -16
  27. package/dist/runtime/api/api/routers/workflows.js +30 -27
  28. package/dist/runtime/api/api/routers/worktrees.d.ts +4 -5
  29. package/dist/runtime/api/api/routers/worktrees.js +11 -11
  30. package/dist/runtime/api/api/trpc.d.ts +16 -16
  31. package/dist/runtime/api/index.js +2 -10
  32. package/dist/runtime/api/lib/local-config.d.ts +245 -0
  33. package/dist/runtime/api/lib/local-config.js +288 -0
  34. package/dist/runtime/api/lib/provider-detection.d.ts +59 -0
  35. package/dist/runtime/api/lib/provider-detection.js +244 -0
  36. package/dist/runtime/api/lib/server/bootstrap.d.ts +38 -0
  37. package/dist/runtime/api/lib/server/bootstrap.js +197 -0
  38. package/dist/runtime/api/lib/server/project-root.js +24 -1
  39. package/dist/runtime/api/lib/trpc/server.d.ts +143 -30
  40. package/dist/runtime/api/lib/trpc/server.js +8 -8
  41. package/dist/runtime/api/lib/trpc/ws-server.js +2 -2
  42. package/dist/runtime/api/router.d.ts +144 -31
  43. package/dist/runtime/api/router.js +9 -31
  44. package/dist/runtime/api/settings-service.js +51 -1
  45. package/dist/runtime/api/types/index.d.ts +8 -1
  46. package/dist/runtime/api/types/settings.d.ts +15 -2
  47. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +8 -3
  48. package/dist/runtime/api/workflows/vibing-orchestrator.js +214 -184
  49. package/dist/runtime/web/.next/BUILD_ID +1 -1
  50. package/dist/runtime/web/.next/app-build-manifest.json +19 -12
  51. package/dist/runtime/web/.next/app-path-routes-manifest.json +2 -1
  52. package/dist/runtime/web/.next/build-manifest.json +2 -2
  53. package/dist/runtime/web/.next/prerender-manifest.json +10 -10
  54. package/dist/runtime/web/.next/routes-manifest.json +8 -0
  55. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +1 -0
  56. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +1 -0
  57. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +1 -0
  58. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  59. package/dist/runtime/web/.next/server/app/_not-found.html +2 -2
  60. package/dist/runtime/web/.next/server/app/_not-found.rsc +5 -5
  61. package/dist/runtime/web/.next/server/app/api/health/route.js +1 -1
  62. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  63. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +1 -1
  64. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +1 -1
  65. package/dist/runtime/web/.next/server/app/api/upload/route.js +1 -1
  66. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +1 -1
  67. package/dist/runtime/web/.next/server/app/index.html +2 -2
  68. package/dist/runtime/web/.next/server/app/index.rsc +6 -6
  69. package/dist/runtime/web/.next/server/app/page.js +21 -21
  70. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +1 -1
  71. package/dist/runtime/web/.next/server/app-paths-manifest.json +2 -1
  72. package/dist/runtime/web/.next/server/chunks/458.js +1 -1
  73. package/dist/runtime/web/.next/server/pages/404.html +2 -2
  74. package/dist/runtime/web/.next/server/pages/500.html +1 -1
  75. package/dist/runtime/web/.next/server/pages-manifest.json +1 -1
  76. package/dist/runtime/web/.next/server/server-reference-manifest.json +1 -1
  77. package/dist/runtime/web/.next/static/5_15u1WQCxN1_eHZpldCv/_buildManifest.js +1 -0
  78. package/dist/runtime/web/.next/static/chunks/{277-0142a939f08738c3.js → 823-6f371a6e829adbba.js} +1 -1
  79. package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-751c9265a65409e5.js +1 -0
  80. package/dist/runtime/web/.next/static/chunks/app/api/health/route-751c9265a65409e5.js +1 -0
  81. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-751c9265a65409e5.js +1 -0
  82. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-751c9265a65409e5.js +1 -0
  83. package/dist/runtime/web/.next/static/chunks/app/{layout-dc0cfd29075b2160.js → layout-8435322f09fd0975.js} +1 -1
  84. package/dist/runtime/web/.next/static/chunks/app/page-9fe7d75095b4ccec.js +1 -0
  85. package/dist/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +5 -1
  87. package/dist/runtime/api/lib/image-paste-drop-extension.d.ts +0 -26
  88. package/dist/runtime/api/lib/image-paste-drop-extension.js +0 -125
  89. package/dist/runtime/api/lib/markdown-utils.d.ts +0 -8
  90. package/dist/runtime/api/lib/markdown-utils.js +0 -282
  91. package/dist/runtime/api/lib/markdown-utils.test.js +0 -348
  92. package/dist/runtime/api/lib/tiptap-utils.clamp-selection.test.js +0 -27
  93. package/dist/runtime/api/lib/tiptap-utils.d.ts +0 -130
  94. package/dist/runtime/api/lib/tiptap-utils.js +0 -327
  95. package/dist/runtime/web/.next/static/1HR8N0rJkCvFRtbTPJMyH/_buildManifest.js +0 -1
  96. package/dist/runtime/web/.next/static/chunks/app/api/health/route-105a61ae865ba536.js +0 -1
  97. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-105a61ae865ba536.js +0 -1
  98. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-105a61ae865ba536.js +0 -1
  99. package/dist/runtime/web/.next/static/chunks/app/page-f34a8b196b18850b.js +0 -1
  100. /package/dist/runtime/api/{lib/markdown-utils.test.d.ts → agent/prompt-service.test.d.ts} +0 -0
  101. /package/dist/runtime/api/{lib/tiptap-utils.clamp-selection.test.d.ts → agent/routing-policy.test.d.ts} +0 -0
  102. /package/dist/runtime/web/.next/static/{1HR8N0rJkCvFRtbTPJMyH → 5_15u1WQCxN1_eHZpldCv}/_ssgManifest.js +0 -0
@@ -3,11 +3,18 @@
3
3
  * Handles provider selection per operation with fallbacks and configuration
4
4
  */
5
5
  import { z } from 'zod';
6
- import fs from 'fs/promises';
7
- import path from 'path';
8
6
  import { log } from '../lib/logger.js';
9
7
  import { getSettingsService } from '../settings-service.js';
10
- import { getVibeDir } from '../lib/server/project-root.js';
8
+ /**
9
+ * Operation types that support AI routing
10
+ */
11
+ const ROUTABLE_OPERATIONS = [
12
+ 'execute_task',
13
+ 'quality_checks',
14
+ 'ai_codereview',
15
+ 'ai_merge',
16
+ 'improve_task',
17
+ ];
11
18
  /**
12
19
  * Generation options for AI execution
13
20
  */
@@ -30,67 +37,83 @@ export const OperationConfigSchema = z.object({
30
37
  */
31
38
  export const RoutingPolicySchema = z.object({
32
39
  defaultProvider: z.string(),
33
- operations: z
34
- .record(z.enum(['execute_task', 'improve_task', 'ai_codereview', 'ai_merge']), OperationConfigSchema)
35
- .optional(),
40
+ operations: z.record(z.enum(ROUTABLE_OPERATIONS), OperationConfigSchema).optional(),
36
41
  });
42
+ export const ROUTABLE_OPERATION_LIST = ROUTABLE_OPERATIONS;
37
43
  /**
38
44
  * Routing Policy Manager
39
- * Manages AI provider routing policies with hot-reload capability
45
+ * Manages AI provider routing policies stored inside settings.json
40
46
  */
41
47
  export class RoutingPolicyManager {
42
48
  constructor() {
43
49
  this.policy = null;
44
- this.lastModified = 0;
45
- this.policyFilePath = path.join(getVibeDir(), 'ai-routing.json');
50
+ this.settingsService = getSettingsService();
51
+ // Invalidate cached policy when settings change
52
+ this.settingsService.on('settingsUpdated', () => {
53
+ this.policy = null;
54
+ });
46
55
  }
47
56
  /**
48
- * Get current effective policy with hot-reload
57
+ * Get current effective policy (lazy loads from settings)
49
58
  */
50
59
  async getPolicy() {
51
- await this.loadPolicyIfChanged();
52
- // Return default policy if none exists
53
60
  if (!this.policy) {
54
- const settings = getSettingsService().getSettings();
55
- return {
56
- defaultProvider: settings.agents.defaultProvider || 'claude-code',
57
- operations: {},
58
- };
61
+ this.policy = this.buildPolicyFromSettings();
59
62
  }
60
63
  return this.policy;
61
64
  }
62
65
  /**
63
- * Update routing policy and persist to disk
66
+ * Update routing policy and persist via settings service
64
67
  */
65
68
  async updatePolicy(updates) {
66
69
  const currentPolicy = await this.getPolicy();
67
- const newPolicy = {
68
- defaultProvider: updates.defaultProvider || currentPolicy.defaultProvider,
69
- operations: {
70
- ...currentPolicy.operations,
71
- ...updates.operations,
72
- },
70
+ const mergedOperations = {
71
+ ...(currentPolicy.operations ?? {}),
72
+ ...(updates.operations ?? {}),
73
+ };
74
+ const operationsKeys = Object.keys(mergedOperations);
75
+ const nextPolicy = {
76
+ defaultProvider: updates.defaultProvider ?? currentPolicy.defaultProvider,
77
+ ...(operationsKeys.length > 0 ? { operations: mergedOperations } : {}),
73
78
  };
74
- // Validate the new policy
75
- const validated = RoutingPolicySchema.parse(newPolicy);
76
- // Ensure .vibeman directory exists
77
- const vibemanDir = path.dirname(this.policyFilePath);
78
- await fs.mkdir(vibemanDir, { recursive: true });
79
- // Write to file
80
- await fs.writeFile(this.policyFilePath, JSON.stringify(validated, null, 2), 'utf-8');
81
- // Update in-memory policy
79
+ const validated = RoutingPolicySchema.parse(nextPolicy);
80
+ await this.settingsService.updateSettings([
81
+ { path: ['agents', 'routingPolicy'], value: validated },
82
+ ]);
82
83
  this.policy = validated;
83
- this.lastModified = Date.now();
84
84
  log.info('Updated AI routing policy', { policy: validated }, 'routing-policy');
85
85
  }
86
86
  /**
87
87
  * Resolve provider for a specific operation
88
88
  */
89
+ async getEffectivePolicy() {
90
+ const base = await this.getPolicy();
91
+ const operations = {
92
+ ...base.operations,
93
+ };
94
+ for (const op of ROUTABLE_OPERATIONS) {
95
+ if (!operations[op]) {
96
+ const resolved = await this.resolveProviderForOperation(op);
97
+ operations[op] = {
98
+ provider: resolved.provider,
99
+ ...(resolved.model ? { model: resolved.model } : {}),
100
+ ...(resolved.options ? { options: resolved.options } : {}),
101
+ ...(resolved.fallbacks && resolved.fallbacks.length
102
+ ? { fallback: resolved.fallbacks }
103
+ : {}),
104
+ };
105
+ }
106
+ }
107
+ return {
108
+ defaultProvider: base.defaultProvider,
109
+ operations,
110
+ };
111
+ }
89
112
  async resolveProviderForOperation(operation, overrides) {
90
113
  const policy = await this.getPolicy();
91
114
  const operationConfig = policy.operations?.[operation];
92
115
  // Pull provider/model defaults from settings per operation
93
- const settings = getSettingsService().getSettings();
116
+ const settings = this.settingsService.getSettings();
94
117
  const coding = settings.agents?.codingAgent;
95
118
  const judge = settings.agents?.judgeAgent;
96
119
  const settingsProviderModel = (() => {
@@ -98,61 +121,54 @@ export class RoutingPolicyManager {
98
121
  case 'ai_codereview':
99
122
  return { provider: judge?.provider, model: judge?.model };
100
123
  case 'execute_task':
101
- case 'improve_task':
124
+ case 'quality_checks':
102
125
  case 'ai_merge':
126
+ case 'improve_task':
103
127
  default:
104
128
  return { provider: coding?.provider, model: coding?.model };
105
129
  }
106
130
  })();
107
131
  // Start with operation-specific config or fall back to settings, then default policy
108
132
  const baseProvider = operationConfig?.provider || settingsProviderModel.provider || policy.defaultProvider;
109
- const baseModel = operationConfig?.model || settingsProviderModel.model;
133
+ const baseModel = operationConfig?.model
134
+ ? operationConfig.model
135
+ : operationConfig?.provider
136
+ ? undefined
137
+ : settingsProviderModel.model;
110
138
  const baseOptions = operationConfig?.options;
111
139
  const baseFallbacks = operationConfig?.fallback || [];
112
140
  // Apply overrides
141
+ const overrideProviderOnly = overrides?.provider && overrides.model === undefined;
113
142
  const resolved = {
114
143
  provider: overrides?.provider || baseProvider,
115
- model: overrides?.model || baseModel,
144
+ model: overrideProviderOnly ? undefined : overrides?.model || baseModel,
116
145
  options: overrides?.options || baseOptions,
117
146
  fallbacks: overrides?.fallbacks || baseFallbacks,
118
147
  };
119
148
  log.debug(`Resolved provider for ${operation}`, { operation, resolved }, 'routing-policy');
120
149
  return resolved;
121
150
  }
122
- /**
123
- * Set default provider
124
- */
125
151
  async setDefaultProvider(provider) {
126
152
  await this.updatePolicy({ defaultProvider: provider });
127
153
  }
128
- /**
129
- * Set operation-specific routing
130
- */
131
154
  async setOperationConfig(operation, config) {
132
155
  const currentPolicy = await this.getPolicy();
133
- await this.updatePolicy({
134
- operations: {
135
- ...currentPolicy.operations,
136
- [operation]: config,
137
- },
138
- });
156
+ const operations = {
157
+ ...(currentPolicy.operations ?? {}),
158
+ [operation]: config,
159
+ };
160
+ await this.updatePolicy({ operations });
139
161
  }
140
- /**
141
- * Validate policy against available providers
142
- */
143
162
  validatePolicy(policy, availableProviders) {
144
163
  const errors = [];
145
- // Check default provider
146
164
  if (!availableProviders.has(policy.defaultProvider)) {
147
165
  errors.push(`Default provider '${policy.defaultProvider}' is not available`);
148
166
  }
149
- // Check operation providers
150
167
  if (policy.operations) {
151
168
  for (const [operation, config] of Object.entries(policy.operations)) {
152
169
  if (!availableProviders.has(config.provider)) {
153
170
  errors.push(`Provider '${config.provider}' for operation '${operation}' is not available`);
154
171
  }
155
- // Check fallback providers
156
172
  if (config.fallback) {
157
173
  for (const fallbackProvider of config.fallback) {
158
174
  if (!availableProviders.has(fallbackProvider)) {
@@ -164,83 +180,17 @@ export class RoutingPolicyManager {
164
180
  }
165
181
  return errors;
166
182
  }
167
- /**
168
- * Load policy from file if it has changed
169
- */
170
- async loadPolicyIfChanged() {
171
- try {
172
- const stats = await fs.stat(this.policyFilePath);
173
- const fileModified = stats.mtime.getTime();
174
- // Only reload if file has changed
175
- if (fileModified <= this.lastModified) {
176
- return;
177
- }
178
- const content = await fs.readFile(this.policyFilePath, 'utf-8');
179
- const parsed = JSON.parse(content);
180
- const validated = RoutingPolicySchema.parse(parsed);
181
- this.policy = validated;
182
- this.lastModified = fileModified;
183
- log.info('Loaded AI routing policy', { policy: validated }, 'routing-policy');
184
- }
185
- catch (error) {
186
- if (error.code === 'ENOENT') {
187
- // File doesn't exist yet, use default
188
- this.policy = null;
189
- return;
190
- }
191
- log.warn('Failed to load routing policy, using defaults', error, 'routing-policy');
192
- this.policy = null;
193
- }
194
- }
195
- /**
196
- * Create example policy file if it doesn't exist
197
- */
198
- async createExamplePolicy() {
199
- const examplePath = path.join(getVibeDir(), 'ai-routing.example.json');
200
- // Do not recreate if it already exists
201
- try {
202
- await fs.stat(examplePath);
203
- return; // already exists; avoid noisy logs
204
- }
205
- catch (err) {
206
- if (err?.code && err.code !== 'ENOENT') {
207
- log.warn('Unable to stat example AI routing policy', err, 'routing-policy');
208
- return;
209
- }
210
- }
211
- const settings = getSettingsService().getSettings();
212
- const example = {
213
- defaultProvider: settings.agents.defaultProvider || 'claude-code',
214
- operations: {
215
- execute_task: {
216
- provider: settings.agents.defaultProvider || 'claude-code',
217
- model: 'claude-sonnet-4-20250514',
218
- fallback: ['codex'],
219
- },
220
- improve_task: {
221
- provider: settings.agents.defaultProvider || 'claude-code',
222
- model: 'claude-sonnet-4-20250514',
223
- },
224
- ai_codereview: {
225
- provider: 'codex',
226
- model: 'gpt-5',
227
- },
228
- ai_merge: {
229
- provider: settings.agents.defaultProvider || 'claude-code',
230
- model: 'claude-sonnet-4-20250514',
231
- },
232
- },
183
+ buildPolicyFromSettings() {
184
+ const settings = this.settingsService.getSettings();
185
+ const settingsPolicy = settings.agents?.routingPolicy;
186
+ const defaultProvider = settingsPolicy?.defaultProvider || settings.agents.defaultProvider || 'claude-code';
187
+ const operations = settingsPolicy?.operations
188
+ ? { ...settingsPolicy.operations }
189
+ : undefined;
190
+ const policy = {
191
+ defaultProvider,
192
+ ...(operations ? { operations } : {}),
233
193
  };
234
- // Ensure .vibeman directory exists
235
- const vibemanDir = path.dirname(examplePath);
236
- await fs.mkdir(vibemanDir, { recursive: true });
237
- await fs.writeFile(examplePath, JSON.stringify(example, null, 2), 'utf-8');
238
- log.info('Created example AI routing policy', { path: examplePath }, 'routing-policy');
239
- }
240
- /**
241
- * Get policy file path for external access
242
- */
243
- getPolicyFilePath() {
244
- return this.policyFilePath;
194
+ return RoutingPolicySchema.parse(policy);
245
195
  }
246
196
  }
@@ -0,0 +1,63 @@
1
+ import { describe, it, expect, beforeAll, afterAll, afterEach } from 'vitest';
2
+ import { RoutingPolicyManager, } from './routing-policy.js';
3
+ import { getSettingsService } from '../settings-service.js';
4
+ const settingsService = getSettingsService();
5
+ const BASE_POLICY = {
6
+ defaultProvider: 'claude-code',
7
+ operations: {},
8
+ };
9
+ let originalRoutingPolicy;
10
+ async function setRoutingPolicy(value) {
11
+ const result = await settingsService.updateSettings([
12
+ { path: ['agents', 'routingPolicy'], value },
13
+ ]);
14
+ if (!result.success) {
15
+ throw new Error(`Failed to set routing policy: ${JSON.stringify(result.errors)}`);
16
+ }
17
+ }
18
+ describe('RoutingPolicyManager resolve precedence', () => {
19
+ beforeAll(async () => {
20
+ await settingsService.initialize();
21
+ const manager = new RoutingPolicyManager();
22
+ originalRoutingPolicy = await manager.getPolicy();
23
+ await setRoutingPolicy(BASE_POLICY);
24
+ });
25
+ afterEach(async () => {
26
+ await setRoutingPolicy(BASE_POLICY);
27
+ });
28
+ afterAll(async () => {
29
+ await setRoutingPolicy(originalRoutingPolicy);
30
+ });
31
+ it('falls back to settings when no operation config or overrides', async () => {
32
+ const rpm = new RoutingPolicyManager();
33
+ const resolved = await rpm.resolveProviderForOperation('execute_task');
34
+ expect(resolved.provider).toBe('claude-code');
35
+ expect(resolved.model).toBe('claude-sonnet-4-20250514');
36
+ });
37
+ it('uses operation-specific policy when provided', async () => {
38
+ const rpm = new RoutingPolicyManager();
39
+ await rpm.updatePolicy({
40
+ operations: {
41
+ ai_merge: { provider: 'codex', model: 'gpt-5' },
42
+ },
43
+ });
44
+ const resolved = await rpm.resolveProviderForOperation('ai_merge');
45
+ expect(resolved.provider).toBe('codex');
46
+ expect(resolved.model).toBe('gpt-5');
47
+ });
48
+ it('when override sets provider without model, does not inherit mismatched model', async () => {
49
+ const rpm = new RoutingPolicyManager();
50
+ await rpm.updatePolicy({ operations: {} });
51
+ const override = { provider: 'codex' };
52
+ const resolved = await rpm.resolveProviderForOperation('execute_task', override);
53
+ expect(resolved.provider).toBe('codex');
54
+ expect(resolved.model).toBeUndefined();
55
+ });
56
+ it('override with provider+model takes full precedence', async () => {
57
+ const rpm = new RoutingPolicyManager();
58
+ const override = { provider: 'codex', model: 'gpt-5' };
59
+ const resolved = await rpm.resolveProviderForOperation('execute_task', override);
60
+ expect(resolved.provider).toBe('codex');
61
+ expect(resolved.model).toBe('gpt-5');
62
+ });
63
+ });
@@ -8,7 +8,7 @@ import { type RoutingPolicy, type RoutableOperation } from '../../agent/routing-
8
8
  * Build AI router with required dependencies
9
9
  */
10
10
  export declare function buildAIRoutes(options: {
11
- requireAgentService: () => AgentService;
11
+ agentService: AgentService;
12
12
  }): {
13
13
  /**
14
14
  * List all registered AI providers with health status
@@ -40,7 +40,19 @@ export declare function buildAIRoutes(options: {
40
40
  */
41
41
  getRoutingPolicy: import("@trpc/server").TRPCQueryProcedure<{
42
42
  input: void;
43
- output: any;
43
+ output: {
44
+ defaultProvider: string;
45
+ operations?: Partial<Record<"execute_task" | "quality_checks" | "improve_task" | "ai_merge" | "ai_codereview", {
46
+ provider: string;
47
+ options?: {
48
+ temperature?: number | undefined;
49
+ maxTokens?: number | undefined;
50
+ tools?: string[] | undefined;
51
+ } | undefined;
52
+ model?: string | undefined;
53
+ fallback?: string[] | undefined;
54
+ }>> | undefined;
55
+ };
44
56
  meta: object;
45
57
  }>;
46
58
  /**
@@ -50,12 +62,12 @@ export declare function buildAIRoutes(options: {
50
62
  input: {
51
63
  policy: {
52
64
  defaultProvider?: string | undefined;
53
- operations?: Partial<Record<"execute_task" | "improve_task" | "ai_codereview" | "ai_merge", {
65
+ operations?: Partial<Record<"execute_task" | "quality_checks" | "improve_task" | "ai_merge" | "ai_codereview", {
54
66
  provider: string;
55
67
  options?: {
68
+ temperature?: number | undefined;
56
69
  maxTokens?: number | undefined;
57
70
  tools?: string[] | undefined;
58
- temperature?: number | undefined;
59
71
  } | undefined;
60
72
  model?: string | undefined;
61
73
  fallback?: string[] | undefined;
@@ -86,17 +98,17 @@ export declare function buildAIRoutes(options: {
86
98
  */
87
99
  setOperationConfig: import("@trpc/server").TRPCMutationProcedure<{
88
100
  input: {
101
+ operation: "execute_task" | "quality_checks" | "improve_task" | "ai_merge" | "ai_codereview";
89
102
  config: {
90
103
  provider: string;
91
104
  options?: {
105
+ temperature?: number | undefined;
92
106
  maxTokens?: number | undefined;
93
107
  tools?: string[] | undefined;
94
- temperature?: number | undefined;
95
108
  } | undefined;
96
109
  model?: string | undefined;
97
110
  fallback?: string[] | undefined;
98
111
  };
99
- operation: "execute_task" | "improve_task" | "ai_codereview" | "ai_merge";
100
112
  };
101
113
  output: {
102
114
  success: boolean;
@@ -130,7 +142,7 @@ export declare function buildAIRoutes(options: {
130
142
  * Useful for unit tests that call functions directly.
131
143
  */
132
144
  export declare function buildAIRouteHandlers(options: {
133
- requireAgentService: () => AgentService;
145
+ agentService: AgentService;
134
146
  }): {
135
147
  readonly listProviders: () => Promise<{
136
148
  name: string;
@@ -20,7 +20,7 @@ const SetDefaultProviderInputSchema = z.object({
20
20
  provider: z.string(),
21
21
  });
22
22
  const SetOperationConfigInputSchema = z.object({
23
- operation: z.enum(['execute_task', 'improve_task', 'ai_codereview', 'ai_merge']),
23
+ operation: z.enum(['execute_task', 'quality_checks', 'ai_codereview', 'ai_merge', 'improve_task']),
24
24
  config: OperationConfigSchema,
25
25
  });
26
26
  const ValidateProvidersInputSchema = z.object({
@@ -30,14 +30,13 @@ const ValidateProvidersInputSchema = z.object({
30
30
  * Build AI router with required dependencies
31
31
  */
32
32
  export function buildAIRoutes(options) {
33
- const { requireAgentService } = options;
33
+ const { agentService } = options;
34
34
  return {
35
35
  /**
36
36
  * List all registered AI providers with health status
37
37
  */
38
38
  listProviders: publicProcedure.query(async () => {
39
39
  try {
40
- const agentService = requireAgentService();
41
40
  const providers = agentService.getAvailableProviders();
42
41
  const providerStatuses = await agentService.validateProviders();
43
42
  const result = Array.from(providers.entries()).map(([name, provider]) => {
@@ -65,7 +64,6 @@ export function buildAIRoutes(options) {
65
64
  */
66
65
  listModels: publicProcedure.input(ListModelsInputSchema.optional()).query(async ({ input }) => {
67
66
  try {
68
- const agentService = requireAgentService();
69
67
  if (input?.provider) {
70
68
  // Get models from specific provider
71
69
  const provider = agentService.getAvailableProviders().get(input.provider);
@@ -94,17 +92,17 @@ export function buildAIRoutes(options) {
94
92
  */
95
93
  getRoutingPolicy: publicProcedure.query(async () => {
96
94
  try {
97
- const agentService = requireAgentService();
98
- const policy = await agentService.getRoutingPolicyManager()?.getPolicy();
99
- if (!policy) {
100
- // Return default policy if none exists
95
+ const rpm = agentService.getRoutingPolicyManager?.();
96
+ if (!rpm) {
101
97
  const settings = getSettingsService().getSettings();
102
- const defaultPolicy = {
98
+ return {
103
99
  defaultProvider: settings.agents.defaultProvider || 'claude-code',
104
100
  operations: {},
105
101
  };
106
- return defaultPolicy;
107
102
  }
103
+ const policy = (rpm.getEffectivePolicy
104
+ ? await rpm.getEffectivePolicy()
105
+ : await rpm.getPolicy());
108
106
  log.debug('Retrieved routing policy', { policy }, 'ai-router');
109
107
  return policy;
110
108
  }
@@ -121,7 +119,6 @@ export function buildAIRoutes(options) {
121
119
  .input(UpdateRoutingPolicyInputSchema)
122
120
  .mutation(async ({ input }) => {
123
121
  try {
124
- const agentService = requireAgentService();
125
122
  const routingManager = agentService.getRoutingPolicyManager();
126
123
  if (!routingManager) {
127
124
  throw new Error('Routing policy manager not available');
@@ -144,7 +141,6 @@ export function buildAIRoutes(options) {
144
141
  .input(SetDefaultProviderInputSchema)
145
142
  .mutation(async ({ input }) => {
146
143
  try {
147
- const agentService = requireAgentService();
148
144
  const routingManager = agentService.getRoutingPolicyManager();
149
145
  if (!routingManager) {
150
146
  throw new Error('Routing policy manager not available');
@@ -171,7 +167,6 @@ export function buildAIRoutes(options) {
171
167
  .input(SetOperationConfigInputSchema)
172
168
  .mutation(async ({ input }) => {
173
169
  try {
174
- const agentService = requireAgentService();
175
170
  const routingManager = agentService.getRoutingPolicyManager();
176
171
  if (!routingManager) {
177
172
  throw new Error('Routing policy manager not available');
@@ -206,7 +201,6 @@ export function buildAIRoutes(options) {
206
201
  .input(ValidateProvidersInputSchema.optional())
207
202
  .mutation(async ({ input }) => {
208
203
  try {
209
- const agentService = requireAgentService();
210
204
  const results = await agentService.validateProviders();
211
205
  const validation = Array.from(results.entries()).map(([name, status]) => ({
212
206
  provider: name,
@@ -239,11 +233,10 @@ export function buildAIRoutes(options) {
239
233
  * Useful for unit tests that call functions directly.
240
234
  */
241
235
  export function buildAIRouteHandlers(options) {
242
- const { requireAgentService } = options;
236
+ const { agentService } = options;
243
237
  return {
244
238
  async listProviders() {
245
239
  try {
246
- const agentService = requireAgentService();
247
240
  const providers = agentService.getAvailableProviders();
248
241
  const providerStatuses = await agentService.validateProviders();
249
242
  return Array.from(providers.entries()).map(([name, provider]) => {
@@ -264,7 +257,6 @@ export function buildAIRouteHandlers(options) {
264
257
  },
265
258
  async listModels(input) {
266
259
  try {
267
- const agentService = requireAgentService();
268
260
  if (input?.provider) {
269
261
  const provider = agentService.getAvailableProviders().get(input.provider);
270
262
  if (!provider)
@@ -279,7 +271,6 @@ export function buildAIRouteHandlers(options) {
279
271
  },
280
272
  async getRoutingPolicy() {
281
273
  try {
282
- const agentService = requireAgentService();
283
274
  const rpm = agentService.getRoutingPolicyManager?.() ||
284
275
  agentService.routingPolicyManager;
285
276
  const policy = await rpm?.getPolicy();
@@ -298,7 +289,6 @@ export function buildAIRouteHandlers(options) {
298
289
  },
299
290
  async updateRoutingPolicy(input) {
300
291
  try {
301
- const agentService = requireAgentService();
302
292
  const routingManager = agentService.getRoutingPolicyManager?.() ||
303
293
  agentService.routingPolicyManager;
304
294
  if (!routingManager)
@@ -313,7 +303,6 @@ export function buildAIRouteHandlers(options) {
313
303
  },
314
304
  async setDefaultProvider(input) {
315
305
  try {
316
- const agentService = requireAgentService();
317
306
  const routingManager = agentService.getRoutingPolicyManager?.() ||
318
307
  agentService.routingPolicyManager;
319
308
  if (!routingManager)
@@ -330,7 +319,6 @@ export function buildAIRouteHandlers(options) {
330
319
  },
331
320
  async setOperationConfig(input) {
332
321
  try {
333
- const agentService = requireAgentService();
334
322
  const routingManager = agentService.getRoutingPolicyManager?.() ||
335
323
  agentService.routingPolicyManager;
336
324
  if (!routingManager)
@@ -355,7 +343,6 @@ export function buildAIRouteHandlers(options) {
355
343
  },
356
344
  async validateProviders() {
357
345
  try {
358
- const agentService = requireAgentService();
359
346
  const results = await agentService.validateProviders();
360
347
  const validation = Array.from(results.entries()).map(([name, status]) => ({
361
348
  provider: name,
@@ -377,7 +364,6 @@ export function buildAIRouteHandlers(options) {
377
364
  },
378
365
  async getProviderHealth() {
379
366
  try {
380
- const agentService = requireAgentService();
381
367
  const providers = agentService.getAvailableProviders();
382
368
  const statuses = await agentService.validateProviders();
383
369
  const health = {
@@ -2,10 +2,9 @@ import type { TaskService } from '../../tasks/task-service.js';
2
2
  import type { VibingOrchestrator } from '../../workflows/vibing-orchestrator.js';
3
3
  type Deps = {
4
4
  taskService: TaskService;
5
- requireOrchestrator: () => Promise<VibingOrchestrator>;
6
- requireOrchestratorSync: () => VibingOrchestrator;
5
+ vibingOrchestrator: VibingOrchestrator;
7
6
  };
8
- export declare function buildExecutionRoutes({ taskService, requireOrchestrator, requireOrchestratorSync, }: Deps): {
7
+ export declare function buildExecutionRoutes({ taskService, vibingOrchestrator }: Deps): {
9
8
  readonly executeTask: import("@trpc/server").TRPCMutationProcedure<{
10
9
  input: {
11
10
  taskId: string;
@@ -66,9 +65,9 @@ export declare function buildExecutionRoutes({ taskService, requireOrchestrator,
66
65
  }>;
67
66
  readonly improveTask: import("@trpc/server").TRPCMutationProcedure<{
68
67
  input: {
68
+ title: string;
69
69
  type: "feature" | "bug" | "chore" | "refactor" | "test" | "doc";
70
70
  priority: "low" | "medium" | "high";
71
- title: string;
72
71
  content: string;
73
72
  taskId: string;
74
73
  executionId?: string | undefined;
@@ -77,6 +76,7 @@ export declare function buildExecutionRoutes({ taskService, requireOrchestrator,
77
76
  type: string;
78
77
  priority: string;
79
78
  content: string;
79
+ title?: string;
80
80
  executionId: string;
81
81
  selectedModel?: string;
82
82
  };