(
input: GenerateInput,
deps: GenerateViaAgentDeps = {},
)
| 961 | * tool calls, and file updates while preserving the GenerateOutput boundary. |
| 962 | */ |
| 963 | export async function generateViaAgent( |
| 964 | input: GenerateInput, |
| 965 | deps: GenerateViaAgentDeps = {}, |
| 966 | ): Promise<GenerateOutput> { |
| 967 | const log = input.logger ?? NOOP_LOGGER; |
| 968 | const ctx = { |
| 969 | provider: input.model.provider, |
| 970 | modelId: input.model.modelId, |
| 971 | } as const; |
| 972 | |
| 973 | if (!input.prompt.trim()) { |
| 974 | throw new CodesignError('Prompt cannot be empty', ERROR_CODES.INPUT_EMPTY_PROMPT); |
| 975 | } |
| 976 | const initialApiKey = input.apiKey.trim(); |
| 977 | if (initialApiKey.length === 0 && input.allowKeyless !== true) { |
| 978 | throw new CodesignError('Missing API key', ERROR_CODES.PROVIDER_AUTH_MISSING); |
| 979 | } |
| 980 | if (!input.systemPrompt && input.mode && input.mode !== 'create') { |
| 981 | throw new CodesignError( |
| 982 | 'generateViaAgent() built-in prompt only supports mode "create".', |
| 983 | ERROR_CODES.INPUT_UNSUPPORTED_MODE, |
| 984 | ); |
| 985 | } |
| 986 | |
| 987 | log.info('[generate] step=resolve_model', ctx); |
| 988 | const resolveStart = Date.now(); |
| 989 | const piModel = buildPiModel( |
| 990 | input.model, |
| 991 | input.wire, |
| 992 | input.baseUrl, |
| 993 | input.httpHeaders, |
| 994 | initialApiKey, |
| 995 | ); |
| 996 | log.info('[generate] step=resolve_model.ok', { ...ctx, ms: Date.now() - resolveStart }); |
| 997 | |
| 998 | log.info('[generate] step=build_request', ctx); |
| 999 | const buildStart = Date.now(); |
| 1000 | const resourceState = cloneResourceState(input.initialResourceState); |
| 1001 | const trackedFs = deps.fs ? trackFsMutations(deps.fs, resourceState) : undefined; |
| 1002 | let doneRepairLimitReached = false; |
| 1003 | const skillsBuiltinDir = input.templatesRoot |
| 1004 | ? path.join(input.templatesRoot, 'skills') |
| 1005 | : undefined; |
| 1006 | const resourceResult = input.systemPrompt |
| 1007 | ? { |
| 1008 | sections: [] as string[], |
| 1009 | warnings: [] as string[], |
| 1010 | skillCount: 0, |
| 1011 | scaffoldCount: 0, |
| 1012 | brandCount: 0, |
| 1013 | } |
| 1014 | : await collectResourceManifest({ |
| 1015 | log, |
| 1016 | providerId: input.model.provider, |
| 1017 | templatesRoot: input.templatesRoot, |
| 1018 | }); |
| 1019 | const preflightTitle = isAutoDesignName(input.currentDesignName) |
| 1020 | ? autoTitleFromPrompt(input.prompt) |
no test coverage detected