summaryrefslogtreecommitdiff
path: root/admin-panel/src/server/agents/builder.ts
diff options
context:
space:
mode:
authorArseney300 <Arseney300@gmail.com>2026-03-05 09:47:09 +0700
committerArseney300 <Arseney300@gmail.com>2026-03-05 09:47:09 +0700
commit0885d20ac18c252f6735cd288448d5d93e95b80f (patch)
treeedfb6814e97d4000605d9f6a918c30c6aca9e10c /admin-panel/src/server/agents/builder.ts
parent22749b796d7a5e4efa9494156a3fdcfe39028da7 (diff)
WIP: admin_panel: add featurefeature/admin_panel
Diffstat (limited to 'admin-panel/src/server/agents/builder.ts')
-rw-r--r--admin-panel/src/server/agents/builder.ts64
1 files changed, 64 insertions, 0 deletions
diff --git a/admin-panel/src/server/agents/builder.ts b/admin-panel/src/server/agents/builder.ts
new file mode 100644
index 0000000..4e555be
--- /dev/null
+++ b/admin-panel/src/server/agents/builder.ts
@@ -0,0 +1,64 @@
+import { BaseAgent, type AgentContext, type AgentResult } from './base-agent.js';
+import type { ClaudeResponse } from '../services/claude.service.js';
+
+export class BuilderAgent extends BaseAgent {
+ name = 'builder';
+ templateFile = 'builder.md';
+ model = 'claude-opus-4-20250514';
+
+ protected getSystemPrompt(): string {
+ return 'You are an expert software engineer. Write clean, correct, production-quality code. Follow the plan precisely. Output complete file contents — never use placeholders or ellipses.';
+ }
+
+ protected getMaxTokens(): number {
+ return 16384;
+ }
+
+ protected parseResponse(response: ClaudeResponse, _ctx: AgentContext): AgentResult {
+ const content = response.content;
+
+ // Extract files from ```FILE: path``` blocks
+ const files = parseFileBlocks(content);
+ const summary = extractSection(content, 'Summary') || '';
+ const implNotes = extractSection(content, 'Implementation Notes') || '';
+
+ return {
+ success: true,
+ content,
+ tokensUsed: response.tokensUsed,
+ model: response.model,
+ updates: {
+ implementation_notes: implNotes || summary,
+ status: 'impl_review',
+ // files are handled by pipeline.service.ts which reads them from content
+ },
+ message: `Implemented ${files.length} file(s)`,
+ };
+ }
+}
+
+export interface FileChange {
+ path: string;
+ content: string;
+}
+
+export function parseFileBlocks(text: string): FileChange[] {
+ const files: FileChange[] = [];
+ const regex = /```FILE:\s*(.+?)\n([\s\S]*?)```/g;
+ let match;
+
+ while ((match = regex.exec(text)) !== null) {
+ files.push({
+ path: match[1].trim(),
+ content: match[2],
+ });
+ }
+
+ return files;
+}
+
+function extractSection(text: string, heading: string): string | null {
+ const regex = new RegExp(`###\\s*${heading}\\s*\\n([\\s\\S]*?)(?=###|$)`, 'i');
+ const match = text.match(regex);
+ return match ? match[1].trim() : null;
+}