mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 21:03:08 +00:00
feat(suggestions): Wire to phaseModels.enhancementModel with Cursor support
The suggestions generation route (Feature Enhancement in UI) was not reading from phaseModels settings and always used the default haiku model. Changes: - Read enhancementModel from phaseModels settings - Add provider routing for Cursor vs Claude models - Pass model to createSuggestionsOptions for Claude SDK - For Cursor, include JSON schema in prompt and use ProviderFactory 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
* Business logic for generating suggestions
|
* Business logic for generating suggestions
|
||||||
|
*
|
||||||
|
* Model is configurable via phaseModels.enhancementModel in settings
|
||||||
|
* (Feature Enhancement in the UI). Supports both Claude and Cursor models.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { query } from '@anthropic-ai/claude-agent-sdk';
|
import { query } from '@anthropic-ai/claude-agent-sdk';
|
||||||
import type { EventEmitter } from '../../lib/events.js';
|
import type { EventEmitter } from '../../lib/events.js';
|
||||||
import { createLogger } from '@automaker/utils';
|
import { createLogger } from '@automaker/utils';
|
||||||
|
import { DEFAULT_PHASE_MODELS, isCursorModel } from '@automaker/types';
|
||||||
|
import { resolveModelString } from '@automaker/model-resolver';
|
||||||
import { createSuggestionsOptions } from '../../lib/sdk-options.js';
|
import { createSuggestionsOptions } from '../../lib/sdk-options.js';
|
||||||
|
import { ProviderFactory } from '../../providers/provider-factory.js';
|
||||||
import { FeatureLoader } from '../../services/feature-loader.js';
|
import { FeatureLoader } from '../../services/feature-loader.js';
|
||||||
import { getAppSpecPath } from '@automaker/platform';
|
import { getAppSpecPath } from '@automaker/platform';
|
||||||
import * as secureFs from '../../lib/secure-fs.js';
|
import * as secureFs from '../../lib/secure-fs.js';
|
||||||
@@ -164,10 +170,65 @@ The response will be automatically formatted as structured JSON.`;
|
|||||||
'[Suggestions]'
|
'[Suggestions]'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Get model from phase settings (Feature Enhancement = enhancementModel)
|
||||||
|
const settings = await settingsService?.getGlobalSettings();
|
||||||
|
const enhancementModel =
|
||||||
|
settings?.phaseModels?.enhancementModel || DEFAULT_PHASE_MODELS.enhancementModel;
|
||||||
|
const model = resolveModelString(enhancementModel);
|
||||||
|
|
||||||
|
logger.info('[Suggestions] Using model:', model);
|
||||||
|
|
||||||
|
let responseText = '';
|
||||||
|
let structuredOutput: { suggestions: Array<Record<string, unknown>> } | null = null;
|
||||||
|
|
||||||
|
// Route to appropriate provider based on model type
|
||||||
|
if (isCursorModel(model)) {
|
||||||
|
// Use Cursor provider for Cursor models
|
||||||
|
logger.info('[Suggestions] Using Cursor provider');
|
||||||
|
|
||||||
|
const provider = ProviderFactory.getProviderForModel(model);
|
||||||
|
|
||||||
|
// For Cursor, include the JSON schema in the prompt
|
||||||
|
const cursorPrompt = `${prompt}
|
||||||
|
|
||||||
|
IMPORTANT: You must respond with a valid JSON object matching this schema:
|
||||||
|
${JSON.stringify(suggestionsSchema, null, 2)}`;
|
||||||
|
|
||||||
|
for await (const msg of provider.executeQuery({
|
||||||
|
prompt: cursorPrompt,
|
||||||
|
model,
|
||||||
|
cwd: projectPath,
|
||||||
|
maxTurns: 250,
|
||||||
|
allowedTools: ['Read', 'Glob', 'Grep'],
|
||||||
|
abortController,
|
||||||
|
})) {
|
||||||
|
if (msg.type === 'assistant' && msg.message?.content) {
|
||||||
|
for (const block of msg.message.content) {
|
||||||
|
if (block.type === 'text' && block.text) {
|
||||||
|
responseText += block.text;
|
||||||
|
events.emit('suggestions:event', {
|
||||||
|
type: 'suggestions_progress',
|
||||||
|
content: block.text,
|
||||||
|
});
|
||||||
|
} else if (block.type === 'tool_use') {
|
||||||
|
events.emit('suggestions:event', {
|
||||||
|
type: 'suggestions_tool',
|
||||||
|
tool: block.name,
|
||||||
|
input: block.input,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use Claude SDK for Claude models
|
||||||
|
logger.info('[Suggestions] Using Claude SDK');
|
||||||
|
|
||||||
const options = createSuggestionsOptions({
|
const options = createSuggestionsOptions({
|
||||||
cwd: projectPath,
|
cwd: projectPath,
|
||||||
abortController,
|
abortController,
|
||||||
autoLoadClaudeMd,
|
autoLoadClaudeMd,
|
||||||
|
model, // Pass the model from settings
|
||||||
outputFormat: {
|
outputFormat: {
|
||||||
type: 'json_schema',
|
type: 'json_schema',
|
||||||
schema: suggestionsSchema,
|
schema: suggestionsSchema,
|
||||||
@@ -175,8 +236,6 @@ The response will be automatically formatted as structured JSON.`;
|
|||||||
});
|
});
|
||||||
|
|
||||||
const stream = query({ prompt, options });
|
const stream = query({ prompt, options });
|
||||||
let responseText = '';
|
|
||||||
let structuredOutput: { suggestions: Array<Record<string, unknown>> } | null = null;
|
|
||||||
|
|
||||||
for await (const msg of stream) {
|
for await (const msg of stream) {
|
||||||
if (msg.type === 'assistant' && msg.message.content) {
|
if (msg.type === 'assistant' && msg.message.content) {
|
||||||
@@ -216,6 +275,7 @@ The response will be automatically formatted as structured JSON.`;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Use structured output if available, otherwise fall back to parsing text
|
// Use structured output if available, otherwise fall back to parsing text
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user