From e9c168a93a1e4701d7a79febab0e2e7a94baf49f Mon Sep 17 00:00:00 2001 From: Ashu463 Date: Wed, 22 Jul 2026 10:24:09 +0530 Subject: [PATCH 1/3] Sandbox path fixed and openaigeneric -> gemini --- apps/backend/src/modules/run.ts | 5 +- packages/agents/agent/config/systemConfig.ts | 2 + packages/agents/agent/subagents/tester.ts | 5 +- packages/agents/agent/utils/sandbox.ts | 46 +- packages/agents/baml_client/async_client.ts | 522 +------------------ packages/agents/baml_client/async_request.ts | 266 +--------- packages/agents/baml_client/inlinedbaml.ts | 14 +- packages/agents/baml_client/parser.ts | 186 +------ packages/agents/baml_client/partial_types.ts | 7 +- packages/agents/baml_client/sync_client.ts | 202 +------ packages/agents/baml_client/sync_request.ts | 266 +--------- packages/agents/baml_client/type_builder.ts | 8 +- packages/agents/baml_client/types.ts | 7 - packages/agents/baml_src/agents.baml | 50 +- packages/agents/baml_src/coderAgent.baml | 2 +- packages/agents/baml_src/context.baml | 16 +- packages/agents/baml_src/debuggerAgent.baml | 2 +- packages/agents/baml_src/mainAgent.baml | 2 +- packages/agents/baml_src/subAgents.baml | 93 +++- packages/agents/baml_src/uiExpert.baml | 2 +- 20 files changed, 151 insertions(+), 1552 deletions(-) diff --git a/apps/backend/src/modules/run.ts b/apps/backend/src/modules/run.ts index 8ccb4cf..e65fd3a 100644 --- a/apps/backend/src/modules/run.ts +++ b/apps/backend/src/modules/run.ts @@ -100,7 +100,6 @@ runRouter.get("/:projectId/runs/:runId", auth, async (req: Request, res: Respons runRouter.get("/:projectId/:runId/todos", auth, async (req: Request, res: Response) => { const { projectId, runId } = req.params; - if ( typeof projectId !== "string" || typeof runId !== "string" @@ -214,6 +213,8 @@ runRouter.get("/:projectId/:runId/summaries", auth, async (req: Request, res: Re runRouter.post("/:projectId/:runId/todos", internalAuth, async (req: Request, res: Response) => { + logger.info(`Saving todos to the db`) + const { projectId, runId } = req.params; const { todos } = req.body as { todos: {id: number, task: string, agent: AgentType, status: "pending" | "completed", dependency: number[], designNeeded?: boolean}[] @@ -233,6 +234,8 @@ runRouter.post("/:projectId/:runId/todos", internalAuth, async (req: Request, re } try { + logger.info(`calling promises to save todos`) + const created = await Promise.all(todos.map((t) => prisma.todo.create({ data: { diff --git a/packages/agents/agent/config/systemConfig.ts b/packages/agents/agent/config/systemConfig.ts index 2a8fdd1..5c1a926 100644 --- a/packages/agents/agent/config/systemConfig.ts +++ b/packages/agents/agent/config/systemConfig.ts @@ -1,4 +1,6 @@ export const PORT = 3000 +export const SANDBOX_HOME = '/home/user' +export const PROJECT_ROOT = `${SANDBOX_HOME}/app` export const MAX_BOOT_WAIT_MS = 20000 export const POLL_INTERVAL_MS = 500 export const BACKEND_URL = process.env.BACKEND_URL ?? `http://localhost:3000` diff --git a/packages/agents/agent/subagents/tester.ts b/packages/agents/agent/subagents/tester.ts index 1566b81..8b14ef1 100644 --- a/packages/agents/agent/subagents/tester.ts +++ b/packages/agents/agent/subagents/tester.ts @@ -2,7 +2,7 @@ import Sandbox from "e2b" import { BaseAgent } from "./baseAgent" import { b, type ErrorResponse, type TesterContext } from "../../baml_client" import { TESTER_ERROR_REFACTOR_PROMPT } from "../config/sysPrompts" -import { MAX_BOOT_WAIT_MS, POLL_INTERVAL_MS, PORT } from "../config/systemConfig" +import { MAX_BOOT_WAIT_MS, POLL_INTERVAL_MS, PORT, PROJECT_ROOT } from "../config/systemConfig" import type { E2BSandbox } from "../utils/sandbox" type TesterInput = "" @@ -26,8 +26,7 @@ export class TesterAgent extends BaseAgent {stdOutBuf += data}, onStderr: (data: string) => {stdErrBuf += data} diff --git a/packages/agents/agent/utils/sandbox.ts b/packages/agents/agent/utils/sandbox.ts index 2ce6ed9..9cb72fa 100644 --- a/packages/agents/agent/utils/sandbox.ts +++ b/packages/agents/agent/utils/sandbox.ts @@ -1,6 +1,7 @@ import { Sandbox } from 'e2b' import type { DeleteFile, EditFile, ReadFile, RunCommand, WriteFile } from '../../baml_client'; import { R2 } from '../services/file-storage/fileStorage'; +import { SANDBOX_HOME, PROJECT_ROOT } from '../config/systemConfig'; export interface ExecuteRes{ success: boolean, @@ -48,8 +49,6 @@ export class E2BSandbox{ await instance.restoreOrBootstrap() return instance } - private readonly APP_DIR = '/home/user/app' - private async restoreOrBootstrap(): Promise { const files = await this.r2.listFiles(this.r2.filesPrefix(this.userId, this.projectId)) @@ -61,7 +60,7 @@ export class E2BSandbox{ const content = await this.r2.getFile(key) await this.Execute(this.sandboxId, { action: 'writeFile', - path: `${this.APP_DIR}${relativePath}`, + path: `${SANDBOX_HOME}${relativePath}`, content }) } @@ -70,19 +69,19 @@ export class E2BSandbox{ } else { console.log('Bootstrapping fresh sandbox') - await this.sandbox.commands.run(`mkdir -p ${this.APP_DIR}`) + await this.sandbox.commands.run(`mkdir -p ${PROJECT_ROOT}`) await this.sandbox.commands.run( 'curl -fsSL https://codeload.github.com/Ashu463/react-template/tar.gz/refs/heads/master -o repo.tar.gz', - { cwd: this.APP_DIR } + { cwd: PROJECT_ROOT } ) await this.sandbox.commands.run( 'tar -xzf repo.tar.gz --strip-components=1 && rm repo.tar.gz', - { cwd: this.APP_DIR } + { cwd: PROJECT_ROOT } ) - const install = await this.sandbox.commands.run('npm install', { cwd: this.APP_DIR }) + const install = await this.sandbox.commands.run('npm install', { cwd: PROJECT_ROOT }) if (install.exitCode !== 0) { console.error('npm install failed:', install.stderr) throw new Error('Bootstrap failed: npm install did not succeed') @@ -92,16 +91,18 @@ export class E2BSandbox{ await this.SyncR2() } - + + } + private resolvePath(path: string): string { + if (path.startsWith('/')) return path + return `${PROJECT_ROOT}/${path.replace(/^\.\//, '')}` } - // implement to increase the TTL of sandbox by one hour whenever any of these - // functions get called. async getRepoTree(): Promise{ try{ const result = await this.sandbox.commands.run( "find . -type f -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -name '.env'", - { cwd: '/home/user/app' } + { cwd: PROJECT_ROOT } ) return result.stdout @@ -114,9 +115,10 @@ export class E2BSandbox{ async Execute(id: string, payload: ReadFile | WriteFile | EditFile | DeleteFile| RunCommand): Promise{ // const homeDir = + if(payload.action === 'read'){ try{ - const result: string = await this.sandbox.files.read(payload.path) + const result: string = await this.sandbox.files.read(this.resolvePath(payload.path)) return { success: true, content: result @@ -129,8 +131,8 @@ export class E2BSandbox{ } else if(payload.action === 'writeFile'){ try{ - const writeRes = await this.sandbox.files.write(payload.path, payload.content) - + const writeRes = await this.sandbox.files.write(this.resolvePath(payload.path), payload.content) + return { success: true, content: `Content written at ${writeRes.path}` @@ -146,8 +148,8 @@ export class E2BSandbox{ } else if(payload.action === 'delete'){ try{ - const deleteRes = await this.sandbox.files.remove(payload.path) - + const deleteRes = await this.sandbox.files.remove(this.resolvePath(payload.path)) + return { success: true, content: `Deleted file is ${deleteRes}` @@ -161,6 +163,7 @@ export class E2BSandbox{ else if(payload.action === 'runCommand'){ try{ const cmdRes = await this.sandbox.commands.run(payload.command, { + cwd: PROJECT_ROOT, timeoutMs: 60000 }) @@ -196,14 +199,13 @@ export class E2BSandbox{ async SyncR2(){ /*Steps: sandbox -> r2 - - create the new path for all such files. + - create the new path for all such files. - putfile with that key for each of the file. copy whole directory of sandbox /home/usr to the R2. */ - const cwd = (await this.sandbox.commands.run("pwd")).stdout.trim() const prefix = this.r2.filesPrefix(this.userId, this.projectId) const findCmd = [ - `find ${cwd} -type f`, + `find ${PROJECT_ROOT} -type f`, `-not -path '*/node_modules/*'`, `-not -path '*/dist/*'`, `-not -path '*/build/*'`, @@ -214,17 +216,15 @@ export class E2BSandbox{ ].join(' ') const result = await this.sandbox.commands.run(findCmd) - // console.log(result, " is the find -type f command result") - // I've to trust the LLM that he'll send me the right folder directory while writing any file const absolutePaths = result.stdout.split('\n') .map(p => p.trim()) .filter(Boolean) - + for(let i = 0 ; i < absolutePaths.length; i += 10){ const batch = absolutePaths.slice(i, i + 10) await Promise.all(batch.map(async (absPath) =>{ - const relPath = absPath.replace(`${cwd}`, "") + const relPath = absPath.replace(SANDBOX_HOME, "") const content = await this.sandbox.files.read(absPath) await this.r2.putFile(prefix + relPath, content) })) diff --git a/packages/agents/baml_client/async_client.ts b/packages/agents/baml_client/async_client.ts index 73a1657..537786a 100644 --- a/packages/agents/baml_client/async_client.ts +++ b/packages/agents/baml_client/async_client.ts @@ -24,7 +24,7 @@ import { toBamlError, BamlStream, BamlAbortError, Collector, ClientRegistry } fr import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types" import type { partial_types } from "./partial_types" import type * as types from "./types" -import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, FinalResponse, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" +import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" import type TypeBuilder from "./type_builder" import { AsyncHttpRequest, AsyncHttpStreamRequest } from "./async_request" import { LlmResponseParser, LlmStreamParser } from "./parser" @@ -97,62 +97,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } - async BugFinder( - errors: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided - route through streaming if so - if (__options__.onTick) { - const __stream__ = this.stream.BugFinder( - errors,systemPrompt, - __baml_options__ - ); - - return await __stream__.getFinalResponse(); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = await this.runtime.callFunction( - "BugFinder", - { - "errors": errors,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.Error[] - } catch (error) { - throw toBamlError(error); - } - } - async CheckComplexityAndGenerateQuestions( systemPrompt: string,userPrompt: string, __baml_options__?: BamlCallOptions @@ -769,62 +713,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } } - async OrchestrateAgent( - systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided - route through streaming if so - if (__options__.onTick) { - const __stream__ = this.stream.OrchestrateAgent( - systemPrompt, - __baml_options__ - ); - - return await __stream__.getFinalResponse(); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = await this.runtime.callFunction( - "OrchestrateAgent", - { - "systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.FinalResponse - } catch (error) { - throw toBamlError(error); - } - } - async OrchestratorSummary( systemPrompt: string,summaries: string[], __baml_options__?: BamlCallOptions @@ -1049,62 +937,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } } - async StreamOneAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided - route through streaming if so - if (__options__.onTick) { - const __stream__ = this.stream.StreamOneAgent( - userPrompt,systemPrompt, - __baml_options__ - ); - - return await __stream__.getFinalResponse(); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = await this.runtime.callFunction( - "StreamOneAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.AgentResponse - } catch (error) { - throw toBamlError(error); - } - } - async SummarizeCoderContext( systemPrompt: string,context: types.CoderContext, __baml_options__?: BamlCallOptions @@ -1329,62 +1161,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } } - async TesterAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided - route through streaming if so - if (__options__.onTick) { - const __stream__ = this.stream.TesterAgent( - userPrompt,systemPrompt, - __baml_options__ - ); - - return await __stream__.getFinalResponse(); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = await this.runtime.callFunction( - "TesterAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.TesterResponse - } catch (error) { - throw toBamlError(error); - } - } - async UIExpertAgent( __baml_options__?: BamlCallOptions @@ -1455,80 +1231,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } - BugFinder( - errors: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): BamlStream - { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - let __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - - let __onTickWrapper__: (() => void) | undefined; - - // Create collector and wrap onTick if provided - if (__options__.onTick) { - const __tickCollector__ = new Collector("on-tick-collector"); - __collector__ = [...__collector__, __tickCollector__]; - - __onTickWrapper__ = () => { - const __log__ = __tickCollector__.last; - if (__log__) { - try { - __options__.onTick!("Unknown", __log__); - } catch (error) { - console.error("Error in onTick callback for BugFinder", error); - } - } - }; - } - - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.streamFunction( - "BugFinder", - { - "errors": errors,"systemPrompt": systemPrompt - }, - undefined, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __onTickWrapper__, - ) - return new BamlStream( - __raw__, - (a): partial_types.Error[] => a, - (a): types.Error[] => a, - this.ctxManager.cloneContext(), - __options__.signal, - ) - } catch (error) { - throw toBamlError(error); - } - } - CheckComplexityAndGenerateQuestions( systemPrompt: string,userPrompt: string, __baml_options__?: BamlCallOptions @@ -2343,80 +2045,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } } - OrchestrateAgent( - systemPrompt: string, - __baml_options__?: BamlCallOptions - ): BamlStream - { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - let __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - - let __onTickWrapper__: (() => void) | undefined; - - // Create collector and wrap onTick if provided - if (__options__.onTick) { - const __tickCollector__ = new Collector("on-tick-collector"); - __collector__ = [...__collector__, __tickCollector__]; - - __onTickWrapper__ = () => { - const __log__ = __tickCollector__.last; - if (__log__) { - try { - __options__.onTick!("Unknown", __log__); - } catch (error) { - console.error("Error in onTick callback for OrchestrateAgent", error); - } - } - }; - } - - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.streamFunction( - "OrchestrateAgent", - { - "systemPrompt": systemPrompt - }, - undefined, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __onTickWrapper__, - ) - return new BamlStream( - __raw__, - (a): partial_types.FinalResponse => a, - (a): types.FinalResponse => a, - this.ctxManager.cloneContext(), - __options__.signal, - ) - } catch (error) { - throw toBamlError(error); - } - } - OrchestratorSummary( systemPrompt: string,summaries: string[], __baml_options__?: BamlCallOptions @@ -2713,80 +2341,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } } - StreamOneAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): BamlStream - { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - let __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - - let __onTickWrapper__: (() => void) | undefined; - - // Create collector and wrap onTick if provided - if (__options__.onTick) { - const __tickCollector__ = new Collector("on-tick-collector"); - __collector__ = [...__collector__, __tickCollector__]; - - __onTickWrapper__ = () => { - const __log__ = __tickCollector__.last; - if (__log__) { - try { - __options__.onTick!("Unknown", __log__); - } catch (error) { - console.error("Error in onTick callback for StreamOneAgent", error); - } - } - }; - } - - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.streamFunction( - "StreamOneAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - undefined, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __onTickWrapper__, - ) - return new BamlStream( - __raw__, - (a): partial_types.AgentResponse => a, - (a): types.AgentResponse => a, - this.ctxManager.cloneContext(), - __options__.signal, - ) - } catch (error) { - throw toBamlError(error); - } - } - SummarizeCoderContext( systemPrompt: string,context: types.CoderContext, __baml_options__?: BamlCallOptions @@ -3083,80 +2637,6 @@ export type RecursivePartialNull = MovedRecursivePartialNull } } - TesterAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): BamlStream - { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - let __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : - [__options__.collector]) : []; - - let __onTickWrapper__: (() => void) | undefined; - - // Create collector and wrap onTick if provided - if (__options__.onTick) { - const __tickCollector__ = new Collector("on-tick-collector"); - __collector__ = [...__collector__, __tickCollector__]; - - __onTickWrapper__ = () => { - const __log__ = __tickCollector__.last; - if (__log__) { - try { - __options__.onTick!("Unknown", __log__); - } catch (error) { - console.error("Error in onTick callback for TesterAgent", error); - } - } - }; - } - - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.streamFunction( - "TesterAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - undefined, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __onTickWrapper__, - ) - return new BamlStream( - __raw__, - (a): partial_types.TesterResponse => a, - (a): types.TesterResponse => a, - this.ctxManager.cloneContext(), - __options__.signal, - ) - } catch (error) { - throw toBamlError(error); - } - } - UIExpertAgent( __baml_options__?: BamlCallOptions diff --git a/packages/agents/baml_client/async_request.ts b/packages/agents/baml_client/async_request.ts index 10dbbe4..7f0bc0a 100644 --- a/packages/agents/baml_client/async_request.ts +++ b/packages/agents/baml_client/async_request.ts @@ -23,7 +23,7 @@ import type { BamlRuntime, BamlCtxManager, Image, Audio, Pdf, Video, FunctionLog import { toBamlError, HTTPRequest, ClientRegistry } from "@boundaryml/baml" import type { Checked, Check } from "./types" import type * as types from "./types" -import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, FinalResponse, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" +import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" import type TypeBuilder from "./type_builder" import type * as events from "./events" @@ -42,39 +42,6 @@ env?: Record constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {} - async BugFinder( - errors: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "BugFinder", - { - "errors": errors,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async CheckComplexityAndGenerateQuestions( systemPrompt: string,userPrompt: string, __baml_options__?: BamlCallOptions @@ -438,39 +405,6 @@ env?: Record } } - async OrchestrateAgent( - systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "OrchestrateAgent", - { - "systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async OrchestratorSummary( systemPrompt: string,summaries: string[], __baml_options__?: BamlCallOptions @@ -603,39 +537,6 @@ env?: Record } } - async StreamOneAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "StreamOneAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async SummarizeCoderContext( systemPrompt: string,context: types.CoderContext, __baml_options__?: BamlCallOptions @@ -768,39 +669,6 @@ env?: Record } } - async TesterAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "TesterAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async UIExpertAgent( __baml_options__?: BamlCallOptions @@ -840,39 +708,6 @@ env?: Record constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {} - async BugFinder( - errors: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "BugFinder", - { - "errors": errors,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async CheckComplexityAndGenerateQuestions( systemPrompt: string,userPrompt: string, __baml_options__?: BamlCallOptions @@ -1236,39 +1071,6 @@ env?: Record } } - async OrchestrateAgent( - systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "OrchestrateAgent", - { - "systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async OrchestratorSummary( systemPrompt: string,summaries: string[], __baml_options__?: BamlCallOptions @@ -1401,39 +1203,6 @@ env?: Record } } - async StreamOneAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "StreamOneAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async SummarizeCoderContext( systemPrompt: string,context: types.CoderContext, __baml_options__?: BamlCallOptions @@ -1566,39 +1335,6 @@ env?: Record } } - async TesterAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): Promise { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return await this.runtime.buildRequest( - "TesterAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__ - ) - } catch (error) { - throw toBamlError(error); - } - } - async UIExpertAgent( __baml_options__?: BamlCallOptions diff --git a/packages/agents/baml_client/inlinedbaml.ts b/packages/agents/baml_client/inlinedbaml.ts index 118a156..f17bf7f 100644 --- a/packages/agents/baml_client/inlinedbaml.ts +++ b/packages/agents/baml_client/inlinedbaml.ts @@ -20,18 +20,18 @@ $ pnpm add @boundaryml/baml const fileMap = { - "agents.baml": "client OpenAIGeneric {\n provider \"openai-generic\"\n options {\n base_url env.LLM_BASE_URL\n api_key env.LLM_API_KEY\n model \"deepseek-v4-flash\"\n }\n}\nclient Gemini {\n provider google-ai\n options {\n model \"gemini-3.5-flash\"\n }\n}\n\nclass AgentResponse{\n \n}\nclass ResearcherResponse{\n query string\n result BraveRes | ApifyRes\n}\n\nclass BraveRes{\n type string\n result BraveResult[]\n}\nclass BraveResult{\n title string\n url string\n description string\n pageAge string // datetime\n}\nclass ApifyRes{\n status string\n itemcount int \n scrapeRes ItemRes[]\n}\nclass ItemRes{\n title string\n description string\n url string\n}\n\n\nclass TesterResponse{\n\n}\n\nfunction StreamOneAgent(userPrompt: string, systemPrompt: string) -> AgentResponse{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}}\n\n {{ctx.output_format}}\n \"#\n}\n\nclass FinalResponse{\n status \"success\" | \"failed\"\n previewUrl string?\n deployUrl string?\n}\nfunction OrchestrateAgent(systemPrompt: string) -> FinalResponse{\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n\n {{ctx.output_format}}\n \"#\n\n}\nfunction ResearchAgent(query: string, systemPrompt: string, searchWay: string) -> ResearcherResponse{\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{query}}\n {{searchWay}}\n\n {{ctx.output_format}}\n \"#\n}\n\n\nfunction BugFinder(errors: string, systemPrompt: string) -> Error[]{\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{errors}}\n\n {{ctx.output_format}}\n \"#\n}\n\nfunction TesterAgent(userPrompt: string, systemPrompt: string, ) -> TesterResponse{\n // just compare the concised version of whatever is built till now and the actual user prompt\n // then find the similarty score of both, if > 75 then okay\n // else loop in again the coder for fixing this. \n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}}\n\n {{ctx.output_format}}\n \"#\n}\nclass PlannerTodo{\n id int\n task string\n agent \"coder\" | \"debuggerr\" | \"tester\" | \"researcher\" | \"uiExpert\"\n status \"pending\" | \"completed\"\n dependency int[]\n designNeeded bool\n}\nclass TaskComplexity{\n complexity bool\n POA PlannerTodo[] | string\n}\n\n// ---New Edit 5/July/26, this file would be acting as utils for baml types\nclass Research{\n action \"research\"\n searchType WebSearch | WebScrape | DocsSearch\n}\nclass WebScrape{\n type \"webScrape\"\n urls string[]\n maxPages int\n}\nclass WebSearch{\n type \"webSearch\"\n query string\n maxResults int\n}\nclass DocsSearch{\n type \"docsSearch\"\n library string\n query string\n}\nclass FileEdit{\n fileName string\n summary string\n}\nclass WriteFile{ // write file or edit file is treated to be same\n action \"writeFile\"\n path string\n content string\n}\nclass ReadFile{\n action \"read\"\n path string\n}\nclass DeleteFile{\n action \"delete\"\n path string\n}\nclass RunCommand{\n action \"runCommand\"\n command string\n}\nclass EditFile{\n action \"editFile\"\n path string\n content string\n}\nclass ToolResult{\n success bool\n content FileEdit[]?\n}\nclass TaskSummary{\n taskId string\n summary string\n}\nenum ContextType{\n CoderContext\n DebuggerContext\n TesterContext\n UIExpertContext\n ResearcherContext\n}\nclass ResearcherContext{\n query string\n}\nclass TesterContext{}\n\nclass SubAgentsContexts{\n coder CoderContext\n debuggerr DebuggerContext // this is not a typo, I made this intentionally \n // because baml have debugger keyword and they don't let me use that.\n tester TesterContext\n researcher ResearcherContext\n uiExpert UIExpertContext\n}\ntype SubAgentsContext = CoderContext | DebuggerContext | TesterContext | ResearcherContext | UIExpertContext\n\nfunction OrchestratorSummary(systemPrompt: string, summaries: string[]) -> string{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{summaries}} - full Run history: the original request, the\nfixed design decision, every subsequent user message with its complexity\nverdict and which path handled it, and the state of whichever delegate is\ncurrently active.\n\n {{ctx.output_format}}\n \"#\n}", + "agents.baml": "client OpenAIGeneric {\n provider \"openai-generic\"\n options {\n base_url env.LLM_BASE_URL\n api_key env.LLM_API_KEY\n model \"deepseek-v4-flash\"\n }\n}\nclient Gemini {\n provider google-ai\n options {\n model \"gemini-3.5-flash\"\n }\n}\n\nclass AgentResponse{\n \n}\nclass ResearcherResponse{\n query string\n result BraveRes | ApifyRes\n}\n\nclass BraveRes{\n type string\n result BraveResult[]\n}\nclass BraveResult{\n title string\n url string\n description string\n pageAge string // datetime\n}\nclass ApifyRes{\n status string\n itemcount int \n scrapeRes ItemRes[]\n}\nclass ItemRes{\n title string\n description string\n url string\n}\n\n\nclass TesterResponse{\n\n}\n\nfunction ResearchAgent(query: string, systemPrompt: string, searchWay: string) -> ResearcherResponse{\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{query}}\n {{searchWay}}\n\n {{ctx.output_format}}\n \"#\n}\n\n\n\nclass PlannerTodo{\n id int\n task string\n agent \"coder\" | \"debuggerr\" | \"tester\" | \"researcher\" | \"uiExpert\"\n status \"pending\" | \"completed\"\n dependency int[]\n designNeeded bool\n}\nclass TaskComplexity{\n complexity bool\n POA PlannerTodo[] | string\n}\n\n// ---New Edit 5/July/26, this file would be acting as utils for baml types\nclass Research{\n action \"research\"\n searchType WebSearch | WebScrape | DocsSearch\n}\nclass WebScrape{\n type \"webScrape\"\n urls string[]\n maxPages int\n}\nclass WebSearch{\n type \"webSearch\"\n query string\n maxResults int\n}\nclass DocsSearch{\n type \"docsSearch\"\n library string\n query string\n}\nclass FileEdit{\n fileName string\n summary string\n}\nclass WriteFile{ // write file or edit file is treated to be same\n action \"writeFile\"\n path string\n content string\n}\nclass ReadFile{\n action \"read\"\n path string\n}\nclass DeleteFile{\n action \"delete\"\n path string\n}\nclass RunCommand{\n action \"runCommand\"\n command string\n}\nclass EditFile{\n action \"editFile\"\n path string\n content string\n}\nclass ToolResult{\n success bool\n content FileEdit[]?\n}\nclass TaskSummary{\n taskId string\n summary string\n}\nenum ContextType{\n CoderContext\n DebuggerContext\n TesterContext\n UIExpertContext\n ResearcherContext\n}\nclass ResearcherContext{\n query string\n}\nclass TesterContext{}\n\nclass SubAgentsContexts{\n coder CoderContext\n debuggerr DebuggerContext // this is not a typo, I made this intentionally \n // because baml have debugger keyword and they don't let me use that.\n tester TesterContext\n researcher ResearcherContext\n uiExpert UIExpertContext\n}\ntype SubAgentsContext = CoderContext | DebuggerContext | TesterContext | ResearcherContext | UIExpertContext\n\nfunction OrchestratorSummary(systemPrompt: string, summaries: string[]) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{summaries}} - full Run history: the original request, the\nfixed design decision, every subsequent user message with its complexity\nverdict and which path handled it, and the state of whichever delegate is\ncurrently active.\n\n {{ctx.output_format}}\n \"#\n}", "clients.baml": "// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview\n\n// Using the new OpenAI Responses API for enhanced formatting\nclient CustomGPT5 {\n provider openai-responses\n options {\n model \"gpt-5\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient CustomGPT5Mini {\n provider openai-responses\n retry_policy Exponential\n options {\n model \"gpt-5-mini\"\n api_key env.OPENAI_API_KEY\n }\n}\n\n// Openai with chat completion\nclient CustomGPT5Chat {\n provider openai\n options {\n model \"gpt-5\"\n api_key env.OPENAI_API_KEY\n }\n}\n\n// Latest Anthropic Claude 4 models\nclient CustomOpus4 {\n provider anthropic\n options {\n model \"claude-opus-4-1-20250805\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\nclient CustomSonnet4 {\n provider anthropic\n options {\n model \"claude-sonnet-4-20250514\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\nclient CustomHaiku {\n provider anthropic\n retry_policy Constant\n options {\n model \"claude-3-5-haiku-20241022\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n// Example Google AI client (uncomment to use)\n// client CustomGemini {\n// provider google-ai\n// options {\n// model \"gemini-2.5-pro\"\n// api_key env.GOOGLE_API_KEY\n// }\n// }\n\n// Example AWS Bedrock client (uncomment to use)\n// client CustomBedrock {\n// provider aws-bedrock\n// options {\n// model \"anthropic.claude-sonnet-4-20250514-v1:0\"\n// region \"us-east-1\"\n// // AWS credentials are auto-detected from env vars\n// }\n// }\n\n// Example Azure OpenAI client (uncomment to use)\n// client CustomAzure {\n// provider azure-openai\n// options {\n// model \"gpt-5\"\n// api_key env.AZURE_OPENAI_API_KEY\n// base_url \"https://MY_RESOURCE_NAME.openai.azure.com/openai/deployments/MY_DEPLOYMENT_ID\"\n// api_version \"2024-10-01-preview\"\n// }\n// }\n\n// Example Vertex AI client (uncomment to use)\n// client CustomVertex {\n// provider vertex-ai\n// options {\n// model \"gemini-2.5-pro\"\n// location \"us-central1\"\n// // Uses Google Cloud Application Default Credentials\n// }\n// }\n\n// Example Ollama client for local models (uncomment to use)\n// client CustomOllama {\n// provider openai-generic\n// options {\n// base_url \"http://localhost:11434/v1\"\n// model \"llama4\"\n// default_role \"user\" // Most local models prefer the user role\n// // No API key needed for local Ollama\n// }\n// }\n\n// https://docs.boundaryml.com/docs/snippets/clients/round-robin\nclient CustomFast {\n provider round-robin\n options {\n // This will alternate between the two clients\n strategy [CustomGPT5Mini, CustomHaiku]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/fallback\nclient OpenaiFallback {\n provider fallback\n options {\n // This will try the clients in order until one succeeds\n strategy [CustomGPT5Mini, CustomGPT5]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/retry\nretry_policy Constant {\n max_retries 3\n strategy {\n type constant_delay\n delay_ms 200\n }\n}\n\nretry_policy Exponential {\n max_retries 2\n strategy {\n type exponential_backoff\n delay_ms 300\n multiplier 1.5\n max_delay_ms 10000\n }\n}", - "coderAgent.baml": "\nclass FetchDocs{\n action \"fetchDocs\"\n query string\n library string // or framework\n}\nclass Done{\n action \"done\"\n filesEdited FileEdit[]\n}\n\nclass CoderContext{\n task string\n dependentSummary TaskSummary[]\n repoTree string\n}\n\nfunction CoderAgent(\n systemPrompt: string, \n figmaBoilerPlate: string?, \n context: CoderContext,\n) -> WriteFile | ReadFile | EditFile | RunCommand | DeleteFile | Research | Done \n {\n // also this figmaBoilerPlate would be run for the first time iteration\n // that means if ths have any conversation history or chat id then don't call stitch MCP]\n client OpenAIGeneric\n \n prompt #\"\n {{systemPrompt}}\n Whatever else {{context}} carries about the current codebase state.\n \n {% if figmaBoilerPlate %}{{ figmaBoilerPlate }} - Stitch-derived design reference/boilerplate for\n this item, when the item touches UI. Treat this as the source of truth\n for layout and visual structure; implement it, don't redesign it.{% endif %}\n {{ctx.output_format}}\n \"#\n \n}\ntest TestName {\n functions [CoderAgent]\n args {\n systemPrompt #\"\n You are a coder agent and \n \"#\n figmaBoilerPlate \"\"\n context {\n task \"Add a hello world route\"\n dependentSummary []\n repoTree #\"\n hello world\n \"#\n }\n }\n}\n", - "context.baml": "\nclass Decision{\n actor string\n decision string\n accepted string\n}\nclass EpisodicMemory{\n sessionGoal string\n userRequests string[]\n impFacts string[] // inside this session\n decisions string[] // made by LLM and user\n toolResults string[]\n generatedArtifacts string[]\n openTasks string[]\n preferences string[]\n entities string[]\n summary string\n}\n\nclass Message {\n role \"user\" | \"assistant\" | \"toolCall\" | \"system\"\n content string\n timestamp string\n}\nfunction CompressContext(systemPrompt: string, session: string[]) -> EpisodicMemory{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{session}}\n\n {{ctx.output_format}}\n \"#\n}\n\nfunction SummarizeEpisodic(systemPrompt: string, episodicMem: EpisodicMemory) -> string{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{episodicMem}}\n\n {{ctx.output_format}}\n \"#\n}\n// Used in Main agent\nfunction CompactContext(systemPrompt: string, context: Message[]) -> Message[]{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{context}}\n\n {{ctx.output_format}}\n \"#\n}\nfunction SummarizeContext(systemPrompt: string, context: Message[]) -> Message[]{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context object, already past compaction.\n\n {{ctx.output_format}}\n \"#\n}\n// Used in Subagents\nfunction CompactCoderContext(systemPrompt: string, context: CoderContext) -> CoderContext{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context object, segmented.\n\n {{ctx.output_format}}\n \"#\n}\nfunction CompactDebuggerContext(systemPrompt: string, context: DebuggerContext) -> DebuggerContext{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context object, segmented.\n\n {{ctx.output_format}}\n \"#\n}\nfunction SummarizeCoderContext(systemPrompt: string, context: CoderContext) -> CoderContext{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context, already past compaction.\n\n {{ctx.output_format}}\n \"#\n}\nfunction SummarizeDebuggerContext(systemPrompt: string, context: DebuggerContext) -> DebuggerContext{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context, already past compaction.\n\n {{ctx.output_format}}\n \"#\n}\n", - "debuggerAgent.baml": "class Error{\n fileName string\n error string\n source \"tester\" | \"build\" | \"deploy\"?\n}\nclass DebuggingDone{\n action \"done\"\n editedFile FileEdit[]\n errors map\n}\nclass Fixes{\n error string\n fixSummary string\n}\nclass DebuggerContext{\n repoTree string\n originalError string\n fixHistory Fixes[]\n}\n// I'm sending errors at each iteration I guess which is not needed.\nfunction DebuggerAgent(\n systemPrompt: string,\n errors: Error[],\n context: DebuggerContext,\n toolResult: ToolResult?\n) -> ReadFile | RunCommand | WriteFile | EditFile | Research | DebuggingDone{\n \n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{errors}} - what failed: the command that failed and its output,\n possibly already structured into error type, location, message, and candidate causes.\n\n {% if toolResult %}ToolResult: {{toolResult}}{%endif%}\n\n {# {{prior_fix_attempts}} — if this is not your first attempt at this item,\n what was tried before and what happened as a result. A non-empty list\n here means your previous approach did not resolve the issue — read what\n was already tried before proposing another fix. #}\n {{ctx.output_format}}\n \"#\n}", + "coderAgent.baml": "\nclass FetchDocs{\n action \"fetchDocs\"\n query string\n library string // or framework\n}\nclass Done{\n action \"done\"\n filesEdited FileEdit[]\n}\n\nclass CoderContext{\n task string\n dependentSummary TaskSummary[]\n repoTree string\n}\n\nfunction CoderAgent(\n systemPrompt: string, \n figmaBoilerPlate: string?, \n context: CoderContext,\n) -> WriteFile | ReadFile | EditFile | RunCommand | DeleteFile | Research | Done \n {\n // also this figmaBoilerPlate would be run for the first time iteration\n // that means if ths have any conversation history or chat id then don't call stitch MCP]\n client Gemini\n \n prompt #\"\n {{systemPrompt}}\n Whatever else {{context}} carries about the current codebase state.\n \n {% if figmaBoilerPlate %}{{ figmaBoilerPlate }} - Stitch-derived design reference/boilerplate for\n this item, when the item touches UI. Treat this as the source of truth\n for layout and visual structure; implement it, don't redesign it.{% endif %}\n {{ctx.output_format}}\n \"#\n \n}\ntest TestName {\n functions [CoderAgent]\n args {\n systemPrompt #\"\n You are a coder agent and \n \"#\n figmaBoilerPlate \"\"\n context {\n task \"Add a hello world route\"\n dependentSummary []\n repoTree #\"\n hello world\n \"#\n }\n }\n}\n", + "context.baml": "\nclass Decision{\n actor string\n decision string\n accepted string\n}\nclass EpisodicMemory{\n sessionGoal string\n userRequests string[]\n impFacts string[] // inside this session\n decisions string[] // made by LLM and user\n toolResults string[]\n generatedArtifacts string[]\n openTasks string[]\n preferences string[]\n entities string[]\n summary string\n}\n\nclass Message {\n role \"user\" | \"assistant\" | \"toolCall\" | \"system\"\n content string\n timestamp string\n}\nfunction CompressContext(systemPrompt: string, session: string[]) -> EpisodicMemory{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{session}}\n\n {{ctx.output_format}}\n \"#\n}\n\nfunction SummarizeEpisodic(systemPrompt: string, episodicMem: EpisodicMemory) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{episodicMem}}\n\n {{ctx.output_format}}\n \"#\n}\n// Used in Main agent\nfunction CompactContext(systemPrompt: string, context: Message[]) -> Message[]{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}}\n\n {{ctx.output_format}}\n \"#\n}\nfunction SummarizeContext(systemPrompt: string, context: Message[]) -> Message[]{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context object, already past compaction.\n\n {{ctx.output_format}}\n \"#\n}\n// Used in Subagents\nfunction CompactCoderContext(systemPrompt: string, context: CoderContext) -> CoderContext{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context object, segmented.\n\n {{ctx.output_format}}\n \"#\n}\nfunction CompactDebuggerContext(systemPrompt: string, context: DebuggerContext) -> DebuggerContext{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context object, segmented.\n\n {{ctx.output_format}}\n \"#\n}\nfunction SummarizeCoderContext(systemPrompt: string, context: CoderContext) -> CoderContext{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context, already past compaction.\n\n {{ctx.output_format}}\n \"#\n}\nfunction SummarizeDebuggerContext(systemPrompt: string, context: DebuggerContext) -> DebuggerContext{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} - the full context, already past compaction.\n\n {{ctx.output_format}}\n \"#\n}\n", + "debuggerAgent.baml": "class Error{\n fileName string\n error string\n source \"tester\" | \"build\" | \"deploy\"?\n}\nclass DebuggingDone{\n action \"done\"\n editedFile FileEdit[]\n errors map\n}\nclass Fixes{\n error string\n fixSummary string\n}\nclass DebuggerContext{\n repoTree string\n originalError string\n fixHistory Fixes[]\n}\n// I'm sending errors at each iteration I guess which is not needed.\nfunction DebuggerAgent(\n systemPrompt: string,\n errors: Error[],\n context: DebuggerContext,\n toolResult: ToolResult?\n) -> ReadFile | RunCommand | WriteFile | EditFile | Research | DebuggingDone{\n \n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{errors}} - what failed: the command that failed and its output,\n possibly already structured into error type, location, message, and candidate causes.\n\n {% if toolResult %}ToolResult: {{toolResult}}{%endif%}\n\n {# {{prior_fix_attempts}} — if this is not your first attempt at this item,\n what was tried before and what happened as a result. A non-empty list\n here means your previous approach did not resolve the issue — read what\n was already tried before proposing another fix. #}\n {{ctx.output_format}}\n \"#\n}", "generators.baml": "// This helps use auto generate libraries you can use in the language of\n// your choice. You can have multiple generators if you use multiple languages.\n// Just ensure that the output_dir is different for each generator.\ngenerator target {\n // Valid values: \"python/pydantic\", \"typescript\", \"go\", \"rust\", \"ruby/sorbet\", \"rest/openapi\"\n output_type \"typescript\"\n\n // Where the generated code will be saved (relative to baml_src/)\n output_dir \"../\"\n\n // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml).\n // The BAML VSCode extension version should also match this version.\n version \"0.223.0\"\n\n // Valid values: \"sync\", \"async\"\n // This controls what `b.FunctionName()` will be (sync or async).\n default_client_mode async\n}\n", - "mainAgent.baml": "enum ToolType {\n Apify\n Context7\n Tavily\n Stitch\n ReadFile\n WriteFile\n EditFile\n RunCommand\n DeleteFile\n QnA\n}\nclass ToolCall {\n type ToolType\n\n apify Apify?\n context7 Context7?\n tavily Tavily?\n stitch StitchTool?\n readFile ReadFile?\n writeFile WriteFile?\n editFile EditFile?\n runCommand RunCommand?\n deleteFile DeleteFile?\n}\nclass StitchTool {\n prompt string\n userId string\n}\n\nclass Apify {\n urls string[]\n maxPages int\n}\n\nclass Context7 {\n library string\n query string\n}\n\nclass Tavily {\n query string\n maxResults int\n}\nclass LLMResponse{\n stopReason \"completed\" | \"aborted\" | \"toolCall\"\n content string\n toolCall ToolCall?\n questions Question[]?\n} \n\nfunction MainLLMCall(\n systemPrompt: string, \n userPrompt: string, \n context: Message[], \n semanticMem: string, \n design: string?,\n orchestratorContext: string\n ) -> LLMResponse{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the specific, already-clarified request you're\n completing.\n {% if design %} - the design system chosen once at the start of\n this Run (layout, visual language, conventions). Never regenerate or\n second-guess this; treat it as settled. {% endif %}\n {{context}} - is the context of main agent\n {{semanticMem}} - Relevant user context for this build, Use this to calibrate scope, defaults, and how much you ask vs decide.\n {{orchestratorContext}} - relevant current state of the app: files, prior\n decisions, whatever the orchestrator has determined is relevant to this\n task.\n \n {{ctx.output_format}}\n \"#\n}\nfunction GenerateMainAgentSummary(systemPrompt: string, context: Message[]) -> string{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{context}} the turn-by-turn tool-call history for this task so far.\n\n\n {{ctx.output_format}}\n \"#\n}\n\ntest TestName {\n functions [MainLLMCall]\n args {\n systemPrompt #\"\n # ROLE\n\nYou are the main agent for Lovable. You've been assigned a single user\nrequest that the orchestrator has already judged simple enough not to need\nthe full coder/debugger/tester pipeline. You own this task end to end —\nthere is no separate agent checking your work afterward, so you are\nresponsible for verifying it yourself before you consider it finished.\n\n# TOOLS AVAILABLE\n\nYou may use one or more of the following per turn when they're genuinely\nindependent of each other's results; use them one at a time when a later\ncall depends on what an earlier one returns.\n\n- **readFile / writeFile / editFile / deleteFile** — standard file\n operations. Use editFile for a targeted change to part of an existing\n file rather than rewriting the whole thing when the change is localized;\n use writeFile for new files or genuine full-content replacement.\n- **runCommand** — run a build, lint, typecheck, or test command. This is\n your only way to verify your own work — use it before considering the\n task done, not just when something looks wrong.\n- **context7** — authoritative, structured documentation lookup for a\n library or API. Prefer this over tavily when your uncertainty is\n specifically \"what does this library's current interface look like,\"\n since it's the more reliable source for that question.\n- **tavily** — general web search. Use this for anything broader than a\n specific library's documented interface — current best practices, how\n something is commonly done, non-library factual lookups.\n- **apify** — structured extraction from a specific external site when the\n task requires pulling in real external data (e.g. \"add a pricing\n comparison table based on competitor X's site\").\n- **stitch** — design generation, but narrowly: only for a genuinely new UI\n surface that the three original design variants didn't cover. This is not\n for revisiting or tweaking the fixed design from {{fixed_design_context}}.\n If you're not sure whether a surface counts as \"new,\" treat it as covered\n by the existing design and stay consistent with it instead.\n\n# RESPONSIBILITIES\n\n1. Scope discipline: do only what {{task_description}} asks. Don't expand\n into adjacent improvements uninvited.\n2. Explore before you assume: if you're not certain a file's current\n content, read it — don't guess at what's there.\n3. Verify before finishing: run the relevant build/lint/test command via\n runCommand and confirm it passes before treating the task as complete.\n Do not report something as done on the basis of \"this should work.\"\n4. Know your limits: you don't have a debugger loop backing you up. If\n verification keeps failing without you converging on a fix after a\n reasonable number of attempts, stop and state the blocker plainly rather\n than continuing to guess — repeated blind attempts here are more costly\n than they would be in the pipeline path, since nothing catches you.\n5. Signal completion clearly: once the task is done and verified, say so\n explicitly and stop taking further actions.\n\n# CONSTRAINTS\n\n- Never regenerate the fixed design; extend it, don't replace it.\n- Never claim verification passed without having actually run it.\n- Don't reach for apify/tavily/context7 for things you already know with\n confidence — they're for genuine uncertainty, not habit.\n \"#\n userPrompt #\"\n Make a simple todo app with black theme\n \"#\n context []\n semanticMem #\"\n \n \"#\n design null\n orchestratorContext #\"\n \n \"#\n }\n}\n", + "mainAgent.baml": "enum ToolType {\n Apify\n Context7\n Tavily\n Stitch\n ReadFile\n WriteFile\n EditFile\n RunCommand\n DeleteFile\n QnA\n}\nclass ToolCall {\n type ToolType\n\n apify Apify?\n context7 Context7?\n tavily Tavily?\n stitch StitchTool?\n readFile ReadFile?\n writeFile WriteFile?\n editFile EditFile?\n runCommand RunCommand?\n deleteFile DeleteFile?\n}\nclass StitchTool {\n prompt string\n userId string\n}\n\nclass Apify {\n urls string[]\n maxPages int\n}\n\nclass Context7 {\n library string\n query string\n}\n\nclass Tavily {\n query string\n maxResults int\n}\nclass LLMResponse{\n stopReason \"completed\" | \"aborted\" | \"toolCall\"\n content string\n toolCall ToolCall?\n questions Question[]?\n} \n\nfunction MainLLMCall(\n systemPrompt: string, \n userPrompt: string, \n context: Message[], \n semanticMem: string, \n design: string?,\n orchestratorContext: string\n ) -> LLMResponse{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the specific, already-clarified request you're\n completing.\n {% if design %} - the design system chosen once at the start of\n this Run (layout, visual language, conventions). Never regenerate or\n second-guess this; treat it as settled. {% endif %}\n {{context}} - is the context of main agent\n {{semanticMem}} - Relevant user context for this build, Use this to calibrate scope, defaults, and how much you ask vs decide.\n {{orchestratorContext}} - relevant current state of the app: files, prior\n decisions, whatever the orchestrator has determined is relevant to this\n task.\n \n {{ctx.output_format}}\n \"#\n}\nfunction GenerateMainAgentSummary(systemPrompt: string, context: Message[]) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} the turn-by-turn tool-call history for this task so far.\n\n\n {{ctx.output_format}}\n \"#\n}\n\ntest TestName {\n functions [MainLLMCall]\n args {\n systemPrompt #\"\n # ROLE\n\nYou are the main agent for Lovable. You've been assigned a single user\nrequest that the orchestrator has already judged simple enough not to need\nthe full coder/debugger/tester pipeline. You own this task end to end —\nthere is no separate agent checking your work afterward, so you are\nresponsible for verifying it yourself before you consider it finished.\n\n# TOOLS AVAILABLE\n\nYou may use one or more of the following per turn when they're genuinely\nindependent of each other's results; use them one at a time when a later\ncall depends on what an earlier one returns.\n\n- **readFile / writeFile / editFile / deleteFile** — standard file\n operations. Use editFile for a targeted change to part of an existing\n file rather than rewriting the whole thing when the change is localized;\n use writeFile for new files or genuine full-content replacement.\n- **runCommand** — run a build, lint, typecheck, or test command. This is\n your only way to verify your own work — use it before considering the\n task done, not just when something looks wrong.\n- **context7** — authoritative, structured documentation lookup for a\n library or API. Prefer this over tavily when your uncertainty is\n specifically \"what does this library's current interface look like,\"\n since it's the more reliable source for that question.\n- **tavily** — general web search. Use this for anything broader than a\n specific library's documented interface — current best practices, how\n something is commonly done, non-library factual lookups.\n- **apify** — structured extraction from a specific external site when the\n task requires pulling in real external data (e.g. \"add a pricing\n comparison table based on competitor X's site\").\n- **stitch** — design generation, but narrowly: only for a genuinely new UI\n surface that the three original design variants didn't cover. This is not\n for revisiting or tweaking the fixed design from {{fixed_design_context}}.\n If you're not sure whether a surface counts as \"new,\" treat it as covered\n by the existing design and stay consistent with it instead.\n\n# RESPONSIBILITIES\n\n1. Scope discipline: do only what {{task_description}} asks. Don't expand\n into adjacent improvements uninvited.\n2. Explore before you assume: if you're not certain a file's current\n content, read it — don't guess at what's there.\n3. Verify before finishing: run the relevant build/lint/test command via\n runCommand and confirm it passes before treating the task as complete.\n Do not report something as done on the basis of \"this should work.\"\n4. Know your limits: you don't have a debugger loop backing you up. If\n verification keeps failing without you converging on a fix after a\n reasonable number of attempts, stop and state the blocker plainly rather\n than continuing to guess — repeated blind attempts here are more costly\n than they would be in the pipeline path, since nothing catches you.\n5. Signal completion clearly: once the task is done and verified, say so\n explicitly and stop taking further actions.\n\n# CONSTRAINTS\n\n- Never regenerate the fixed design; extend it, don't replace it.\n- Never claim verification passed without having actually run it.\n- Don't reach for apify/tavily/context7 for things you already know with\n confidence — they're for genuine uncertainty, not habit.\n \"#\n userPrompt #\"\n Make a simple todo app with black theme\n \"#\n context []\n semanticMem #\"\n \n \"#\n design null\n orchestratorContext #\"\n \n \"#\n }\n}\n", "planTasks.baml": "\nenum Agent {\n CoderAgent\n DebuggerAgent\n TesterAgent\n UIExpertAgent\n ResearcherAgent\n}\nfunction PlanComplexTask(systemPrompt: string, userPrompt: string, context: string) -> PlannerTodo[]{\n// context here is the orchestrator context sended with main agent, subagent, and planner task\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the request to plan for, already past complexity and\n clarification checks.\n {{context}} - current app state and prior decisions.\n\n {{ctx.output_format}}\n\n \"#\n}\n\ntest TestName {\n functions [PlanComplexTask]\n args {\n systemPrompt #\"\n # ROLE\n\nYou are the planner, invoked when the orchestrator has judged a request\ncomplex enough to need the full pipeline. You decompose the request into\nSubAgentsTodo items for CoderAgent to execute one at a time, plus a\nPlannerTodo summary for the orchestrator to relay to the user in plain\nlanguage.\n\nCoder is the only executor you're planning for. Debugger is invoked\nautomatically and reactively if an item's verification fails — you don't\nplan for it. Research and documentation lookup are tools Coder reaches for\nitself mid-item — you don't plan separate research steps, though you may\nflag an item as research-heavy as a hint.\n\n# DECOMPOSITION PRINCIPLES\n\n- Break work into the smallest units independently verifiable by a build/\n test/lint command. A unit bundling unrelated changes makes it harder to\n isolate what actually failed if verification fails.\n- Order items so that anything a later item structurally depends on comes\n first. Mark items parallel-safe only when they touch genuinely disjoint\n files/surfaces.\n- Don't over-decompose trivial requests into multiple items when one covers\n it.\n- If an item is likely to require nontrivial documentation lookup or web\n research before Coder can implement it confidently, note that as a hint\n in the item — it's still one Coder-executed item, just flagged.\n\n# CONSTRAINTS\n\n- Every item must be independently verifiable by a command Coder can run.\n- Scope what must be true when the item is done, not implementation detail\n that's Coder's own decision to make.\n- If decomposing requires an assumption material enough to change the\n outcome, don't guess — this should have been caught by the complexity\n checker already, but if it wasn't, say so explicitly in the planner\n summary rather than silently picking an interpretation.\n\n \"#\n userPrompt #\"\n Built a very complex todo app with black background.\n\n\n \"#\n context #\"\n Should the todo data be persisted to a local browser database or a backend database with user authentication?\nLocal storage only (browser-based)\n\nWhich advanced feature is the priority for making this 'complex'\nSubtasks, categories, and tags\n\n \"#\n }\n}\n", "qna.baml": "class Question{\n question string\n option string[]\n}\nclass SimpleComplexity{\n complex false\n}\nclass ComplexComplexity{\n complex true\n questions Question[]\n}\ntype ComplexityLevel = SimpleComplexity | ComplexComplexity\nfunction CheckComplexityAndGenerateQuestions(systemPrompt: string, userPrompt: string) -> SimpleComplexity | ComplexComplexity {\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the message to assess.\n {# {{app_context}} — current app state. #}\n {# {{run_stage}} — whether this is the Run's first message (design not yet\n chosen) or a follow-up (design already fixed — never ask design-related\n questions on a follow-up, and don't factor design selection into this\n message's complexity judgment). #}\n\n {{ctx.output_format}}\n \"#\n}\n// class ComplexityLevel{\n// complex bool\n// qnaNeeded bool\n// }\n// function CheckComplexity(userPrompt: string, systemPrompt: string) -> ComplexityLevel{\n\n// client OpenAIGeneric\n// prompt #\"\n// {{systemPrompt}}\n// {{userPrompt}}\n\n// {{ctx.output_format}}\n// \"#\n// }\n\n// function GenerateQuestion(userPrompt: string, systemPrompt: string) -> Question[]{\n\n// client OpenAIGeneric\n// prompt #\"\n// {{systemPrompt}}\n// {{userPrompt}}\n\n// {{ctx.output_format}}\n// \"#\n// }\n\ntest TestName {\n functions [CheckComplexityAndGenerateQuestions]\n args {\n systemPrompt #\"\n # ROLE\n\nYou do two things for every incoming user message in a Run: judge whether\nit's simple enough for the single main-agent path or complex enough to need\nthe full coder/debugger pipeline, and decide whether it can proceed as-is\nor needs clarifying questions first. The complexity verdict is not advisory\n— the orchestrator branches its execution path directly on it.\n\n# COMPLEXITY JUDGMENT\n\nJudge complex when the request plausibly touches multiple files/surfaces,\nintroduces or changes structural/data-model decisions, or is the kind of\nchange where a single generalist pass without a debugger safety net is a\nreal risk of shipping something broken. Judge simple when it's a bounded,\nsingle-surface change a capable generalist could implement and verify\ndirectly — copy changes, small isolated features, single-component fixes.\n\n# CLARIFICATION JUDGMENT\n\nDefault toward proceeding with stated assumptions — asking costs the user a\nfull round trip, and most ambiguity has a reasonable default. Proceed when\na reasonable default exists and a wrong guess would be cheap to redo. Ask\nwhen the request implies a data-model or permissions decision that would be\nexpensive to unwind if guessed wrong, when two plausible interpretations\nwould lead to materially different scopes of work (not just different\ndetails within the same scope), or when the request conflicts with a prior\nstated constraint and it's unclear which should win.\n\nBatch genuinely necessary questions together rather than trickling them out\nturn by turn. Questions must be specific and answerable in one line each —\nnot open-ended.\n\n# CONSTRAINTS\n\n- Complexity and clarification are separate judgments — a request can be\n simple but ambiguous, or complex but unambiguous. Don't conflate them.\n- Never ask about anything resolvable from {{app_context}} or reasonable\n convention.\n- Never revisit design selection on a follow-up message.\n\n \"#\n userPrompt #\"\n Built a very complex todo app with black background.\n \"#\n }\n}", - "subAgents.baml": "class AgentContext{}\n\n// Subagent session map, for generating summary\nfunction GenerateSubagentSummary(systemPrompt: string, subagentType: string, context: SessionMap) -> string{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{subagentType}}\n {{context}}\n\n {{ctx.output_format}}\n \"#\n}\nclass SessionMap {\n coder CoderSession\n debuggerr DebuggerSession\n tester TesterSession\n researcher ResearcherSession\n uiExpert UIExpertSession\n}\n\ntype Role = \"user\" | \"assistant\" | \"tool\"\ntype Status = \"in_progress\" | \"halted\" | \"resolved\" | \"done\"\n\nclass DebuggerSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n rawTranscript string?\n}\n\nclass CoderSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass TesterSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass ResearcherSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass UIExpertSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\n", + "subAgents.baml": "class AgentContext{}\n\n// Subagent session map, for generating summary\nfunction GenerateSubagentSummary(systemPrompt: string, subagentType: string, context: SessionMap) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{subagentType}}\n {{context}}\n\n {{ctx.output_format}}\n \"#\n}\nclass SessionMap {\n coder CoderSession\n debuggerr DebuggerSession\n tester TesterSession\n researcher ResearcherSession\n uiExpert UIExpertSession\n}\n\ntype Role = \"user\" | \"assistant\" | \"tool\"\ntype Status = \"in_progress\" | \"halted\" | \"resolved\" | \"done\"\n\nclass DebuggerSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n rawTranscript string?\n}\n\nclass CoderSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass TesterSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass ResearcherSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass UIExpertSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\ntest TestName {\n functions [GenerateSubagentSummary]\n args {\n systemPrompt #\"\n \n# ROLE\n\nYou summarize a single completed CoderAgent or DebuggerAgent run into a\nshort digest attached to the orchestrator's persistent state. The\norchestrator should never need to read a sub-agent's full action-by-action\ntranscript once this digest exists.\n\n# RESPONSIBILITIES\n\n1. State what actually happened, in terms the orchestrator (and whichever\n item comes next in the plan) can act on.\n2. List files touched, at the path level, with the action taken on each\n (created/modified/deleted).\n3. Note any decision or tradeoff made that a later step should be aware of\n — e.g. \"extended the existing X util rather than creating a new one;\n later items touching X should expect this.\"\n4. State the outcome plainly: success, failure, or needs-input. If failure,\n point at the relevant error signature rather than re-describing the\n error in prose — that detail already lives in the structured error\n report.\n\n# CONSTRAINTS\n\n- Don't re-narrate the reasoning process, only the outcome and what\n downstream steps need to know.\n- Keep this genuinely short — if it's approaching the length of the\n original transcript, it isn't a summary.\n\n \"#\n subagentType #\"\n coder\n \"#\n context {\n coder {\n taskId 1\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n debuggerr {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n rawTranscript null\n }\n tester {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n researcher {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n uiExpert {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n }\n }\n}\n", "testerAgent.baml": "\n\nclass ErrorResponse{\n error string\n file string\n line int\n}\n// function TestCodebase(systemPrompt: string) -> string{\n\n// client \n// }\nfunction ReframeError(systemPrompt: string, error: string) -> ErrorResponse{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{error}} - unstructured stdout/stderr from a failed\nbuild/lint/test command.\n\n\n {{ctx.output_format}}\n \"#\n}", - "uiExpert.baml": "\nclass Design{\n taskId int\n summary string\n}\nclass UIExpertContext{\n userPrompt string\n priorDesigns Design[]\n}\n\nclass DesignVariants{\n prompts string[]\n}\nfunction FramePrompts(systemPrompt: string, userPrompt: string, semanticMem: string) -> DesignVariants{\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - what's being built, already past complexity and\n clarification checks.\n {# {{target_surfaces}} — which pages/components are in initial scope. #}\n\n {{ctx.output_format}}\n \"#\n}\nfunction UIExpertAgent() -> string{\n\n}", + "uiExpert.baml": "\nclass Design{\n taskId int\n summary string\n}\nclass UIExpertContext{\n userPrompt string\n priorDesigns Design[]\n}\n\nclass DesignVariants{\n prompts string[]\n}\nfunction FramePrompts(systemPrompt: string, userPrompt: string, semanticMem: string) -> DesignVariants{\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - what's being built, already past complexity and\n clarification checks.\n {# {{target_surfaces}} — which pages/components are in initial scope. #}\n\n {{ctx.output_format}}\n \"#\n}\nfunction UIExpertAgent() -> string{\n\n}", } export const getBamlFiles = () => { return fileMap; diff --git a/packages/agents/baml_client/parser.ts b/packages/agents/baml_client/parser.ts index 10bbac8..ad0e8f5 100644 --- a/packages/agents/baml_client/parser.ts +++ b/packages/agents/baml_client/parser.ts @@ -23,36 +23,13 @@ import { toBamlError } from "@boundaryml/baml" import type { Checked, Check } from "./types" import type { partial_types } from "./partial_types" import type * as types from "./types" -import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, FinalResponse, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" +import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" import type TypeBuilder from "./type_builder" export class LlmResponseParser { constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {} - BugFinder( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): types.Error[] { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "BugFinder", - llmResponse, - false, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as types.Error[] - } catch (error) { - throw toBamlError(error); - } - } - CheckComplexityAndGenerateQuestions( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } @@ -306,29 +283,6 @@ export class LlmResponseParser { } } - OrchestrateAgent( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): types.FinalResponse { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "OrchestrateAgent", - llmResponse, - false, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as types.FinalResponse - } catch (error) { - throw toBamlError(error); - } - } - OrchestratorSummary( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } @@ -421,29 +375,6 @@ export class LlmResponseParser { } } - StreamOneAgent( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): types.AgentResponse { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "StreamOneAgent", - llmResponse, - false, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as types.AgentResponse - } catch (error) { - throw toBamlError(error); - } - } - SummarizeCoderContext( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } @@ -536,29 +467,6 @@ export class LlmResponseParser { } } - TesterAgent( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): types.TesterResponse { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "TesterAgent", - llmResponse, - false, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as types.TesterResponse - } catch (error) { - throw toBamlError(error); - } - } - UIExpertAgent( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } @@ -588,29 +496,6 @@ export class LlmStreamParser { constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {} - BugFinder( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): partial_types.Error[] { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "BugFinder", - llmResponse, - true, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as partial_types.Error[] - } catch (error) { - throw toBamlError(error); - } - } - CheckComplexityAndGenerateQuestions( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } @@ -864,29 +749,6 @@ export class LlmStreamParser { } } - OrchestrateAgent( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): partial_types.FinalResponse { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "OrchestrateAgent", - llmResponse, - true, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as partial_types.FinalResponse - } catch (error) { - throw toBamlError(error); - } - } - OrchestratorSummary( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } @@ -979,29 +841,6 @@ export class LlmStreamParser { } } - StreamOneAgent( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): partial_types.AgentResponse { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "StreamOneAgent", - llmResponse, - true, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as partial_types.AgentResponse - } catch (error) { - throw toBamlError(error); - } - } - SummarizeCoderContext( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } @@ -1094,29 +933,6 @@ export class LlmStreamParser { } } - TesterAgent( - llmResponse: string, - __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } - ): partial_types.TesterResponse { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - return this.runtime.parseLlmResponse( - "TesterAgent", - llmResponse, - true, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __baml_options__?.clientRegistry, - __env__, - ) as partial_types.TesterResponse - } catch (error) { - throw toBamlError(error); - } - } - UIExpertAgent( llmResponse: string, __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, env?: Record } diff --git a/packages/agents/baml_client/partial_types.ts b/packages/agents/baml_client/partial_types.ts index f088f5b..1bf8037 100644 --- a/packages/agents/baml_client/partial_types.ts +++ b/packages/agents/baml_client/partial_types.ts @@ -20,7 +20,7 @@ $ pnpm add @boundaryml/baml import type { Image, Audio, Pdf, Video } from "@boundaryml/baml" import type { Checked, Check } from "./types" -import type { Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, FinalResponse, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile } from "./types" +import type { Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile } from "./types" import type * as types from "./types" /****************************************************************************** @@ -160,11 +160,6 @@ export namespace partial_types { fileName?: string | null summary?: string | null } - export interface FinalResponse { - status?: "success" | "failed" | null - previewUrl?: string | null - deployUrl?: string | null - } export interface Fixes { error?: string | null fixSummary?: string | null diff --git a/packages/agents/baml_client/sync_client.ts b/packages/agents/baml_client/sync_client.ts index e48d090..cf67c4d 100644 --- a/packages/agents/baml_client/sync_client.ts +++ b/packages/agents/baml_client/sync_client.ts @@ -22,7 +22,7 @@ import type { BamlRuntime, FunctionResult, BamlCtxManager, Image, Audio, Pdf, Vi import { toBamlError, BamlAbortError, ClientRegistry, type HTTPRequest } from "@boundaryml/baml" import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types" import type * as types from "./types" -import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, FinalResponse, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" +import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" import type TypeBuilder from "./type_builder" import { HttpRequest, HttpStreamRequest } from "./sync_request" import { LlmResponseParser, LlmStreamParser } from "./parser" @@ -97,56 +97,6 @@ export class BamlSyncClient { } - BugFinder( - errors: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): types.Error[] { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided and reject for sync operations - if (__options__.onTick) { - throw new Error("onTick is not supported for synchronous functions. Please use the async client instead."); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.callFunctionSync( - "BugFinder", - { - "errors": errors,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.Error[] - } catch (error: any) { - throw toBamlError(error); - } - } - CheckComplexityAndGenerateQuestions( systemPrompt: string,userPrompt: string, __baml_options__?: BamlCallOptions @@ -697,56 +647,6 @@ export class BamlSyncClient { } } - OrchestrateAgent( - systemPrompt: string, - __baml_options__?: BamlCallOptions - ): types.FinalResponse { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided and reject for sync operations - if (__options__.onTick) { - throw new Error("onTick is not supported for synchronous functions. Please use the async client instead."); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.callFunctionSync( - "OrchestrateAgent", - { - "systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.FinalResponse - } catch (error: any) { - throw toBamlError(error); - } - } - OrchestratorSummary( systemPrompt: string,summaries: string[], __baml_options__?: BamlCallOptions @@ -947,56 +847,6 @@ export class BamlSyncClient { } } - StreamOneAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): types.AgentResponse { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided and reject for sync operations - if (__options__.onTick) { - throw new Error("onTick is not supported for synchronous functions. Please use the async client instead."); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.callFunctionSync( - "StreamOneAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.AgentResponse - } catch (error: any) { - throw toBamlError(error); - } - } - SummarizeCoderContext( systemPrompt: string,context: types.CoderContext, __baml_options__?: BamlCallOptions @@ -1197,56 +1047,6 @@ export class BamlSyncClient { } } - TesterAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): types.TesterResponse { - try { - const __options__ = { ...this.bamlOptions, ...(__baml_options__ || {}) } - const __signal__ = __options__.signal; - - if (__signal__?.aborted) { - throw new BamlAbortError('Operation was aborted', __signal__.reason); - } - - // Check if onTick is provided and reject for sync operations - if (__options__.onTick) { - throw new Error("onTick is not supported for synchronous functions. Please use the async client instead."); - } - - const __collector__ = __options__.collector ? (Array.isArray(__options__.collector) ? __options__.collector : [__options__.collector]) : []; - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __options__.clientRegistry; - if (__options__.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__options__.client); - } - - const __raw__ = this.runtime.callFunctionSync( - "TesterAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __options__.tb?.__tb(), - __clientRegistry__, - __collector__, - __options__.tags || {}, - __env__, - __signal__, - __options__.watchers, - ) - return __raw__.parsed(false) as types.TesterResponse - } catch (error: any) { - throw toBamlError(error); - } - } - UIExpertAgent( __baml_options__?: BamlCallOptions diff --git a/packages/agents/baml_client/sync_request.ts b/packages/agents/baml_client/sync_request.ts index 6b1540e..6e338f2 100644 --- a/packages/agents/baml_client/sync_request.ts +++ b/packages/agents/baml_client/sync_request.ts @@ -22,7 +22,7 @@ import type { BamlRuntime, BamlCtxManager, Image, Audio, Pdf, Video } from "@bou import { toBamlError, HTTPRequest, ClientRegistry } from "@boundaryml/baml" import type { Checked, Check } from "./types" import type * as types from "./types" -import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, FinalResponse, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" +import type {Agent, AgentContext, AgentResponse, Apify, ApifyRes, BraveRes, BraveResult, CoderContext, CoderSession, ComplexComplexity, Context7, ContextType, DebuggerContext, DebuggerSession, DebuggingDone, Decision, DeleteFile, Design, DesignVariants, DocsSearch, Done, EditFile, EpisodicMemory, Error, ErrorResponse, FetchDocs, FileEdit, Fixes, ItemRes, LLMResponse, Message, PlannerTodo, Question, ReadFile, Research, ResearcherContext, ResearcherResponse, ResearcherSession, RunCommand, SessionMap, SimpleComplexity, StitchTool, SubAgentsContexts, TaskComplexity, TaskSummary, Tavily, TesterContext, TesterResponse, TesterSession, ToolCall, ToolResult, ToolType, UIExpertContext, UIExpertSession, WebScrape, WebSearch, WriteFile} from "./types" import type TypeBuilder from "./type_builder" import type * as events from "./events" @@ -38,39 +38,6 @@ export class HttpRequest { constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {} - BugFinder( - errors: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "BugFinder", - { - "errors": errors,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - CheckComplexityAndGenerateQuestions( systemPrompt: string,userPrompt: string, __baml_options__?: BamlCallOptions @@ -434,39 +401,6 @@ export class HttpRequest { } } - OrchestrateAgent( - systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "OrchestrateAgent", - { - "systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - OrchestratorSummary( systemPrompt: string,summaries: string[], __baml_options__?: BamlCallOptions @@ -599,39 +533,6 @@ export class HttpRequest { } } - StreamOneAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "StreamOneAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - SummarizeCoderContext( systemPrompt: string,context: types.CoderContext, __baml_options__?: BamlCallOptions @@ -764,39 +665,6 @@ export class HttpRequest { } } - TesterAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "TesterAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - false, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - UIExpertAgent( __baml_options__?: BamlCallOptions @@ -836,39 +704,6 @@ export class HttpStreamRequest { constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {} - BugFinder( - errors: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "BugFinder", - { - "errors": errors,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - CheckComplexityAndGenerateQuestions( systemPrompt: string,userPrompt: string, __baml_options__?: BamlCallOptions @@ -1232,39 +1067,6 @@ export class HttpStreamRequest { } } - OrchestrateAgent( - systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "OrchestrateAgent", - { - "systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - OrchestratorSummary( systemPrompt: string,summaries: string[], __baml_options__?: BamlCallOptions @@ -1397,39 +1199,6 @@ export class HttpStreamRequest { } } - StreamOneAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "StreamOneAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - SummarizeCoderContext( systemPrompt: string,context: types.CoderContext, __baml_options__?: BamlCallOptions @@ -1562,39 +1331,6 @@ export class HttpStreamRequest { } } - TesterAgent( - userPrompt: string,systemPrompt: string, - __baml_options__?: BamlCallOptions - ): HTTPRequest { - try { - const __rawEnv__ = __baml_options__?.env ? { ...process.env, ...__baml_options__.env } : { ...process.env }; - const __env__: Record = Object.fromEntries( - Object.entries(__rawEnv__).filter(([_, value]) => value !== undefined) as [string, string][] - ); - - // Resolve client option to clientRegistry (client takes precedence) - let __clientRegistry__ = __baml_options__?.clientRegistry; - if (__baml_options__?.client) { - __clientRegistry__ = __clientRegistry__ || new ClientRegistry(); - __clientRegistry__.setPrimary(__baml_options__.client); - } - - return this.runtime.buildRequestSync( - "TesterAgent", - { - "userPrompt": userPrompt,"systemPrompt": systemPrompt - }, - this.ctxManager.cloneContext(), - __baml_options__?.tb?.__tb(), - __clientRegistry__, - true, - __env__, - ) - } catch (error) { - throw toBamlError(error); - } - } - UIExpertAgent( __baml_options__?: BamlCallOptions diff --git a/packages/agents/baml_client/type_builder.ts b/packages/agents/baml_client/type_builder.ts index c6aa1c8..ce57d34 100644 --- a/packages/agents/baml_client/type_builder.ts +++ b/packages/agents/baml_client/type_builder.ts @@ -77,8 +77,6 @@ export default class TypeBuilder { FileEdit: ClassViewer<'FileEdit', "fileName" | "summary">; - FinalResponse: ClassViewer<'FinalResponse', "status" | "previewUrl" | "deployUrl">; - Fixes: ClassViewer<'Fixes', "error" | "fixSummary">; ItemRes: ClassViewer<'ItemRes', "title" | "description" | "url">; @@ -148,7 +146,7 @@ export default class TypeBuilder { constructor() { this.tb = new _TypeBuilder({ classes: new Set([ - "AgentContext","AgentResponse","Apify","ApifyRes","BraveRes","BraveResult","CoderContext","CoderSession","ComplexComplexity","Context7","DebuggerContext","DebuggerSession","DebuggingDone","Decision","DeleteFile","Design","DesignVariants","DocsSearch","Done","EditFile","EpisodicMemory","Error","ErrorResponse","FetchDocs","FileEdit","FinalResponse","Fixes","ItemRes","LLMResponse","Message","PlannerTodo","Question","ReadFile","Research","ResearcherContext","ResearcherResponse","ResearcherSession","RunCommand","SessionMap","SimpleComplexity","StitchTool","SubAgentsContexts","TaskComplexity","TaskSummary","Tavily","TesterContext","TesterResponse","TesterSession","ToolCall","ToolResult","UIExpertContext","UIExpertSession","WebScrape","WebSearch","WriteFile", + "AgentContext","AgentResponse","Apify","ApifyRes","BraveRes","BraveResult","CoderContext","CoderSession","ComplexComplexity","Context7","DebuggerContext","DebuggerSession","DebuggingDone","Decision","DeleteFile","Design","DesignVariants","DocsSearch","Done","EditFile","EpisodicMemory","Error","ErrorResponse","FetchDocs","FileEdit","Fixes","ItemRes","LLMResponse","Message","PlannerTodo","Question","ReadFile","Research","ResearcherContext","ResearcherResponse","ResearcherSession","RunCommand","SessionMap","SimpleComplexity","StitchTool","SubAgentsContexts","TaskComplexity","TaskSummary","Tavily","TesterContext","TesterResponse","TesterSession","ToolCall","ToolResult","UIExpertContext","UIExpertSession","WebScrape","WebSearch","WriteFile", ]), enums: new Set([ "Agent","ContextType","ToolType", @@ -256,10 +254,6 @@ export default class TypeBuilder { "fileName","summary", ]); - this.FinalResponse = this.tb.classViewer("FinalResponse", [ - "status","previewUrl","deployUrl", - ]); - this.Fixes = this.tb.classViewer("Fixes", [ "error","fixSummary", ]); diff --git a/packages/agents/baml_client/types.ts b/packages/agents/baml_client/types.ts index 88279f5..fa439f9 100644 --- a/packages/agents/baml_client/types.ts +++ b/packages/agents/baml_client/types.ts @@ -250,13 +250,6 @@ export interface FileEdit { } -export interface FinalResponse { - status: "success" | "failed" - previewUrl?: string | null - deployUrl?: string | null - -} - export interface Fixes { error: string fixSummary: string diff --git a/packages/agents/baml_src/agents.baml b/packages/agents/baml_src/agents.baml index 203dfd0..1aed8b4 100644 --- a/packages/agents/baml_src/agents.baml +++ b/packages/agents/baml_src/agents.baml @@ -47,33 +47,8 @@ class TesterResponse{ } -function StreamOneAgent(userPrompt: string, systemPrompt: string) -> AgentResponse{ - - client OpenAIGeneric - prompt #" - {{systemPrompt}} - {{userPrompt}} - - {{ctx.output_format}} - "# -} - -class FinalResponse{ - status "success" | "failed" - previewUrl string? - deployUrl string? -} -function OrchestrateAgent(systemPrompt: string) -> FinalResponse{ - client OpenAIGeneric - prompt #" - {{systemPrompt}} - - {{ctx.output_format}} - "# - -} function ResearchAgent(query: string, systemPrompt: string, searchWay: string) -> ResearcherResponse{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{query}} @@ -84,28 +59,7 @@ function ResearchAgent(query: string, systemPrompt: string, searchWay: string) - } -function BugFinder(errors: string, systemPrompt: string) -> Error[]{ - client OpenAIGeneric - prompt #" - {{systemPrompt}} - {{errors}} - - {{ctx.output_format}} - "# -} - -function TesterAgent(userPrompt: string, systemPrompt: string, ) -> TesterResponse{ - // just compare the concised version of whatever is built till now and the actual user prompt - // then find the similarty score of both, if > 75 then okay - // else loop in again the coder for fixing this. - client OpenAIGeneric - prompt #" - {{systemPrompt}} - {{userPrompt}} - {{ctx.output_format}} - "# -} class PlannerTodo{ id int task string @@ -197,7 +151,7 @@ type SubAgentsContext = CoderContext | DebuggerContext | TesterContext | Researc function OrchestratorSummary(systemPrompt: string, summaries: string[]) -> string{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{summaries}} - full Run history: the original request, the diff --git a/packages/agents/baml_src/coderAgent.baml b/packages/agents/baml_src/coderAgent.baml index 9447ab3..c8fbfc3 100644 --- a/packages/agents/baml_src/coderAgent.baml +++ b/packages/agents/baml_src/coderAgent.baml @@ -23,7 +23,7 @@ function CoderAgent( { // also this figmaBoilerPlate would be run for the first time iteration // that means if ths have any conversation history or chat id then don't call stitch MCP] - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} diff --git a/packages/agents/baml_src/context.baml b/packages/agents/baml_src/context.baml index 4db3941..5007c38 100644 --- a/packages/agents/baml_src/context.baml +++ b/packages/agents/baml_src/context.baml @@ -24,7 +24,7 @@ class Message { } function CompressContext(systemPrompt: string, session: string[]) -> EpisodicMemory{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{session}} @@ -35,7 +35,7 @@ function CompressContext(systemPrompt: string, session: string[]) -> EpisodicMem function SummarizeEpisodic(systemPrompt: string, episodicMem: EpisodicMemory) -> string{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{episodicMem}} @@ -46,7 +46,7 @@ function SummarizeEpisodic(systemPrompt: string, episodicMem: EpisodicMemory) -> // Used in Main agent function CompactContext(systemPrompt: string, context: Message[]) -> Message[]{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{context}} @@ -56,7 +56,7 @@ function CompactContext(systemPrompt: string, context: Message[]) -> Message[]{ } function SummarizeContext(systemPrompt: string, context: Message[]) -> Message[]{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{context}} - the full context object, already past compaction. @@ -67,7 +67,7 @@ function SummarizeContext(systemPrompt: string, context: Message[]) -> Message[] // Used in Subagents function CompactCoderContext(systemPrompt: string, context: CoderContext) -> CoderContext{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{context}} - the full context object, segmented. @@ -77,7 +77,7 @@ function CompactCoderContext(systemPrompt: string, context: CoderContext) -> Cod } function CompactDebuggerContext(systemPrompt: string, context: DebuggerContext) -> DebuggerContext{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{context}} - the full context object, segmented. @@ -87,7 +87,7 @@ function CompactDebuggerContext(systemPrompt: string, context: DebuggerContext) } function SummarizeCoderContext(systemPrompt: string, context: CoderContext) -> CoderContext{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{context}} - the full context, already past compaction. @@ -97,7 +97,7 @@ function SummarizeCoderContext(systemPrompt: string, context: CoderContext) -> C } function SummarizeDebuggerContext(systemPrompt: string, context: DebuggerContext) -> DebuggerContext{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{context}} - the full context, already past compaction. diff --git a/packages/agents/baml_src/debuggerAgent.baml b/packages/agents/baml_src/debuggerAgent.baml index 24c4626..b3b8da9 100644 --- a/packages/agents/baml_src/debuggerAgent.baml +++ b/packages/agents/baml_src/debuggerAgent.baml @@ -25,7 +25,7 @@ function DebuggerAgent( toolResult: ToolResult? ) -> ReadFile | RunCommand | WriteFile | EditFile | Research | DebuggingDone{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{errors}} - what failed: the command that failed and its output, diff --git a/packages/agents/baml_src/mainAgent.baml b/packages/agents/baml_src/mainAgent.baml index 0ea2c6f..dc94ac5 100644 --- a/packages/agents/baml_src/mainAgent.baml +++ b/packages/agents/baml_src/mainAgent.baml @@ -77,7 +77,7 @@ function MainLLMCall( } function GenerateMainAgentSummary(systemPrompt: string, context: Message[]) -> string{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{context}} the turn-by-turn tool-call history for this task so far. diff --git a/packages/agents/baml_src/subAgents.baml b/packages/agents/baml_src/subAgents.baml index 31ab530..efc458b 100644 --- a/packages/agents/baml_src/subAgents.baml +++ b/packages/agents/baml_src/subAgents.baml @@ -3,7 +3,7 @@ class AgentContext{} // Subagent session map, for generating summary function GenerateSubagentSummary(systemPrompt: string, subagentType: string, context: SessionMap) -> string{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{subagentType}} @@ -73,4 +73,95 @@ class UIExpertSession { content string? } +test TestName { + functions [GenerateSubagentSummary] + args { + systemPrompt #" + +# ROLE +You summarize a single completed CoderAgent or DebuggerAgent run into a +short digest attached to the orchestrator's persistent state. The +orchestrator should never need to read a sub-agent's full action-by-action +transcript once this digest exists. + +# RESPONSIBILITIES + +1. State what actually happened, in terms the orchestrator (and whichever + item comes next in the plan) can act on. +2. List files touched, at the path level, with the action taken on each + (created/modified/deleted). +3. Note any decision or tradeoff made that a later step should be aware of + — e.g. "extended the existing X util rather than creating a new one; + later items touching X should expect this." +4. State the outcome plainly: success, failure, or needs-input. If failure, + point at the relevant error signature rather than re-describing the + error in prose — that detail already lives in the structured error + report. + +# CONSTRAINTS + +- Don't re-narrate the reasoning process, only the outcome and what + downstream steps need to know. +- Keep this genuinely short — if it's approaching the length of the + original transcript, it isn't a summary. + + "# + subagentType #" + coder + "# + context { + coder { + taskId 1 + role "user" + status "in_progress" + iterationCount 123 + timestamp #" + hello world + "# + content null + } + debuggerr { + taskId 123 + role "user" + status "in_progress" + iterationCount 123 + timestamp #" + hello world + "# + content null + rawTranscript null + } + tester { + taskId 123 + role "user" + status "in_progress" + iterationCount 123 + timestamp #" + hello world + "# + content null + } + researcher { + taskId 123 + role "user" + status "in_progress" + iterationCount 123 + timestamp #" + hello world + "# + content null + } + uiExpert { + taskId 123 + role "user" + status "in_progress" + iterationCount 123 + timestamp #" + hello world + "# + content null + } + } + } +} diff --git a/packages/agents/baml_src/uiExpert.baml b/packages/agents/baml_src/uiExpert.baml index 9b31964..09c4b56 100644 --- a/packages/agents/baml_src/uiExpert.baml +++ b/packages/agents/baml_src/uiExpert.baml @@ -12,7 +12,7 @@ class DesignVariants{ prompts string[] } function FramePrompts(systemPrompt: string, userPrompt: string, semanticMem: string) -> DesignVariants{ - client OpenAIGeneric + client Gemini prompt #" {{systemPrompt}} {{userPrompt}} - what's being built, already past complexity and From 8b8809f91d174aa5f8e6ff2c558eac9b19532454 Mon Sep 17 00:00:00 2001 From: Ashu463 Date: Wed, 22 Jul 2026 14:28:59 +0530 Subject: [PATCH 2/3] Refactoring during testing, gonna refactor tools/skills to the agents --- .../migration.sql | 11 ++++ apps/backend/prisma/schema.prisma | 7 --- apps/backend/src/modules/sessions.ts | 59 ++++++++++++------- packages/agents/agent/agent.ts | 11 ++-- packages/agents/agent/mainAgent.ts | 4 +- packages/agents/agent/subAgent.ts | 27 +++++---- packages/agents/agent/subagents/researcher.ts | 8 +-- packages/agents/agent/subagents/tester.ts | 9 ++- packages/agents/agent/subagents/uiExpert.ts | 4 +- packages/agents/agent/tools/stitch.ts | 8 +-- packages/agents/agent/tools/test.ts | 2 +- packages/agents/agent/utils/sandbox.ts | 32 +++++----- packages/agents/baml_client/async_client.ts | 10 ++-- packages/agents/baml_client/async_request.ts | 8 +-- packages/agents/baml_client/inlinedbaml.ts | 2 +- packages/agents/baml_client/sync_client.ts | 4 +- packages/agents/baml_client/sync_request.ts | 8 +-- packages/agents/baml_src/subAgents.baml | 4 +- 18 files changed, 126 insertions(+), 92 deletions(-) create mode 100644 apps/backend/prisma/migrations/20260722054651_drop_unused_session_model/migration.sql diff --git a/apps/backend/prisma/migrations/20260722054651_drop_unused_session_model/migration.sql b/apps/backend/prisma/migrations/20260722054651_drop_unused_session_model/migration.sql new file mode 100644 index 0000000..7c4de6d --- /dev/null +++ b/apps/backend/prisma/migrations/20260722054651_drop_unused_session_model/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - You are about to drop the `Session` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- AlterTable +ALTER TABLE "User" ALTER COLUMN "semanticMem" SET DEFAULT ''; + +-- DropTable +DROP TABLE "Session"; diff --git a/apps/backend/prisma/schema.prisma b/apps/backend/prisma/schema.prisma index b640d23..2b3ec89 100644 --- a/apps/backend/prisma/schema.prisma +++ b/apps/backend/prisma/schema.prisma @@ -181,11 +181,4 @@ model RunEvent { createdAt DateTime @default(now()) @@index([runId, createdAt]) -} - -model Session{ - id String @id @default(uuid()) - session Json[] - context Json[] - iteration Int } \ No newline at end of file diff --git a/apps/backend/src/modules/sessions.ts b/apps/backend/src/modules/sessions.ts index c8211e5..6b79332 100644 --- a/apps/backend/src/modules/sessions.ts +++ b/apps/backend/src/modules/sessions.ts @@ -3,6 +3,7 @@ import { internalAuth } from "./middleware"; import { prisma } from "../prisma"; import { randomUUIDv7 } from "bun"; import type { OrchestratorEvent } from "../../../../packages/agents"; +import { logger } from "./utils"; /* POST /internal/sessions/:runId/events @@ -16,34 +17,52 @@ sessionRouter.post('/:runId/events', internalAuth, async (req: Request, res: Res const event: OrchestratorEvent = req.body if(typeof runId !== 'string'){ - return res.send({message: `Invalid runId type`}).status(400) + return res.status(400).json({success: false, message: `Invalid runId type`}) + } + + try{ + await prisma.runEvent.create({data: { + id: randomUUIDv7(), + runId: runId, + type: event.type, + createdAt: new Date(), + }}) + return res.status(200).json({success: true, message: `event saved`}) + } catch(e){ + logger.error(`Failed to save event for run ${runId}: ${e}`) + return res.status(500).json({success: false, message: `Internal server error`}) } - const db = await prisma.runEvent.create({data: { - id: randomUUIDv7(), - runId: runId, - type: event.type, - createdAt: new Date(), - }}) - - return res.status(200).json({success: true, message: `event saved`}) }) +// Run already carries dedicated snapshot columns for exactly this — no +// separate table needed. Both fields are `String? @db.Text`, so the +// snapshots (which can be arrays or single objects depending on the caller) +// must arrive JSON.stringify'd; we don't re-stringify here since that'd +// double-encode whatever the caller already sent. sessionRouter.post('/:runId/state', internalAuth, async (req: Request, res: Response) =>{ - const {runId} = req.params - const data = req.body + const {context_snapshot, session_snapshot, iteration} = req.body as { + context_snapshot?: string, session_snapshot?: string, iteration?: number + } if(typeof runId !== 'string'){ - return res.send({message: `Invalid runId type`}).status(400) + return res.status(400).json({success: false, message: `Invalid runId type`}) + } + + try{ + await prisma.run.update({ + where: {id: runId}, + data: { + contextSnapshot: context_snapshot, + sessionSnapshot: session_snapshot, + currentStep: iteration !== undefined ? String(iteration) : undefined, + } + }) + return res.status(200).json({success: true, message: `session and context state saved`}) + } catch(e){ + logger.error(`Failed to save session state for run ${runId}: ${e}`) + return res.status(500).json({success: false, message: `Internal server error`}) } - const db = await prisma.session.create({data: { - id: randomUUIDv7(), - session: data.session_snapshot, - context: data.context_snapshot, - iteration: data.iteration - }}) - - return res.status(200).json({success: true, message: `session and context state to db`}) }) export default sessionRouter; \ No newline at end of file diff --git a/packages/agents/agent/agent.ts b/packages/agents/agent/agent.ts index 70ffe08..0940202 100644 --- a/packages/agents/agent/agent.ts +++ b/packages/agents/agent/agent.ts @@ -169,7 +169,7 @@ export class OrchestratorAgent{ const savedQuestions = questionRes.data.data const questions: Question[] = savedQuestions.map((q) => ({question: q.question, option: q.options})) const designs = designRes.data.data - logger.info(`${questions} and ${designs} are response from backend`) + logger.info(`Fetched ${questions.length} saved question(s) and ${designs.length} saved design(s)`) if(answers){ logger.info(`Answer added to user prompt`) userPrompt += `Answers for these ${questions} are: ${answers}` @@ -330,19 +330,18 @@ export class OrchestratorAgent{ let summaries: string[] = [] for(let i = 0 ; i < sequentialTodos.length; i++){ - logger.info(`Starting task ${sequentialTodos[i]?.task}`) const todo = sequentialTodos[i]; + logger.info(`Task ${todo?.id}: ${todo?.task}`) // #TODO: Failure handling of planner if (!todo?.agent){ - console.warn(`This ${todo} is not assigned with any agent.`) + logger.warn(`Task ${todo?.id} has no agent assigned, stopping DAG execution`) break; } const agentType = todo?.agent const input = this.inputBuilders[agentType](todo, this.context, this.state, this.semanticMem) - logger.info(`${input} is the input made for ${agentType}`) const subagent = new SubAgent(agentType, input, this.userId, this.projectId, this.runId, this.sandbox, this.selectedDesign) - logger.info(`Starting runloop for the subagent`) + logger.info(`Starting runloop for ${agentType} (task ${todo.id})`) const result = await subagent.runLoop() summaries.push(result.summary) @@ -479,7 +478,7 @@ export class OrchestratorAgent{ } } catch(e){ - console.error(e) + logger.error(`TesterDebuggerLoop failed: ${e}`) return{ success: false, summaries, diff --git a/packages/agents/agent/mainAgent.ts b/packages/agents/agent/mainAgent.ts index 7c84d6e..f306d34 100644 --- a/packages/agents/agent/mainAgent.ts +++ b/packages/agents/agent/mainAgent.ts @@ -228,8 +228,8 @@ export class MainAgent{ async saveSessionState(){ try{ await axios.post(`${BACKEND_URL}/internal/session/${this.runId}/state`, { - context_snapshot: this.context, - session_snapshot: this.session, + context_snapshot: JSON.stringify(this.context), + session_snapshot: JSON.stringify(this.session), iteration: this.iterations, }, { headers: internalAuthHeader(), diff --git a/packages/agents/agent/subAgent.ts b/packages/agents/agent/subAgent.ts index 75f24c1..6d3075d 100644 --- a/packages/agents/agent/subAgent.ts +++ b/packages/agents/agent/subAgent.ts @@ -71,10 +71,16 @@ export class SubAgent { return this.agentType === 'tester' || this.agentType === 'researcher' || this.agentType === 'uiExpert' } + private summarizeToolCall(res: any): string { + if (!res || typeof res !== 'object') return String(res) + if (res.path) return `${res.action}:${res.path}` + if (res.command) return `${res.action}:${res.command}` + if (res.filesEdited) return `${res.action} (${res.filesEdited.length} file(s))` + return String(res.action ?? 'unknown') + } + async runLoop(): Promise { - logger.info(`Building context for ${this.agentType}`) this.context = await this.BuildInitialContext() - logger.info(`${this.context} is the context for ${this.agentType}`) let success = true while (true) { @@ -89,22 +95,21 @@ export class SubAgent { break } if(res.stopReason === 'aborted'){ - logger.info(`Aborted`) + logger.warn(`${this.agentType} aborted at iteration ${this.iteration}`) this.pushSession('assistant', 'halted', res) await this.SaveSessionState() success = false break; } - logger.info(`Executing tool call, ${res}`) + logger.info(`${this.agentType} tool call: ${this.summarizeToolCall(res)}`) const toolRes = await this.agentInstance.executeFunction(res) this.pushSession('assistant', 'in_progress', res) this.pushSession('tool', 'done', toolRes) this.context = await this.ManageContext(toolRes) - logger.info(`${toolRes}, is the tool res.`) await this.emitSSEUpdate(toolRes) - this.SaveSessionState().catch(err => console.error(`Failed to save session for task ${this.taskId}`, err)) + this.SaveSessionState().catch(err => logger.error(`Failed to save session for task ${this.taskId}: ${err}`)) this.iteration++ if (this.iteration >= this.maxIterations()) { @@ -199,9 +204,9 @@ export class SubAgent { // #CRITICAL: See session map of baml side and here agent side are not imported from same direction // so might cause some issue here. // Fix for it is store stringified version of whatever thing you want to save - return await b.GenerateSubagentSummary(SUBAGENT_SUMMARY_PROMPT, this.agentType, this.session as unknown as SessionMap) + return await b.GenerateSubagentSummary(SUBAGENT_SUMMARY_PROMPT, this.agentType, JSON.stringify(this.session)) } catch (e) { - console.error("Error occurred while generating summary") + logger.error(`Error occurred while generating summary for ${this.agentType}: ${e}`) throw e } } @@ -250,14 +255,14 @@ export class SubAgent { try{ await axios.post(`${BACKEND_URL}/internal/session/${this.runId}/state`, { iteration: this.iteration, - context_snapshot: this.context, - session_snapshot: this.session + context_snapshot: JSON.stringify(this.context), + session_snapshot: JSON.stringify(this.session) }, { headers: internalAuthHeader(), timeout: 5000, }) } catch(e){ - console.error(`Failed to save session state for task ${this.taskId}:`, e) + logger.error(`Failed to save session state for task ${this.taskId}: ${e}`) } } } \ No newline at end of file diff --git a/packages/agents/agent/subagents/researcher.ts b/packages/agents/agent/subagents/researcher.ts index a661687..d9b1852 100644 --- a/packages/agents/agent/subagents/researcher.ts +++ b/packages/agents/agent/subagents/researcher.ts @@ -32,10 +32,10 @@ export class Researcher extends BaseAgent { @@ -74,7 +77,7 @@ export class TesterAgent extends BaseAgent { try{ const res = await b.FramePrompts(UI_VARIANTS_PROMPT, request.userPrompt, request.semanticMem) - logger.info(`Design variant prompts: ${JSON.stringify(res)}`) + logger.info(`Framed ${res.prompts.length} design variant prompt(s)`) return res } catch(e){ - console.error(e) + logger.error(`Failed to frame design variant prompts: ${e}`) throw e } } diff --git a/packages/agents/agent/tools/stitch.ts b/packages/agents/agent/tools/stitch.ts index 77631b4..12faea6 100644 --- a/packages/agents/agent/tools/stitch.ts +++ b/packages/agents/agent/tools/stitch.ts @@ -1,4 +1,5 @@ import { Screen, stitch } from "@google/stitch-sdk"; +import { logger } from "../utils/logger"; type CreateProjectResult = { name: string; // "projects/5539700355047826969" @@ -13,8 +14,6 @@ export async function makeOneScreen(prompt: string, userId: string): Promise 0) { - console.log(`Restoring ${files.length} files from R2`) + logger.info(`Restoring ${files.length} files from R2`) for (const key of files) { const relativePath = key.replace(this.r2.filesPrefix(this.userId, this.projectId), '') @@ -65,9 +66,9 @@ export class E2BSandbox{ }) } - console.log('Restore complete') + logger.info('Restore complete') } else { - console.log('Bootstrapping fresh sandbox') + logger.info('Bootstrapping fresh sandbox') await this.sandbox.commands.run(`mkdir -p ${PROJECT_ROOT}`) @@ -83,11 +84,11 @@ export class E2BSandbox{ const install = await this.sandbox.commands.run('npm install', { cwd: PROJECT_ROOT }) if (install.exitCode !== 0) { - console.error('npm install failed:', install.stderr) + logger.error(`npm install failed: ${install.stderr}`) throw new Error('Bootstrap failed: npm install did not succeed') } - console.log('Bootstrap complete, sandboxId:', this.sandboxId) + logger.info(`Bootstrap complete, sandboxId: ${this.sandboxId}`) await this.SyncR2() } @@ -108,7 +109,7 @@ export class E2BSandbox{ } catch(e){ - console.warn(e) + logger.error(`Failed to generate repo tree: ${e}`) throw new Error(`Error occurred while generating repository tree`) } } @@ -117,21 +118,23 @@ export class E2BSandbox{ // const homeDir = if(payload.action === 'read'){ + const path = this.resolvePath(payload.path) try{ - const result: string = await this.sandbox.files.read(this.resolvePath(payload.path)) + const result: string = await this.sandbox.files.read(path) return { success: true, content: result } } catch(e){ - console.warn(e) + logger.error(`Failed to read ${path}: ${e}`) throw new Error("Error occured while reading from sandbox file") } } else if(payload.action === 'writeFile'){ + const path = this.resolvePath(payload.path) try{ - const writeRes = await this.sandbox.files.write(this.resolvePath(payload.path), payload.content) + const writeRes = await this.sandbox.files.write(path, payload.content) return { success: true, @@ -139,7 +142,7 @@ export class E2BSandbox{ } } catch(e){ - console.warn(e) + logger.error(`Failed to write ${path}: ${e}`) throw new Error("Error occurred while executing write sandbox file") } } @@ -147,8 +150,9 @@ export class E2BSandbox{ throw new Error(`To be implemented don't call this please`) } else if(payload.action === 'delete'){ + const path = this.resolvePath(payload.path) try{ - const deleteRes = await this.sandbox.files.remove(this.resolvePath(payload.path)) + const deleteRes = await this.sandbox.files.remove(path) return { success: true, @@ -156,7 +160,7 @@ export class E2BSandbox{ } } catch(e){ - console.warn(e) + logger.error(`Failed to delete ${path}: ${e}`) throw new Error("Error occurred while executing deleting sandbox file") } } @@ -169,7 +173,7 @@ export class E2BSandbox{ if(cmdRes.exitCode !== 0){ return { - success: false, + success: false, content: cmdRes.stderr || cmdRes.stdout } } @@ -181,7 +185,7 @@ export class E2BSandbox{ } } catch(e){ - console.warn(e) + logger.error(`Failed to run command "${payload.command}": ${e}`) throw new Error("Error occurred while executing sandbox cmd") } } diff --git a/packages/agents/baml_client/async_client.ts b/packages/agents/baml_client/async_client.ts index 537786a..222d587 100644 --- a/packages/agents/baml_client/async_client.ts +++ b/packages/agents/baml_client/async_client.ts @@ -602,7 +602,7 @@ export type RecursivePartialNull = MovedRecursivePartialNull } async GenerateSubagentSummary( - systemPrompt: string,subagentType: string,context: types.SessionMap, + systemPrompt: string,subagentType: string,session: string, __baml_options__?: BamlCallOptions ): Promise { try { @@ -616,7 +616,7 @@ export type RecursivePartialNull = MovedRecursivePartialNull // Check if onTick is provided - route through streaming if so if (__options__.onTick) { const __stream__ = this.stream.GenerateSubagentSummary( - systemPrompt,subagentType,context, + systemPrompt,subagentType,session, __baml_options__ ); @@ -640,7 +640,7 @@ export type RecursivePartialNull = MovedRecursivePartialNull const __raw__ = await this.runtime.callFunction( "GenerateSubagentSummary", { - "systemPrompt": systemPrompt,"subagentType": subagentType,"context": context + "systemPrompt": systemPrompt,"subagentType": subagentType,"session": session }, this.ctxManager.cloneContext(), __options__.tb?.__tb(), @@ -1898,7 +1898,7 @@ export type RecursivePartialNull = MovedRecursivePartialNull } GenerateSubagentSummary( - systemPrompt: string,subagentType: string,context: types.SessionMap, + systemPrompt: string,subagentType: string,session: string, __baml_options__?: BamlCallOptions ): BamlStream { @@ -1947,7 +1947,7 @@ export type RecursivePartialNull = MovedRecursivePartialNull const __raw__ = this.runtime.streamFunction( "GenerateSubagentSummary", { - "systemPrompt": systemPrompt,"subagentType": subagentType,"context": context + "systemPrompt": systemPrompt,"subagentType": subagentType,"session": session }, undefined, this.ctxManager.cloneContext(), diff --git a/packages/agents/baml_client/async_request.ts b/packages/agents/baml_client/async_request.ts index 7f0bc0a..f44e61c 100644 --- a/packages/agents/baml_client/async_request.ts +++ b/packages/agents/baml_client/async_request.ts @@ -340,7 +340,7 @@ env?: Record } async GenerateSubagentSummary( - systemPrompt: string,subagentType: string,context: types.SessionMap, + systemPrompt: string,subagentType: string,session: string, __baml_options__?: BamlCallOptions ): Promise { try { @@ -359,7 +359,7 @@ env?: Record return await this.runtime.buildRequest( "GenerateSubagentSummary", { - "systemPrompt": systemPrompt,"subagentType": subagentType,"context": context + "systemPrompt": systemPrompt,"subagentType": subagentType,"session": session }, this.ctxManager.cloneContext(), __baml_options__?.tb?.__tb(), @@ -1006,7 +1006,7 @@ env?: Record } async GenerateSubagentSummary( - systemPrompt: string,subagentType: string,context: types.SessionMap, + systemPrompt: string,subagentType: string,session: string, __baml_options__?: BamlCallOptions ): Promise { try { @@ -1025,7 +1025,7 @@ env?: Record return await this.runtime.buildRequest( "GenerateSubagentSummary", { - "systemPrompt": systemPrompt,"subagentType": subagentType,"context": context + "systemPrompt": systemPrompt,"subagentType": subagentType,"session": session }, this.ctxManager.cloneContext(), __baml_options__?.tb?.__tb(), diff --git a/packages/agents/baml_client/inlinedbaml.ts b/packages/agents/baml_client/inlinedbaml.ts index f17bf7f..1402e9c 100644 --- a/packages/agents/baml_client/inlinedbaml.ts +++ b/packages/agents/baml_client/inlinedbaml.ts @@ -29,7 +29,7 @@ const fileMap = { "mainAgent.baml": "enum ToolType {\n Apify\n Context7\n Tavily\n Stitch\n ReadFile\n WriteFile\n EditFile\n RunCommand\n DeleteFile\n QnA\n}\nclass ToolCall {\n type ToolType\n\n apify Apify?\n context7 Context7?\n tavily Tavily?\n stitch StitchTool?\n readFile ReadFile?\n writeFile WriteFile?\n editFile EditFile?\n runCommand RunCommand?\n deleteFile DeleteFile?\n}\nclass StitchTool {\n prompt string\n userId string\n}\n\nclass Apify {\n urls string[]\n maxPages int\n}\n\nclass Context7 {\n library string\n query string\n}\n\nclass Tavily {\n query string\n maxResults int\n}\nclass LLMResponse{\n stopReason \"completed\" | \"aborted\" | \"toolCall\"\n content string\n toolCall ToolCall?\n questions Question[]?\n} \n\nfunction MainLLMCall(\n systemPrompt: string, \n userPrompt: string, \n context: Message[], \n semanticMem: string, \n design: string?,\n orchestratorContext: string\n ) -> LLMResponse{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the specific, already-clarified request you're\n completing.\n {% if design %} - the design system chosen once at the start of\n this Run (layout, visual language, conventions). Never regenerate or\n second-guess this; treat it as settled. {% endif %}\n {{context}} - is the context of main agent\n {{semanticMem}} - Relevant user context for this build, Use this to calibrate scope, defaults, and how much you ask vs decide.\n {{orchestratorContext}} - relevant current state of the app: files, prior\n decisions, whatever the orchestrator has determined is relevant to this\n task.\n \n {{ctx.output_format}}\n \"#\n}\nfunction GenerateMainAgentSummary(systemPrompt: string, context: Message[]) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} the turn-by-turn tool-call history for this task so far.\n\n\n {{ctx.output_format}}\n \"#\n}\n\ntest TestName {\n functions [MainLLMCall]\n args {\n systemPrompt #\"\n # ROLE\n\nYou are the main agent for Lovable. You've been assigned a single user\nrequest that the orchestrator has already judged simple enough not to need\nthe full coder/debugger/tester pipeline. You own this task end to end —\nthere is no separate agent checking your work afterward, so you are\nresponsible for verifying it yourself before you consider it finished.\n\n# TOOLS AVAILABLE\n\nYou may use one or more of the following per turn when they're genuinely\nindependent of each other's results; use them one at a time when a later\ncall depends on what an earlier one returns.\n\n- **readFile / writeFile / editFile / deleteFile** — standard file\n operations. Use editFile for a targeted change to part of an existing\n file rather than rewriting the whole thing when the change is localized;\n use writeFile for new files or genuine full-content replacement.\n- **runCommand** — run a build, lint, typecheck, or test command. This is\n your only way to verify your own work — use it before considering the\n task done, not just when something looks wrong.\n- **context7** — authoritative, structured documentation lookup for a\n library or API. Prefer this over tavily when your uncertainty is\n specifically \"what does this library's current interface look like,\"\n since it's the more reliable source for that question.\n- **tavily** — general web search. Use this for anything broader than a\n specific library's documented interface — current best practices, how\n something is commonly done, non-library factual lookups.\n- **apify** — structured extraction from a specific external site when the\n task requires pulling in real external data (e.g. \"add a pricing\n comparison table based on competitor X's site\").\n- **stitch** — design generation, but narrowly: only for a genuinely new UI\n surface that the three original design variants didn't cover. This is not\n for revisiting or tweaking the fixed design from {{fixed_design_context}}.\n If you're not sure whether a surface counts as \"new,\" treat it as covered\n by the existing design and stay consistent with it instead.\n\n# RESPONSIBILITIES\n\n1. Scope discipline: do only what {{task_description}} asks. Don't expand\n into adjacent improvements uninvited.\n2. Explore before you assume: if you're not certain a file's current\n content, read it — don't guess at what's there.\n3. Verify before finishing: run the relevant build/lint/test command via\n runCommand and confirm it passes before treating the task as complete.\n Do not report something as done on the basis of \"this should work.\"\n4. Know your limits: you don't have a debugger loop backing you up. If\n verification keeps failing without you converging on a fix after a\n reasonable number of attempts, stop and state the blocker plainly rather\n than continuing to guess — repeated blind attempts here are more costly\n than they would be in the pipeline path, since nothing catches you.\n5. Signal completion clearly: once the task is done and verified, say so\n explicitly and stop taking further actions.\n\n# CONSTRAINTS\n\n- Never regenerate the fixed design; extend it, don't replace it.\n- Never claim verification passed without having actually run it.\n- Don't reach for apify/tavily/context7 for things you already know with\n confidence — they're for genuine uncertainty, not habit.\n \"#\n userPrompt #\"\n Make a simple todo app with black theme\n \"#\n context []\n semanticMem #\"\n \n \"#\n design null\n orchestratorContext #\"\n \n \"#\n }\n}\n", "planTasks.baml": "\nenum Agent {\n CoderAgent\n DebuggerAgent\n TesterAgent\n UIExpertAgent\n ResearcherAgent\n}\nfunction PlanComplexTask(systemPrompt: string, userPrompt: string, context: string) -> PlannerTodo[]{\n// context here is the orchestrator context sended with main agent, subagent, and planner task\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the request to plan for, already past complexity and\n clarification checks.\n {{context}} - current app state and prior decisions.\n\n {{ctx.output_format}}\n\n \"#\n}\n\ntest TestName {\n functions [PlanComplexTask]\n args {\n systemPrompt #\"\n # ROLE\n\nYou are the planner, invoked when the orchestrator has judged a request\ncomplex enough to need the full pipeline. You decompose the request into\nSubAgentsTodo items for CoderAgent to execute one at a time, plus a\nPlannerTodo summary for the orchestrator to relay to the user in plain\nlanguage.\n\nCoder is the only executor you're planning for. Debugger is invoked\nautomatically and reactively if an item's verification fails — you don't\nplan for it. Research and documentation lookup are tools Coder reaches for\nitself mid-item — you don't plan separate research steps, though you may\nflag an item as research-heavy as a hint.\n\n# DECOMPOSITION PRINCIPLES\n\n- Break work into the smallest units independently verifiable by a build/\n test/lint command. A unit bundling unrelated changes makes it harder to\n isolate what actually failed if verification fails.\n- Order items so that anything a later item structurally depends on comes\n first. Mark items parallel-safe only when they touch genuinely disjoint\n files/surfaces.\n- Don't over-decompose trivial requests into multiple items when one covers\n it.\n- If an item is likely to require nontrivial documentation lookup or web\n research before Coder can implement it confidently, note that as a hint\n in the item — it's still one Coder-executed item, just flagged.\n\n# CONSTRAINTS\n\n- Every item must be independently verifiable by a command Coder can run.\n- Scope what must be true when the item is done, not implementation detail\n that's Coder's own decision to make.\n- If decomposing requires an assumption material enough to change the\n outcome, don't guess — this should have been caught by the complexity\n checker already, but if it wasn't, say so explicitly in the planner\n summary rather than silently picking an interpretation.\n\n \"#\n userPrompt #\"\n Built a very complex todo app with black background.\n\n\n \"#\n context #\"\n Should the todo data be persisted to a local browser database or a backend database with user authentication?\nLocal storage only (browser-based)\n\nWhich advanced feature is the priority for making this 'complex'\nSubtasks, categories, and tags\n\n \"#\n }\n}\n", "qna.baml": "class Question{\n question string\n option string[]\n}\nclass SimpleComplexity{\n complex false\n}\nclass ComplexComplexity{\n complex true\n questions Question[]\n}\ntype ComplexityLevel = SimpleComplexity | ComplexComplexity\nfunction CheckComplexityAndGenerateQuestions(systemPrompt: string, userPrompt: string) -> SimpleComplexity | ComplexComplexity {\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the message to assess.\n {# {{app_context}} — current app state. #}\n {# {{run_stage}} — whether this is the Run's first message (design not yet\n chosen) or a follow-up (design already fixed — never ask design-related\n questions on a follow-up, and don't factor design selection into this\n message's complexity judgment). #}\n\n {{ctx.output_format}}\n \"#\n}\n// class ComplexityLevel{\n// complex bool\n// qnaNeeded bool\n// }\n// function CheckComplexity(userPrompt: string, systemPrompt: string) -> ComplexityLevel{\n\n// client OpenAIGeneric\n// prompt #\"\n// {{systemPrompt}}\n// {{userPrompt}}\n\n// {{ctx.output_format}}\n// \"#\n// }\n\n// function GenerateQuestion(userPrompt: string, systemPrompt: string) -> Question[]{\n\n// client OpenAIGeneric\n// prompt #\"\n// {{systemPrompt}}\n// {{userPrompt}}\n\n// {{ctx.output_format}}\n// \"#\n// }\n\ntest TestName {\n functions [CheckComplexityAndGenerateQuestions]\n args {\n systemPrompt #\"\n # ROLE\n\nYou do two things for every incoming user message in a Run: judge whether\nit's simple enough for the single main-agent path or complex enough to need\nthe full coder/debugger pipeline, and decide whether it can proceed as-is\nor needs clarifying questions first. The complexity verdict is not advisory\n— the orchestrator branches its execution path directly on it.\n\n# COMPLEXITY JUDGMENT\n\nJudge complex when the request plausibly touches multiple files/surfaces,\nintroduces or changes structural/data-model decisions, or is the kind of\nchange where a single generalist pass without a debugger safety net is a\nreal risk of shipping something broken. Judge simple when it's a bounded,\nsingle-surface change a capable generalist could implement and verify\ndirectly — copy changes, small isolated features, single-component fixes.\n\n# CLARIFICATION JUDGMENT\n\nDefault toward proceeding with stated assumptions — asking costs the user a\nfull round trip, and most ambiguity has a reasonable default. Proceed when\na reasonable default exists and a wrong guess would be cheap to redo. Ask\nwhen the request implies a data-model or permissions decision that would be\nexpensive to unwind if guessed wrong, when two plausible interpretations\nwould lead to materially different scopes of work (not just different\ndetails within the same scope), or when the request conflicts with a prior\nstated constraint and it's unclear which should win.\n\nBatch genuinely necessary questions together rather than trickling them out\nturn by turn. Questions must be specific and answerable in one line each —\nnot open-ended.\n\n# CONSTRAINTS\n\n- Complexity and clarification are separate judgments — a request can be\n simple but ambiguous, or complex but unambiguous. Don't conflate them.\n- Never ask about anything resolvable from {{app_context}} or reasonable\n convention.\n- Never revisit design selection on a follow-up message.\n\n \"#\n userPrompt #\"\n Built a very complex todo app with black background.\n \"#\n }\n}", - "subAgents.baml": "class AgentContext{}\n\n// Subagent session map, for generating summary\nfunction GenerateSubagentSummary(systemPrompt: string, subagentType: string, context: SessionMap) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{subagentType}}\n {{context}}\n\n {{ctx.output_format}}\n \"#\n}\nclass SessionMap {\n coder CoderSession\n debuggerr DebuggerSession\n tester TesterSession\n researcher ResearcherSession\n uiExpert UIExpertSession\n}\n\ntype Role = \"user\" | \"assistant\" | \"tool\"\ntype Status = \"in_progress\" | \"halted\" | \"resolved\" | \"done\"\n\nclass DebuggerSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n rawTranscript string?\n}\n\nclass CoderSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass TesterSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass ResearcherSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass UIExpertSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\ntest TestName {\n functions [GenerateSubagentSummary]\n args {\n systemPrompt #\"\n \n# ROLE\n\nYou summarize a single completed CoderAgent or DebuggerAgent run into a\nshort digest attached to the orchestrator's persistent state. The\norchestrator should never need to read a sub-agent's full action-by-action\ntranscript once this digest exists.\n\n# RESPONSIBILITIES\n\n1. State what actually happened, in terms the orchestrator (and whichever\n item comes next in the plan) can act on.\n2. List files touched, at the path level, with the action taken on each\n (created/modified/deleted).\n3. Note any decision or tradeoff made that a later step should be aware of\n — e.g. \"extended the existing X util rather than creating a new one;\n later items touching X should expect this.\"\n4. State the outcome plainly: success, failure, or needs-input. If failure,\n point at the relevant error signature rather than re-describing the\n error in prose — that detail already lives in the structured error\n report.\n\n# CONSTRAINTS\n\n- Don't re-narrate the reasoning process, only the outcome and what\n downstream steps need to know.\n- Keep this genuinely short — if it's approaching the length of the\n original transcript, it isn't a summary.\n\n \"#\n subagentType #\"\n coder\n \"#\n context {\n coder {\n taskId 1\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n debuggerr {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n rawTranscript null\n }\n tester {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n researcher {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n uiExpert {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n }\n }\n}\n", + "subAgents.baml": "class AgentContext{}\n\n// Subagent session map, for generating summary\nfunction GenerateSubagentSummary(systemPrompt: string, subagentType: string, session: string) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{subagentType}}\n {{session}}\n\n {{ctx.output_format}}\n \"#\n}\nclass SessionMap {\n coder CoderSession\n debuggerr DebuggerSession\n tester TesterSession\n researcher ResearcherSession\n uiExpert UIExpertSession\n}\n\ntype Role = \"user\" | \"assistant\" | \"tool\"\ntype Status = \"in_progress\" | \"halted\" | \"resolved\" | \"done\"\n\nclass DebuggerSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n rawTranscript string?\n}\n\nclass CoderSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass TesterSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass ResearcherSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass UIExpertSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\ntest TestName {\n functions [GenerateSubagentSummary]\n args {\n systemPrompt #\"\n \n# ROLE\n\nYou summarize a single completed CoderAgent or DebuggerAgent run into a\nshort digest attached to the orchestrator's persistent state. The\norchestrator should never need to read a sub-agent's full action-by-action\ntranscript once this digest exists.\n\n# RESPONSIBILITIES\n\n1. State what actually happened, in terms the orchestrator (and whichever\n item comes next in the plan) can act on.\n2. List files touched, at the path level, with the action taken on each\n (created/modified/deleted).\n3. Note any decision or tradeoff made that a later step should be aware of\n — e.g. \"extended the existing X util rather than creating a new one;\n later items touching X should expect this.\"\n4. State the outcome plainly: success, failure, or needs-input. If failure,\n point at the relevant error signature rather than re-describing the\n error in prose — that detail already lives in the structured error\n report.\n\n# CONSTRAINTS\n\n- Don't re-narrate the reasoning process, only the outcome and what\n downstream steps need to know.\n- Keep this genuinely short — if it's approaching the length of the\n original transcript, it isn't a summary.\n\n \"#\n subagentType #\"\n coder\n \"#\n context {\n coder {\n taskId 1\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n debuggerr {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n rawTranscript null\n }\n tester {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n researcher {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n uiExpert {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n }\n }\n}\n", "testerAgent.baml": "\n\nclass ErrorResponse{\n error string\n file string\n line int\n}\n// function TestCodebase(systemPrompt: string) -> string{\n\n// client \n// }\nfunction ReframeError(systemPrompt: string, error: string) -> ErrorResponse{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{error}} - unstructured stdout/stderr from a failed\nbuild/lint/test command.\n\n\n {{ctx.output_format}}\n \"#\n}", "uiExpert.baml": "\nclass Design{\n taskId int\n summary string\n}\nclass UIExpertContext{\n userPrompt string\n priorDesigns Design[]\n}\n\nclass DesignVariants{\n prompts string[]\n}\nfunction FramePrompts(systemPrompt: string, userPrompt: string, semanticMem: string) -> DesignVariants{\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - what's being built, already past complexity and\n clarification checks.\n {# {{target_surfaces}} — which pages/components are in initial scope. #}\n\n {{ctx.output_format}}\n \"#\n}\nfunction UIExpertAgent() -> string{\n\n}", } diff --git a/packages/agents/baml_client/sync_client.ts b/packages/agents/baml_client/sync_client.ts index cf67c4d..59ed5b7 100644 --- a/packages/agents/baml_client/sync_client.ts +++ b/packages/agents/baml_client/sync_client.ts @@ -548,7 +548,7 @@ export class BamlSyncClient { } GenerateSubagentSummary( - systemPrompt: string,subagentType: string,context: types.SessionMap, + systemPrompt: string,subagentType: string,session: string, __baml_options__?: BamlCallOptions ): string { try { @@ -580,7 +580,7 @@ export class BamlSyncClient { const __raw__ = this.runtime.callFunctionSync( "GenerateSubagentSummary", { - "systemPrompt": systemPrompt,"subagentType": subagentType,"context": context + "systemPrompt": systemPrompt,"subagentType": subagentType,"session": session }, this.ctxManager.cloneContext(), __options__.tb?.__tb(), diff --git a/packages/agents/baml_client/sync_request.ts b/packages/agents/baml_client/sync_request.ts index 6e338f2..53009df 100644 --- a/packages/agents/baml_client/sync_request.ts +++ b/packages/agents/baml_client/sync_request.ts @@ -336,7 +336,7 @@ export class HttpRequest { } GenerateSubagentSummary( - systemPrompt: string,subagentType: string,context: types.SessionMap, + systemPrompt: string,subagentType: string,session: string, __baml_options__?: BamlCallOptions ): HTTPRequest { try { @@ -355,7 +355,7 @@ export class HttpRequest { return this.runtime.buildRequestSync( "GenerateSubagentSummary", { - "systemPrompt": systemPrompt,"subagentType": subagentType,"context": context + "systemPrompt": systemPrompt,"subagentType": subagentType,"session": session }, this.ctxManager.cloneContext(), __baml_options__?.tb?.__tb(), @@ -1002,7 +1002,7 @@ export class HttpStreamRequest { } GenerateSubagentSummary( - systemPrompt: string,subagentType: string,context: types.SessionMap, + systemPrompt: string,subagentType: string,session: string, __baml_options__?: BamlCallOptions ): HTTPRequest { try { @@ -1021,7 +1021,7 @@ export class HttpStreamRequest { return this.runtime.buildRequestSync( "GenerateSubagentSummary", { - "systemPrompt": systemPrompt,"subagentType": subagentType,"context": context + "systemPrompt": systemPrompt,"subagentType": subagentType,"session": session }, this.ctxManager.cloneContext(), __baml_options__?.tb?.__tb(), diff --git a/packages/agents/baml_src/subAgents.baml b/packages/agents/baml_src/subAgents.baml index efc458b..0791d14 100644 --- a/packages/agents/baml_src/subAgents.baml +++ b/packages/agents/baml_src/subAgents.baml @@ -1,13 +1,13 @@ class AgentContext{} // Subagent session map, for generating summary -function GenerateSubagentSummary(systemPrompt: string, subagentType: string, context: SessionMap) -> string{ +function GenerateSubagentSummary(systemPrompt: string, subagentType: string, session: string) -> string{ client Gemini prompt #" {{systemPrompt}} {{subagentType}} - {{context}} + {{session}} {{ctx.output_format}} "# From 08b1be2a73ebea39e71f612a47e59637cd8f0a3e Mon Sep 17 00:00:00 2001 From: Ashu463 Date: Fri, 24 Jul 2026 09:58:34 +0530 Subject: [PATCH 3/3] added skills --- apps/backend/src/modules/project.ts | 1 + .../agent/skills/acceptance-criteria/SKILL.md | 45 +++++++++ .../agent/skills/acceptance-test/SKILL.md | 45 +++++++++ .../agents/agent/skills/add-a-route/SKILL.md | 32 ++++++ .../skills/api-route-convention/SKILL.md | 50 ++++++++++ .../agent/skills/baseline-checks/SKILL.md | 40 ++++++++ .../agent/skills/code-reviewer-addy/SKILL.md | 97 +++++++++++++++++++ .../agent/skills/common-build-errors/SKILL.md | 44 +++++++++ .../agent/skills/db-integration/SKILL.md | 44 +++++++++ .../agents/agent/skills/dependency/SKILL.md | 48 +++++++++ .../agent/skills/design-systems/SKILL.md | 81 ++++++++++++++++ .../agents/agent/skills/design-ui/SKILL.md | 82 ++++++++++++++++ .../agent/skills/project-conventions/SKILL.md | 83 ++++++++++++++++ .../agent/skills/research-format/SKILL.md | 49 ++++++++++ packages/agents/agent/skills/triage/SKILL.md | 46 +++++++++ packages/agents/agent/subAgent.ts | 8 -- packages/agents/baml_client/inlinedbaml.ts | 2 +- packages/agents/baml_src/subAgents.baml | 65 +++---------- 18 files changed, 800 insertions(+), 62 deletions(-) create mode 100644 packages/agents/agent/skills/acceptance-criteria/SKILL.md create mode 100644 packages/agents/agent/skills/acceptance-test/SKILL.md create mode 100644 packages/agents/agent/skills/add-a-route/SKILL.md create mode 100644 packages/agents/agent/skills/api-route-convention/SKILL.md create mode 100644 packages/agents/agent/skills/baseline-checks/SKILL.md create mode 100644 packages/agents/agent/skills/code-reviewer-addy/SKILL.md create mode 100644 packages/agents/agent/skills/common-build-errors/SKILL.md create mode 100644 packages/agents/agent/skills/db-integration/SKILL.md create mode 100644 packages/agents/agent/skills/dependency/SKILL.md create mode 100644 packages/agents/agent/skills/design-systems/SKILL.md create mode 100644 packages/agents/agent/skills/design-ui/SKILL.md create mode 100644 packages/agents/agent/skills/project-conventions/SKILL.md create mode 100644 packages/agents/agent/skills/research-format/SKILL.md create mode 100644 packages/agents/agent/skills/triage/SKILL.md diff --git a/apps/backend/src/modules/project.ts b/apps/backend/src/modules/project.ts index d0e064a..78bc01a 100644 --- a/apps/backend/src/modules/project.ts +++ b/apps/backend/src/modules/project.ts @@ -18,6 +18,7 @@ projectRouter.get("/", auth, async (req: AuthRequest, res: Response) => { res.status(401).json({success: false, message: `UserId not given`}) } + await prisma.project.findMany({where: {userId: userId}}) const projects = await prisma.project.findMany({where: {userId: userId}}) if(!projects){ diff --git a/packages/agents/agent/skills/acceptance-criteria/SKILL.md b/packages/agents/agent/skills/acceptance-criteria/SKILL.md new file mode 100644 index 0000000..896af0c --- /dev/null +++ b/packages/agents/agent/skills/acceptance-criteria/SKILL.md @@ -0,0 +1,45 @@ +--- +name: derive-acceptance-criteria +description: Turns a task description into concrete, checkable pass/fail assertions before testing begins. Use before writing or running any test, and whenever a task's "done" condition is ambiguous or implicit. +--- + +# Derive Acceptance Criteria + +Before running anything, convert the task into a list of assertions that +are each independently checkable as true/false. If you can't tell whether +an assertion passed or failed by inspection or a command's output, rewrite +it until you can. + +## Procedure + +1. Read the original task/task-node description and the design record (if + any UI is involved). +2. Write out explicit criteria covering: + - **Functional** — what the feature must actually do (e.g. "submitting + the form with valid input creates a record and redirects") + - **Structural** — build passes, no type errors, no unresolved imports + - **Visual** (if UI involved) — matches the design record's tokens, no + layout overflow, responsive at standard breakpoints + - **Negative cases** — what must NOT happen (e.g. "invalid input does + not submit," "no console errors on load") +3. Do not invent criteria the task never implied — stick to what was asked + plus baseline quality bars from `smoke-checklist`. +4. If the task is genuinely ambiguous about what "done" means, surface that + rather than guessing a scope. + +## Format + +Write each criterion as a single falsifiable statement, not a vague goal. + +Wrong: "The form should work well." +Right: "Submitting the form with all required fields filled shows a success +state and clears the form. Submitting with a required field empty shows an +inline error and does not submit." + +## Do not + +- Test only the happy path because it's what the task description led with. +- Treat "it renders without crashing" as sufficient acceptance criteria for + anything with actual logic in it. +- Skip this step for small tasks — a one-line criteria list still catches + more than testing on vibes. \ No newline at end of file diff --git a/packages/agents/agent/skills/acceptance-test/SKILL.md b/packages/agents/agent/skills/acceptance-test/SKILL.md new file mode 100644 index 0000000..896af0c --- /dev/null +++ b/packages/agents/agent/skills/acceptance-test/SKILL.md @@ -0,0 +1,45 @@ +--- +name: derive-acceptance-criteria +description: Turns a task description into concrete, checkable pass/fail assertions before testing begins. Use before writing or running any test, and whenever a task's "done" condition is ambiguous or implicit. +--- + +# Derive Acceptance Criteria + +Before running anything, convert the task into a list of assertions that +are each independently checkable as true/false. If you can't tell whether +an assertion passed or failed by inspection or a command's output, rewrite +it until you can. + +## Procedure + +1. Read the original task/task-node description and the design record (if + any UI is involved). +2. Write out explicit criteria covering: + - **Functional** — what the feature must actually do (e.g. "submitting + the form with valid input creates a record and redirects") + - **Structural** — build passes, no type errors, no unresolved imports + - **Visual** (if UI involved) — matches the design record's tokens, no + layout overflow, responsive at standard breakpoints + - **Negative cases** — what must NOT happen (e.g. "invalid input does + not submit," "no console errors on load") +3. Do not invent criteria the task never implied — stick to what was asked + plus baseline quality bars from `smoke-checklist`. +4. If the task is genuinely ambiguous about what "done" means, surface that + rather than guessing a scope. + +## Format + +Write each criterion as a single falsifiable statement, not a vague goal. + +Wrong: "The form should work well." +Right: "Submitting the form with all required fields filled shows a success +state and clears the form. Submitting with a required field empty shows an +inline error and does not submit." + +## Do not + +- Test only the happy path because it's what the task description led with. +- Treat "it renders without crashing" as sufficient acceptance criteria for + anything with actual logic in it. +- Skip this step for small tasks — a one-line criteria list still catches + more than testing on vibes. \ No newline at end of file diff --git a/packages/agents/agent/skills/add-a-route/SKILL.md b/packages/agents/agent/skills/add-a-route/SKILL.md new file mode 100644 index 0000000..0a4b845 --- /dev/null +++ b/packages/agents/agent/skills/add-a-route/SKILL.md @@ -0,0 +1,32 @@ +--- +name: add-a-route +description: Full checklist and conventions for adding a new page or route. Use whenever a task involves creating a new page, screen, or user-reachable endpoint — not for editing an existing route. +--- + +# Add a Route + +## Steps (all required, in order) + +1. Create the route file following `project-conventions` naming/location. +2. Register the route in the router configuration. +3. If the route is user-reachable (not an internal/API-only route), add the + nav entry linking to it. +4. Add loading and error states for any data the route fetches — never ship + a route that can render a bare unhandled fetch or a blank screen on error. +5. If the route requires auth, apply the project's existing auth-guard + pattern rather than inventing a new one. +6. Run the checklist in `smoke-checklist` before reporting done. + +## Conventions + +- Route components live in `src/pages/`, one file per route. +- Route-level data fetching happens in the route component, not buried in + a deeply nested child. +- Dynamic route params are typed, not accessed as untyped strings. + +## Do not + +- Register a route without a corresponding nav entry when it's meant to be + user-reachable — this is the single most common incomplete-route failure. +- Duplicate an existing route's path. +- Fetch data with no loading/error handling "because it'll usually work." \ No newline at end of file diff --git a/packages/agents/agent/skills/api-route-convention/SKILL.md b/packages/agents/agent/skills/api-route-convention/SKILL.md new file mode 100644 index 0000000..e2fea49 --- /dev/null +++ b/packages/agents/agent/skills/api-route-convention/SKILL.md @@ -0,0 +1,50 @@ +--- +name: api-route-conventions +description: Error shape, status codes, and the streaming/SSE pattern for backend routes. Use whenever writing or editing an API or server route. +--- + +# API Route Conventions + +## Error responses + +Use a consistent error shape across every route: + +```json +{ "error": { "message": "", "code": "" } } +``` + +Never return a bare string, a stack trace, or an inconsistent shape from +one route to another. + +## Status codes + +- 200 — success +- 201 — resource created +- 400 — invalid input (validation failure) +- 401 — not authenticated +- 403 — authenticated but not authorized +- 404 — resource not found +- 500 — unexpected server error (should be rare; most failures should be + caught and mapped to a specific 4xx) + +## Streaming / SSE + +Follow the project's existing SSE pattern exactly if one exists — do not +introduce a second streaming mechanism. If none exists yet and the task +requires one, keep the event backend-owned and stream through the existing +relay path rather than having the client connect directly to any sandboxed +process. + +## Validation + +Validate and parse all inputs at the top of the route handler before any +business logic runs. Don't validate halfway through. + +## Do not + +- Return different error shapes from different routes. +- Use 200 with an `error` field in the body instead of an actual error + status code. +- Let an unhandled exception fall through to a generic 500 without at least + logging enough to debug it later. +- Introduce a second streaming mechanism alongside an existing SSE setup. \ No newline at end of file diff --git a/packages/agents/agent/skills/baseline-checks/SKILL.md b/packages/agents/agent/skills/baseline-checks/SKILL.md new file mode 100644 index 0000000..5c2ec9c --- /dev/null +++ b/packages/agents/agent/skills/baseline-checks/SKILL.md @@ -0,0 +1,40 @@ +--- +name: smoke-checklist +description: Fixed baseline checks (build passes, no console errors, all routes render, no unresolved imports, no placeholder content) that apply to every task regardless of what it was about. Use before marking any task complete or reporting results to the orchestrator. +--- + +# Smoke Checklist + +Run this in full before reporting any task as complete — regardless of how +small the task was. These catch the failures that don't show up in +feature-specific testing. + +## Checklist + +- [ ] Build/compile succeeds with no errors +- [ ] No new type errors introduced +- [ ] No unresolved/broken imports +- [ ] Every route touched by this task renders without a console error +- [ ] No `TODO`, placeholder text, or lorem-ipsum-style content left in + anything user-facing +- [ ] No leftover debug logging (`console.log` used for debugging, not + intentional app logging) +- [ ] Existing functionality outside the task's scope still behaves the + same (spot-check, not a full regression pass) +- [ ] If the task touched navigation, the new/changed route is actually + reachable from the UI, not just defined in the router + +## Reporting + +If any item fails, do not report the task as complete — report the +specific failing item back through the normal failure path (to Debugger, +or `clarification_needed` if the failure indicates a scope problem, not a +bug). + +## Do not + +- Mark a task complete based on "the code looks right" without actually + running the build/tests. +- Skip this checklist because `derive-acceptance-criteria` already covered + feature-specific behavior — this is the baseline layer underneath that, + not a replacement for it. \ No newline at end of file diff --git a/packages/agents/agent/skills/code-reviewer-addy/SKILL.md b/packages/agents/agent/skills/code-reviewer-addy/SKILL.md new file mode 100644 index 0000000..96cac1d --- /dev/null +++ b/packages/agents/agent/skills/code-reviewer-addy/SKILL.md @@ -0,0 +1,97 @@ +--- +name: code-reviewer +description: Senior code reviewer that evaluates changes across five dimensions — correctness, readability, architecture, security, and performance. Use for thorough code review before merge. +--- + +# Senior Code Reviewer + +You are an experienced Staff Engineer conducting a thorough code review. Your role is to evaluate the proposed changes and provide actionable, categorized feedback. + +## Review Framework + +Evaluate every change across these five dimensions: + +### 1. Correctness +- Does the code do what the spec/task says it should? +- Are edge cases handled (null, empty, boundary values, error paths)? +- Do the tests actually verify the behavior? Are they testing the right things? +- Are there race conditions, off-by-one errors, or state inconsistencies? + +### 2. Readability +- Can another engineer understand this without explanation? +- Are names descriptive and consistent with project conventions? +- Is the control flow straightforward (no deeply nested logic)? +- Is the code well-organized (related code grouped, clear boundaries)? + +### 3. Architecture +- Does the change follow existing patterns or introduce a new one? +- If a new pattern, is it justified and documented? +- Are module boundaries maintained? Any circular dependencies? +- Is the abstraction level appropriate (not over-engineered, not too coupled)? +- Are dependencies flowing in the right direction? + +### 4. Security +- Is user input validated and sanitized at system boundaries? +- Are secrets kept out of code, logs, and version control? +- Is authentication/authorization checked where needed? +- Are queries parameterized? Is output encoded? +- Any new dependencies with known vulnerabilities? + +### 5. Performance +- Any N+1 query patterns? +- Any unbounded loops or unconstrained data fetching? +- Any synchronous operations that should be async? +- Any unnecessary re-renders (in UI components)? +- Any missing pagination on list endpoints? + +## Output Format + +Categorize every finding: + +**Critical** — Must fix before merge (security vulnerability, data loss risk, broken functionality) + +**Important** — Should fix before merge (missing test, wrong abstraction, poor error handling) + +**Suggestion** — Consider for improvement (naming, code style, optional optimization) + +## Review Output Template + +```markdown +## Review Summary + +**Verdict:** APPROVE | REQUEST CHANGES + +**Overview:** [1-2 sentences summarizing the change and overall assessment] + +### Critical Issues +- [File:line] [Description and recommended fix] + +### Important Issues +- [File:line] [Description and recommended fix] + +### Suggestions +- [File:line] [Description] + +### What's Done Well +- [Positive observation — always include at least one] + +### Verification Story +- Tests reviewed: [yes/no, observations] +- Build verified: [yes/no] +- Security checked: [yes/no, observations] +``` + +## Rules + +1. Review the tests first — they reveal intent and coverage +2. Read the spec or task description before reviewing code +3. Every Critical and Important finding should include a specific fix recommendation +4. Don't approve code with Critical issues +5. Acknowledge what's done well — specific praise motivates good practices +6. If you're uncertain about something, say so and suggest investigation rather than guessing + +## Composition + +- **Invoke directly when:** the user asks for a review of a specific change, file, or PR. +- **Invoke via:** `/review` (single-perspective review) or `/ship` (parallel fan-out alongside `security-auditor` and `test-engineer`). +- **Do not invoke from another persona.** If you find yourself wanting to delegate to `security-auditor` or `test-engineer`, surface that as a recommendation in your report instead — orchestration belongs to slash commands, not personas. See [docs/agents.md](../docs/agents.md). diff --git a/packages/agents/agent/skills/common-build-errors/SKILL.md b/packages/agents/agent/skills/common-build-errors/SKILL.md new file mode 100644 index 0000000..737067e --- /dev/null +++ b/packages/agents/agent/skills/common-build-errors/SKILL.md @@ -0,0 +1,44 @@ +--- +name: common-build-errors +description: Catalog of recurring build and runtime error signatures mapped to root cause and fix, built from actual observed run failures. Load this whenever an error doesn't cleanly match the general triage-protocol steps, or when the same error signature has been seen before. +--- + +# Common Build Errors + +This file is intentionally seeded empty. It should be populated from real +RunEvent failure logs, not invented — a guessed catalog teaches nothing and +just adds context weight. Append an entry here every time the Debugger +resolves an error that isn't already covered. + +## How to add an entry + +For each recurring error, add a row with: + +- **Signature** — the distinctive part of the error message/stack (enough + to match on, not the full stack trace) +- **Cause** — the actual root cause, not the symptom +- **Fix** — the specific correct fix +- **Wrong fixes seen** — approaches that seemed to work but didn't, or that + masked the problem instead of fixing it + +## Catalog + +| Signature | Cause | Fix | Wrong fixes seen | +|---|---|---|---| +| _(empty — populate from observed failures)_ | | | | + +## Structure note + +Once this table exceeds roughly 30–40 rows, split it by error family into +`references/` (e.g. `references/type-errors.md`, `references/build-tool.md`) +and turn this file into a router: state which reference file to read based +on the error signature, rather than keeping one giant table here. + +## Do not + +- Add a speculative entry for an error that hasn't actually been observed. +- Record only the fix without the root cause — future triage needs to know + *why*, not just *what to type*. +- Let "wrong fixes seen" go unfilled — that column is often more valuable + than the fix itself, since it stops the Debugger from re-trying a known + dead end. \ No newline at end of file diff --git a/packages/agents/agent/skills/db-integration/SKILL.md b/packages/agents/agent/skills/db-integration/SKILL.md new file mode 100644 index 0000000..6326077 --- /dev/null +++ b/packages/agents/agent/skills/db-integration/SKILL.md @@ -0,0 +1,44 @@ +--- +name: database-integration +description: Client setup, schema conventions, row-level security, and the migration procedure. Use whenever a task touches the database — creating or modifying tables, writing migrations, querying data, or anything involving auth-adjacent data access. +--- + +# Database Integration + +## Before writing any query or migration + +- Call the schema-lookup tool to get the actual current table schema — + never assume a column exists or guess its type from the task description. +- Check version compatibility between the ORM/client version in use and + the database version before using any newer API surface. + +## Migrations + +- One logical change per migration. Don't bundle unrelated schema changes. +- Migrations are additive by default — avoid destructive changes (dropping + columns/tables) unless the task explicitly calls for it, and flag + destructive migrations in the task summary so they can be reviewed. +- Never hand-edit a previously applied migration — write a new one. + +## Row-level security / access rules + +- Any new table holding user data gets an explicit access policy — do not + leave a new table without one and assume it'll be added later. +- Match the access pattern of similar existing tables in the project rather + than inventing a new permission model per table. + +## Queries + +- Use the project's existing query/ORM layer consistently — don't mix raw + SQL and ORM calls for the same kind of operation within one project. +- Avoid N+1 patterns — batch or join instead of looping queries. +- Parameterize all inputs; never interpolate user input into a raw query + string. + +## Do not + +- Apply a migration without having read the current schema first. +- Add a column/table without an access policy when the project's existing + tables all have one. +- Guess at a schema instead of calling the schema tool. +- Make a destructive schema change without flagging it explicitly. \ No newline at end of file diff --git a/packages/agents/agent/skills/dependency/SKILL.md b/packages/agents/agent/skills/dependency/SKILL.md new file mode 100644 index 0000000..95dcabc --- /dev/null +++ b/packages/agents/agent/skills/dependency/SKILL.md @@ -0,0 +1,48 @@ +--- +name: dependency-policy +description: Approved libraries and the bar for adding a new dependency, including version compatibility checks against the current environment. Use whenever considering npm install, importing a package not already in package.json, or facing a problem that "a library could solve." Check this before adding any dependency, not after. +--- + +# Dependency Policy + +## Before adding anything + +1. Check `package.json` — is something already installed that covers this? + Don't add a second library for a problem an existing dependency solves. +2. Check whether the standard library / framework already covers it + (e.g. don't add a date library for something `Intl` handles). +3. If a new dependency is genuinely needed, verify **version compatibility + with the current environment** before installing: + - Node/Bun/runtime version actually in use in this project + - Existing major versions of related packages (framework version, + bundler version) — check the new package's peer dependencies against + what's installed, not against the latest docs + - Whether the package has a maintained release compatible with the + project's module system (ESM vs CJS) + Do not assume the latest version of a library is safe to add — check + its peer dependency range against what's already in `package.json` + first, and prefer the newest version that satisfies existing peers. + +## Approved categories (safe to add without escalation) + +- Well-known, actively maintained utility libraries for a narrow, common + problem (date formatting, schema validation, class-name merging) +- Official SDKs for services already integrated in the project (e.g. the + project's existing database or auth provider's own client) + +## Requires justification in the task summary + +- Anything that adds a new category of infrastructure (a new database + client, a new state-management library, a new build tool) +- Anything with low weekly downloads or no commits in the last year +- Anything that duplicates functionality of an existing dependency + +## Do not + +- Add a dependency to solve a problem solvable in under ~15 lines of + project code. +- Add a library still in alpha/beta for anything on the critical path. +- Upgrade an existing dependency's major version as a side effect of an + unrelated task — that's a separate, deliberate task. +- Install without checking peer dependency ranges against the current + lockfile. diff --git a/packages/agents/agent/skills/design-systems/SKILL.md b/packages/agents/agent/skills/design-systems/SKILL.md new file mode 100644 index 0000000..4969b16 --- /dev/null +++ b/packages/agents/agent/skills/design-systems/SKILL.md @@ -0,0 +1,81 @@ +--- +name: design-system +description: Tokens, spacing scale, typography, color palette, and the Stitch design-variant workflow for generated UI. Use whenever writing or editing any component that renders visible markup, choosing colors/spacing/fonts, generating design variants from a user prompt, or reviewing UI for visual consistency. Always consult before hardcoding a style value or before UIExpert generates designs. +--- + +# Design System + +Rules for keeping generated UI visually coherent across every agent that +touches it, and for how UIExpert's Stitch-generated design variants flow +into the Coder. + +## Design-variant workflow (UIExpert) + +For any task that generates or substantially reshapes UI, do not go straight +from the user prompt to a single design. Instead: + +1. Generate **three prompt variations** of the original user request — + distinct enough to explore different visual directions (e.g. more + minimal vs. more editorial vs. more dense/dashboard-like), but each still + a faithful interpretation of what the user actually asked for. Do not + invent requirements the user didn't imply. +2. Run each variation through the Stitch SDK to produce three candidate + designs. +3. Select (or have the orchestrator/user select) the design to proceed with. +4. Record the **selected variant's tokens** — palette, spacing, type scale, + component shapes — into the shared design record (see below). This + record, not the Stitch output itself, is what the Coder reads. + +## Design record: the sync contract with Coder + +UIExpert and Coder must never independently re-derive style decisions from +the same user prompt — that produces mismatched output (different accent +colors, different spacing rhythm) even when both are "right" individually. + +The design record is the single source of truth once a variant is chosen. +It must include: + +- Color palette (primary, secondary, accent, neutral scale, semantic colors + for success/warning/error) +- Type scale (font family, size steps, weight steps) +- Spacing scale (base unit and multiples in use) +- Border radius and shadow conventions +- Any component-shape decisions from the chosen Stitch variant (e.g. pill + buttons vs. rounded-rect, card elevation style) + +Coder reads this record before writing any styled markup for the task. If +the record doesn't exist yet for a task that needs one, Coder should not +guess — flag it back to the orchestrator rather than inventing values that +UIExpert will later contradict. + +## Baseline tokens (used when no variant-specific record exists) + +Use the project's already-established tokens if the project has prior UI. +Only fall back to defaults below for a brand-new project with no existing +design record. + +| Token | Default | +|----------------|--------------------------------------------| +| Spacing unit | 4px base, scale: 4/8/12/16/24/32/48/64 | +| Radius | sm: 4px, md: 8px, lg: 12px, full: 9999px | +| Font sizes | 12/14/16/18/24/32/40 | +| Font weights | 400 regular, 500 medium, 600 semibold, 700 bold | + +## Rules + +- No hardcoded hex/px values in component markup — reference the design + record or the project's token source (theme file, CSS variables, config). +- One accent color per project. Don't introduce a second "primary" color + mid-project. +- Match the spacing scale exactly — no arbitrary values like `padding: 13px`. +- Icon set, once chosen for a project, stays consistent — don't mix icon + libraries within one app. + +## Do not + +- Generate only one design variant when three were expected — the point is + giving the user/orchestrator a real choice, not rubber-stamping the first + attempt. +- Let Coder style a component before the design record exists for that task. +- Silently override a token from the design record because a value "looks + better" — if it's actually wrong, flag it, don't just diverge. \ No newline at end of file diff --git a/packages/agents/agent/skills/design-ui/SKILL.md b/packages/agents/agent/skills/design-ui/SKILL.md new file mode 100644 index 0000000..e37dc0c --- /dev/null +++ b/packages/agents/agent/skills/design-ui/SKILL.md @@ -0,0 +1,82 @@ +----------DO NOT USE THIS SKILL UNTIL UI EXPERT IS READY-------------------------------- +--- +name: design-system +description: Tokens, spacing scale, typography, color palette, and the Stitch design-variant workflow for generated UI. Use whenever writing or editing any component that renders visible markup, choosing colors/spacing/fonts, generating design variants from a user prompt, or reviewing UI for visual consistency. Always consult before hardcoding a style value or before UIExpert generates designs. +--- + +# Design System + +Rules for keeping generated UI visually coherent across every agent that +touches it, and for how UIExpert's Stitch-generated design variants flow +into the Coder. + +## Design-variant workflow (UIExpert) + +For any task that generates or substantially reshapes UI, do not go straight +from the user prompt to a single design. Instead: + +1. Generate **three prompt variations** of the original user request — + distinct enough to explore different visual directions (e.g. more + minimal vs. more editorial vs. more dense/dashboard-like), but each still + a faithful interpretation of what the user actually asked for. Do not + invent requirements the user didn't imply. +2. Run each variation through the Stitch SDK to produce three candidate + designs. +3. Select (or have the orchestrator/user select) the design to proceed with. +4. Record the **selected variant's tokens** — palette, spacing, type scale, + component shapes — into the shared design record (see below). This + record, not the Stitch output itself, is what the Coder reads. + +## Design record: the sync contract with Coder + +UIExpert and Coder must never independently re-derive style decisions from +the same user prompt — that produces mismatched output (different accent +colors, different spacing rhythm) even when both are "right" individually. + +The design record is the single source of truth once a variant is chosen. +It must include: + +- Color palette (primary, secondary, accent, neutral scale, semantic colors + for success/warning/error) +- Type scale (font family, size steps, weight steps) +- Spacing scale (base unit and multiples in use) +- Border radius and shadow conventions +- Any component-shape decisions from the chosen Stitch variant (e.g. pill + buttons vs. rounded-rect, card elevation style) + +Coder reads this record before writing any styled markup for the task. If +the record doesn't exist yet for a task that needs one, Coder should not +guess — flag it back to the orchestrator rather than inventing values that +UIExpert will later contradict. + +## Baseline tokens (used when no variant-specific record exists) + +Use the project's already-established tokens if the project has prior UI. +Only fall back to defaults below for a brand-new project with no existing +design record. + +| Token | Default | +|----------------|--------------------------------------------| +| Spacing unit | 4px base, scale: 4/8/12/16/24/32/48/64 | +| Radius | sm: 4px, md: 8px, lg: 12px, full: 9999px | +| Font sizes | 12/14/16/18/24/32/40 | +| Font weights | 400 regular, 500 medium, 600 semibold, 700 bold | + +## Rules + +- No hardcoded hex/px values in component markup — reference the design + record or the project's token source (theme file, CSS variables, config). +- One accent color per project. Don't introduce a second "primary" color + mid-project. +- Match the spacing scale exactly — no arbitrary values like `padding: 13px`. +- Icon set, once chosen for a project, stays consistent — don't mix icon + libraries within one app. + +## Do not + +- Generate only one design variant when three were expected — the point is + giving the user/orchestrator a real choice, not rubber-stamping the first + attempt. +- Let Coder style a component before the design record exists for that task. +- Silently override a token from the design record because a value "looks + better" — if it's actually wrong, flag it, don't just diverge. diff --git a/packages/agents/agent/skills/project-conventions/SKILL.md b/packages/agents/agent/skills/project-conventions/SKILL.md new file mode 100644 index 0000000..baf015b --- /dev/null +++ b/packages/agents/agent/skills/project-conventions/SKILL.md @@ -0,0 +1,83 @@ +--- +name: project-conventions +description: File layout, naming, and import rules for generated projects. Use this whenever creating, moving, or renaming any file, adding a component, page, hook, or utility, wiring up imports, or deciding where new code belongs. Consult this before writing the first line of any new file, even for a small change. +--- + +# Project Conventions + +Structural rules for every generated project. These are not suggestions — +inconsistent structure across agents causes integration failures downstream. + +## Directory layout + +``` +src/ +├── components/ Reusable UI. One folder per component. +│ └── ui/ Base primitives. Do not hand-edit these. +├── pages/ Route-level components. One file per route. +├── hooks/ Custom hooks. One hook per file. +├── lib/ Pure utilities, no framework imports. +├── integrations/ External clients (db, third-party APIs). +└── types/ Shared types only. Component-local types stay local. +``` + +If the current project's actual layout differs from this (check the repo +before assuming), follow what's already there and do not restructure it. + +## Naming + +| Thing | Case | Example | +|---------------------|------------|---------------------------------| +| Component file | PascalCase | `UserCard.tsx` | +| Hook file | camelCase | `useAuth.ts` | +| Utility file | kebab-case | `format-date.ts` | +| Type/interface | PascalCase | `interface UserProfile` | +| Boolean prop/var | is/has/can | `isLoading`, `hasError` | + +Never suffix components with `Component`. `UserCard`, not `UserCardComponent`. + +## Imports + +Use the project's configured path alias (e.g. `@/`) for anything under `src/`. +Relative imports only within the same folder. + +``` +// Wrong +import { UserCard } from '../../components/UserCard' + +// Right +import { UserCard } from '@/components/UserCard' +``` + +Order: external packages → internal alias imports → relative imports → styles. +Blank line between groups. + +## Component rules + +- One exported component per file. Named export, not default export. +- Props interface declared directly above the component, named `Props`. +- No inline styles — use the styling system already in the project. +- If a component exceeds ~150 lines, extract subcomponents into the same folder. + +## Adding a new route + +Do all four steps below. A route added without navigation wired up is a +common and easy-to-miss failure. + +1. Create the route file in `src/pages/`. +2. Register it in the router. +3. Add the nav entry if the route is user-reachable. +4. Add loading and error states — never render a bare unhandled fetch. + +## Do not + +- Create top-level directories outside the layout above without a clear reason. +- Hand-edit generated/vendored UI primitives — regenerate them instead. +- Add a dependency without checking whether an existing one already covers it + (see `dependency-policy`). +- Leave `TODO`, placeholder text, or lorem-ipsum-style content in shipped output. + +## Escape hatch + +If the user explicitly requests a different structure, follow the user. Note +the deviation in your task summary so downstream agents don't fight it. \ No newline at end of file diff --git a/packages/agents/agent/skills/research-format/SKILL.md b/packages/agents/agent/skills/research-format/SKILL.md new file mode 100644 index 0000000..092340b --- /dev/null +++ b/packages/agents/agent/skills/research-format/SKILL.md @@ -0,0 +1,49 @@ +--- +name: report-format +description: Fixed output schema for research findings so the orchestrator and other agents can parse them deterministically. Use whenever compiling or returning any research result, regardless of the research topic. +--- + +# Report Format + +The orchestrator consumes research output programmatically. Free-form prose +summaries are harder to parse reliably and should be avoided in favor of +this structure. + +## Required output shape + +```json +{ + "query": "", + "findings": [ + { + "claim": "", + "confidence": "high | medium | low", + "source": "" + } + ], + "unresolved": [ + "" + ], + "recommendation": "" +} +``` + +## Rules + +- Each `finding` is one claim, not a paragraph bundling several. Split + bundled findings into separate entries so downstream agents can act on + them individually. +- `confidence: high` only for claims backed by an authoritative or + primary source. Aggregator/forum-sourced claims are `medium` at best. +- List genuinely unresolved questions in `unresolved` rather than silently + omitting them or papering over the gap with a guess. +- Do not include a `recommendation` field unless the task explicitly asked + for one — pure fact-finding tasks should stop at `findings`. + +## Do not + +- Return a narrative summary instead of the structured shape. +- Merge multiple distinct claims into one `finding` entry. +- State a claim without a `source` — if there's no source, it doesn't + belong in `findings`. \ No newline at end of file diff --git a/packages/agents/agent/skills/triage/SKILL.md b/packages/agents/agent/skills/triage/SKILL.md new file mode 100644 index 0000000..c469a38 --- /dev/null +++ b/packages/agents/agent/skills/triage/SKILL.md @@ -0,0 +1,46 @@ +--- +name: triage-protocol +description: Reproduce, localize, minimal-fix, verify procedure for fixing any failing build, test, or reported bug, plus the rule for when to escalate instead of retrying. Use for any failing build, test failure, runtime error, or reported bug — before touching any file. +--- + +# Triage Protocol + +The fixed procedure for the Debugger agent. Do not skip steps even when the +fix seems obvious — the obvious fix is often the symptom, not the cause. + +## Procedure + +1. **Reproduce** — confirm the actual failure signature (exact error message, + stack trace, failing test name). Do not fix based on a guess about what's + probably wrong. +2. **Localize** — find the specific file/line/function responsible. Use the + stack trace and `common-build-errors` (load it if the signature doesn't + match anything obvious) before searching broadly. +3. **Minimal fix** — fix the root cause with the smallest change that + resolves it. Do not refactor unrelated code, rename things, or "clean up" + while fixing. +4. **Verify** — re-run the exact command/test that failed. Do not report + success from reading the diff alone. + +## Escalation rule + +Track the error signature (message + file) across attempts. If two +consecutive attempts fail with the **same signature**, stop retrying the +same approach. Either: +- try a materially different hypothesis for the root cause, or +- report `clarification_needed` / escalate to the orchestrator with what + was tried and why it didn't work. + +Do not attempt a third variation of the same fix. Repeating a failed +approach with small tweaks wastes turns and rarely converges. + +## Do not + +- Delete or comment out a failing test to make the suite pass. +- Add a broad try/catch that swallows the error instead of fixing it. +- Cast to `any` (or equivalent) to silence a type error instead of fixing + the actual type mismatch. +- Change a version/dependency as a first resort — check `common-build-errors` + and the actual stack trace first. +- Mark a task complete because the specific reported symptom is gone, + without re-running the original failing command. \ No newline at end of file diff --git a/packages/agents/agent/subAgent.ts b/packages/agents/agent/subAgent.ts index 6d3075d..da2ad6b 100644 --- a/packages/agents/agent/subAgent.ts +++ b/packages/agents/agent/subAgent.ts @@ -59,14 +59,6 @@ export class SubAgent { } } - // coder/debuggerr genuinely return a tagged union with a Done/DebuggingDone - // {action: "done"} variant, so checking res.action there is meaningful. - // tester/researcher/uiExpert don't — TesterAgent.callLLM returns - // ErrorResponse, Researcher.callLLM returns a bare string, UIExpert.callLLM - // returns DesignVariants — none of them ever carry `action`/`stopReason` - // at all (TLLMResponse is typed `any` here, so nothing caught this at - // compile time). Each of those three is a single LLM call by design, not - // a multi-turn tool loop, so treat their first response as the end. private isSingleShotAgent(): boolean { return this.agentType === 'tester' || this.agentType === 'researcher' || this.agentType === 'uiExpert' } diff --git a/packages/agents/baml_client/inlinedbaml.ts b/packages/agents/baml_client/inlinedbaml.ts index 1402e9c..1c44812 100644 --- a/packages/agents/baml_client/inlinedbaml.ts +++ b/packages/agents/baml_client/inlinedbaml.ts @@ -29,7 +29,7 @@ const fileMap = { "mainAgent.baml": "enum ToolType {\n Apify\n Context7\n Tavily\n Stitch\n ReadFile\n WriteFile\n EditFile\n RunCommand\n DeleteFile\n QnA\n}\nclass ToolCall {\n type ToolType\n\n apify Apify?\n context7 Context7?\n tavily Tavily?\n stitch StitchTool?\n readFile ReadFile?\n writeFile WriteFile?\n editFile EditFile?\n runCommand RunCommand?\n deleteFile DeleteFile?\n}\nclass StitchTool {\n prompt string\n userId string\n}\n\nclass Apify {\n urls string[]\n maxPages int\n}\n\nclass Context7 {\n library string\n query string\n}\n\nclass Tavily {\n query string\n maxResults int\n}\nclass LLMResponse{\n stopReason \"completed\" | \"aborted\" | \"toolCall\"\n content string\n toolCall ToolCall?\n questions Question[]?\n} \n\nfunction MainLLMCall(\n systemPrompt: string, \n userPrompt: string, \n context: Message[], \n semanticMem: string, \n design: string?,\n orchestratorContext: string\n ) -> LLMResponse{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the specific, already-clarified request you're\n completing.\n {% if design %} - the design system chosen once at the start of\n this Run (layout, visual language, conventions). Never regenerate or\n second-guess this; treat it as settled. {% endif %}\n {{context}} - is the context of main agent\n {{semanticMem}} - Relevant user context for this build, Use this to calibrate scope, defaults, and how much you ask vs decide.\n {{orchestratorContext}} - relevant current state of the app: files, prior\n decisions, whatever the orchestrator has determined is relevant to this\n task.\n \n {{ctx.output_format}}\n \"#\n}\nfunction GenerateMainAgentSummary(systemPrompt: string, context: Message[]) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{context}} the turn-by-turn tool-call history for this task so far.\n\n\n {{ctx.output_format}}\n \"#\n}\n\ntest TestName {\n functions [MainLLMCall]\n args {\n systemPrompt #\"\n # ROLE\n\nYou are the main agent for Lovable. You've been assigned a single user\nrequest that the orchestrator has already judged simple enough not to need\nthe full coder/debugger/tester pipeline. You own this task end to end —\nthere is no separate agent checking your work afterward, so you are\nresponsible for verifying it yourself before you consider it finished.\n\n# TOOLS AVAILABLE\n\nYou may use one or more of the following per turn when they're genuinely\nindependent of each other's results; use them one at a time when a later\ncall depends on what an earlier one returns.\n\n- **readFile / writeFile / editFile / deleteFile** — standard file\n operations. Use editFile for a targeted change to part of an existing\n file rather than rewriting the whole thing when the change is localized;\n use writeFile for new files or genuine full-content replacement.\n- **runCommand** — run a build, lint, typecheck, or test command. This is\n your only way to verify your own work — use it before considering the\n task done, not just when something looks wrong.\n- **context7** — authoritative, structured documentation lookup for a\n library or API. Prefer this over tavily when your uncertainty is\n specifically \"what does this library's current interface look like,\"\n since it's the more reliable source for that question.\n- **tavily** — general web search. Use this for anything broader than a\n specific library's documented interface — current best practices, how\n something is commonly done, non-library factual lookups.\n- **apify** — structured extraction from a specific external site when the\n task requires pulling in real external data (e.g. \"add a pricing\n comparison table based on competitor X's site\").\n- **stitch** — design generation, but narrowly: only for a genuinely new UI\n surface that the three original design variants didn't cover. This is not\n for revisiting or tweaking the fixed design from {{fixed_design_context}}.\n If you're not sure whether a surface counts as \"new,\" treat it as covered\n by the existing design and stay consistent with it instead.\n\n# RESPONSIBILITIES\n\n1. Scope discipline: do only what {{task_description}} asks. Don't expand\n into adjacent improvements uninvited.\n2. Explore before you assume: if you're not certain a file's current\n content, read it — don't guess at what's there.\n3. Verify before finishing: run the relevant build/lint/test command via\n runCommand and confirm it passes before treating the task as complete.\n Do not report something as done on the basis of \"this should work.\"\n4. Know your limits: you don't have a debugger loop backing you up. If\n verification keeps failing without you converging on a fix after a\n reasonable number of attempts, stop and state the blocker plainly rather\n than continuing to guess — repeated blind attempts here are more costly\n than they would be in the pipeline path, since nothing catches you.\n5. Signal completion clearly: once the task is done and verified, say so\n explicitly and stop taking further actions.\n\n# CONSTRAINTS\n\n- Never regenerate the fixed design; extend it, don't replace it.\n- Never claim verification passed without having actually run it.\n- Don't reach for apify/tavily/context7 for things you already know with\n confidence — they're for genuine uncertainty, not habit.\n \"#\n userPrompt #\"\n Make a simple todo app with black theme\n \"#\n context []\n semanticMem #\"\n \n \"#\n design null\n orchestratorContext #\"\n \n \"#\n }\n}\n", "planTasks.baml": "\nenum Agent {\n CoderAgent\n DebuggerAgent\n TesterAgent\n UIExpertAgent\n ResearcherAgent\n}\nfunction PlanComplexTask(systemPrompt: string, userPrompt: string, context: string) -> PlannerTodo[]{\n// context here is the orchestrator context sended with main agent, subagent, and planner task\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the request to plan for, already past complexity and\n clarification checks.\n {{context}} - current app state and prior decisions.\n\n {{ctx.output_format}}\n\n \"#\n}\n\ntest TestName {\n functions [PlanComplexTask]\n args {\n systemPrompt #\"\n # ROLE\n\nYou are the planner, invoked when the orchestrator has judged a request\ncomplex enough to need the full pipeline. You decompose the request into\nSubAgentsTodo items for CoderAgent to execute one at a time, plus a\nPlannerTodo summary for the orchestrator to relay to the user in plain\nlanguage.\n\nCoder is the only executor you're planning for. Debugger is invoked\nautomatically and reactively if an item's verification fails — you don't\nplan for it. Research and documentation lookup are tools Coder reaches for\nitself mid-item — you don't plan separate research steps, though you may\nflag an item as research-heavy as a hint.\n\n# DECOMPOSITION PRINCIPLES\n\n- Break work into the smallest units independently verifiable by a build/\n test/lint command. A unit bundling unrelated changes makes it harder to\n isolate what actually failed if verification fails.\n- Order items so that anything a later item structurally depends on comes\n first. Mark items parallel-safe only when they touch genuinely disjoint\n files/surfaces.\n- Don't over-decompose trivial requests into multiple items when one covers\n it.\n- If an item is likely to require nontrivial documentation lookup or web\n research before Coder can implement it confidently, note that as a hint\n in the item — it's still one Coder-executed item, just flagged.\n\n# CONSTRAINTS\n\n- Every item must be independently verifiable by a command Coder can run.\n- Scope what must be true when the item is done, not implementation detail\n that's Coder's own decision to make.\n- If decomposing requires an assumption material enough to change the\n outcome, don't guess — this should have been caught by the complexity\n checker already, but if it wasn't, say so explicitly in the planner\n summary rather than silently picking an interpretation.\n\n \"#\n userPrompt #\"\n Built a very complex todo app with black background.\n\n\n \"#\n context #\"\n Should the todo data be persisted to a local browser database or a backend database with user authentication?\nLocal storage only (browser-based)\n\nWhich advanced feature is the priority for making this 'complex'\nSubtasks, categories, and tags\n\n \"#\n }\n}\n", "qna.baml": "class Question{\n question string\n option string[]\n}\nclass SimpleComplexity{\n complex false\n}\nclass ComplexComplexity{\n complex true\n questions Question[]\n}\ntype ComplexityLevel = SimpleComplexity | ComplexComplexity\nfunction CheckComplexityAndGenerateQuestions(systemPrompt: string, userPrompt: string) -> SimpleComplexity | ComplexComplexity {\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - the message to assess.\n {# {{app_context}} — current app state. #}\n {# {{run_stage}} — whether this is the Run's first message (design not yet\n chosen) or a follow-up (design already fixed — never ask design-related\n questions on a follow-up, and don't factor design selection into this\n message's complexity judgment). #}\n\n {{ctx.output_format}}\n \"#\n}\n// class ComplexityLevel{\n// complex bool\n// qnaNeeded bool\n// }\n// function CheckComplexity(userPrompt: string, systemPrompt: string) -> ComplexityLevel{\n\n// client OpenAIGeneric\n// prompt #\"\n// {{systemPrompt}}\n// {{userPrompt}}\n\n// {{ctx.output_format}}\n// \"#\n// }\n\n// function GenerateQuestion(userPrompt: string, systemPrompt: string) -> Question[]{\n\n// client OpenAIGeneric\n// prompt #\"\n// {{systemPrompt}}\n// {{userPrompt}}\n\n// {{ctx.output_format}}\n// \"#\n// }\n\ntest TestName {\n functions [CheckComplexityAndGenerateQuestions]\n args {\n systemPrompt #\"\n # ROLE\n\nYou do two things for every incoming user message in a Run: judge whether\nit's simple enough for the single main-agent path or complex enough to need\nthe full coder/debugger pipeline, and decide whether it can proceed as-is\nor needs clarifying questions first. The complexity verdict is not advisory\n— the orchestrator branches its execution path directly on it.\n\n# COMPLEXITY JUDGMENT\n\nJudge complex when the request plausibly touches multiple files/surfaces,\nintroduces or changes structural/data-model decisions, or is the kind of\nchange where a single generalist pass without a debugger safety net is a\nreal risk of shipping something broken. Judge simple when it's a bounded,\nsingle-surface change a capable generalist could implement and verify\ndirectly — copy changes, small isolated features, single-component fixes.\n\n# CLARIFICATION JUDGMENT\n\nDefault toward proceeding with stated assumptions — asking costs the user a\nfull round trip, and most ambiguity has a reasonable default. Proceed when\na reasonable default exists and a wrong guess would be cheap to redo. Ask\nwhen the request implies a data-model or permissions decision that would be\nexpensive to unwind if guessed wrong, when two plausible interpretations\nwould lead to materially different scopes of work (not just different\ndetails within the same scope), or when the request conflicts with a prior\nstated constraint and it's unclear which should win.\n\nBatch genuinely necessary questions together rather than trickling them out\nturn by turn. Questions must be specific and answerable in one line each —\nnot open-ended.\n\n# CONSTRAINTS\n\n- Complexity and clarification are separate judgments — a request can be\n simple but ambiguous, or complex but unambiguous. Don't conflate them.\n- Never ask about anything resolvable from {{app_context}} or reasonable\n convention.\n- Never revisit design selection on a follow-up message.\n\n \"#\n userPrompt #\"\n Built a very complex todo app with black background.\n \"#\n }\n}", - "subAgents.baml": "class AgentContext{}\n\n// Subagent session map, for generating summary\nfunction GenerateSubagentSummary(systemPrompt: string, subagentType: string, session: string) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{subagentType}}\n {{session}}\n\n {{ctx.output_format}}\n \"#\n}\nclass SessionMap {\n coder CoderSession\n debuggerr DebuggerSession\n tester TesterSession\n researcher ResearcherSession\n uiExpert UIExpertSession\n}\n\ntype Role = \"user\" | \"assistant\" | \"tool\"\ntype Status = \"in_progress\" | \"halted\" | \"resolved\" | \"done\"\n\nclass DebuggerSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n rawTranscript string?\n}\n\nclass CoderSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass TesterSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass ResearcherSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass UIExpertSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\ntest TestName {\n functions [GenerateSubagentSummary]\n args {\n systemPrompt #\"\n \n# ROLE\n\nYou summarize a single completed CoderAgent or DebuggerAgent run into a\nshort digest attached to the orchestrator's persistent state. The\norchestrator should never need to read a sub-agent's full action-by-action\ntranscript once this digest exists.\n\n# RESPONSIBILITIES\n\n1. State what actually happened, in terms the orchestrator (and whichever\n item comes next in the plan) can act on.\n2. List files touched, at the path level, with the action taken on each\n (created/modified/deleted).\n3. Note any decision or tradeoff made that a later step should be aware of\n — e.g. \"extended the existing X util rather than creating a new one;\n later items touching X should expect this.\"\n4. State the outcome plainly: success, failure, or needs-input. If failure,\n point at the relevant error signature rather than re-describing the\n error in prose — that detail already lives in the structured error\n report.\n\n# CONSTRAINTS\n\n- Don't re-narrate the reasoning process, only the outcome and what\n downstream steps need to know.\n- Keep this genuinely short — if it's approaching the length of the\n original transcript, it isn't a summary.\n\n \"#\n subagentType #\"\n coder\n \"#\n context {\n coder {\n taskId 1\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n debuggerr {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n rawTranscript null\n }\n tester {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n researcher {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n uiExpert {\n taskId 123\n role \"user\"\n status \"in_progress\"\n iterationCount 123\n timestamp #\"\n hello world\n \"#\n content null\n }\n }\n }\n}\n", + "subAgents.baml": "class AgentContext{}\n\n// Subagent session map, for generating summary\nfunction GenerateSubagentSummary(systemPrompt: string, subagentType: string, session: string) -> string{\n\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{subagentType}}\n {{session}}\n\n {{ctx.output_format}}\n \"#\n}\nclass SessionMap {\n coder CoderSession\n debuggerr DebuggerSession\n tester TesterSession\n researcher ResearcherSession\n uiExpert UIExpertSession\n}\n\ntype Role = \"user\" | \"assistant\" | \"tool\"\ntype Status = \"in_progress\" | \"halted\" | \"resolved\" | \"done\"\n\nclass DebuggerSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n rawTranscript string?\n}\n\nclass CoderSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass TesterSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass ResearcherSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\n\nclass UIExpertSession {\n taskId int\n role Role\n status Status\n iterationCount int\n timestamp string\n\n content string?\n}\ntest TestName {\n functions [GenerateSubagentSummary]\n args {\n systemPrompt #\"\n \n# ROLE\n\nYou summarize a single completed CoderAgent or DebuggerAgent run into a\nshort digest attached to the orchestrator's persistent state. The\norchestrator should never need to read a sub-agent's full action-by-action\ntranscript once this digest exists.\n\n# RESPONSIBILITIES\n\n1. State what actually happened, in terms the orchestrator (and whichever\n item comes next in the plan) can act on.\n2. List files touched, at the path level, with the action taken on each\n (created/modified/deleted).\n3. Note any decision or tradeoff made that a later step should be aware of\n — e.g. \"extended the existing X util rather than creating a new one;\n later items touching X should expect this.\"\n4. State the outcome plainly: success, failure, or needs-input. If failure,\n point at the relevant error signature rather than re-describing the\n error in prose — that detail already lives in the structured error\n report.\n\n# CONSTRAINTS\n\n- Don't re-narrate the reasoning process, only the outcome and what\n downstream steps need to know.\n- Keep this genuinely short — if it's approaching the length of the\n original transcript, it isn't a summary.\n\n \"#\n subagentType #\"\n coder\n \"#\n session #\"\n [\n {\n \"taskId\": 1,\n \"role\": \"assistant\",\n \"status\": \"done\",\n \"iterationCount\": 3,\n \"timestamp\": \"2026-07-21T08:00:00Z\",\n \"content\": \"Created src/routes/hello.ts with a hello world route.\"\n }\n ]\n \"#\n }\n}\n", "testerAgent.baml": "\n\nclass ErrorResponse{\n error string\n file string\n line int\n}\n// function TestCodebase(systemPrompt: string) -> string{\n\n// client \n// }\nfunction ReframeError(systemPrompt: string, error: string) -> ErrorResponse{\n\n client OpenAIGeneric\n prompt #\"\n {{systemPrompt}}\n {{error}} - unstructured stdout/stderr from a failed\nbuild/lint/test command.\n\n\n {{ctx.output_format}}\n \"#\n}", "uiExpert.baml": "\nclass Design{\n taskId int\n summary string\n}\nclass UIExpertContext{\n userPrompt string\n priorDesigns Design[]\n}\n\nclass DesignVariants{\n prompts string[]\n}\nfunction FramePrompts(systemPrompt: string, userPrompt: string, semanticMem: string) -> DesignVariants{\n client Gemini\n prompt #\"\n {{systemPrompt}}\n {{userPrompt}} - what's being built, already past complexity and\n clarification checks.\n {# {{target_surfaces}} — which pages/components are in initial scope. #}\n\n {{ctx.output_format}}\n \"#\n}\nfunction UIExpertAgent() -> string{\n\n}", } diff --git a/packages/agents/baml_src/subAgents.baml b/packages/agents/baml_src/subAgents.baml index 0791d14..59b7476 100644 --- a/packages/agents/baml_src/subAgents.baml +++ b/packages/agents/baml_src/subAgents.baml @@ -110,58 +110,17 @@ transcript once this digest exists. subagentType #" coder "# - context { - coder { - taskId 1 - role "user" - status "in_progress" - iterationCount 123 - timestamp #" - hello world - "# - content null - } - debuggerr { - taskId 123 - role "user" - status "in_progress" - iterationCount 123 - timestamp #" - hello world - "# - content null - rawTranscript null - } - tester { - taskId 123 - role "user" - status "in_progress" - iterationCount 123 - timestamp #" - hello world - "# - content null - } - researcher { - taskId 123 - role "user" - status "in_progress" - iterationCount 123 - timestamp #" - hello world - "# - content null - } - uiExpert { - taskId 123 - role "user" - status "in_progress" - iterationCount 123 - timestamp #" - hello world - "# - content null - } - } + session #" + [ + { + "taskId": 1, + "role": "assistant", + "status": "done", + "iterationCount": 3, + "timestamp": "2026-07-21T08:00:00Z", + "content": "Created src/routes/hello.ts with a hello world route." + } + ] + "# } }