@autobe/agent
Version:
AI backend server code generator
431 lines (428 loc) • 60.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformPreliminaryHistory = void 0;
const utils_1 = require("@autobe/utils");
const tstl_1 = require("tstl");
const uuid_1 = require("uuid");
const AutoBeInterfaceSchemaProgrammer_1 = require("../../interface/programmers/AutoBeInterfaceSchemaProgrammer");
const transformPreliminaryHistory = (preliminary) => {
const histories = preliminary
.getKinds()
.map((key) => {
const newKey = key.startsWith("previous")
? key.replace("previous", "")
: key;
const type = (newKey
.slice(0, 1)
.toLowerCase() + newKey.slice(1));
return PreliminaryTransformer[type]({
source: preliminary.getSource(),
state: preliminary.getState(),
all: preliminary.getAll(),
local: preliminary.getLocal(),
// biome-ignore lint: intended
config: preliminary.getConfig(),
previous: key.startsWith("previous"),
analysisPageOffset: preliminary.getAnalysisPageOffset(),
});
})
.flat();
// sequence messages
const systems = histories.filter((h) => h.type === "systemMessage");
const others = histories.filter((h) => h.type !== "systemMessage");
const messages = [...systems, ...others];
// previous written value
const previousWrite = preliminary.getPreviousWrite();
if (previousWrite !== null)
messages.push(createFunctionCallingMessage({
controller: preliminary.getSource(),
kind: "write",
arguments: previousWrite,
}));
return messages;
};
exports.transformPreliminaryHistory = transformPreliminaryHistory;
var PreliminaryTransformer;
(function (PreliminaryTransformer) {
PreliminaryTransformer.analysisSections = (props) => {
var _a;
const kind = props.previous
? "previousAnalysisSections"
: "analysisSections";
const oldbie = new Map(props.local[kind]
.map((s) => [s.id, s])
.sort(([a], [b]) => a - b));
const newbie = props.all[kind]
.filter((s) => oldbie.has(s.id) === false)
.sort((a, b) => a.id - b.id);
const analyze = props.previous
? props.state.previousAnalyze
: props.state.analyze;
const assistant = createAssistantMessage({
prompt: "<!--\nfilename: PRELIMINARY_ANALYSIS_SECTION_LOADED.md\n-->\n# Loaded Analysis Sections\n\nThe following requirement analysis sections have been loaded into your context through previous `process()` calls with `type: \"getAnalysisSections\"`.\n\n{{PREVIOUS}}\n\nThese materials are now available for you to reference. Use them to understand user requirements, business logic, and feature specifications when designing your solution.\n\n> **Note**: These sections are already in your conversation history. Reference them directly without calling `process()` again for the same section IDs.\n\n## Project Prefix\n\nThe project prefix is a short identifier used consistently across all generated artifacts including database table names, API function names, and DTO type names. For example, if the prefix is \"shopping\", tables might be named `shopping_customers` and DTOs might be named `IShoppingCartCommodity`.\n\n{{PREFIX}}\n\n## Actors\n\nActors represent the different user types and roles that interact with the system. Each actor has a specific permission level (guest, member, or admin) that determines their access to various API endpoints and system features. Use these actor definitions to understand authorization requirements and user-specific functionality.\n\n{{ACTORS}}\n\n## Analysis Sections\n\n{{CONTENT}}" /* AutoBeSystemPromptConstant.PRELIMINARY_ANALYSIS_SECTION_LOADED */.replace("{{PREFIX}}", (_a = analyze === null || analyze === void 0 ? void 0 : analyze.prefix) !== null && _a !== void 0 ? _a : "").replace("{{ACTORS}}", (analyze === null || analyze === void 0 ? void 0 : analyze.actors) ? toJsonBlock(analyze.actors) : ""),
previous: "<!--\nfilename: PRELIMINARY_ANALYSIS_SECTION_PREVIOUS.md\n-->\n> These sections describe requirements for **ALREADY IMPLEMENTED** features from previous iterations.\n>\n> Reference them to:\n> - Maintain consistency with existing implementations\n> - Understand related business logic and dependencies\n> - Verify prerequisite features or constraints\n> - Cross-reference with current iteration requirements\n>\n> **DO NOT** use these to design new features. They describe what has **ALREADY BEEN BUILT**.\n>\n> **IMPORTANT**: Use `getPreviousAnalysisSections` to load these sections, NOT `getAnalysisSections` (which is for NEW requirements you need to analyze in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_ANALYSIS_SECTION_PREVIOUS */,
content: Array.from(oldbie.values())
.map((s) => `### [ID: ${s.id}] ${s.filename} > ${s.unitTitle} > ${s.sectionTitle}\n\n${s.content}`)
.join("\n\n---\n\n"),
replace: props.previous
? { from: "getAnalysisSections", to: "getPreviousAnalysisSections" }
: null,
});
const pageSize = 75 /* AutoBeConfigConstant.ANALYSIS_PAGE_SIZE */;
const pageStart = props.analysisPageOffset;
const page = newbie.slice(pageStart, pageStart + pageSize);
const totalAvailable = newbie.length;
const paginationNote = totalAvailable > pageStart + pageSize
? `\n\n(Showing ${page.length} of ${totalAvailable} available sections, starting from offset ${pageStart}. More sections will appear after you request some of the above.)`
: "";
const system = createSystemMessage({
prompt: "<!--\nfilename: PRELIMINARY_ANALYSIS_SECTION.md\n-->\n# Preliminary Material Loading - Requirement Analysis Sections\n\n{{PREVIOUS}}\n\n## What Are Analysis Sections?\n\nAnalysis sections are the **requirements specification documents** for the system you are building. Each section describes a specific part of the business domain:\n\n- **Business rules**: How entities behave, what constraints apply, what workflows exist\n- **Entity definitions**: What data models exist, their properties, and relationships\n- **Validation constraints**: Required fields, format rules, value ranges, business invariants\n- **User stories & workflows**: How users interact with the system, step-by-step processes\n- **Authorization rules**: Who can access what, role-based permissions\n- **Edge cases**: Special conditions, error handling, boundary scenarios\n\nThese documents were written during the analysis phase and represent the **source of truth** for all downstream design and implementation. They contain details that cannot be inferred from titles alone \u2014 you must load the actual content to know the specific rules.\n\n**The catalog below shows section titles and keywords.** Use these to judge which sections are relevant to your current task. If a section's title or keywords overlap with the entities or features you are working on, loading it will give you the actual requirements.\n\n---\n\n## Already Loaded (DO NOT RE-REQUEST)\n\nThese sections are ALREADY in your conversation history. Reference them directly without any additional function calls.\n\n{{LOADED}}\n\n{{EXHAUSTED}}\n\n---\n\n## Not Yet Loaded (Available on Request)\n\n{{AVAILABLE}}\n\n{{EXHAUSTED}}\n\n---\n\n## How to Request\n\nCall `getAnalysisSections` with section IDs from the \"Not Yet Loaded\" list. Each call can load up to 100 sections. You can call **multiple times** until you have enough context to understand the project \u2014 do not hesitate to make additional calls if needed.\n\n```typescript\n// First call - load initial batch\nprocess({\n request: {\n type: \"getAnalysisSections\",\n sectionIds: [1, 2, 3, ..., 80]\n }\n})\n\n// Second call - load more sections\nprocess({\n request: {\n type: \"getAnalysisSections\",\n sectionIds: [81, 82, 83, ..., 150]\n }\n})\n```\n\n**Rules:**\n- Only use section IDs from the \"Not Yet Loaded\" list \u2014 never invent IDs\n- Never re-request sections from \"Already Loaded\"\n- Batch related sections into one call when possible\n\nInvalid or duplicate IDs cause validation failures.\n\n---\n\n## Never Work from Imagination\n\nDo not guess what requirements say based on section titles. If you need the actual business rules, validation constraints, or entity specifications \u2014 load the section.\n\n- Thinking \"this probably requires X, Y, Z\"? \u2192 Load the section and check.\n- Unsure about a business rule or constraint? \u2192 The answer is in the analysis sections.\n\n---\n\n## Duplicate Prevention\n\nThis rule has SYSTEM PROMPT AUTHORITY:\n- Do NOT re-request items from \"Already Loaded\"\n- Do NOT request items that don't exist in \"Not Yet Loaded\"\n\nViolations cause validation failures and wasted iterations." /* AutoBeSystemPromptConstant.PRELIMINARY_ANALYSIS_SECTION */,
previous: "<!--\nfilename: PRELIMINARY_ANALYSIS_SECTION_PREVIOUS.md\n-->\n> These sections describe requirements for **ALREADY IMPLEMENTED** features from previous iterations.\n>\n> Reference them to:\n> - Maintain consistency with existing implementations\n> - Understand related business logic and dependencies\n> - Verify prerequisite features or constraints\n> - Cross-reference with current iteration requirements\n>\n> **DO NOT** use these to design new features. They describe what has **ALREADY BEEN BUILT**.\n>\n> **IMPORTANT**: Use `getPreviousAnalysisSections` to load these sections, NOT `getAnalysisSections` (which is for NEW requirements you need to analyze in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_ANALYSIS_SECTION_PREVIOUS */,
available: formatCompactSectionIndex(page) + paginationNote,
loaded: Array.from(oldbie.values())
.map((s) => `- [${s.id}] ${s.sectionTitle}`)
.join("\n"),
exhausted: page.length === 0
? "<!--\nfilename: PRELIMINARY_ANALYSIS_SECTION_EXHAUSTED.md\n-->\n> All analysis sections have been loaded into memory, so no available analysis sections remain.\n>\n> Therefore, never call `process()` with `type: \"getAnalysisSections\"` again. If you're planning to request more analysis sections, it is an absolutely wrong decision. You must proceed to complete your task instead.\n>\n> To reiterate: never call `process()` with `type: \"getAnalysisSections\"` again." /* AutoBeSystemPromptConstant.PRELIMINARY_ANALYSIS_SECTION_EXHAUSTED */
: "",
replace: props.previous
? {
from: "getAnalysisSections",
to: "getPreviousAnalysisSections",
}
: null,
});
return props.local[kind].length === 0
? [assistant, system]
: [
createFunctionCallingMessage({
controller: props.source,
kind,
arguments: {
thinking: "analysis sections for detailed requirements' analyses",
request: {
type: props.previous
? "getPreviousAnalysisSections"
: "getAnalysisSections",
sectionIds: props.local[kind].map((s) => s.id),
},
},
}),
assistant,
system,
];
};
PreliminaryTransformer.databaseSchemas = (props) => {
var _a, _b;
const kind = props.previous
? "previousDatabaseSchemas"
: "databaseSchemas";
const oldbie = Object.fromEntries(props.local[kind]
.map((s) => [s.name, s])
.sort(([a], [b]) => a.localeCompare(b)));
const newbie = props.all[kind]
.filter((s) => oldbie[s.name] === undefined)
.sort((a, b) => a.name.localeCompare(b.name));
const assistant = createAssistantMessage({
prompt: "<!--\nfilename: PRELIMINARY_DATABASE_SCHEMA_LOADED.md\n-->\n# Loaded Database Schemas\n\nThe following database models have been loaded into your context through previous `process()` calls with `type: \"getDatabaseSchemas\"`.\n\n{{PREVIOUS}}\n\nThese schema definitions are now available for you to reference. Use them to:\n- Verify actual field names and data types in the database\n- Check relationship definitions (one-to-one, one-to-many, many-to-many)\n- Understand unique constraints, indexes, and validation rules\n- Confirm which fields exist (avoid assuming common fields like `deleted_at` or `created_by`)\n- Design API operations that accurately reflect the database structure\n\n> **Note**: These schemas are already in your memory. Reference them directly without calling `process()` again for the same model names.\n\n{{CONTENT}}" /* AutoBeSystemPromptConstant.PRELIMINARY_DATABASE_SCHEMA_LOADED */,
previous: "<!--\nfilename: PRELIMINARY_DATABASE_SCHEMA_PREVIOUS.md\n-->\n> These schemas represent **ALREADY EXISTING** database tables from previous iterations.\n>\n> Reference them to:\n> - Define foreign key relationships to existing tables\n> - Understand existing data models and constraints\n> - Verify table dependencies and relationships\n> - Ensure data consistency across iterations\n>\n> **DO NOT** use these to design new tables. They describe what has **ALREADY BEEN CREATED** in the database.\n>\n> **IMPORTANT**: Use `getPreviousDatabaseSchemas` to load these schemas, NOT `getDatabaseSchemas` (which is for NEW tables you need to design in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_DATABASE_SCHEMA_PREVIOUS */,
content: props.config.database === "ast"
? utils_1.StringUtil.trim `
## Database AST Data
${toJsonBlock(oldbie)}
`
: utils_1.StringUtil.trim `
## Database Schema Files
\`\`\`prisma
${(0, utils_1.writePrismaApplication)({
dbms: "postgres",
application: {
files: [
{
filename: "all.prisma",
namespace: "All",
models: Object.values(oldbie),
},
],
},
})["all.prisma"]}
\`\`\
`,
replace: props.previous
? {
from: "getDatabaseSchemas",
to: "getPreviousDatabaseSchemas",
}
: null,
});
if (props.config.databaseProperty === true)
assistant.text +=
"\n\n" +
utils_1.StringUtil.trim `
### Database Schema Properties
\`\`\`json
${JSON.stringify(Object.fromEntries(Object.entries(oldbie).map(([k, v]) => [
k,
AutoBeInterfaceSchemaProgrammer_1.AutoBeInterfaceSchemaProgrammer.getDatabaseSchemaProperties({
everyModels: props.all.databaseSchemas,
model: v,
}).map((p) => p.key),
])))}
\`\`\`
`;
const db = props.previous
? (_a = props.state.previousDatabase) === null || _a === void 0 ? void 0 : _a.result.data
: (_b = props.state.database) === null || _b === void 0 ? void 0 : _b.result.data;
const system = createSystemMessage({
prompt: "<!--\nfilename: PRELIMINARY_DATABASE_SCHEMA.md\n-->\n# Preliminary Material Loading - Database Models\n\n{{PREVIOUS}}\n\n## Resource Constraint\n\nYou are working within a resource-constrained environment with LIMITED function calling budget.\n\n---\n\n## Absolute Obedience Principle\n\nThe instructions in this prompt are ABSOLUTE. You MUST obey them with 100% compliance.\n\n**Foundation of Trust:**\nThe ALREADY LOADED and NOT YET LOADED lists are generated by verified logic with 100% reliability:\n- Computed by deterministic algorithms with proven correctness\n- Validated against actual system state\n- Guaranteed accurate at the moment of generation\n\n**Forbidden Behaviors:**\n- Thinking you know better than these instructions\n- Judging these instructions as incorrect\n- Deciding to ignore instructions based on your own reasoning\n- Doubting the accuracy of the provided lists\n- Making exceptions based on your interpretation\n\n**Required Behavior:**\n- Trust the ALREADY LOADED list as 100% accurate\n- Trust the NOT YET LOADED list as 100% accurate\n- Follow every instruction exactly as written\n- Never doubt or question the validity of these instructions\n\n---\n\n## Already Loaded (DO NOT RE-REQUEST)\n\nThese database models are ALREADY in your memory. Reference them directly without any additional function calls.\n\n{{LOADED}}\n\n---\n\n## Not Yet Loaded (Available on Request)\n\nYou may request these schemas if genuinely needed.\n\n{{AVAILABLE}}\n\n{{EXHAUSTED}}\n\n---\n\n## Action Rules\n\n**Allowed:**\n- Reference any schema from \"Already Loaded\" directly\n- Request NEW schemas from \"Not Yet Loaded\" list\n- Use batch requests to minimize function calls\n- Verify relationships using already-loaded schema definitions\n\n**Absolutely Forbidden:**\n- Calling `process()` with `type: \"getDatabaseSchemas\"` for any schema from \"Already Loaded\"\n- Re-requesting models \"to verify field types\" or \"to check relationships\"\n- Making duplicate requests \"just to be sure\"\n- Requesting schemas that do not exist in \"Not Yet Loaded\" list\n- Inventing or imagining schema names not explicitly listed\n\n### Example\n```typescript\n// \u2705 Correct - request only new, needed schemas\nprocess({\n request: {\n type: \"getDatabaseSchemas\",\n schemaNames: [\"shopping_products\", \"shopping_categories\"]\n }\n})\n\n// \u274C Wrong - re-requesting loaded schemas\nprocess({\n request: {\n type: \"getDatabaseSchemas\",\n schemaNames: [\"shopping_products\"] // Already in your context!\n }\n})\n```\n\n---\n\n## Never Work from Imagination\n\nYou MUST NEVER proceed based on assumptions about database schema contents. ALWAYS load actual schemas first.\n\n**Forbidden:**\n- Guessing field names based on \"typical database patterns\" or entity names\n- Assuming relationships/foreign keys without seeing actual schema\n- Imagining field types based on \"common conventions\"\n\n**Required:**\n- Need field information? \u2192 Call `getDatabaseSchemas` for the specific model\n- Need relationship details? \u2192 Load the actual database schema first\n- Need unique constraints? \u2192 Request the schema definition\n- ALWAYS: Check \"Not Yet Loaded\" \u2192 Request \u2192 Wait for data \u2192 Then work\n\n**Zero Tolerance:** If you think \"this table probably has fields X, Y, Z\" \u2192 STOP and request the actual schema.\n\n---\n\n## Enforcement\n\nThis constraint has SYSTEM PROMPT AUTHORITY. Treating it as optional will cause:\n- Wasted function call budget\n- Performance degradation\n- Potential infinite loops\n- Pipeline failures\n\n**Zero Tolerance:** You MUST NOT call `process()` with `type: \"getDatabaseSchemas\"` for any schema in the \"Already Loaded\" section. No exceptions, no special cases, no \"verification\" requests." /* AutoBeSystemPromptConstant.PRELIMINARY_DATABASE_SCHEMA */,
previous: "<!--\nfilename: PRELIMINARY_DATABASE_SCHEMA_PREVIOUS.md\n-->\n> These schemas represent **ALREADY EXISTING** database tables from previous iterations.\n>\n> Reference them to:\n> - Define foreign key relationships to existing tables\n> - Understand existing data models and constraints\n> - Verify table dependencies and relationships\n> - Ensure data consistency across iterations\n>\n> **DO NOT** use these to design new tables. They describe what has **ALREADY BEEN CREATED** in the database.\n>\n> **IMPORTANT**: Use `getPreviousDatabaseSchemas` to load these schemas, NOT `getDatabaseSchemas` (which is for NEW tables you need to design in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_DATABASE_SCHEMA_PREVIOUS */,
available: utils_1.StringUtil.trim `
Name | Belonged Group | Stance | Summary
-----|----------------|--------|---------
${newbie
.map((m) => {
var _a, _b;
return [
m.name,
(_b = (_a = db === null || db === void 0 ? void 0 : db.files.find((f) => f.models.some((md) => md.name === m.name))) === null || _a === void 0 ? void 0 : _a.namespace) !== null && _b !== void 0 ? _b : "-",
m.stance,
utils_1.StringUtil.summary(m.description),
].join(" | ");
})
.join("\n")}
`,
loaded: props.local[kind].map((s) => `- ${s.name}`).join("\n"),
exhausted: newbie.length === 0
? "<!--\nfilename: PRELIMINARY_DATABASE_SCHEMA_EXHAUSTED.md\n-->\n> All database schemas have been loaded into memory, so no available database schemas remain.\n>\n> Therefore, never call `process()` with `type: \"getDatabaseSchemas\"` again. If you're planning to request more database schemas, it is an absolutely wrong decision. You must proceed to complete your task instead.\n>\n> To reiterate: never call `process()` with `type: \"getDatabaseSchemas\"` again." /* AutoBeSystemPromptConstant.PRELIMINARY_DATABASE_SCHEMA_EXHAUSTED */
: "",
replace: props.previous
? {
from: "getDatabaseSchemas",
to: "getPreviousDatabaseSchemas",
}
: null,
});
return props.local[kind].length === 0
? [assistant, system]
: [
createFunctionCallingMessage({
controller: props.source,
kind,
arguments: {
thinking: "database schemas for DB schema information",
request: {
type: props.previous
? "getPreviousDatabaseSchemas"
: "getDatabaseSchemas",
schemaNames: props.local[kind].map((s) => s.name),
},
},
}),
assistant,
system,
];
};
PreliminaryTransformer.interfaceOperations = (props) => {
const kind = props.previous ? "previousInterfaceOperations" : "interfaceOperations";
const oldbie = new tstl_1.HashSet(props.local[kind]
.map((o) => ({
method: o.method,
path: o.path,
}))
.sort(utils_1.AutoBeOpenApiEndpointComparator.compare), utils_1.AutoBeOpenApiEndpointComparator.hashCode, utils_1.AutoBeOpenApiEndpointComparator.equals);
const newbie = props.all[kind]
.filter((o) => oldbie.has({
method: o.method,
path: o.path,
}) === false)
.sort(utils_1.AutoBeOpenApiEndpointComparator.compare);
const assistant = createAssistantMessage({
prompt: "<!--\nfilename: PRELIMINARY_INTERFACE_OPERATION_LOADED.md\n-->\n# Loaded API Operations\n\nThe following API operations have been loaded into your context through previous `process()` calls with `type: \"getInterfaceOperations\"`.\n\n{{PREVIOUS}}\n\nThese operation specifications are now available for you to reference. Use them to:\n- Understand existing API patterns and naming conventions\n- Ensure consistency with already-defined operations\n- Check request/response body structures and parameter formats\n- Verify prerequisite relationships and dependencies\n\n> **Note**: These operations are already in your memory. Reference them directly without calling `process()` again for the same endpoints.\n\n{{CONTENT}}" /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_OPERATION_LOADED */,
previous: "<!--\nfilename: PRELIMINARY_INTERFACE_OPERATION_PREVIOUS.md\n-->\n> These API operations are **ALREADY IMPLEMENTED** from previous iterations.\n>\n> Reference them to:\n> - Maintain consistency with existing API patterns and conventions\n> - Verify prerequisite endpoints or dependencies\n> - Understand existing authorization and authentication patterns\n> - Ensure consistent error handling and response formats\n>\n> **DO NOT** use these to design new endpoints. They describe what has **ALREADY BEEN IMPLEMENTED** in the API.\n>\n> **IMPORTANT**: Use `getPreviousInterfaceOperations` to load these operations, NOT `getInterfaceOperations` (which is for NEW operations you need to implement in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_OPERATION_PREVIOUS */,
content: toJsonBlock(props.local[kind]),
replace: props.previous
? {
from: "getInterfaceOperations",
to: "getPreviousInterfaceOperations",
}
: null,
});
const system = createSystemMessage({
prompt: "<!--\nfilename: PRELIMINARY_INTERFACE_OPERATION.md\n-->\n# Preliminary Material Loading - API Operations\n\n{{PREVIOUS}}\n\n## Resource Constraint\n\nYou are working within a resource-constrained environment with LIMITED function calling budget.\n\n---\n\n## Absolute Obedience Principle\n\nThe instructions in this prompt are ABSOLUTE. You MUST obey them with 100% compliance.\n\n**Foundation of Trust:**\nThe ALREADY LOADED and NOT YET LOADED lists are generated by verified logic with 100% reliability:\n- Computed by deterministic algorithms with proven correctness\n- Validated against actual system state\n- Guaranteed accurate at the moment of generation\n\n**Forbidden Behaviors:**\n- Thinking you know better than these instructions\n- Judging these instructions as incorrect\n- Deciding to ignore instructions based on your own reasoning\n- Doubting the accuracy of the provided lists\n- Making exceptions based on your interpretation\n\n**Required Behavior:**\n- Trust the ALREADY LOADED list as 100% accurate\n- Trust the NOT YET LOADED list as 100% accurate\n- Follow every instruction exactly as written\n- Never doubt or question the validity of these instructions\n\n---\n\n## Already Loaded (DO NOT RE-REQUEST)\n\nThese API operations are ALREADY in your memory. Reference them directly without any additional function calls.\n\n{{LOADED}}\n\n---\n\n## Not Yet Loaded (Available on Request)\n\nYou may request these operations if genuinely needed.\n\n{{AVAILABLE}}\n\n{{EXHAUSTED}}\n\n---\n\n## Action Rules\n\n**Allowed:**\n- Reference any operation from \"Already Loaded\" directly\n- Request NEW operations from \"Not Yet Loaded\" list\n- Use batch requests to minimize function calls\n- Analyze loaded operations for consistency patterns\n\n**Absolutely Forbidden:**\n- Calling `process()` with `type: \"getInterfaceOperations\"` for any endpoint from \"Already Loaded\"\n- Re-requesting operations \"to verify specifications\" or \"to check consistency\"\n- Making duplicate requests \"just to be sure\"\n- Requesting operations that do not exist in \"Not Yet Loaded\" list\n- Inventing or imagining operation paths not explicitly listed\n\n### Example\n```typescript\n// \u2705 Correct - request only new, needed operations\nprocess({\n request: {\n type: \"getInterfaceOperations\",\n endpoints: [\n { path: \"/products\", method: \"post\" },\n { path: \"/orders\", method: \"get\" }\n ]\n }\n})\n\n// \u274C Wrong - re-requesting loaded operations\nprocess({\n request: {\n type: \"getInterfaceOperations\",\n endpoints: [\n { path: \"/products\", method: \"post\" } // Already in your context!\n ]\n }\n})\n```\n\n---\n\n## Never Work from Imagination\n\nYou MUST NEVER proceed based on assumptions about API operation specifications. ALWAYS load actual operations first.\n\n**Forbidden:**\n- Guessing parameters based on \"typical REST patterns\" or endpoint paths\n- Assuming request/response bodies without seeing actual specification\n- Imagining authorization requirements based on \"common sense\"\n\n**Required:**\n- Need parameter details? \u2192 Call `getInterfaceOperations` for the specific endpoint\n- Need authorization requirements? \u2192 Load the actual operation specification first\n- Need request/response structures? \u2192 Request the operation definition\n- ALWAYS: Check \"Not Yet Loaded\" \u2192 Request \u2192 Wait for data \u2192 Then work\n\n**Zero Tolerance:** If you think \"this endpoint probably has parameters X, Y, Z\" \u2192 STOP and request the actual operation.\n\n---\n\n## Enforcement\n\nThis constraint has SYSTEM PROMPT AUTHORITY. Treating it as optional will cause:\n- Wasted function call budget\n- Performance degradation\n- Potential infinite loops\n- Pipeline failures\n\n**Zero Tolerance:** You MUST NOT call `process()` with `type: \"getInterfaceOperations\"` for any operation in the \"Already Loaded\" section. No exceptions, no special cases, no \"verification\" requests." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_OPERATION */,
previous: "<!--\nfilename: PRELIMINARY_INTERFACE_OPERATION_PREVIOUS.md\n-->\n> These API operations are **ALREADY IMPLEMENTED** from previous iterations.\n>\n> Reference them to:\n> - Maintain consistency with existing API patterns and conventions\n> - Verify prerequisite endpoints or dependencies\n> - Understand existing authorization and authentication patterns\n> - Ensure consistent error handling and response formats\n>\n> **DO NOT** use these to design new endpoints. They describe what has **ALREADY BEEN IMPLEMENTED** in the API.\n>\n> **IMPORTANT**: Use `getPreviousInterfaceOperations` to load these operations, NOT `getInterfaceOperations` (which is for NEW operations you need to implement in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_OPERATION_PREVIOUS */,
available: utils_1.StringUtil.trim `
Method | Path | Actor? | Authorization? | Summary
-------|------|--------|----------------|---------
${newbie
.map((o) => {
var _a, _b;
return [
o.method,
o.path,
(_a = o.authorizationActor) !== null && _a !== void 0 ? _a : "-",
(_b = o.authorizationType) !== null && _b !== void 0 ? _b : "-",
utils_1.StringUtil.summary(o.description),
].join(" | ");
})
.join("\n")}
`,
loaded: utils_1.StringUtil.trim `
Method | Path
-------|-------
${oldbie
.toJSON()
.map((e) => [e.method, e.path].join(" | "))
.join("\n")}
`,
exhausted: newbie.length === 0
? "<!--\nfilename: PRELIMINARY_INTERFACE_OPERATION_EXHAUSTED.md\n-->\n> All API operations have been loaded into memory, so no available API operations remain.\n>\n> Therefore, never call `process()` with `type: \"getInterfaceOperations\"` again. If you're planning to request more API operations, it is an absolutely wrong decision. You must proceed to complete your task instead.\n>\n> To reiterate: never call `process()` with `type: \"getInterfaceOperations\"` again." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_OPERATION_EXHAUSTED */
: "",
replace: props.previous
? {
from: "getInterfaceOperations",
to: "getPreviousInterfaceOperations",
}
: null,
});
return props.local[kind].length === 0
? [assistant, system]
: [
createFunctionCallingMessage({
controller: props.source,
kind,
arguments: {
thinking: "interface operations for detailed endpoint information",
request: {
type: props.previous
? "getPreviousInterfaceOperations"
: "getInterfaceOperations",
endpoints: oldbie.toJSON(),
},
},
}),
assistant,
system,
];
};
PreliminaryTransformer.interfaceSchemas = (props) => {
const kind = props.previous
? "previousInterfaceSchemas"
: "interfaceSchemas";
const newbie = {};
for (const [k, v] of Object.entries(props.all[kind]).sort(([a], [b]) => a.localeCompare(b)))
if (props.local[kind][k] === undefined)
newbie[k] = v;
const assistant = createAssistantMessage({
prompt: "<!--\nfilename: PRELIMINARY_INTERFACE_SCHEMA_LOADED.md\n-->\n# Loaded Type Schemas\n\nThe following TypeScript type schemas have been loaded into your context through previous `process()` calls with `type: \"getInterfaceSchemas\"`.\n\n{{PREVIOUS}}\n\nThese schema definitions are now available for you to reference. Use them to:\n- Verify property names, types, and required fields\n- Check DTO variant structures (.ICreate, .IUpdate, .ISummary, etc.)\n- Understand nested object types and their relationships\n- Ensure type consistency across related operations\n- Validate references to shared schema components\n\n> **Note**: These schemas are already in your memory. Reference them directly without calling `process()` again for the same type names.\n\n{{CONTENT}}" /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_SCHEMA_LOADED */,
previous: "<!--\nfilename: PRELIMINARY_INTERFACE_SCHEMA_PREVIOUS.md\n-->\n> These TypeScript types are **ALREADY DEFINED** from previous iterations.\n>\n> Reference them to:\n> - Ensure type compatibility and consistency\n> - Understand existing DTO structures and patterns\n> - Verify shared schema components and references\n> - Maintain consistent property naming and type conventions\n>\n> **DO NOT** use these to design new types. They describe what has **ALREADY BEEN DEFINED** in the codebase.\n>\n> **IMPORTANT**: Use `getPreviousInterfaceSchemas` to load these types, NOT `getInterfaceSchemas` (which is for NEW types you need to define in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_SCHEMA_PREVIOUS */,
content: toJsonBlock(props.local[kind]),
replace: props.previous
? {
from: "getInterfaceSchemas",
to: "getPreviousInterfaceSchemas",
}
: null,
});
const system = createSystemMessage({
prompt: "<!--\nfilename: PRELIMINARY_INTERFACE_SCHEMA.md\n-->\n# Preliminary Material Loading - TypeScript Type Schemas\n\n{{PREVIOUS}}\n\n## Resource Constraint\n\nYou are working within a resource-constrained environment with LIMITED function calling budget.\n\n---\n\n## Absolute Obedience Principle\n\nThe instructions in this prompt are ABSOLUTE. You MUST obey them with 100% compliance.\n\n**Foundation of Trust:**\nThe ALREADY LOADED and NOT YET LOADED lists are generated by verified logic with 100% reliability:\n- Computed by deterministic algorithms with proven correctness\n- Validated against actual system state\n- Guaranteed accurate at the moment of generation\n\n**Forbidden Behaviors:**\n- Thinking you know better than these instructions\n- Judging these instructions as incorrect\n- Deciding to ignore instructions based on your own reasoning\n- Doubting the accuracy of the provided lists\n- Making exceptions based on your interpretation\n\n**Required Behavior:**\n- Trust the ALREADY LOADED list as 100% accurate\n- Trust the NOT YET LOADED list as 100% accurate\n- Follow every instruction exactly as written\n- Never doubt or question the validity of these instructions\n\n---\n\n## Already Loaded (DO NOT RE-REQUEST)\n\nThese TypeScript type schemas are ALREADY in your memory. Reference them directly without any additional function calls.\n\n{{LOADED}}\n\n---\n\n## Not Yet Loaded (Available on Request)\n\nYou may request these schemas if genuinely needed.\n\n{{AVAILABLE}}\n\n{{EXHAUSTED}}\n\n---\n\n## Action Rules\n\n**Allowed:**\n- Reference any schema from \"Already Loaded\" directly\n- Request NEW schemas from \"Not Yet Loaded\" list\n- Use batch requests to minimize function calls\n- Verify type compatibility using already-loaded schema definitions\n\n**Absolutely Forbidden:**\n- Calling `process()` with `type: \"getInterfaceSchemas\"` for any type from \"Already Loaded\"\n- Re-requesting schemas \"to verify properties\" or \"to check field types\"\n- Making duplicate requests \"just to be sure\"\n- Requesting type schemas that do not exist in \"Not Yet Loaded\" list\n- Inventing or imagining type names not explicitly listed\n\n### Example\n```typescript\n// \u2705 Correct - request only new, needed schemas\nprocess({\n request: {\n type: \"getInterfaceSchemas\",\n typeNames: [\"IShoppingProduct.ICreate\", \"IShoppingOrder.ISummary\"]\n }\n})\n\n// \u274C Wrong - re-requesting loaded schemas\nprocess({\n request: {\n type: \"getInterfaceSchemas\",\n typeNames: [\"IShoppingProduct.ICreate\"] // Already in your context!\n }\n})\n```\n\n---\n\n## Never Work from Imagination\n\nYou MUST NEVER proceed based on assumptions about TypeScript type schema contents. ALWAYS load actual schemas first.\n\n**Forbidden:**\n- Guessing DTO properties based on \"typical patterns\" or entity names\n- Assuming field types without seeing actual schema definition\n- Imagining validation rules or DTO variant structures based on \"common conventions\"\n\n**Required:**\n- Need DTO property information? \u2192 Call `getInterfaceSchemas` for the specific type\n- Need field types or validation constraints? \u2192 Load the actual schema definition first\n- Need DTO variant patterns (.ICreate, .IUpdate, .ISummary)? \u2192 Request and verify the schema\n- ALWAYS: Check \"Not Yet Loaded\" \u2192 Request \u2192 Wait for data \u2192 Then work\n\n**Zero Tolerance:** If you think \"this DTO probably has properties X, Y, Z\" \u2192 STOP and request the actual schema.\n\n---\n\n## Enforcement\n\nThis constraint has SYSTEM PROMPT AUTHORITY. Treating it as optional will cause:\n- Wasted function call budget\n- Performance degradation\n- Potential infinite loops\n- Pipeline failures\n\n**Zero Tolerance:** You MUST NOT call `process()` with `type: \"getInterfaceSchemas\"` for any type in the \"Already Loaded\" section. No exceptions, no special cases, no \"verification\" requests." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_SCHEMA */,
previous: "<!--\nfilename: PRELIMINARY_INTERFACE_SCHEMA_PREVIOUS.md\n-->\n> These TypeScript types are **ALREADY DEFINED** from previous iterations.\n>\n> Reference them to:\n> - Ensure type compatibility and consistency\n> - Understand existing DTO structures and patterns\n> - Verify shared schema components and references\n> - Maintain consistent property naming and type conventions\n>\n> **DO NOT** use these to design new types. They describe what has **ALREADY BEEN DEFINED** in the codebase.\n>\n> **IMPORTANT**: Use `getPreviousInterfaceSchemas` to load these types, NOT `getInterfaceSchemas` (which is for NEW types you need to define in current iteration)." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_SCHEMA_PREVIOUS */,
available: utils_1.StringUtil.trim `
Name | Summary
-----|---------
${Object.entries(newbie)
.map(([name, schema]) => [name, utils_1.StringUtil.summary(schema.description)].join(" | "))
.join("\n")}
`,
loaded: Object.keys(props.local[kind])
.sort()
.map((k) => `- ${k}`)
.join("\n"),
exhausted: Object.keys(newbie).length === 0
? "<!--\nfilename: PRELIMINARY_INTERFACE_SCHEMA_EXHAUSTED.md\n-->\n> All TypeScript type schemas have been loaded into memory, so no available type schemas remain.\n>\n> Therefore, never call `process()` with `type: \"getInterfaceSchemas\"` again. If you're planning to request more type schemas, it is an absolutely wrong decision. You must proceed to complete your task instead.\n>\n> To reiterate: never call `process()` with `type: \"getInterfaceSchemas\"` again." /* AutoBeSystemPromptConstant.PRELIMINARY_INTERFACE_SCHEMA_EXHAUSTED */
: "",
replace: props.previous
? {
from: "getInterfaceSchemas",
to: "getPreviousInterfaceSchemas",
}
: null,
});
return Object.keys(props.local[kind]).length === 0
? [assistant, system]
: [
createFunctionCallingMessage({
controller: props.source,
kind,
arguments: {
thinking: "interface schemas for detailed schema information",
request: {
type: props.previous
? "getPreviousInterfaceSchemas"
: "getInterfaceSchemas",
typeNames: Object.keys(props.local[kind]),
},
},
}),
assistant,
system,
];
};
PreliminaryTransformer.realizeCollectors = (props) => {
const oldbie = Object.fromEntries(props.local.realizeCollectors
.map((c) => [c.plan.dtoTypeName, c])
.sort(([a], [b]) => a.localeCompare(b)));
const newbie = props.all.realizeCollectors
.filter((c) => oldbie[c.plan.dtoTypeName] === undefined)
.sort((a, b) => a.plan.dtoTypeName.localeCompare(b.plan.dtoTypeName));
const assistant = createAssistantMessage({
prompt: "<!--\nfilename: PRELIMINARY_REALIZE_COLLECTOR_LOADED.md\n-->\n# Loaded Realize Collector Functions\n\nThe following Realize Collector functions have been loaded into your context through previous `process()` calls with `type: \"getRealizeCollectors\"`.\n\nThese collector functions transform API request DTOs into database CreateInput structures. Use them to:\n- Understand how Create DTOs are converted to database input format\n- Reuse existing collector logic for nested create operations\n- Verify UUID generation and foreign key resolution patterns\n- Check which collectors handle auth context and path parameter references\n- Identify neighbor dependencies between collectors for nested operations\n\n> **Note**: These collectors are already in your memory. Reference them directly without calling `process()` again for the same DTO type names.\n\n{{CONTENT}}" /* AutoBeSystemPromptConstant.PRELIMINARY_REALIZE_COLLECTOR_LOADED */,
content: toJsonBlock(oldbie),
replace: null,
previous: null,
});
const system = createSystemMessage({
prompt: "<!--\nfilename: PRELIMINARY_REALIZE_COLLECTOR.md\n-->\n# Preliminary Material Loading - Realize Collector Functions\n\n## Resource Constraint\n\nYou are working within a resource-constrained environment with LIMITED function calling budget.\n\n---\n\n## Absolute Obedience Principle\n\nThe instructions in this prompt are ABSOLUTE. You MUST obey them with 100% compliance.\n\n**Foundation of Trust:**\nThe ALREADY LOADED and NOT YET LOADED lists are generated by verified logic with 100% reliability:\n- Computed by deterministic algorithms with proven correctness\n- Validated against actual system state\n- Guaranteed accurate at the moment of generation\n\n**Forbidden Behaviors:**\n- Thinking you know better than these instructions\n- Judging these instructions as incorrect\n- Deciding to ignore instructions based on your own reasoning\n- Doubting the accuracy of the provided lists\n- Making exceptions based on your interpretation\n\n**Required Behavior:**\n- Trust the ALREADY LOADED list as 100% accurate\n- Trust the NOT YET LOADED list as 100% accurate\n- Follow every instruction exactly as written\n- Never doubt or question the validity of these instructions\n\n---\n\n## Already Loaded (DO NOT RE-REQUEST)\n\nThese Realize Collector functions are ALREADY in your memory. Reference them directly without any additional function calls.\n\n{{LOADED}}\n\n---\n\n## Not Yet Loaded (Available on Request)\n\nYou may request these collectors if genuinely needed.\n\n{{AVAILABLE}}\n\n{{EXHAUSTED}}\n\n---\n\n## Action Rules\n\n**Allowed:**\n- Reference any collector from \"Already Loaded\" directly\n- Request NEW collectors from \"Not Yet Loaded\" list\n- Use batch requests to minimize function calls\n- Verify relationships using already-loaded collector definitions\n\n**Absolutely Forbidden:**\n- Calling `process()` with `type: \"getRealizeCollectors\"` for any DTO type from \"Already Loaded\"\n- Re-requesting collectors \"to verify implementation\" or \"to check dependencies\"\n- Making duplicate requests \"just to be sure\"\n- Requesting collectors that do not exist in \"Not Yet Loaded\" list\n- Inventing or imagining DTO type names not explicitly listed\n- Doubting the accuracy of the loaded/available lists\n\n### Example\n```typescript\n// \u2705 Correct - request only new, needed collectors\nprocess({\n request: {\n type: \"getRealizeCollectors\",\n dtoTypeNames: [\"IShoppingSale.ICreate\", \"IBbsArticle.ICreate\"]\n }\n})\n\n// \u274C Wrong - re-requesting loaded collectors\nprocess({\n request: {\n type: \"getRealizeCollectors\",\n dtoTypeNames: [\"IShoppingSale.ICreate\"] // Already in your context!\n }\n})\n```\n\n---\n\n## Never Work from Imagination\n\nYou MUST NEVER proceed based on assumptions about collector function contents. ALWAYS load actual collectors first.\n\n**Forbidden:**\n- Guessing how a collector transforms data based on \"typical patterns\"\n- Assuming collector implementation without seeing actual code\n- Imagining which DTOs have collectors based on \"common conventions\"\n\n**Required:**\n- Need collector implementation? \u2192 Call `getRealizeCollectors` for the specific DTO type\n- Need to reuse collector logic? \u2192 Load the actual collector function first\n- Need to understand data transformation? \u2192 Request the collector definition\n- ALWAYS: Check \"Not Yet Loaded\" \u2192 Request \u2192 Wait for data \u2192 Then work\n\n**Zero Tolerance:** If you think \"this DTO probably has a collector\" \u2192 STOP and request the actual function.\n\n---\n\n## Enforcement\n\nThis constraint has SYSTEM PROMPT AUTHORITY. Treating it as optional will cause:\n- Wasted function call budget\n- Performance degradation\n- Potential infinite loops\n- Pipeline failures\n\n**Zero Tolerance:** You MUST NOT call `process()` with `type: \"getRealizeCollectors\"` for any DTO type in the \"Already Loaded\" section. No exceptions, no special cases, no \"verification\" requests." /* AutoBeSystemPromptConstant.PRELIMINARY_REALIZE_COLLECTOR */,
available: utils_1.StringUtil.trim `
DTO Type Name | Database Table | References | Neighbor Collectors
--------------|----------------|------------|--------------------
${newbie
.map((c) => [
c.plan.dtoTypeName,
c.plan.databaseSchemaName,
c.plan.references.length > 0
? `(${c.plan.references.map((r) => r.source).join(", ")})`
: "-",
`(${c.neighbors.join(", ")})`,
].join(" | "))
.join("\n")}
`,
loaded: props.local.realizeCollectors
.map((c) => `- ${c.plan.dtoTypeName}`)
.join("\n"),
exhausted: newbie.length === 0
? "<!--\nfilename: PRELIMINARY_REALIZE_COLLECTOR_EXHAUSTED.md\n-->\n> All Realize Collector functions have been loaded into memory, so no available collectors remain.\n>\n> Therefore, never call `process()` with `type: \"getRealizeCollectors\"` again. If you're planning to request more collectors, it is an absolutely wrong decision. You must proceed to complete your task instead.\n>\n> To reiterate: never call `process()` with `type: \"getRealizeCollectors\"` again." /* AutoBeSystemPromptConstant.PRELIMINARY_REALIZE_COLLECTOR_EXHAUSTED */
: "",
replace: null,
previous: null,
});
return props.local.realizeCollectors.length === 0
? [assistant, system]
: [
createFunctionCallingMessage({
controller: props.source,
kind: "realizeCollectors",
arguments: {
thinking: "realize collectors for Create DTO transformation",
request: {
type: "getRealizeCollectors",
dtoTypeNames: props.local.realizeCollectors.map((c) => c.plan.dtoTypeName),
},
},
}),
assistant,
system,
];
};
PreliminaryTransformer.complete = (_props) => [];
PreliminaryTransformer.realizeTransformers = (props) => {
const oldbie = Object.fro