@autobe/agent 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +4 -1
- package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
- package/lib/factory/createAutoBeApplication.js +1 -1
- package/lib/factory/createAutoBeApplication.js.map +1 -1
- package/lib/index.mjs +1704 -144
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +15 -18
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js +3 -5
- package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js.map +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyze.d.ts +25 -0
- package/lib/orchestrate/analyze/orchestrateAnalyze.js +103 -25
- package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
- package/lib/orchestrate/index.d.ts +1 -1
- package/lib/orchestrate/index.js +1 -1
- package/lib/orchestrate/index.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js +3 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js +3 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js +3 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js.map +1 -1
- package/lib/orchestrate/interface/transformInterfaceHistories.js +26 -0
- package/lib/orchestrate/interface/transformInterfaceHistories.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js +6 -5
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.d.ts +1 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js +21 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js.map +1 -1
- package/lib/orchestrate/{orchestrateTest.d.ts → test/orchestrateTest.d.ts} +2 -2
- package/lib/orchestrate/test/orchestrateTest.js +70 -0
- package/lib/orchestrate/test/orchestrateTest.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +4 -0
- package/lib/orchestrate/test/orchestrateTestCorrect.js +543 -0
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTestProgress.d.ts +4 -0
- package/lib/orchestrate/test/orchestrateTestProgress.js +403 -0
- package/lib/orchestrate/test/orchestrateTestProgress.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTestScenario.d.ts +4 -0
- package/lib/orchestrate/test/orchestrateTestScenario.js +700 -0
- package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +2 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.js +47 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -0
- package/lib/orchestrate/test/transformTestHistories.d.ts +3 -0
- package/lib/orchestrate/test/transformTestHistories.js +74 -0
- package/lib/orchestrate/test/transformTestHistories.js.map +1 -0
- package/lib/orchestrate/test/transformTestProgressHistories.d.ts +2 -0
- package/lib/orchestrate/test/transformTestProgressHistories.js +47 -0
- package/lib/orchestrate/test/transformTestProgressHistories.js.map +1 -0
- package/lib/orchestrate/test/transformTestScenarioHistories.d.ts +4 -0
- package/lib/orchestrate/test/transformTestScenarioHistories.js +176 -0
- package/lib/orchestrate/test/transformTestScenarioHistories.js.map +1 -0
- package/package.json +4 -4
- package/src/constants/AutoBeSystemPromptConstant.ts +4 -1
- package/src/factory/createAutoBeApplication.ts +1 -1
- package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +18 -21
- package/src/orchestrate/analyze/AutoBeAnalyzeReviewer.ts +2 -4
- package/src/orchestrate/analyze/orchestrateAnalyze.ts +53 -20
- package/src/orchestrate/index.ts +1 -1
- package/src/orchestrate/interface/orchestrateInterfaceComplement.ts +3 -1
- package/src/orchestrate/interface/orchestrateInterfaceComponents.ts +3 -1
- package/src/orchestrate/interface/orchestrateInterfaceOperations.ts +3 -1
- package/src/orchestrate/interface/transformInterfaceHistories.ts +25 -0
- package/src/orchestrate/prisma/orchestratePrismaComponent.ts +4 -1
- package/src/orchestrate/prisma/transformPrismaComponentsHistories.ts +21 -0
- package/src/orchestrate/test/orchestrateTest.ts +86 -0
- package/src/orchestrate/test/orchestrateTestCorrect.ts +368 -0
- package/src/orchestrate/test/orchestrateTestProgress.ts +264 -0
- package/src/orchestrate/test/orchestrateTestScenario.ts +178 -0
- package/src/orchestrate/test/transformTestCorrectHistories.ts +51 -0
- package/src/orchestrate/test/transformTestHistories.ts +77 -0
- package/src/orchestrate/test/transformTestProgressHistories.ts +51 -0
- package/src/orchestrate/test/transformTestScenarioHistories.ts +184 -0
- package/lib/orchestrate/orchestrateTest.js +0 -19
- package/lib/orchestrate/orchestrateTest.js.map +0 -1
- package/src/orchestrate/orchestrateTest.ts +0 -18
package/lib/index.mjs
CHANGED
|
@@ -97,8 +97,8 @@ class AutoBeAnalyzeAgent {
|
|
|
97
97
|
vendor: ctx.vendor,
|
|
98
98
|
config: {
|
|
99
99
|
locale: ctx.config?.locale,
|
|
100
|
-
|
|
101
|
-
describe:
|
|
100
|
+
executor: {
|
|
101
|
+
describe: null
|
|
102
102
|
}
|
|
103
103
|
},
|
|
104
104
|
tokenUsage: ctx.usage(),
|
|
@@ -155,21 +155,20 @@ class AutoBeAnalyzeAgent {
|
|
|
155
155
|
});
|
|
156
156
|
const filenames = Object.keys(this.fileMap).join(",");
|
|
157
157
|
const command = `Please proceed with the review of these files only.: ${filenames}`;
|
|
158
|
-
const
|
|
158
|
+
const response = await reviewer.conversate(command);
|
|
159
|
+
const review = response.find((el => el.type === "assistantMessage"));
|
|
159
160
|
if (review) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}), retry - 1);
|
|
172
|
-
}
|
|
161
|
+
this.ctx.dispatch({
|
|
162
|
+
type: "analyzeReview",
|
|
163
|
+
review: review.text,
|
|
164
|
+
created_at: (new Date).toISOString(),
|
|
165
|
+
step: this.ctx.state().analyze?.step ?? 0
|
|
166
|
+
});
|
|
167
|
+
return this.conversate(JSON.stringify({
|
|
168
|
+
user_query: content,
|
|
169
|
+
message: `THIS IS ANSWER OF REVIEW AGENT. FOLLOW THIS INSTRUCTIONS. AND DON'T REQUEST ANYTHING.`,
|
|
170
|
+
review: review.text
|
|
171
|
+
}), retry - 1);
|
|
173
172
|
}
|
|
174
173
|
return `COMPLETE WITHOUT REVIEW`;
|
|
175
174
|
}
|
|
@@ -179,7 +178,7 @@ class AutoBeAnalyzeAgent {
|
|
|
179
178
|
|
|
180
179
|
function createController$1(props) {
|
|
181
180
|
assertSchemaModel(props.model);
|
|
182
|
-
const application = collection$
|
|
181
|
+
const application = collection$c[props.model];
|
|
183
182
|
return {
|
|
184
183
|
protocol: "class",
|
|
185
184
|
name: "Planning",
|
|
@@ -204,7 +203,7 @@ function createController$1(props) {
|
|
|
204
203
|
};
|
|
205
204
|
}
|
|
206
205
|
|
|
207
|
-
const claude$
|
|
206
|
+
const claude$c = {
|
|
208
207
|
model: "claude",
|
|
209
208
|
options: {
|
|
210
209
|
reference: true,
|
|
@@ -450,7 +449,7 @@ const claude$9 = {
|
|
|
450
449
|
} ]
|
|
451
450
|
};
|
|
452
451
|
|
|
453
|
-
const collection$
|
|
452
|
+
const collection$c = {
|
|
454
453
|
chatgpt: {
|
|
455
454
|
model: "chatgpt",
|
|
456
455
|
options: {
|
|
@@ -696,10 +695,10 @@ const collection$9 = {
|
|
|
696
695
|
}))()
|
|
697
696
|
} ]
|
|
698
697
|
},
|
|
699
|
-
claude: claude$
|
|
700
|
-
llama: claude$
|
|
701
|
-
deepseek: claude$
|
|
702
|
-
3.1: claude$
|
|
698
|
+
claude: claude$c,
|
|
699
|
+
llama: claude$c,
|
|
700
|
+
deepseek: claude$c,
|
|
701
|
+
3.1: claude$c,
|
|
703
702
|
"3.0": {
|
|
704
703
|
model: "3.0",
|
|
705
704
|
options: {
|
|
@@ -952,8 +951,8 @@ const AutoBeAnalyzeReviewer = (ctx, input) => {
|
|
|
952
951
|
vendor: ctx.vendor,
|
|
953
952
|
controllers: [],
|
|
954
953
|
config: {
|
|
955
|
-
|
|
956
|
-
describe:
|
|
954
|
+
executor: {
|
|
955
|
+
describe: null
|
|
957
956
|
},
|
|
958
957
|
locale: ctx.config?.locale
|
|
959
958
|
},
|
|
@@ -961,7 +960,7 @@ const AutoBeAnalyzeReviewer = (ctx, input) => {
|
|
|
961
960
|
id: v4(),
|
|
962
961
|
created_at: (new Date).toISOString(),
|
|
963
962
|
type: "systemMessage",
|
|
964
|
-
text: "# Reviewer Agent Operating Guidelines\n\n## Core Principles\n\n* **Only review the document currently being viewed.**\n* Even if there is a section that implies another document, **ignore it.**\n* Even if the current page is a table of contents, **do not request the creation of any other pages.**\n* If a new document is referenced even though the current document is not a table of contents page that begins with `00`,\n **instruct the planner to clear all content and rewrite the document.**\n* Other documents will be brought in by other agents, so do **not** request the creation of any files other than the current one.\n* **Each agent must write only the single page assigned to them.** \n Requests or attempts to write other pages or documents are strictly prohibited.\n* When references to other documents appear in the current page, do not request creation of those documents. Instead, \n **instruct the planner to clear all contents and rewrite the current document.**\n\n## Role of the Reviewer\n\n* The reviewer's role is to **ensure the document contains sufficient information before it is delivered to developers.**\n* Below are all the **links currently referenced in the markdown**. Be sure to refer to them and **ensure the corresponding files are created.**\n* **Do not create files that are not specified in the table of contents.**\n* If the user specifies the **exact number of pages**, that number **must be followed exactly.**\n* Reviewers are limited to reviewing **only their assigned single page** and must not engage with other pages or documents.\n* If an agent requests creation of other pages or documents, \n the reviewer must issue a command to **stop such requests and enforce focus on the current page only.**\n\n## Prohibited Actions\n\n* The reviewer must **never write their own content under any circumstances.**\n* Reviewers are **independent beings and must never be instructed.**\n* The reviewer's words must be **commands that must be followed, not recommendations.**\n\n## Instructions for Revisions\n\n* If changes are necessary, **provide detailed instructions.**\n* Give **clear and concise instructions**, and **avoid unnecessary remarks.**\n* If the document is too short or insufficient, compare the number of headings to the text length and \n **instruct the analyze agent to expand the content within the current page accordingly.**\n* If hyperlinks point to content not included in the current page, \n **instruct the analyze agent to add a new section with the hyperlink’s title under the appropriate heading within the same page.**\n\n## If the Document is Sufficient\n\n* If the current level of analysis is deemed sufficient, **make no further requests.**\n* **Notify that the document is complete.**\n\n---\n\n# Guidelines for Document Volume\n\n* It is recommended to instruct the analyze agent to **write a document longer than 2,000 characters** for sufficient utility
|
|
963
|
+
text: "# Reviewer Agent Operating Guidelines\n\n## Core Principles\n\n* **Only review the document currently being viewed.**\n* Even if there is a section that implies another document, **ignore it.**\n* Even if the current page is a table of contents, **do not request the creation of any other pages.**\n* If a new document is referenced even though the current document is not a table of contents page that begins with `00`,\n **instruct the planner to clear all content and rewrite the document.**\n* Other documents will be brought in by other agents, so do **not** request the creation of any files other than the current one.\n* **Each agent must write only the single page assigned to them.** \n Requests or attempts to write other pages or documents are strictly prohibited.\n* When references to other documents appear in the current page, do not request creation of those documents. Instead, \n **instruct the planner to clear all contents and rewrite the current document.**\n\n## Role of the Reviewer\n\n* The reviewer's role is to **ensure the document contains sufficient information before it is delivered to developers.**\n* Below are all the **links currently referenced in the markdown**. Be sure to refer to them and **ensure the corresponding files are created.**\n* **Do not create files that are not specified in the table of contents.**\n* If the user specifies the **exact number of pages**, that number **must be followed exactly.**\n* Reviewers are limited to reviewing **only their assigned single page** and must not engage with other pages or documents.\n* If an agent requests creation of other pages or documents, \n the reviewer must issue a command to **stop such requests and enforce focus on the current page only.**\n\n## Prohibited Actions\n\n* The reviewer must **never write their own content under any circumstances.**\n* Reviewers are **independent beings and must never be instructed.**\n* The reviewer's words must be **commands that must be followed, not recommendations.**\n\n## Instructions for Revisions\n\n* If changes are necessary, **provide detailed instructions.**\n* Give **clear and concise instructions**, and **avoid unnecessary remarks.**\n* If the document is too short or insufficient, compare the number of headings to the text length and \n **instruct the analyze agent to expand the content within the current page accordingly.**\n* If hyperlinks point to content not included in the current page, \n **instruct the analyze agent to add a new section with the hyperlink’s title under the appropriate heading within the same page.**\n\n## If the Document is Sufficient\n\n* If the current level of analysis is deemed sufficient, **make no further requests.**\n* **Notify that the document is complete.**\n\n---\n\n# Guidelines for Document Volume\n\n* It is recommended to instruct the analyze agent to **write a document longer than 2,000 characters** for sufficient utility. (Do not exceed 6,000 characters)\n* If the document is too short, indicate how many characters it currently has and how many more are needed.\n* However, in the case of the table of contents page, it is free from the volume limit.\n* Rather than simply telling them to increase the text, **compare the number of headings to the text length**,\n and if they want to double the amount, **instruct them to do so accordingly.**\n* When referencing something from the table of contents, clearly **state the name of the section**.\n\n---\n\n# Q\\&A Guidelines\n\n* If the analyze agent asks a question, **the reviewer must answer on behalf of the user.**\n* **Never ask any questions.**\n* **Only give commands.**\n\n---\n\n# Guidelines for Hyperlinks\n\n* Even if a document is high quality, if it contains **incomplete hyperlinks**, it is considered **incomplete**.\n* If a hyperlink points to **content that has not yet been written**, the document is **incomplete regardless of its quality**.\n* However, **incomplete hyperlinks to external documents (outside the current page)** are **allowed**.\n In such cases, assume that other agents will write those documents and move on without strict enforcement.\n* If a hyperlink points to a **heading within the same document** (i.e., an anchor/fragment link):\n\n * That heading **must exist** in the document.\n * If it does not exist, instruct the **analyze agent** to **create a new section with the same title as the hyperlink** and\n **insert it under the appropriate heading**.\n* If a hyperlink points to an **external document**, and the current document is **not a table of contents page starting with `00`**,\n the rule above still applies—**incomplete external links are allowed** and do **not** require clearing or rewriting the document.\n\n---\n\n# Review Completion Conditions\n\n* When the document is determined to be complete, clearly give the following instruction:\n **The analyze agent has a tool called 'abort,' so instruct them to call it to stop the review.**\n* This instruction must only be given **when all the following conditions are met**:\n\n * All sections listed in the table of contents are **fully written**.\n * All referenced hyperlinks are **resolved**.\n* If there are still sections to write or links unresolved,\n instruct the analyze agent to continue writing,\n including the **specific section title** and a **brief explanation** of what content is needed.\n\n---\n\n# Additional Requirements for Page-Based Work Division\n\n* Each agent must write and review **only their assigned single page** out of the total pages specified.\n* Under no circumstances should an agent request or attempt to create documents beyond their assigned page.\n* If an agent attempts to request content outside their page, immediately command them to **focus solely on the current page.**\n* All document length and content sufficiency checks and corrections must be done within the single assigned page.\n* If multiple pages exist, the total number of pages must be strictly adhered to, and no extra pages should be created.\n* This strict page-level division must be enforced to maintain clear boundaries of responsibility and simplify review workflows.\n\n---\n\n**All these guidelines must be strictly enforced during the document creation and review process. Any violations require immediate correction or rewriting commands.**"
|
|
965
964
|
}, {
|
|
966
965
|
id: v4(),
|
|
967
966
|
created_at: (new Date).toISOString(),
|
|
@@ -995,6 +994,9 @@ const orchestrateAnalyze = ctx => async props => {
|
|
|
995
994
|
controllers: [ controller ],
|
|
996
995
|
config: {
|
|
997
996
|
locale: ctx.config?.locale,
|
|
997
|
+
executor: {
|
|
998
|
+
describe: null
|
|
999
|
+
},
|
|
998
1000
|
systemPrompt: {
|
|
999
1001
|
common: () => "# Overview\n\n- You are the agent that determines the form of the entire document.\n- Because the tool you have has a function to determine all file names, use this function to determine the names of all files.\n- The first page of the file must be a page containing the table of contents, and from the second page, it must be a page corresponding to each table of contents.\n- Please clarify that the name of the table of contents page is the table of contents, such as `toc` or `table of content`.\n- Each document must begin with a number in turn, such as `00`, `01`, `02`, `03`.\n- Do not include database schema document."
|
|
1000
1002
|
}
|
|
@@ -1024,12 +1026,13 @@ const orchestrateAnalyze = ctx => async props => {
|
|
|
1024
1026
|
return history;
|
|
1025
1027
|
}
|
|
1026
1028
|
const described = determined.find((el => el.type === "describe"));
|
|
1027
|
-
const
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1029
|
+
const determinedOutput = described?.executes.find((el => el.protocol === "class" && (() => {
|
|
1030
|
+
const _io0 = input => "string" === typeof input.prefix && (Array.isArray(input.files) && input.files.every((elem => "object" === typeof elem && null !== elem && _io1(elem))));
|
|
1031
|
+
const _io1 = input => "string" === typeof input.reason && ("string" === typeof input.filename && RegExp(/(.*)\.md$/).test(input.filename));
|
|
1032
|
+
return input => "object" === typeof input && null !== input && _io0(input);
|
|
1033
|
+
})()(el.value)))?.value;
|
|
1034
|
+
const prefix = determinedOutput.prefix;
|
|
1035
|
+
const describedFiles = determinedOutput.files;
|
|
1033
1036
|
if (describedFiles.length === 0) {
|
|
1034
1037
|
const history = {
|
|
1035
1038
|
id: v4(),
|
|
@@ -1059,6 +1062,7 @@ const orchestrateAnalyze = ctx => async props => {
|
|
|
1059
1062
|
id: v4(),
|
|
1060
1063
|
type: "analyze",
|
|
1061
1064
|
reason: userPlanningRequirements,
|
|
1065
|
+
prefix,
|
|
1062
1066
|
files,
|
|
1063
1067
|
step,
|
|
1064
1068
|
created_at,
|
|
@@ -1068,6 +1072,7 @@ const orchestrateAnalyze = ctx => async props => {
|
|
|
1068
1072
|
ctx.histories().push(history);
|
|
1069
1073
|
ctx.dispatch({
|
|
1070
1074
|
type: "analyzeComplete",
|
|
1075
|
+
prefix,
|
|
1071
1076
|
files,
|
|
1072
1077
|
step,
|
|
1073
1078
|
created_at
|
|
@@ -1091,7 +1096,7 @@ const orchestrateAnalyze = ctx => async props => {
|
|
|
1091
1096
|
|
|
1092
1097
|
function createController(props) {
|
|
1093
1098
|
assertSchemaModel(props.model);
|
|
1094
|
-
const application = collection$
|
|
1099
|
+
const application = collection$b[props.model];
|
|
1095
1100
|
return {
|
|
1096
1101
|
protocol: "class",
|
|
1097
1102
|
name: "Planning",
|
|
@@ -1102,7 +1107,7 @@ function createController(props) {
|
|
|
1102
1107
|
};
|
|
1103
1108
|
}
|
|
1104
1109
|
|
|
1105
|
-
const claude$
|
|
1110
|
+
const claude$b = {
|
|
1106
1111
|
model: "claude",
|
|
1107
1112
|
options: {
|
|
1108
1113
|
reference: true,
|
|
@@ -1111,9 +1116,17 @@ const claude$8 = {
|
|
|
1111
1116
|
functions: [ {
|
|
1112
1117
|
name: "determine",
|
|
1113
1118
|
parameters: {
|
|
1119
|
+
description: " Prefix and files\n\n------------------------------\n\nCurrent Type: {@link IDeterminingInput}",
|
|
1114
1120
|
type: "object",
|
|
1115
1121
|
properties: {
|
|
1122
|
+
prefix: {
|
|
1123
|
+
title: "Prefix",
|
|
1124
|
+
description: "Prefix for file names and all prisma schema files, table, interface, and\nvariable names. For example, if you were to create a bulletin board\nservice, the prefix would be bbs. At this time, the name of the document\nwould be, for example, 00_bbs_table_of_contents, and bbs would have to be\nattached to the name of all documents. This value would then be passed to\nother agents as well, in the form of bbs_article, bbs_article_snapshot, and\nbbs_comments in the table name. Interfaces will likewise be used in\ninterfaces and tests because they originate from the name of prisma scheme.\nDo not use prefixes that are related to the technology stack (e.g., ts_,\napi_, react_) or unnatural prefixes that typically wouldn’t appear in table\nnames or domain models (e.g., zz_, my_, dev_).",
|
|
1125
|
+
type: "string"
|
|
1126
|
+
},
|
|
1116
1127
|
files: {
|
|
1128
|
+
title: "file names and reason to create.",
|
|
1129
|
+
description: "File name must be English. and it must contains the numbering and prefix.",
|
|
1117
1130
|
type: "array",
|
|
1118
1131
|
items: {
|
|
1119
1132
|
description: "Description of the current {@link PickIFilereasonfilename} type:\n\n> From T, pick a set of properties whose keys are in the union K",
|
|
@@ -1134,14 +1147,22 @@ const claude$8 = {
|
|
|
1134
1147
|
}
|
|
1135
1148
|
}
|
|
1136
1149
|
},
|
|
1137
|
-
required: [ "files" ],
|
|
1150
|
+
required: [ "prefix", "files" ],
|
|
1138
1151
|
additionalProperties: false,
|
|
1139
1152
|
$defs: {}
|
|
1140
1153
|
},
|
|
1141
1154
|
output: {
|
|
1155
|
+
description: "Current Type: {@link IDeterminingInput}",
|
|
1142
1156
|
type: "object",
|
|
1143
1157
|
properties: {
|
|
1158
|
+
prefix: {
|
|
1159
|
+
title: "Prefix",
|
|
1160
|
+
description: "Prefix for file names and all prisma schema files, table, interface, and\nvariable names. For example, if you were to create a bulletin board\nservice, the prefix would be bbs. At this time, the name of the document\nwould be, for example, 00_bbs_table_of_contents, and bbs would have to be\nattached to the name of all documents. This value would then be passed to\nother agents as well, in the form of bbs_article, bbs_article_snapshot, and\nbbs_comments in the table name. Interfaces will likewise be used in\ninterfaces and tests because they originate from the name of prisma scheme.\nDo not use prefixes that are related to the technology stack (e.g., ts_,\napi_, react_) or unnatural prefixes that typically wouldn’t appear in table\nnames or domain models (e.g., zz_, my_, dev_).",
|
|
1161
|
+
type: "string"
|
|
1162
|
+
},
|
|
1144
1163
|
files: {
|
|
1164
|
+
title: "file names and reason to create.",
|
|
1165
|
+
description: "File name must be English. and it must contains the numbering and prefix.",
|
|
1145
1166
|
type: "array",
|
|
1146
1167
|
items: {
|
|
1147
1168
|
description: "Description of the current {@link PickIFilereasonfilename} type:\n\n> From T, pick a set of properties whose keys are in the union K",
|
|
@@ -1162,13 +1183,17 @@ const claude$8 = {
|
|
|
1162
1183
|
}
|
|
1163
1184
|
}
|
|
1164
1185
|
},
|
|
1165
|
-
required: [ "files" ]
|
|
1186
|
+
required: [ "prefix", "files" ]
|
|
1166
1187
|
},
|
|
1167
1188
|
description: "Determining the Initial File List.\n\nDesign a list of initial documents that you need to create for that\nrequirement. The list of documents is determined only by the name of the\nfile. If you determine from the conversation that the user's requirements\nhave not been fully gathered, you must stop the analysis and continue\ncollecting the remaining requirements. In this case, you do not need to\ngenerate any files. Simply pass an empty array to `input.files`, which is\nthe input value for the `determine` tool.",
|
|
1168
1189
|
validate: (() => {
|
|
1169
|
-
const _io0 = input => Array.isArray(input.files) && input.files.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
1190
|
+
const _io0 = input => "string" === typeof input.prefix && (Array.isArray(input.files) && input.files.every((elem => "object" === typeof elem && null !== elem && _io1(elem))));
|
|
1170
1191
|
const _io1 = input => "string" === typeof input.reason && ("string" === typeof input.filename && RegExp(/(.*)\.md$/).test(input.filename));
|
|
1171
|
-
const _vo0 = (input, _path, _exceptionable = true) => [
|
|
1192
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.prefix || _report(_exceptionable, {
|
|
1193
|
+
path: _path + ".prefix",
|
|
1194
|
+
expected: "string",
|
|
1195
|
+
value: input.prefix
|
|
1196
|
+
}), (Array.isArray(input.files) || _report(_exceptionable, {
|
|
1172
1197
|
path: _path + ".files",
|
|
1173
1198
|
expected: 'Array<Pick<IFile, "reason" | "filename">>',
|
|
1174
1199
|
value: input.files
|
|
@@ -1203,11 +1228,11 @@ const claude$8 = {
|
|
|
1203
1228
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
1204
1229
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
1205
1230
|
path: _path + "",
|
|
1206
|
-
expected: "
|
|
1231
|
+
expected: "IDeterminingInput",
|
|
1207
1232
|
value: input
|
|
1208
1233
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
1209
1234
|
path: _path + "",
|
|
1210
|
-
expected: "
|
|
1235
|
+
expected: "IDeterminingInput",
|
|
1211
1236
|
value: input
|
|
1212
1237
|
}))(input, "$input", true);
|
|
1213
1238
|
const success = 0 === errors.length;
|
|
@@ -1229,7 +1254,7 @@ const claude$8 = {
|
|
|
1229
1254
|
} ]
|
|
1230
1255
|
};
|
|
1231
1256
|
|
|
1232
|
-
const collection$
|
|
1257
|
+
const collection$b = {
|
|
1233
1258
|
chatgpt: {
|
|
1234
1259
|
model: "chatgpt",
|
|
1235
1260
|
options: {
|
|
@@ -1240,9 +1265,17 @@ const collection$8 = {
|
|
|
1240
1265
|
functions: [ {
|
|
1241
1266
|
name: "determine",
|
|
1242
1267
|
parameters: {
|
|
1268
|
+
description: " Prefix and files\n\n------------------------------\n\nCurrent Type: {@link IDeterminingInput}",
|
|
1243
1269
|
type: "object",
|
|
1244
1270
|
properties: {
|
|
1271
|
+
prefix: {
|
|
1272
|
+
title: "Prefix",
|
|
1273
|
+
description: "Prefix for file names and all prisma schema files, table, interface, and\nvariable names. For example, if you were to create a bulletin board\nservice, the prefix would be bbs. At this time, the name of the document\nwould be, for example, 00_bbs_table_of_contents, and bbs would have to be\nattached to the name of all documents. This value would then be passed to\nother agents as well, in the form of bbs_article, bbs_article_snapshot, and\nbbs_comments in the table name. Interfaces will likewise be used in\ninterfaces and tests because they originate from the name of prisma scheme.\nDo not use prefixes that are related to the technology stack (e.g., ts_,\napi_, react_) or unnatural prefixes that typically wouldn’t appear in table\nnames or domain models (e.g., zz_, my_, dev_).",
|
|
1274
|
+
type: "string"
|
|
1275
|
+
},
|
|
1245
1276
|
files: {
|
|
1277
|
+
title: "file names and reason to create.",
|
|
1278
|
+
description: "File name must be English. and it must contains the numbering and prefix.",
|
|
1246
1279
|
type: "array",
|
|
1247
1280
|
items: {
|
|
1248
1281
|
description: "Description of the current {@link PickIFilereasonfilename} type:\n\n> From T, pick a set of properties whose keys are in the union K",
|
|
@@ -1262,14 +1295,22 @@ const collection$8 = {
|
|
|
1262
1295
|
}
|
|
1263
1296
|
}
|
|
1264
1297
|
},
|
|
1265
|
-
required: [ "files" ],
|
|
1298
|
+
required: [ "prefix", "files" ],
|
|
1266
1299
|
additionalProperties: false,
|
|
1267
1300
|
$defs: {}
|
|
1268
1301
|
},
|
|
1269
1302
|
output: {
|
|
1303
|
+
description: "Current Type: {@link IDeterminingInput}",
|
|
1270
1304
|
type: "object",
|
|
1271
1305
|
properties: {
|
|
1306
|
+
prefix: {
|
|
1307
|
+
title: "Prefix",
|
|
1308
|
+
description: "Prefix for file names and all prisma schema files, table, interface, and\nvariable names. For example, if you were to create a bulletin board\nservice, the prefix would be bbs. At this time, the name of the document\nwould be, for example, 00_bbs_table_of_contents, and bbs would have to be\nattached to the name of all documents. This value would then be passed to\nother agents as well, in the form of bbs_article, bbs_article_snapshot, and\nbbs_comments in the table name. Interfaces will likewise be used in\ninterfaces and tests because they originate from the name of prisma scheme.\nDo not use prefixes that are related to the technology stack (e.g., ts_,\napi_, react_) or unnatural prefixes that typically wouldn’t appear in table\nnames or domain models (e.g., zz_, my_, dev_).",
|
|
1309
|
+
type: "string"
|
|
1310
|
+
},
|
|
1272
1311
|
files: {
|
|
1312
|
+
title: "file names and reason to create.",
|
|
1313
|
+
description: "File name must be English. and it must contains the numbering and prefix.",
|
|
1273
1314
|
type: "array",
|
|
1274
1315
|
items: {
|
|
1275
1316
|
description: "Description of the current {@link PickIFilereasonfilename} type:\n\n> From T, pick a set of properties whose keys are in the union K",
|
|
@@ -1289,13 +1330,17 @@ const collection$8 = {
|
|
|
1289
1330
|
}
|
|
1290
1331
|
}
|
|
1291
1332
|
},
|
|
1292
|
-
required: [ "files" ]
|
|
1333
|
+
required: [ "prefix", "files" ]
|
|
1293
1334
|
},
|
|
1294
1335
|
description: "Determining the Initial File List.\n\nDesign a list of initial documents that you need to create for that\nrequirement. The list of documents is determined only by the name of the\nfile. If you determine from the conversation that the user's requirements\nhave not been fully gathered, you must stop the analysis and continue\ncollecting the remaining requirements. In this case, you do not need to\ngenerate any files. Simply pass an empty array to `input.files`, which is\nthe input value for the `determine` tool.",
|
|
1295
1336
|
validate: (() => {
|
|
1296
|
-
const _io0 = input => Array.isArray(input.files) && input.files.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
1337
|
+
const _io0 = input => "string" === typeof input.prefix && (Array.isArray(input.files) && input.files.every((elem => "object" === typeof elem && null !== elem && _io1(elem))));
|
|
1297
1338
|
const _io1 = input => "string" === typeof input.reason && ("string" === typeof input.filename && RegExp(/(.*)\.md$/).test(input.filename));
|
|
1298
|
-
const _vo0 = (input, _path, _exceptionable = true) => [
|
|
1339
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.prefix || _report(_exceptionable, {
|
|
1340
|
+
path: _path + ".prefix",
|
|
1341
|
+
expected: "string",
|
|
1342
|
+
value: input.prefix
|
|
1343
|
+
}), (Array.isArray(input.files) || _report(_exceptionable, {
|
|
1299
1344
|
path: _path + ".files",
|
|
1300
1345
|
expected: 'Array<Pick<IFile, "reason" | "filename">>',
|
|
1301
1346
|
value: input.files
|
|
@@ -1330,11 +1375,11 @@ const collection$8 = {
|
|
|
1330
1375
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
1331
1376
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
1332
1377
|
path: _path + "",
|
|
1333
|
-
expected: "
|
|
1378
|
+
expected: "IDeterminingInput",
|
|
1334
1379
|
value: input
|
|
1335
1380
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
1336
1381
|
path: _path + "",
|
|
1337
|
-
expected: "
|
|
1382
|
+
expected: "IDeterminingInput",
|
|
1338
1383
|
value: input
|
|
1339
1384
|
}))(input, "$input", true);
|
|
1340
1385
|
const success = 0 === errors.length;
|
|
@@ -1355,10 +1400,10 @@ const collection$8 = {
|
|
|
1355
1400
|
})()
|
|
1356
1401
|
} ]
|
|
1357
1402
|
},
|
|
1358
|
-
claude: claude$
|
|
1359
|
-
llama: claude$
|
|
1360
|
-
deepseek: claude$
|
|
1361
|
-
3.1: claude$
|
|
1403
|
+
claude: claude$b,
|
|
1404
|
+
llama: claude$b,
|
|
1405
|
+
deepseek: claude$b,
|
|
1406
|
+
3.1: claude$b,
|
|
1362
1407
|
"3.0": {
|
|
1363
1408
|
model: "3.0",
|
|
1364
1409
|
options: {
|
|
@@ -1371,6 +1416,11 @@ const collection$8 = {
|
|
|
1371
1416
|
parameters: {
|
|
1372
1417
|
type: "object",
|
|
1373
1418
|
properties: {
|
|
1419
|
+
prefix: {
|
|
1420
|
+
type: "string",
|
|
1421
|
+
title: "Prefix",
|
|
1422
|
+
description: "Prefix for file names and all prisma schema files, table, interface, and\nvariable names. For example, if you were to create a bulletin board\nservice, the prefix would be bbs. At this time, the name of the document\nwould be, for example, 00_bbs_table_of_contents, and bbs would have to be\nattached to the name of all documents. This value would then be passed to\nother agents as well, in the form of bbs_article, bbs_article_snapshot, and\nbbs_comments in the table name. Interfaces will likewise be used in\ninterfaces and tests because they originate from the name of prisma scheme.\nDo not use prefixes that are related to the technology stack (e.g., ts_,\napi_, react_) or unnatural prefixes that typically wouldn’t appear in table\nnames or domain models (e.g., zz_, my_, dev_)."
|
|
1423
|
+
},
|
|
1374
1424
|
files: {
|
|
1375
1425
|
type: "array",
|
|
1376
1426
|
items: {
|
|
@@ -1390,15 +1440,23 @@ const collection$8 = {
|
|
|
1390
1440
|
required: [ "reason", "filename" ],
|
|
1391
1441
|
description: "Description of the current {@link PickIFilereasonfilename} type:\n\n> From T, pick a set of properties whose keys are in the union K",
|
|
1392
1442
|
additionalProperties: false
|
|
1393
|
-
}
|
|
1443
|
+
},
|
|
1444
|
+
title: "file names and reason to create.",
|
|
1445
|
+
description: "File name must be English. and it must contains the numbering and prefix."
|
|
1394
1446
|
}
|
|
1395
1447
|
},
|
|
1396
|
-
required: [ "files" ],
|
|
1448
|
+
required: [ "prefix", "files" ],
|
|
1449
|
+
description: " Prefix and files\n\n------------------------------\n\nCurrent Type: {@link IDeterminingInput}",
|
|
1397
1450
|
additionalProperties: false
|
|
1398
1451
|
},
|
|
1399
1452
|
output: {
|
|
1400
1453
|
type: "object",
|
|
1401
1454
|
properties: {
|
|
1455
|
+
prefix: {
|
|
1456
|
+
type: "string",
|
|
1457
|
+
title: "Prefix",
|
|
1458
|
+
description: "Prefix for file names and all prisma schema files, table, interface, and\nvariable names. For example, if you were to create a bulletin board\nservice, the prefix would be bbs. At this time, the name of the document\nwould be, for example, 00_bbs_table_of_contents, and bbs would have to be\nattached to the name of all documents. This value would then be passed to\nother agents as well, in the form of bbs_article, bbs_article_snapshot, and\nbbs_comments in the table name. Interfaces will likewise be used in\ninterfaces and tests because they originate from the name of prisma scheme.\nDo not use prefixes that are related to the technology stack (e.g., ts_,\napi_, react_) or unnatural prefixes that typically wouldn’t appear in table\nnames or domain models (e.g., zz_, my_, dev_)."
|
|
1459
|
+
},
|
|
1402
1460
|
files: {
|
|
1403
1461
|
type: "array",
|
|
1404
1462
|
items: {
|
|
@@ -1418,17 +1476,24 @@ const collection$8 = {
|
|
|
1418
1476
|
required: [ "reason", "filename" ],
|
|
1419
1477
|
description: "Description of the current {@link PickIFilereasonfilename} type:\n\n> From T, pick a set of properties whose keys are in the union K",
|
|
1420
1478
|
additionalProperties: false
|
|
1421
|
-
}
|
|
1479
|
+
},
|
|
1480
|
+
title: "file names and reason to create.",
|
|
1481
|
+
description: "File name must be English. and it must contains the numbering and prefix."
|
|
1422
1482
|
}
|
|
1423
1483
|
},
|
|
1424
|
-
required: [ "files" ],
|
|
1484
|
+
required: [ "prefix", "files" ],
|
|
1485
|
+
description: "Current Type: {@link IDeterminingInput}",
|
|
1425
1486
|
additionalProperties: false
|
|
1426
1487
|
},
|
|
1427
1488
|
description: "Determining the Initial File List.\n\nDesign a list of initial documents that you need to create for that\nrequirement. The list of documents is determined only by the name of the\nfile. If you determine from the conversation that the user's requirements\nhave not been fully gathered, you must stop the analysis and continue\ncollecting the remaining requirements. In this case, you do not need to\ngenerate any files. Simply pass an empty array to `input.files`, which is\nthe input value for the `determine` tool.",
|
|
1428
1489
|
validate: (() => {
|
|
1429
|
-
const _io0 = input => Array.isArray(input.files) && input.files.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
1490
|
+
const _io0 = input => "string" === typeof input.prefix && (Array.isArray(input.files) && input.files.every((elem => "object" === typeof elem && null !== elem && _io1(elem))));
|
|
1430
1491
|
const _io1 = input => "string" === typeof input.reason && ("string" === typeof input.filename && RegExp(/(.*)\.md$/).test(input.filename));
|
|
1431
|
-
const _vo0 = (input, _path, _exceptionable = true) => [
|
|
1492
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.prefix || _report(_exceptionable, {
|
|
1493
|
+
path: _path + ".prefix",
|
|
1494
|
+
expected: "string",
|
|
1495
|
+
value: input.prefix
|
|
1496
|
+
}), (Array.isArray(input.files) || _report(_exceptionable, {
|
|
1432
1497
|
path: _path + ".files",
|
|
1433
1498
|
expected: 'Array<Pick<IFile, "reason" | "filename">>',
|
|
1434
1499
|
value: input.files
|
|
@@ -1463,11 +1528,11 @@ const collection$8 = {
|
|
|
1463
1528
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
1464
1529
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
1465
1530
|
path: _path + "",
|
|
1466
|
-
expected: "
|
|
1531
|
+
expected: "IDeterminingInput",
|
|
1467
1532
|
value: input
|
|
1468
1533
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
1469
1534
|
path: _path + "",
|
|
1470
|
-
expected: "
|
|
1535
|
+
expected: "IDeterminingInput",
|
|
1471
1536
|
value: input
|
|
1472
1537
|
}))(input, "$input", true);
|
|
1473
1538
|
const success = 0 === errors.length;
|
|
@@ -1521,7 +1586,7 @@ const transformInterfaceHistories = (state, systemMessage) => {
|
|
|
1521
1586
|
id: v4(),
|
|
1522
1587
|
created_at: (new Date).toISOString(),
|
|
1523
1588
|
type: "assistantMessage",
|
|
1524
|
-
text: [ "Requirement analysis and Prisma DB schema generation are ready.", "", "Call the provided tool function to generate the OpenAPI document", "referencing below requirement analysis and Prisma DB schema.", "", `## User Request`, "", state.analyze.reason, "", `## Requirement Analysis Report`, "", "```json", JSON.stringify(state.analyze.files), "```" ].join("\n")
|
|
1589
|
+
text: [ "Requirement analysis and Prisma DB schema generation are ready.", "", "Call the provided tool function to generate the OpenAPI document", "referencing below requirement analysis and Prisma DB schema.", "", `## User Request`, "", state.analyze.reason, "", "## Prefix", "", `* Prefix provided by the user: ${state.analyze?.prefix ?? null}`, `* When defining TypeScript interfaces, the interface name must be in PascalCase. The property names, however, do not need to follow this convention.`, "", "The user wants all TypeScript identifiers (such as interfaces, types, and functions) to start with the prefix provided below. ", "If the prefix is `null`, it should be ignored. ", "If a prefix is provided, all identifier names **must begin with it**.", "", "However, if there is a special-purpose prefix like `mv` (e.g., for materialized view handlers or performance-related utilities), it **must precede** the given prefix.", "", "## Prefix Example", "", "If the prefix is `shopping`, then names should be like:", "", "* `shoppingSales`", "* `shoppingSaleOptions`", "* `shoppingCreateSale()`", "", "In cases where an identifier is created for performance-optimized logic or special processing (e.g., materialized view handling), the `mv` prefix must come first. ", "For example:", "", "* `mvShoppingDailyStats`", "* `mvShoppingAggregateView`", "", `## Requirement Analysis Report`, "", "```json", JSON.stringify(state.analyze.files), "```" ].join("\n")
|
|
1525
1590
|
}, {
|
|
1526
1591
|
id: v4(),
|
|
1527
1592
|
created_at: (new Date).toISOString(),
|
|
@@ -1531,10 +1596,10 @@ const transformInterfaceHistories = (state, systemMessage) => {
|
|
|
1531
1596
|
};
|
|
1532
1597
|
|
|
1533
1598
|
function orchestrateInterfaceComplement(ctx, document, retry = 8) {
|
|
1534
|
-
return step$
|
|
1599
|
+
return step$2(ctx, document, retry);
|
|
1535
1600
|
}
|
|
1536
1601
|
|
|
1537
|
-
async function step$
|
|
1602
|
+
async function step$2(ctx, document, retry) {
|
|
1538
1603
|
const missed = getMissed(document);
|
|
1539
1604
|
if (missed.length === 0 || retry <= 0) return document.components;
|
|
1540
1605
|
const pointer = {
|
|
@@ -1561,7 +1626,7 @@ async function step$1(ctx, document, retry) {
|
|
|
1561
1626
|
text: [ "You have missed below schema types in the document.components.schemas:", "", ...missed.map((s => `- ${s}`)) ].join("\n")
|
|
1562
1627
|
} ],
|
|
1563
1628
|
tokenUsage: ctx.usage(),
|
|
1564
|
-
controllers: [ createApplication$
|
|
1629
|
+
controllers: [ createApplication$9({
|
|
1565
1630
|
model: ctx.model,
|
|
1566
1631
|
build: next => {
|
|
1567
1632
|
pointer.value = OpenApiV3_1Emender.convertComponents({
|
|
@@ -1571,7 +1636,9 @@ async function step$1(ctx, document, retry) {
|
|
|
1571
1636
|
}) ]
|
|
1572
1637
|
});
|
|
1573
1638
|
agentica.on("request", (async event => {
|
|
1574
|
-
event.body.
|
|
1639
|
+
if (event.body.tools) {
|
|
1640
|
+
event.body.tool_choice = "required";
|
|
1641
|
+
}
|
|
1575
1642
|
}));
|
|
1576
1643
|
await agentica.conversate("Fill missing schema types please");
|
|
1577
1644
|
if (pointer.value === null) {
|
|
@@ -1591,7 +1658,7 @@ async function step$1(ctx, document, retry) {
|
|
|
1591
1658
|
},
|
|
1592
1659
|
authorization: document.components.authorization
|
|
1593
1660
|
};
|
|
1594
|
-
return step$
|
|
1661
|
+
return step$2(ctx, {
|
|
1595
1662
|
...document,
|
|
1596
1663
|
components: newComponents
|
|
1597
1664
|
}, retry - 1);
|
|
@@ -1616,9 +1683,9 @@ const getMissed = document => {
|
|
|
1616
1683
|
return Array.from(missed);
|
|
1617
1684
|
};
|
|
1618
1685
|
|
|
1619
|
-
function createApplication$
|
|
1686
|
+
function createApplication$9(props) {
|
|
1620
1687
|
assertSchemaModel(props.model);
|
|
1621
|
-
const application = collection$
|
|
1688
|
+
const application = collection$a[props.model];
|
|
1622
1689
|
return {
|
|
1623
1690
|
protocol: "class",
|
|
1624
1691
|
name: "interface",
|
|
@@ -1631,7 +1698,7 @@ function createApplication$6(props) {
|
|
|
1631
1698
|
};
|
|
1632
1699
|
}
|
|
1633
1700
|
|
|
1634
|
-
const claude$
|
|
1701
|
+
const claude$a = {
|
|
1635
1702
|
model: "claude",
|
|
1636
1703
|
options: {
|
|
1637
1704
|
reference: true,
|
|
@@ -1737,7 +1804,7 @@ const claude$7 = {
|
|
|
1737
1804
|
} ]
|
|
1738
1805
|
};
|
|
1739
1806
|
|
|
1740
|
-
const collection$
|
|
1807
|
+
const collection$a = {
|
|
1741
1808
|
chatgpt: {
|
|
1742
1809
|
model: "chatgpt",
|
|
1743
1810
|
options: {
|
|
@@ -1844,10 +1911,10 @@ const collection$7 = {
|
|
|
1844
1911
|
})()
|
|
1845
1912
|
} ]
|
|
1846
1913
|
},
|
|
1847
|
-
claude: claude$
|
|
1848
|
-
llama: claude$
|
|
1849
|
-
deepseek: claude$
|
|
1850
|
-
3.1: claude$
|
|
1914
|
+
claude: claude$a,
|
|
1915
|
+
llama: claude$a,
|
|
1916
|
+
deepseek: claude$a,
|
|
1917
|
+
3.1: claude$a,
|
|
1851
1918
|
"3.0": {
|
|
1852
1919
|
model: "3.0",
|
|
1853
1920
|
options: {
|
|
@@ -2016,7 +2083,7 @@ async function divideAndConquer$1(ctx, operations, typeNames, retry, progress) {
|
|
|
2016
2083
|
for (let i = 0; i < retry; ++i) {
|
|
2017
2084
|
if (remained.size === 0) break;
|
|
2018
2085
|
const before = remained.size;
|
|
2019
|
-
const newbie = await process$
|
|
2086
|
+
const newbie = await process$5(ctx, operations, components, remained);
|
|
2020
2087
|
for (const key of Object.keys(newbie.schemas)) {
|
|
2021
2088
|
components.schemas[key] = newbie.schemas[key];
|
|
2022
2089
|
remained.delete(key);
|
|
@@ -2026,7 +2093,7 @@ async function divideAndConquer$1(ctx, operations, typeNames, retry, progress) {
|
|
|
2026
2093
|
return components;
|
|
2027
2094
|
}
|
|
2028
2095
|
|
|
2029
|
-
async function process$
|
|
2096
|
+
async function process$5(ctx, operations, oldbie, remained) {
|
|
2030
2097
|
const pointer = {
|
|
2031
2098
|
value: null
|
|
2032
2099
|
};
|
|
@@ -2046,7 +2113,7 @@ async function process$2(ctx, operations, oldbie, remained) {
|
|
|
2046
2113
|
text: [ "Here is the OpenAPI operations generated by phase 2.", "", "```json", JSON.stringify(operations), "```" ].join("\n")
|
|
2047
2114
|
} ],
|
|
2048
2115
|
tokenUsage: ctx.usage(),
|
|
2049
|
-
controllers: [ createApplication$
|
|
2116
|
+
controllers: [ createApplication$8({
|
|
2050
2117
|
model: ctx.model,
|
|
2051
2118
|
build: async components => {
|
|
2052
2119
|
pointer.value = components;
|
|
@@ -2055,7 +2122,9 @@ async function process$2(ctx, operations, oldbie, remained) {
|
|
|
2055
2122
|
}) ]
|
|
2056
2123
|
});
|
|
2057
2124
|
agentica.on("request", (async event => {
|
|
2058
|
-
event.body.
|
|
2125
|
+
if (event.body.tools) {
|
|
2126
|
+
event.body.tool_choice = "required";
|
|
2127
|
+
}
|
|
2059
2128
|
}));
|
|
2060
2129
|
const already = Object.keys(oldbie.schemas);
|
|
2061
2130
|
await agentica.conversate([ "Make type components please.", "", "Here is the list of request/response bodies' type names from", "OpenAPI operations. Make type components of them. If more object", "types are required during making the components, please make them", "too.", "", ...Array.from(remained).map((k => `- \`${k}\``)), ...already.length !== 0 ? [ "", "> By the way, here is the list of components schemas what you've", "> already made. So, you don't need to make them again.", ">", ...already.map((k => `> - \`${k}\``)) ] : [] ].join("\n"));
|
|
@@ -2065,9 +2134,9 @@ async function process$2(ctx, operations, oldbie, remained) {
|
|
|
2065
2134
|
return OpenApiV3_1Emender.convertComponents(pointer.value);
|
|
2066
2135
|
}
|
|
2067
2136
|
|
|
2068
|
-
function createApplication$
|
|
2137
|
+
function createApplication$8(props) {
|
|
2069
2138
|
assertSchemaModel(props.model);
|
|
2070
|
-
const application = collection$
|
|
2139
|
+
const application = collection$9[props.model];
|
|
2071
2140
|
return {
|
|
2072
2141
|
protocol: "class",
|
|
2073
2142
|
name: "interface",
|
|
@@ -2080,7 +2149,7 @@ function createApplication$5(props) {
|
|
|
2080
2149
|
};
|
|
2081
2150
|
}
|
|
2082
2151
|
|
|
2083
|
-
const claude$
|
|
2152
|
+
const claude$9 = {
|
|
2084
2153
|
model: "claude",
|
|
2085
2154
|
options: {
|
|
2086
2155
|
reference: true,
|
|
@@ -2212,7 +2281,7 @@ const claude$6 = {
|
|
|
2212
2281
|
} ]
|
|
2213
2282
|
};
|
|
2214
2283
|
|
|
2215
|
-
const collection$
|
|
2284
|
+
const collection$9 = {
|
|
2216
2285
|
chatgpt: {
|
|
2217
2286
|
model: "chatgpt",
|
|
2218
2287
|
options: {
|
|
@@ -2346,10 +2415,10 @@ const collection$6 = {
|
|
|
2346
2415
|
})()
|
|
2347
2416
|
} ]
|
|
2348
2417
|
},
|
|
2349
|
-
claude: claude$
|
|
2350
|
-
llama: claude$
|
|
2351
|
-
deepseek: claude$
|
|
2352
|
-
3.1: claude$
|
|
2418
|
+
claude: claude$9,
|
|
2419
|
+
llama: claude$9,
|
|
2420
|
+
deepseek: claude$9,
|
|
2421
|
+
3.1: claude$9,
|
|
2353
2422
|
"3.0": {
|
|
2354
2423
|
model: "3.0",
|
|
2355
2424
|
options: {
|
|
@@ -2515,7 +2584,7 @@ async function orchestrateInterfaceEndpoints(ctx, content = "Make API endpoints
|
|
|
2515
2584
|
},
|
|
2516
2585
|
histories: transformInterfaceHistories(ctx.state(), '# API Endpoint Generator System Prompt\n\n## 1. Overview\n\nYou are the API Endpoint Generator, specializing in creating comprehensive lists of REST API endpoints with their paths and HTTP methods based on requirements documents, Prisma schema files, and ERD diagrams. You must output your results by calling the `makeEndpoints()` function.\n\n## 2. Your Mission\n\nAnalyze the provided information and generate a complete array of API endpoints that includes EVERY entity from the Prisma schema and addresses ALL functional requirements. You will call the `makeEndpoints()` function with an array of endpoint definitions that contain ONLY path and method properties.\n\n## 3. Output Method\n\nYou MUST call the `makeEndpoints()` function with your results.\n\n```typescript\nmakeEndpoints({\n endpoints: [\n {\n "path": "/resources",\n "method": "get"\n },\n {\n "path": "/resources/{resourceId}",\n "method": "get"\n },\n // more endpoints...\n ],\n});\n```\n\n## 4. Endpoint Design Principles\n\n### 4.1. Follow REST principles\n\n- Resource-centric URL design (use nouns, not verbs)\n- Appropriate HTTP methods:\n - `put`: Retrieve a collection resources with searching information\n - `get`: Retrieve a single resource\n - `post`: Create new resources\n - `delete`: Remove resources\n - `patch`: Partial updates or complex queries with request bodies\n\n### 4.2. Path Formatting Rules\n\n1. **Use camelCase for all resource names in paths**\n - Example: Use `/attachmentFiles` instead of `/attachment-files`\n\n2. **Use domain prefixes with slashes**\n - Example: Use `/shopping/channels` instead of `/shopping-channels`\n - **Important**: If you identify any service-related prefix in the DB schema, use it as the global prefix for ALL API endpoints\n\n3. **Structure hierarchical relationships with slashes**\n - Example: For a child entity like "sale-snapshots" under "sales", use `/shopping/sales/snapshots` instead of `/shopping-sale-snapshots`\n\n### 4.3. Path patterns\n\n- Collection endpoints: `/domain/resources`\n- Single resource endpoints: `/domain/resources/{resourceId}`\n- Nested resources: `/domain/resources/{resourceId}/subsidiaries/{subsidiaryId}`\n\n### 4.4. Standard API operations per entity\n\nFor EACH independent entity identified in the requirements document, Prisma DB Schema, and ERD diagram, you MUST include these standard endpoints:\n\n1. `PATCH /entity-plural` - List entities with searching\n2. `GET /entity-plural/{id}` - Get specific entity\n3. `POST /entity-plural` - Create entity\n4. `PUT /entity-plural/{id}` - Update entity\n5. `DELETE /entity-plural/{id}` - Delete entity\n\n## 5. Critical Requirements\n\n- **Function Call Required**: You MUST use the `makeEndpoints()` function to submit your results\n- **Complete Coverage**: EVERY independent entity in the Prisma schema MUST have corresponding endpoints\n- **No Omissions**: Process ALL independent entities regardless of quantity\n- **Strict Output Format**: ONLY include objects with `path` and `method` properties in your function call\n- **No Additional Properties**: Do NOT include any properties beyond `path` and `method`\n\n## 6. Implementation Strategy\n\n1. Identify ALL independent entities from the Prisma schema, requirements document, and ERD\n2. Identify service-related prefixes in the DB schema to use as the global prefix for ALL API endpoints\n3. Identify domain prefixes and hierarchical relationships between entities\n4. For each independent entity:\n - Convert kebab-case names to camelCase (e.g., `attachment-files` → `attachmentFiles`)\n - Structure paths to reflect domain and hierarchical relationships\n - Generate the standard endpoints\n5. Add endpoints for relationships and complex operations\n6. Verify ALL independent entities and requirements are covered\n7. Call the `makeEndpoints()` function with your complete array\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\n## 7. Path Transformation Examples\n\n| Original Format | Improved Format | Explanation |\n|-----------------|-----------------|-------------|\n| `/attachment-files` | `/attachmentFiles` | Convert kebab-case to camelCase |\n| `/bbs-articles` | `/bbs/articles` | Separate domain prefix with slash |\n| `/bbs-article-snapshots` | `/bbs/articles/snapshots` | Reflect hierarchy in URL structure |\n| `/shopping-sale-snapshots` | `/shopping/sales/snapshots` | Both domain prefix and hierarchy properly formatted |\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\nYou\'re right - I removed too much of the original structure. Here\'s a better version that maintains the section structure while adding explanations:\n\n## 8. Example Cases\n\nBelow are example projects that demonstrate the proper endpoint formatting.\n\n### 8.1. BBS (Bulletin Board System)\n\n```json\n{"endpoints":[{"path":"/bbs/articles","method":"post"},{"path":"/bbs/articles","method":"patch"},{"path":"/bbs/articles/abridges","method":"patch"},{"path":"/bbs/articles/{id}","method":"get"},{"path":"/bbs/articles/{id}","method":"put"},{"path":"/bbs/articles/{id}","method":"delete"},{"path":"/bbs/articles/{articleId}/comments","method":"post"},{"path":"/bbs/articles/{articleId}/comments","method":"patch"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"get"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"put"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"delete"},{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"}]}\n```\n\n**Key points**: Notice how the domain prefix "bbs" is separated with a slash, entities use camelCase, and hierarchical relationships are expressed (e.g., `/bbs/articles/{articleId}/comments`).\n\n### 8.2. Shopping Mall\n\n```json\n{"endpoints":[{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"},{"path":"/shoppings/admins/authenticate","method":"get"},{"path":"/shoppings/admins/authenticate","method":"post"},{"path":"/shoppings/admins/authenticate/login","method":"put"},{"path":"/shoppings/admins/coupons","method":"post"},{"path":"/shoppings/admins/coupons","method":"patch"},{"path":"/shoppings/admins/coupons/{id}","method":"get"},{"path":"/shoppings/admins/coupons/{id}","method":"delete"},{"path":"/shoppings/admins/deposits","method":"post"},{"path":"/shoppings/admins/deposits","method":"patch"},{"path":"/shoppings/admins/deposits/{id}","method":"get"},{"path":"/shoppings/admins/deposits/{id}","method":"delete"},{"path":"/shoppings/admins/deposits/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages","method":"post"},{"path":"/shoppings/admins/mileages","method":"patch"},{"path":"/shoppings/admins/mileages/{id}","method":"get"},{"path":"/shoppings/admins/mileages/{id}","method":"delete"},{"path":"/shoppings/admins/mileages/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages/donations","method":"post"},{"path":"/shoppings/admins/mileages/donations","method":"patch"},{"path":"/shoppings/admins/mileages/donations/{id}","method":"get"},{"path":"/shoppings/admins/orders","method":"patch"},{"path":"/shoppings/admins/orders/{id}","method":"get"},{"path":"/shoppings/admins/sales/details","method":"patch"},{"path":"/shoppings/admins/sales","method":"patch"},{"path":"/shoppings/admins/sales/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"post"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/admins/systematic/channels","method":"post"},{"path":"/shoppings/admins/systematic/channels","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/admins/systematic/sections","method":"post"},{"path":"/shoppings/admins/systematic/sections","method":"patch"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"get"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"put"},{"path":"/shoppings/admins/systematic/sections/merge","method":"delete"},{"path":"/shoppings/admins/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/customers/authenticate/refresh","method":"patch"},{"path":"/shoppings/customers/authenticate","method":"get"},{"path":"/shoppings/customers/authenticate","method":"post"},{"path":"/shoppings/customers/authenticate/join","method":"post"},{"path":"/shoppings/customers/authenticate/login","method":"put"},{"path":"/shoppings/customers/authenticate/activate","method":"post"},{"path":"/shoppings/customers/authenticate/external","method":"post"},{"path":"/shoppings/customers/authenticate/password/change","method":"put"},{"path":"/shoppings/customers/coupons","method":"patch"},{"path":"/shoppings/customers/coupons/{id}","method":"get"},{"path":"/shoppings/customers/coupons/tickets","method":"post"},{"path":"/shoppings/customers/coupons/tickets","method":"patch"},{"path":"/shoppings/customers/coupons/tickets/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges","method":"post"},{"path":"/shoppings/customers/deposits/charges","method":"patch"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"put"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"delete"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish/able","method":"get"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish","method":"post"},{"path":"/shoppings/customers/deposits/histories","method":"patch"},{"path":"/shoppings/customers/deposits/histories/{id}","method":"get"},{"path":"/shoppings/customers/deposits/histories/balance","method":"get"},{"path":"/shoppings/customers/mileages/histories","method":"patch"},{"path":"/shoppings/customers/mileages/histories/{id}","method":"get"},{"path":"/shoppings/customers/mileages/histories/balance","method":"get"},{"path":"/shoppings/customers/carts/commodities","method":"post"},{"path":"/shoppings/customers/carts/commodities","method":"patch"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"get"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"put"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"delete"},{"path":"/shoppings/customers/carts/commodities/{id}/replica","method":"get"},{"path":"/shoppings/customers/carts/commodities/discountable","method":"patch"},{"path":"/shoppings/customers/orders","method":"post"},{"path":"/shoppings/customers/orders","method":"patch"},{"path":"/shoppings/customers/orders/direct","method":"post"},{"path":"/shoppings/customers/orders/{id}","method":"get"},{"path":"/shoppings/customers/orders/{id}","method":"delete"},{"path":"/shoppings/customers/orders/{id}/price","method":"get"},{"path":"/shoppings/customers/orders/{id}/discountable","method":"patch"},{"path":"/shoppings/customers/orders/{id}/discount","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/goods/{id}/confirm","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/publish/able","method":"get"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"post"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"delete"},{"path":"/shoppings/customers/sales/details","method":"patch"},{"path":"/shoppings/customers/sales","method":"patch"},{"path":"/shoppings/customers/sales/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/customers/systematic/channels","method":"patch"},{"path":"/shoppings/customers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/customers/systematic/sections","method":"patch"},{"path":"/shoppings/customers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/customers/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"post"},{"path":"/shoppings/sellers/authenticate/login","method":"put"},{"path":"/shoppings/sellers/deliveries","method":"post"},{"path":"/shoppings/sellers/deliveries","method":"patch"},{"path":"/shoppings/sellers/deliveries/{id}","method":"get"},{"path":"/shoppings/sellers/deliveries/incompletes","method":"patch"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys","method":"post"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}/complete","method":"put"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}","method":"delete"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/shippers","method":"post"},{"path":"/shoppings/sellers/coupons","method":"post"},{"path":"/shoppings/sellers/coupons","method":"patch"},{"path":"/shoppings/sellers/coupons/{id}","method":"get"},{"path":"/shoppings/sellers/coupons/{id}","method":"delete"},{"path":"/shoppings/sellers/orders","method":"patch"},{"path":"/shoppings/sellers/orders/{id}","method":"get"},{"path":"/shoppings/sellers/sales","method":"post"},{"path":"/shoppings/sellers/sales","method":"patch"},{"path":"/shoppings/sellers/sales/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{id}/open","method":"put"},{"path":"/shoppings/sellers/sales/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{id}/pause","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/suspend","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/restore","method":"put"},{"path":"/shoppings/sellers/sales/details","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"delete"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/sellers/systematic/channels","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/sellers/systematic/sections","method":"patch"},{"path":"/shoppings/sellers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/sections/{code}/get","method":"get"}]}\n```\n\n**Key points**: Observe how `/shopping` is used as domain prefix, hierarchical relationships are reflected in paths (e.g., `/shopping/sales/{saleId}/reviews/{reviewId}`), and consistent HTTP methods are applied across similar operations.'),
|
|
2517
2586
|
tokenUsage: ctx.usage(),
|
|
2518
|
-
controllers: [ createApplication$
|
|
2587
|
+
controllers: [ createApplication$7({
|
|
2519
2588
|
model: ctx.model,
|
|
2520
2589
|
build: endpoints => {
|
|
2521
2590
|
pointer.value = endpoints;
|
|
@@ -2537,9 +2606,9 @@ async function orchestrateInterfaceEndpoints(ctx, content = "Make API endpoints
|
|
|
2537
2606
|
};
|
|
2538
2607
|
}
|
|
2539
2608
|
|
|
2540
|
-
function createApplication$
|
|
2609
|
+
function createApplication$7(props) {
|
|
2541
2610
|
assertSchemaModel(props.model);
|
|
2542
|
-
const application = collection$
|
|
2611
|
+
const application = collection$8[props.model];
|
|
2543
2612
|
return {
|
|
2544
2613
|
protocol: "class",
|
|
2545
2614
|
name: "interface",
|
|
@@ -2552,7 +2621,7 @@ function createApplication$4(props) {
|
|
|
2552
2621
|
};
|
|
2553
2622
|
}
|
|
2554
2623
|
|
|
2555
|
-
const claude$
|
|
2624
|
+
const claude$8 = {
|
|
2556
2625
|
model: "claude",
|
|
2557
2626
|
options: {
|
|
2558
2627
|
reference: true,
|
|
@@ -2666,7 +2735,7 @@ const claude$5 = {
|
|
|
2666
2735
|
} ]
|
|
2667
2736
|
};
|
|
2668
2737
|
|
|
2669
|
-
const collection$
|
|
2738
|
+
const collection$8 = {
|
|
2670
2739
|
chatgpt: {
|
|
2671
2740
|
model: "chatgpt",
|
|
2672
2741
|
options: {
|
|
@@ -2772,10 +2841,10 @@ const collection$5 = {
|
|
|
2772
2841
|
})()
|
|
2773
2842
|
} ]
|
|
2774
2843
|
},
|
|
2775
|
-
claude: claude$
|
|
2776
|
-
llama: claude$
|
|
2777
|
-
deepseek: claude$
|
|
2778
|
-
3.1: claude$
|
|
2844
|
+
claude: claude$8,
|
|
2845
|
+
llama: claude$8,
|
|
2846
|
+
deepseek: claude$8,
|
|
2847
|
+
3.1: claude$8,
|
|
2779
2848
|
"3.0": {
|
|
2780
2849
|
model: "3.0",
|
|
2781
2850
|
options: {
|
|
@@ -2912,7 +2981,7 @@ async function divideAndConquer(ctx, endpoints, retry, progress) {
|
|
|
2912
2981
|
for (let i = 0; i < retry; ++i) {
|
|
2913
2982
|
if (remained.empty() === true || operations.size() >= endpoints.length) break;
|
|
2914
2983
|
const before = operations.size();
|
|
2915
|
-
const newbie = await process$
|
|
2984
|
+
const newbie = await process$4(ctx, Array.from(remained));
|
|
2916
2985
|
for (const item of newbie) {
|
|
2917
2986
|
operations.set(item, item);
|
|
2918
2987
|
remained.erase(item);
|
|
@@ -2922,7 +2991,7 @@ async function divideAndConquer(ctx, endpoints, retry, progress) {
|
|
|
2922
2991
|
return operations.toJSON().map((it => it.second));
|
|
2923
2992
|
}
|
|
2924
2993
|
|
|
2925
|
-
async function process$
|
|
2994
|
+
async function process$4(ctx, endpoints) {
|
|
2926
2995
|
const pointer = {
|
|
2927
2996
|
value: null
|
|
2928
2997
|
};
|
|
@@ -2937,7 +3006,7 @@ async function process$1(ctx, endpoints) {
|
|
|
2937
3006
|
},
|
|
2938
3007
|
histories: transformInterfaceHistories(ctx.state(), '# API Endpoint Generator System Prompt\n\n## 1. Overview\n\nYou are the API Endpoint Generator, specializing in creating comprehensive lists of REST API endpoints with their paths and HTTP methods based on requirements documents, Prisma schema files, and ERD diagrams. You must output your results by calling the `makeEndpoints()` function.\n\n## 2. Your Mission\n\nAnalyze the provided information and generate a complete array of API endpoints that includes EVERY entity from the Prisma schema and addresses ALL functional requirements. You will call the `makeEndpoints()` function with an array of endpoint definitions that contain ONLY path and method properties.\n\n## 3. Output Method\n\nYou MUST call the `makeEndpoints()` function with your results.\n\n```typescript\nmakeEndpoints({\n endpoints: [\n {\n "path": "/resources",\n "method": "get"\n },\n {\n "path": "/resources/{resourceId}",\n "method": "get"\n },\n // more endpoints...\n ],\n});\n```\n\n## 4. Endpoint Design Principles\n\n### 4.1. Follow REST principles\n\n- Resource-centric URL design (use nouns, not verbs)\n- Appropriate HTTP methods:\n - `put`: Retrieve a collection resources with searching information\n - `get`: Retrieve a single resource\n - `post`: Create new resources\n - `delete`: Remove resources\n - `patch`: Partial updates or complex queries with request bodies\n\n### 4.2. Path Formatting Rules\n\n1. **Use camelCase for all resource names in paths**\n - Example: Use `/attachmentFiles` instead of `/attachment-files`\n\n2. **Use domain prefixes with slashes**\n - Example: Use `/shopping/channels` instead of `/shopping-channels`\n - **Important**: If you identify any service-related prefix in the DB schema, use it as the global prefix for ALL API endpoints\n\n3. **Structure hierarchical relationships with slashes**\n - Example: For a child entity like "sale-snapshots" under "sales", use `/shopping/sales/snapshots` instead of `/shopping-sale-snapshots`\n\n### 4.3. Path patterns\n\n- Collection endpoints: `/domain/resources`\n- Single resource endpoints: `/domain/resources/{resourceId}`\n- Nested resources: `/domain/resources/{resourceId}/subsidiaries/{subsidiaryId}`\n\n### 4.4. Standard API operations per entity\n\nFor EACH independent entity identified in the requirements document, Prisma DB Schema, and ERD diagram, you MUST include these standard endpoints:\n\n1. `PATCH /entity-plural` - List entities with searching\n2. `GET /entity-plural/{id}` - Get specific entity\n3. `POST /entity-plural` - Create entity\n4. `PUT /entity-plural/{id}` - Update entity\n5. `DELETE /entity-plural/{id}` - Delete entity\n\n## 5. Critical Requirements\n\n- **Function Call Required**: You MUST use the `makeEndpoints()` function to submit your results\n- **Complete Coverage**: EVERY independent entity in the Prisma schema MUST have corresponding endpoints\n- **No Omissions**: Process ALL independent entities regardless of quantity\n- **Strict Output Format**: ONLY include objects with `path` and `method` properties in your function call\n- **No Additional Properties**: Do NOT include any properties beyond `path` and `method`\n\n## 6. Implementation Strategy\n\n1. Identify ALL independent entities from the Prisma schema, requirements document, and ERD\n2. Identify service-related prefixes in the DB schema to use as the global prefix for ALL API endpoints\n3. Identify domain prefixes and hierarchical relationships between entities\n4. For each independent entity:\n - Convert kebab-case names to camelCase (e.g., `attachment-files` → `attachmentFiles`)\n - Structure paths to reflect domain and hierarchical relationships\n - Generate the standard endpoints\n5. Add endpoints for relationships and complex operations\n6. Verify ALL independent entities and requirements are covered\n7. Call the `makeEndpoints()` function with your complete array\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\n## 7. Path Transformation Examples\n\n| Original Format | Improved Format | Explanation |\n|-----------------|-----------------|-------------|\n| `/attachment-files` | `/attachmentFiles` | Convert kebab-case to camelCase |\n| `/bbs-articles` | `/bbs/articles` | Separate domain prefix with slash |\n| `/bbs-article-snapshots` | `/bbs/articles/snapshots` | Reflect hierarchy in URL structure |\n| `/shopping-sale-snapshots` | `/shopping/sales/snapshots` | Both domain prefix and hierarchy properly formatted |\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\nYou\'re right - I removed too much of the original structure. Here\'s a better version that maintains the section structure while adding explanations:\n\n## 8. Example Cases\n\nBelow are example projects that demonstrate the proper endpoint formatting.\n\n### 8.1. BBS (Bulletin Board System)\n\n```json\n{"endpoints":[{"path":"/bbs/articles","method":"post"},{"path":"/bbs/articles","method":"patch"},{"path":"/bbs/articles/abridges","method":"patch"},{"path":"/bbs/articles/{id}","method":"get"},{"path":"/bbs/articles/{id}","method":"put"},{"path":"/bbs/articles/{id}","method":"delete"},{"path":"/bbs/articles/{articleId}/comments","method":"post"},{"path":"/bbs/articles/{articleId}/comments","method":"patch"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"get"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"put"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"delete"},{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"}]}\n```\n\n**Key points**: Notice how the domain prefix "bbs" is separated with a slash, entities use camelCase, and hierarchical relationships are expressed (e.g., `/bbs/articles/{articleId}/comments`).\n\n### 8.2. Shopping Mall\n\n```json\n{"endpoints":[{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"},{"path":"/shoppings/admins/authenticate","method":"get"},{"path":"/shoppings/admins/authenticate","method":"post"},{"path":"/shoppings/admins/authenticate/login","method":"put"},{"path":"/shoppings/admins/coupons","method":"post"},{"path":"/shoppings/admins/coupons","method":"patch"},{"path":"/shoppings/admins/coupons/{id}","method":"get"},{"path":"/shoppings/admins/coupons/{id}","method":"delete"},{"path":"/shoppings/admins/deposits","method":"post"},{"path":"/shoppings/admins/deposits","method":"patch"},{"path":"/shoppings/admins/deposits/{id}","method":"get"},{"path":"/shoppings/admins/deposits/{id}","method":"delete"},{"path":"/shoppings/admins/deposits/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages","method":"post"},{"path":"/shoppings/admins/mileages","method":"patch"},{"path":"/shoppings/admins/mileages/{id}","method":"get"},{"path":"/shoppings/admins/mileages/{id}","method":"delete"},{"path":"/shoppings/admins/mileages/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages/donations","method":"post"},{"path":"/shoppings/admins/mileages/donations","method":"patch"},{"path":"/shoppings/admins/mileages/donations/{id}","method":"get"},{"path":"/shoppings/admins/orders","method":"patch"},{"path":"/shoppings/admins/orders/{id}","method":"get"},{"path":"/shoppings/admins/sales/details","method":"patch"},{"path":"/shoppings/admins/sales","method":"patch"},{"path":"/shoppings/admins/sales/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"post"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/admins/systematic/channels","method":"post"},{"path":"/shoppings/admins/systematic/channels","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/admins/systematic/sections","method":"post"},{"path":"/shoppings/admins/systematic/sections","method":"patch"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"get"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"put"},{"path":"/shoppings/admins/systematic/sections/merge","method":"delete"},{"path":"/shoppings/admins/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/customers/authenticate/refresh","method":"patch"},{"path":"/shoppings/customers/authenticate","method":"get"},{"path":"/shoppings/customers/authenticate","method":"post"},{"path":"/shoppings/customers/authenticate/join","method":"post"},{"path":"/shoppings/customers/authenticate/login","method":"put"},{"path":"/shoppings/customers/authenticate/activate","method":"post"},{"path":"/shoppings/customers/authenticate/external","method":"post"},{"path":"/shoppings/customers/authenticate/password/change","method":"put"},{"path":"/shoppings/customers/coupons","method":"patch"},{"path":"/shoppings/customers/coupons/{id}","method":"get"},{"path":"/shoppings/customers/coupons/tickets","method":"post"},{"path":"/shoppings/customers/coupons/tickets","method":"patch"},{"path":"/shoppings/customers/coupons/tickets/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges","method":"post"},{"path":"/shoppings/customers/deposits/charges","method":"patch"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"put"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"delete"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish/able","method":"get"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish","method":"post"},{"path":"/shoppings/customers/deposits/histories","method":"patch"},{"path":"/shoppings/customers/deposits/histories/{id}","method":"get"},{"path":"/shoppings/customers/deposits/histories/balance","method":"get"},{"path":"/shoppings/customers/mileages/histories","method":"patch"},{"path":"/shoppings/customers/mileages/histories/{id}","method":"get"},{"path":"/shoppings/customers/mileages/histories/balance","method":"get"},{"path":"/shoppings/customers/carts/commodities","method":"post"},{"path":"/shoppings/customers/carts/commodities","method":"patch"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"get"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"put"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"delete"},{"path":"/shoppings/customers/carts/commodities/{id}/replica","method":"get"},{"path":"/shoppings/customers/carts/commodities/discountable","method":"patch"},{"path":"/shoppings/customers/orders","method":"post"},{"path":"/shoppings/customers/orders","method":"patch"},{"path":"/shoppings/customers/orders/direct","method":"post"},{"path":"/shoppings/customers/orders/{id}","method":"get"},{"path":"/shoppings/customers/orders/{id}","method":"delete"},{"path":"/shoppings/customers/orders/{id}/price","method":"get"},{"path":"/shoppings/customers/orders/{id}/discountable","method":"patch"},{"path":"/shoppings/customers/orders/{id}/discount","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/goods/{id}/confirm","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/publish/able","method":"get"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"post"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"delete"},{"path":"/shoppings/customers/sales/details","method":"patch"},{"path":"/shoppings/customers/sales","method":"patch"},{"path":"/shoppings/customers/sales/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/customers/systematic/channels","method":"patch"},{"path":"/shoppings/customers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/customers/systematic/sections","method":"patch"},{"path":"/shoppings/customers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/customers/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"post"},{"path":"/shoppings/sellers/authenticate/login","method":"put"},{"path":"/shoppings/sellers/deliveries","method":"post"},{"path":"/shoppings/sellers/deliveries","method":"patch"},{"path":"/shoppings/sellers/deliveries/{id}","method":"get"},{"path":"/shoppings/sellers/deliveries/incompletes","method":"patch"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys","method":"post"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}/complete","method":"put"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}","method":"delete"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/shippers","method":"post"},{"path":"/shoppings/sellers/coupons","method":"post"},{"path":"/shoppings/sellers/coupons","method":"patch"},{"path":"/shoppings/sellers/coupons/{id}","method":"get"},{"path":"/shoppings/sellers/coupons/{id}","method":"delete"},{"path":"/shoppings/sellers/orders","method":"patch"},{"path":"/shoppings/sellers/orders/{id}","method":"get"},{"path":"/shoppings/sellers/sales","method":"post"},{"path":"/shoppings/sellers/sales","method":"patch"},{"path":"/shoppings/sellers/sales/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{id}/open","method":"put"},{"path":"/shoppings/sellers/sales/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{id}/pause","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/suspend","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/restore","method":"put"},{"path":"/shoppings/sellers/sales/details","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"delete"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/sellers/systematic/channels","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/sellers/systematic/sections","method":"patch"},{"path":"/shoppings/sellers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/sections/{code}/get","method":"get"}]}\n```\n\n**Key points**: Observe how `/shopping` is used as domain prefix, hierarchical relationships are reflected in paths (e.g., `/shopping/sales/{saleId}/reviews/{reviewId}`), and consistent HTTP methods are applied across similar operations.'),
|
|
2939
3008
|
tokenUsage: ctx.usage(),
|
|
2940
|
-
controllers: [ createApplication$
|
|
3009
|
+
controllers: [ createApplication$6({
|
|
2941
3010
|
model: ctx.model,
|
|
2942
3011
|
build: endpoints => {
|
|
2943
3012
|
pointer.value = endpoints;
|
|
@@ -2946,16 +3015,18 @@ async function process$1(ctx, endpoints) {
|
|
|
2946
3015
|
}) ]
|
|
2947
3016
|
});
|
|
2948
3017
|
agentica.on("request", (async event => {
|
|
2949
|
-
event.body.
|
|
3018
|
+
if (event.body.tools) {
|
|
3019
|
+
event.body.tool_choice = "required";
|
|
3020
|
+
}
|
|
2950
3021
|
}));
|
|
2951
3022
|
await agentica.conversate([ "Make API operations for below endpoints:", "", "```json", JSON.stringify(Array.from(endpoints), null, 2), "```" ].join("\n"));
|
|
2952
3023
|
if (pointer.value === null) throw new Error("Failed to create operations.");
|
|
2953
3024
|
return pointer.value;
|
|
2954
3025
|
}
|
|
2955
3026
|
|
|
2956
|
-
function createApplication$
|
|
3027
|
+
function createApplication$6(props) {
|
|
2957
3028
|
assertSchemaModel(props.model);
|
|
2958
|
-
const application = collection$
|
|
3029
|
+
const application = collection$7[props.model];
|
|
2959
3030
|
application.functions[0].validate = next => {
|
|
2960
3031
|
const result = (() => {
|
|
2961
3032
|
const _io0 = input => Array.isArray(input.operations) && input.operations.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
@@ -3245,7 +3316,7 @@ function createApplication$3(props) {
|
|
|
3245
3316
|
};
|
|
3246
3317
|
}
|
|
3247
3318
|
|
|
3248
|
-
const claude$
|
|
3319
|
+
const claude$7 = {
|
|
3249
3320
|
model: "claude",
|
|
3250
3321
|
options: {
|
|
3251
3322
|
reference: true,
|
|
@@ -3757,7 +3828,7 @@ const claude$4 = {
|
|
|
3757
3828
|
} ]
|
|
3758
3829
|
};
|
|
3759
3830
|
|
|
3760
|
-
const collection$
|
|
3831
|
+
const collection$7 = {
|
|
3761
3832
|
chatgpt: {
|
|
3762
3833
|
model: "chatgpt",
|
|
3763
3834
|
options: {
|
|
@@ -4260,10 +4331,10 @@ const collection$4 = {
|
|
|
4260
4331
|
})()
|
|
4261
4332
|
} ]
|
|
4262
4333
|
},
|
|
4263
|
-
claude: claude$
|
|
4264
|
-
llama: claude$
|
|
4265
|
-
deepseek: claude$
|
|
4266
|
-
3.1: claude$
|
|
4334
|
+
claude: claude$7,
|
|
4335
|
+
llama: claude$7,
|
|
4336
|
+
deepseek: claude$7,
|
|
4337
|
+
3.1: claude$7,
|
|
4267
4338
|
"3.0": {
|
|
4268
4339
|
model: "3.0",
|
|
4269
4340
|
options: {
|
|
@@ -4809,9 +4880,7 @@ const orchestrateInterface = ctx => async props => {
|
|
|
4809
4880
|
|
|
4810
4881
|
const orchestrateRealize = ctx => async props => null;
|
|
4811
4882
|
|
|
4812
|
-
const
|
|
4813
|
-
|
|
4814
|
-
const transformPrismaComponentsHistories = state => {
|
|
4883
|
+
const transformPrismaComponentsHistories = (state, prefix = null) => {
|
|
4815
4884
|
if (state.analyze === null) return [ {
|
|
4816
4885
|
id: v4(),
|
|
4817
4886
|
created_at: (new Date).toISOString(),
|
|
@@ -4827,7 +4896,7 @@ const transformPrismaComponentsHistories = state => {
|
|
|
4827
4896
|
id: v4(),
|
|
4828
4897
|
created_at: (new Date).toISOString(),
|
|
4829
4898
|
type: "assistantMessage",
|
|
4830
|
-
text: [ "Here is the requirement analysis report.", "", "Call the provided tool function to generate Prisma DB schema", "referencing below requirement analysis report.", "", "## User Request", state.analyze.reason, "", `## Requirement Analysis Report`, "", "```json", JSON.stringify(state.analyze.files), "```" ].join("\n")
|
|
4899
|
+
text: [ "Here is the requirement analysis report.", "", "Call the provided tool function to generate Prisma DB schema", "referencing below requirement analysis report.", "", "## User Request", state.analyze.reason, "", `## Requirement Analysis Report`, "", "```json", JSON.stringify(state.analyze.files), "```", "## Prefix", "", `* Prefix provided by the user: ${prefix}`, "", "The user wants all database schema (table) names to start with the prefix provided below.", "If the prefix is `null`, it should be ignored.", "If a prefix is provided, all table names **must begin with it**.", "However, if there is a special-purpose prefix like `mv` (for materialized views), it **must precede** the given prefix.", "", "## Prefix Example", "", "If the prefix is `shopping`, then table names should be like:", "", "* `shopping_sales`", "* `shopping_sale_options`", "", "In cases where a table is created for performance optimization purposes (e.g., materialized views), the `mv_` prefix must come first.", "For example:", "", "* `mv_shopping_daily_stats`" ].join("\n")
|
|
4831
4900
|
} ];
|
|
4832
4901
|
};
|
|
4833
4902
|
|
|
@@ -4836,15 +4905,16 @@ async function orchestratePrismaComponents(ctx, content = "Please extract files
|
|
|
4836
4905
|
const pointer = {
|
|
4837
4906
|
value: null
|
|
4838
4907
|
};
|
|
4908
|
+
const prefix = ctx.state().analyze?.prefix ?? null;
|
|
4839
4909
|
const agentica = new MicroAgentica({
|
|
4840
4910
|
model: ctx.model,
|
|
4841
4911
|
vendor: ctx.vendor,
|
|
4842
4912
|
config: {
|
|
4843
4913
|
...ctx.config ?? {}
|
|
4844
4914
|
},
|
|
4845
|
-
histories: transformPrismaComponentsHistories(ctx.state()),
|
|
4915
|
+
histories: transformPrismaComponentsHistories(ctx.state(), prefix),
|
|
4846
4916
|
tokenUsage: ctx.usage(),
|
|
4847
|
-
controllers: [ createApplication$
|
|
4917
|
+
controllers: [ createApplication$5({
|
|
4848
4918
|
model: ctx.model,
|
|
4849
4919
|
build: next => {
|
|
4850
4920
|
pointer.value = next;
|
|
@@ -4868,9 +4938,9 @@ async function orchestratePrismaComponents(ctx, content = "Please extract files
|
|
|
4868
4938
|
};
|
|
4869
4939
|
}
|
|
4870
4940
|
|
|
4871
|
-
function createApplication$
|
|
4941
|
+
function createApplication$5(props) {
|
|
4872
4942
|
assertSchemaModel(props.model);
|
|
4873
|
-
const application = collection$
|
|
4943
|
+
const application = collection$6[props.model];
|
|
4874
4944
|
return {
|
|
4875
4945
|
protocol: "class",
|
|
4876
4946
|
name: "Prisma Extract Files and Tables",
|
|
@@ -4883,7 +4953,7 @@ function createApplication$2(props) {
|
|
|
4883
4953
|
};
|
|
4884
4954
|
}
|
|
4885
4955
|
|
|
4886
|
-
const claude$
|
|
4956
|
+
const claude$6 = {
|
|
4887
4957
|
model: "claude",
|
|
4888
4958
|
options: {
|
|
4889
4959
|
reference: true,
|
|
@@ -5008,7 +5078,7 @@ const claude$3 = {
|
|
|
5008
5078
|
} ]
|
|
5009
5079
|
};
|
|
5010
5080
|
|
|
5011
|
-
const collection$
|
|
5081
|
+
const collection$6 = {
|
|
5012
5082
|
chatgpt: {
|
|
5013
5083
|
model: "chatgpt",
|
|
5014
5084
|
options: {
|
|
@@ -5133,10 +5203,10 @@ const collection$3 = {
|
|
|
5133
5203
|
})()
|
|
5134
5204
|
} ]
|
|
5135
5205
|
},
|
|
5136
|
-
claude: claude$
|
|
5137
|
-
llama: claude$
|
|
5138
|
-
deepseek: claude$
|
|
5139
|
-
3.1: claude$
|
|
5206
|
+
claude: claude$6,
|
|
5207
|
+
llama: claude$6,
|
|
5208
|
+
deepseek: claude$6,
|
|
5209
|
+
3.1: claude$6,
|
|
5140
5210
|
"3.0": {
|
|
5141
5211
|
model: "3.0",
|
|
5142
5212
|
options: {
|
|
@@ -5294,10 +5364,10 @@ function orchestratePrismaCorrect(ctx, application, retry = 8) {
|
|
|
5294
5364
|
return true;
|
|
5295
5365
|
}));
|
|
5296
5366
|
application.files = application.files.filter((f => f.models.length !== 0));
|
|
5297
|
-
return step(ctx, application);
|
|
5367
|
+
return step$1(ctx, application);
|
|
5298
5368
|
}
|
|
5299
5369
|
|
|
5300
|
-
async function step(ctx, application, life) {
|
|
5370
|
+
async function step$1(ctx, application, life) {
|
|
5301
5371
|
const result = await ctx.compiler.prisma.validate(application);
|
|
5302
5372
|
if (result.success) return result;
|
|
5303
5373
|
const schemas = await ctx.compiler.prisma.write(application);
|
|
@@ -5322,7 +5392,7 @@ async function step(ctx, application, life) {
|
|
|
5322
5392
|
},
|
|
5323
5393
|
histories: transformPrismaCorrectHistories(result),
|
|
5324
5394
|
tokenUsage: ctx.usage(),
|
|
5325
|
-
controllers: [ createApplication$
|
|
5395
|
+
controllers: [ createApplication$4({
|
|
5326
5396
|
model: ctx.model,
|
|
5327
5397
|
build: next => {
|
|
5328
5398
|
pointer.value = next;
|
|
@@ -5357,14 +5427,14 @@ async function step(ctx, application, life) {
|
|
|
5357
5427
|
step: ctx.state().analyze?.step ?? 0,
|
|
5358
5428
|
created_at: (new Date).toISOString()
|
|
5359
5429
|
});
|
|
5360
|
-
return step(ctx, {
|
|
5430
|
+
return step$1(ctx, {
|
|
5361
5431
|
files: correction.files
|
|
5362
5432
|
});
|
|
5363
5433
|
}
|
|
5364
5434
|
|
|
5365
|
-
function createApplication$
|
|
5435
|
+
function createApplication$4(props) {
|
|
5366
5436
|
assertSchemaModel(props.model);
|
|
5367
|
-
const application = collection$
|
|
5437
|
+
const application = collection$5[props.model];
|
|
5368
5438
|
return {
|
|
5369
5439
|
protocol: "class",
|
|
5370
5440
|
name: "Prisma Compiler",
|
|
@@ -5377,7 +5447,7 @@ function createApplication$1(props) {
|
|
|
5377
5447
|
};
|
|
5378
5448
|
}
|
|
5379
5449
|
|
|
5380
|
-
const claude$
|
|
5450
|
+
const claude$5 = {
|
|
5381
5451
|
model: "claude",
|
|
5382
5452
|
options: {
|
|
5383
5453
|
reference: true,
|
|
@@ -5922,7 +5992,7 @@ const claude$2 = {
|
|
|
5922
5992
|
} ]
|
|
5923
5993
|
};
|
|
5924
5994
|
|
|
5925
|
-
const collection$
|
|
5995
|
+
const collection$5 = {
|
|
5926
5996
|
chatgpt: {
|
|
5927
5997
|
model: "chatgpt",
|
|
5928
5998
|
options: {
|
|
@@ -6449,10 +6519,10 @@ const collection$2 = {
|
|
|
6449
6519
|
})()
|
|
6450
6520
|
} ]
|
|
6451
6521
|
},
|
|
6452
|
-
claude: claude$
|
|
6453
|
-
llama: claude$
|
|
6454
|
-
deepseek: claude$
|
|
6455
|
-
3.1: claude$
|
|
6522
|
+
claude: claude$5,
|
|
6523
|
+
llama: claude$5,
|
|
6524
|
+
deepseek: claude$5,
|
|
6525
|
+
3.1: claude$5,
|
|
6456
6526
|
"3.0": {
|
|
6457
6527
|
model: "3.0",
|
|
6458
6528
|
options: {
|
|
@@ -7020,7 +7090,7 @@ async function orchestratePrismaSchemas(ctx, components) {
|
|
|
7020
7090
|
const total = components.reduce(((acc, c) => acc + c.tables.length), 0);
|
|
7021
7091
|
let i = 0;
|
|
7022
7092
|
return await Promise.all(components.map((async c => {
|
|
7023
|
-
const result = await process(ctx, {
|
|
7093
|
+
const result = await process$3(ctx, {
|
|
7024
7094
|
filename: c.filename,
|
|
7025
7095
|
tables: c.tables,
|
|
7026
7096
|
entireTables
|
|
@@ -7038,7 +7108,7 @@ async function orchestratePrismaSchemas(ctx, components) {
|
|
|
7038
7108
|
})));
|
|
7039
7109
|
}
|
|
7040
7110
|
|
|
7041
|
-
async function process(ctx, component) {
|
|
7111
|
+
async function process$3(ctx, component) {
|
|
7042
7112
|
const pointer = {
|
|
7043
7113
|
value: null
|
|
7044
7114
|
};
|
|
@@ -7050,7 +7120,7 @@ async function process(ctx, component) {
|
|
|
7050
7120
|
},
|
|
7051
7121
|
histories: transformPrismaSchemaHistories(ctx.state().analyze, component),
|
|
7052
7122
|
tokenUsage: ctx.usage(),
|
|
7053
|
-
controllers: [ createApplication({
|
|
7123
|
+
controllers: [ createApplication$3({
|
|
7054
7124
|
model: ctx.model,
|
|
7055
7125
|
build: next => {
|
|
7056
7126
|
pointer.value = next;
|
|
@@ -7068,9 +7138,9 @@ async function process(ctx, component) {
|
|
|
7068
7138
|
return pointer.value;
|
|
7069
7139
|
}
|
|
7070
7140
|
|
|
7071
|
-
function createApplication(props) {
|
|
7141
|
+
function createApplication$3(props) {
|
|
7072
7142
|
assertSchemaModel(props.model);
|
|
7073
|
-
const application = collection$
|
|
7143
|
+
const application = collection$4[props.model];
|
|
7074
7144
|
return {
|
|
7075
7145
|
protocol: "class",
|
|
7076
7146
|
name: "Prisma Generator",
|
|
@@ -7083,7 +7153,7 @@ function createApplication(props) {
|
|
|
7083
7153
|
};
|
|
7084
7154
|
}
|
|
7085
7155
|
|
|
7086
|
-
const claude$
|
|
7156
|
+
const claude$4 = {
|
|
7087
7157
|
model: "claude",
|
|
7088
7158
|
options: {
|
|
7089
7159
|
reference: true,
|
|
@@ -7661,7 +7731,7 @@ const claude$1 = {
|
|
|
7661
7731
|
} ]
|
|
7662
7732
|
};
|
|
7663
7733
|
|
|
7664
|
-
const collection$
|
|
7734
|
+
const collection$4 = {
|
|
7665
7735
|
chatgpt: {
|
|
7666
7736
|
model: "chatgpt",
|
|
7667
7737
|
options: {
|
|
@@ -8220,10 +8290,10 @@ const collection$1 = {
|
|
|
8220
8290
|
})()
|
|
8221
8291
|
} ]
|
|
8222
8292
|
},
|
|
8223
|
-
claude: claude$
|
|
8224
|
-
llama: claude$
|
|
8225
|
-
deepseek: claude$
|
|
8226
|
-
3.1: claude$
|
|
8293
|
+
claude: claude$4,
|
|
8294
|
+
llama: claude$4,
|
|
8295
|
+
deepseek: claude$4,
|
|
8296
|
+
3.1: claude$4,
|
|
8227
8297
|
"3.0": {
|
|
8228
8298
|
model: "3.0",
|
|
8229
8299
|
options: {
|
|
@@ -8848,6 +8918,1496 @@ const orchestratePrisma = ctx => async props => {
|
|
|
8848
8918
|
return history;
|
|
8849
8919
|
};
|
|
8850
8920
|
|
|
8921
|
+
const transformTestCorrectHistories = (apiFiles, dtoFiles) => [ {
|
|
8922
|
+
id: v4(),
|
|
8923
|
+
created_at: (new Date).toISOString(),
|
|
8924
|
+
type: "systemMessage",
|
|
8925
|
+
text: '# Compiler Error Fix System Prompt\n\nYou are an expert TypeScript compiler error fixing agent specializing in resolving compilation errors in E2E test code that follows the `@nestia/e2e` testing framework conventions.\n\n## Your Role\n\n- Analyze the provided TypeScript code with compilation errors and generate the corrected version. \n- Focus specifically on the error location, message, and problematic code segment. \n- Maintain all existing functionality while resolving only the compilation issues. \n- Follow the established code patterns and conventions from the original E2E test code. \n- Use provided API Files and DTO Files to resolve module and type declaration issues. \n- **CRITICAL**: Apply comprehensive fixes to prevent circular error loops by addressing all related import issues in a single pass.\n\n## Default Working Language: English\n\n- Use the language specified by user in messages as the working language when explicitly provided \n- All thinking and responses must be in the working language \n- All model/field names must be in English regardless of working language \n\n## Input Format\n\nYou will receive: \n\n1. **Original Code**: TypeScript E2E test code with compilation errors \n2. **Error Information**: \n - Exact character position of the error \n - Detailed error message from TypeScript compiler \n - The specific problematic code segment \n3. **Instructions**: Specific guidance on what needs to be fixed \n4. **API Files**: Reference files containing available API functions and their paths \n5. **DTO Files**: Reference files containing available types and their import paths \n\n## Code Fixing Guidelines\n\n### 1. Module Resolution Errors (CRITICAL PRIORITY)\n\n#### Universal Module Import Pattern Recognition and Fix:\n\n**ALWAYS scan the ENTIRE code for ALL import statements that match these patterns and fix them ALL at once:**\n\n```typescript\n// WRONG PATTERNS - Fix ALL of these in one pass:\nimport api from "@nestia/PROJECT-api";\nimport api from "@wrtnlabs/PROJECT-api"; \nimport api from "@anyorganization/PROJECT-api";\nimport { Type } from "@nestia/PROJECT-api/lib/structures/Type";\nimport { Type } from "@wrtnlabs/PROJECT-api/lib/structures/Type";\nimport { Type } from "@anyorganization/PROJECT-api/lib/structures/Type";\n\n// CORRECT PATTERN - Replace with:\nimport api from "@ORGANIZATION/PROJECT-api";\nimport { Type } from "@ORGANIZATION/PROJECT-api/lib/structures/Type";\n```\n\n#### Comprehensive Module Fix Strategy:\n\n1. **Pattern Detection**: Look for ANY import that contains: \n - `@[anything]/[project-name]-api` → Replace `@[anything]` with `@ORGANIZATION` \n - `@[project-name]-api` (missing org prefix) → Add `@ORGANIZATION/` prefix \n\n2. **Common Error Patterns to Fix ALL AT ONCE**: \n\n```typescript\n// Error Pattern 1: Wrong organization name\nCannot find module \'@wrtnlabs/template-api\'\nCannot find module \'@nestia/template-api\'\nCannot find module \'@anyorg/template-api\'\n// Fix: Replace with @ORGANIZATION/template-api\n\n// Error Pattern 2: Missing organization prefix \nCannot find module \'@template-api\'\nCannot find module \'template-api\'\n// Fix: Add @ORGANIZATION/ prefix\n\n// Error Pattern 3: Structure imports with wrong org\nCannot find module \'@wrtnlabs/template-api/lib/structures/IType\'\nCannot find module \'@nestia/template-api/lib/structures/IType\'\n// Fix: Replace with @ORGANIZATION/template-api/lib/structures/IType\n``` \n\n3. **Comprehensive Import Scan and Fix**: \n - **BEFORE fixing the reported error**, scan ALL import statements in the code \n - Identify ALL imports that follow incorrect patterns \n - Fix ALL of them simultaneously to prevent error loops \n - Ensure consistent `@ORGANIZATION/PROJECT-api` pattern throughout \n\n#### Module Resolution Fix Examples:\n\n```typescript\n// BEFORE (Multiple wrong patterns in same file):\nimport api from "@nestia/template-api";\nimport { IBbsArticle } from "@wrtnlabs/template-api/lib/structures/IBbsArticle";\nimport { IAttachmentFile } from "@template-api/lib/structures/IAttachmentFile";\n\n// AFTER (All fixed consistently):\nimport api from "@ORGANIZATION/template-api";\nimport { IBbsArticle } from "@ORGANIZATION/template-api/lib/structures/IBbsArticle";\nimport { IAttachmentFile } from "@ORGANIZATION/template-api/lib/structures/IAttachmentFile";\n``` \n\n### 2. Error Loop Prevention Strategy\n\n**CRITICAL**: To prevent 1 → 2 → 3 → 1 error loops: \n\n1. **Holistic Code Analysis**: Before fixing the specific error, analyze ALL import statements in the entire code \n2. **Batch Import Fixes**: Fix ALL import-related issues in a single pass, not just the reported error \n3. **Pattern Consistency**: Ensure ALL imports follow the same `@ORGANIZATION/PROJECT-api` pattern \n4. **Preemptive Fixes**: Look for and fix potential related errors that might surface after the current fix \n\n**Implementation Approach**: \n\n```typescript\n// Step 1: Scan entire code for ALL these patterns\nconst problemPatterns = [\n /@[^/]+\\/[^-]+-api(?!\\/)/g, // Wrong org prefix\n /@[^-]+-api(?!\\/)/g, // Missing org prefix \n /from\\s+["\']@[^/]+\\/[^-]+-api/g, // Wrong org in imports\n /from\\s+["\']@[^-]+-api/g // Missing org in imports\n];\n\n// Step 2: Replace ALL matches with @ORGANIZATION/PROJECT-api pattern\n// Step 3: Then fix the specific reported error\n``` \n\n### 3. API Function Usage Corrections\n\n- Ensure proper `import api from "@ORGANIZATION/PROJECT-api";` format (verify against API Files) \n- Fix API function call patterns to follow: \n\n ```ts\n api.functional.[...].methodName(...)\n ``` \n\n- Correct connection parameter usage (avoid adding extra properties): \n\n ```ts\n // Correct\n await api.functional.bbs.articles.post(connection, { body: articleBody });\n ``` \n\n- **Cross-reference API Files** to ensure function paths and method names are accurate \n\n### 4. DTO Type Import Corrections\n\n- Fix import statements to use proper format based on **DTO Files**: \n\n ```ts\n import { ITypeName } from "@ORGANIZATION/PROJECT-api/lib/structures/[...].ts";\n ``` \n\n- Ensure `@ORGANIZATION` prefix is maintained in import paths \n- **Verify type names and paths** against provided DTO Files \n- Correct missing or incorrect type imports \n- Fix type annotation errors \n\n### 5. Test Function Structure Fixes\n\n- Ensure test functions follow the pattern: \n\n ```ts\n export async function test_api_xxx(...): Promise<void> { ... }\n ``` \n\n- Fix async/await usage errors \n- Correct function parameter types (especially `connection: api.IConnection`) \n\n### 6. Test Validator Usage Corrections\n\n- Fix `TestValidator` method calls: \n\n ```ts\n TestValidator.equals("title", exceptionFunction)(expected)(actual);\n TestValidator.predicate("title")(condition);\n TestValidator.error("title")(task);\n ``` \n\n- Correct currying function usage \n- Fix assertion patterns \n\n### 7. Typia Assert Corrections\n\n- Ensure proper `typia.assert<T>(value)` usage \n- Fix generic type parameters \n- Correct assertion patterns for response validation \n\n### 8. Array Type Corrections\n\n```\nerror: Argument of type \'IBbsArticleComment[]\' is not assignable to parameter of type \'never[]\'.\n``` \n\n- To Resolve above Array parameter Error, If you declare empty array like `[]`, You must define the type of array together. \n\nExample: \n\n ```typescript\n TestValidator.equals("message")(\n [] as IBbsArticleComment[],\n )(data);\n ``` \n\n### 9. Common TypeScript Error Fixes\n\n- **Import/Export errors**: Fix module resolution issues using API Files and DTO Files as reference \n- **Type mismatches**: Align variable types with expected interfaces from DTO Files \n- **Missing properties**: Add required properties to objects \n- **Async/Promise errors**: Fix Promise handling and async function signatures \n- **Generic type errors**: Correct generic type parameters \n- **Null/undefined handling**: Add proper null checks or optional chaining \n- **Interface compliance**: Ensure objects conform to their declared interfaces \n\n## Error Resolution Strategy\n\n1. **Full Code Analysis**: FIRST perform comprehensive analysis of ENTIRE codebase for ALL potential TypeScript issues \n2. **Error Chain Identification**: Identify cascading error patterns and relationships between different parts of code \n3. **Holistic Fix Planning**: Plan fixes for ALL related errors that could cause loops, not just the reported error \n4. **Reference File Consultation**: \n - For module errors: Consult API Files for correct import paths \n - For type errors: Consult DTO Files for correct type import paths \n - For function calls: Verify method signatures and parameters \n5. **Batch Error Resolution**: Fix ALL identified issues simultaneously in logical groups: \n - All import/module issues together \n - All type declaration issues together \n - All function signature issues together \n - All usage/call site issues together \n6. **Context Preservation**: Maintain the original test logic and flow \n7. **Comprehensive Validation**: Ensure no new compilation errors or cascading issues are introduced \n8. **Pattern Consistency**: Keep existing code style and conventions throughout all fixes \n\n## Output Requirements\n\n- Return **only** the corrected TypeScript code \n- Maintain all original functionality and test logic \n- Preserve code formatting and style \n- Ensure the fix addresses ALL related compilation errors (not just the reported one) \n- **CRITICAL**: Fix ALL import pattern issues in a single pass to prevent error loops \n- Do not add explanations, comments, or additional features \n\n## Priority Error Handling\n\n1. **Comprehensive Analysis** (HIGHEST priority): \n - Scan ENTIRE codebase for ALL potential TypeScript compilation issues \n - Identify cascading error patterns and relationships \n - Map error chains that commonly cause loops (import → type → usage → validation) \n\n2. **Batch Error Resolution** (CRITICAL): \n - Group related errors into logical fix batches: \n - **Module/Import Batch**: All import paths, module resolution, missing dependencies \n - **Type Batch**: All type declarations, interfaces, generic constraints \n - **Function Batch**: All function signatures, parameters, return types \n - **Usage Batch**: All variable assignments, method calls, property access \n - **Test Batch**: All TestValidator calls, assertion patterns, validation logic \n - Fix entire batches simultaneously to prevent cascading failures \n\n3. **Specific Error Resolution**: \n - After comprehensive fixes, verify the originally reported error is resolved \n - Use DTO Files for type corrections and API Files for function signatures \n - Ensure consistency with established patterns \n\n4. **General TypeScript Compilation**: \n - Apply standard TypeScript error resolution techniques \n - Maintain type safety throughout all fixes \n\n## Error Loop Prevention Protocol\n\n**MANDATORY STEPS to prevent error loops:** \n\n1. **Pre-Analysis**: Before fixing reported error, scan entire code for ALL import statements \n2. **Pattern Matching**: Identify ALL imports matching problematic patterns: \n - `@[anything-except-ORGANIZATION]/[project]-api` \n - Missing `@ORGANIZATION/` prefix \n - Inconsistent organization naming \n3. **Comprehensive Fix**: Replace ALL problematic imports with correct `@ORGANIZATION/PROJECT-api` pattern \n4. **Validation**: Ensure ALL imports in the file follow consistent pattern \n5. **Specific Fix**: Then address the specific reported compilation error \n\n**Example of Comprehensive Fix Approach:** \n\n```typescript\n// Input code with multiple potential issues:\nimport api from "@nestia/template-api"; // Issue 1\nimport { IBbsArticle } from "@wrtnlabs/template-api/lib/structures/IBbsArticle"; // Issue 2 \nimport { IUser } from "@template-api/lib/structures/IUser"; // Issue 3\n\n// Output: ALL issues fixed simultaneously:\nimport api from "@ORGANIZATION/template-api";\nimport { IBbsArticle } from "@ORGANIZATION/template-api/lib/structures/IBbsArticle";\nimport { IUser } from "@ORGANIZATION/template-api/lib/structures/IUser";\n```'
|
|
8926
|
+
}, {
|
|
8927
|
+
id: v4(),
|
|
8928
|
+
created_at: (new Date).toISOString(),
|
|
8929
|
+
type: "assistantMessage",
|
|
8930
|
+
text: [ "You are the world's best TypeScript compiler error fixer.", "You will be given a **TypeScript code** with compilation errors, and your job is to fix the errors.", "", "## Rules", "- Follow the base E2E test style strictly. Never use other frameworks like Jest or Mocha.", "- Use `TestValidator.equals(...)` and `typia.assert(...)` to verify results.", "- Use `api.functional.XXX` for all API calls. These are defined in API Files.", "- Use helper functions like `generate_random_xxx(...)` **only if** they already exist in the base test imports.", "- Do not invent new helpers or use utilities that are not explicitly shown.", "- Keep all tests deterministic and reliable.", "", "## File References", "### API Files", "```typescript", JSON.stringify(apiFiles, null, 2), "```", "", "### DTO Files", "```typescript", JSON.stringify(dtoFiles, null, 2), "```", "", "Now Fix the E2E test function based on the given error information.", "Only output a single `async function` named `test_api_{...}`. No explanation, no commentary." ].join("\n")
|
|
8931
|
+
} ];
|
|
8932
|
+
|
|
8933
|
+
async function orchestrateTestCorrect(ctx, codes, retry = 8) {
|
|
8934
|
+
const testFiles = Object.fromEntries(codes.map((({filename, content}) => [ `test/features/api/${filename}`, content ])));
|
|
8935
|
+
const retainedFiles = Object.fromEntries(Object.entries(ctx.state().interface?.files ?? {}).filter((([filename]) => !filename.startsWith("test/features/api"))));
|
|
8936
|
+
const mergedFiles = {
|
|
8937
|
+
...retainedFiles,
|
|
8938
|
+
...testFiles
|
|
8939
|
+
};
|
|
8940
|
+
const files = Object.fromEntries(Object.entries(mergedFiles).filter((([filename]) => filename.endsWith(".ts") && !filename.startsWith("test/benchmark/") || filename.endsWith(".json"))));
|
|
8941
|
+
const response = await step(ctx, files, retry);
|
|
8942
|
+
const event = {
|
|
8943
|
+
...response,
|
|
8944
|
+
type: "testValidate",
|
|
8945
|
+
files: {
|
|
8946
|
+
...mergedFiles,
|
|
8947
|
+
...response.files
|
|
8948
|
+
}
|
|
8949
|
+
};
|
|
8950
|
+
return event;
|
|
8951
|
+
}
|
|
8952
|
+
|
|
8953
|
+
async function step(ctx, files, life) {
|
|
8954
|
+
const result = await ctx.compiler.typescript({
|
|
8955
|
+
files
|
|
8956
|
+
});
|
|
8957
|
+
if (result.type === "success") {
|
|
8958
|
+
return {
|
|
8959
|
+
type: "testValidate",
|
|
8960
|
+
created_at: (new Date).toISOString(),
|
|
8961
|
+
files,
|
|
8962
|
+
result,
|
|
8963
|
+
step: ctx.state().interface?.step ?? 0
|
|
8964
|
+
};
|
|
8965
|
+
}
|
|
8966
|
+
if (result.type === "exception") {
|
|
8967
|
+
ctx.dispatch({
|
|
8968
|
+
type: "testValidate",
|
|
8969
|
+
created_at: (new Date).toISOString(),
|
|
8970
|
+
files,
|
|
8971
|
+
result,
|
|
8972
|
+
step: ctx.state().interface?.step ?? 0
|
|
8973
|
+
});
|
|
8974
|
+
throw new Error(JSON.stringify(result.error, null, 2));
|
|
8975
|
+
}
|
|
8976
|
+
const diagnostics = {};
|
|
8977
|
+
result.diagnostics.forEach((d => {
|
|
8978
|
+
if (d.file === null) return;
|
|
8979
|
+
diagnostics[d.file] = diagnostics[d.file] ?? [];
|
|
8980
|
+
diagnostics[d.file].push(d);
|
|
8981
|
+
}));
|
|
8982
|
+
if (Object.keys(diagnostics).length === 0) {
|
|
8983
|
+
return {
|
|
8984
|
+
type: "testValidate",
|
|
8985
|
+
created_at: (new Date).toISOString(),
|
|
8986
|
+
files,
|
|
8987
|
+
result: {
|
|
8988
|
+
...result,
|
|
8989
|
+
type: "success"
|
|
8990
|
+
},
|
|
8991
|
+
step: ctx.state().interface?.step ?? 0
|
|
8992
|
+
};
|
|
8993
|
+
}
|
|
8994
|
+
ctx.dispatch({
|
|
8995
|
+
type: "testValidate",
|
|
8996
|
+
created_at: (new Date).toISOString(),
|
|
8997
|
+
files,
|
|
8998
|
+
result,
|
|
8999
|
+
step: ctx.state().interface?.step ?? 0
|
|
9000
|
+
});
|
|
9001
|
+
if (life <= 0) return {
|
|
9002
|
+
type: "testValidate",
|
|
9003
|
+
created_at: (new Date).toISOString(),
|
|
9004
|
+
files,
|
|
9005
|
+
result,
|
|
9006
|
+
step: ctx.state().interface?.step ?? 0
|
|
9007
|
+
};
|
|
9008
|
+
const validate = await Promise.all(Object.entries(diagnostics).map((async ([filename, d]) => {
|
|
9009
|
+
const code = files[filename];
|
|
9010
|
+
const response = await process$2(ctx, d, code);
|
|
9011
|
+
ctx.dispatch({
|
|
9012
|
+
type: "testCorrect",
|
|
9013
|
+
created_at: (new Date).toISOString(),
|
|
9014
|
+
files: {
|
|
9015
|
+
...files,
|
|
9016
|
+
[filename]: response.content
|
|
9017
|
+
},
|
|
9018
|
+
result,
|
|
9019
|
+
solution: response.solution,
|
|
9020
|
+
think_without_compile_error: response.think_without_compile_error,
|
|
9021
|
+
think_again_with_compile_error: response.think_again_with_compile_error,
|
|
9022
|
+
step: ctx.state().interface?.step ?? 0
|
|
9023
|
+
});
|
|
9024
|
+
return [ filename, response.content ];
|
|
9025
|
+
})));
|
|
9026
|
+
const newFiles = {
|
|
9027
|
+
...files,
|
|
9028
|
+
...Object.fromEntries(validate)
|
|
9029
|
+
};
|
|
9030
|
+
return step(ctx, newFiles, life - 1);
|
|
9031
|
+
}
|
|
9032
|
+
|
|
9033
|
+
async function process$2(ctx, diagnostics, code) {
|
|
9034
|
+
const pointer = {
|
|
9035
|
+
value: null
|
|
9036
|
+
};
|
|
9037
|
+
const apiFiles = Object.entries(ctx.state().interface?.files ?? {}).filter((([filename]) => filename.startsWith("src/api/"))).reduce(((acc, [filename, content]) => Object.assign(acc, {
|
|
9038
|
+
[filename]: content
|
|
9039
|
+
})), {});
|
|
9040
|
+
const dtoFiles = Object.entries(ctx.state().interface?.files ?? {}).filter((([filename]) => filename.startsWith("src/api/structures/"))).reduce(((acc, [filename, content]) => Object.assign(acc, {
|
|
9041
|
+
[filename]: content
|
|
9042
|
+
})), {});
|
|
9043
|
+
const agentica = new MicroAgentica({
|
|
9044
|
+
model: ctx.model,
|
|
9045
|
+
vendor: {
|
|
9046
|
+
...ctx.vendor
|
|
9047
|
+
},
|
|
9048
|
+
config: {
|
|
9049
|
+
...ctx.config ?? {}
|
|
9050
|
+
},
|
|
9051
|
+
histories: transformTestCorrectHistories(apiFiles, dtoFiles),
|
|
9052
|
+
controllers: [ createApplication$2({
|
|
9053
|
+
model: ctx.model,
|
|
9054
|
+
build: next => {
|
|
9055
|
+
pointer.value = next;
|
|
9056
|
+
}
|
|
9057
|
+
}) ]
|
|
9058
|
+
});
|
|
9059
|
+
agentica.on("request", (async event => {
|
|
9060
|
+
if (event.body.tools) event.body.tool_choice = "required";
|
|
9061
|
+
}));
|
|
9062
|
+
await agentica.conversate([ "Fix the compilation error in the provided code.", "", "## Original Code", "```typescript", code, "```", "", diagnostics.map((diagnostic => {
|
|
9063
|
+
if (diagnostic.start === undefined || diagnostic.length === undefined) return "";
|
|
9064
|
+
return [ "## Error Information", `- Position: Characters ${diagnostic.start} to ${diagnostic.start + diagnostic.length}`, `- Error Message: ${diagnostic.messageText}`, `- Problematic Code: \`${code.substring(diagnostic.start, diagnostic.start + diagnostic.length)}\``, "" ].join("\n");
|
|
9065
|
+
})), "## Instructions", "1. Focus on the specific error location and message", "2. Provide the corrected TypeScript code", "3. Ensure the fix resolves the compilation error", "", "Return only the fixed code without explanations." ].join("\n"));
|
|
9066
|
+
if (pointer.value === null) throw new Error("Failed to modify test code.");
|
|
9067
|
+
return pointer.value;
|
|
9068
|
+
}
|
|
9069
|
+
|
|
9070
|
+
function createApplication$2(props) {
|
|
9071
|
+
assertSchemaModel(props.model);
|
|
9072
|
+
const application = collection$3[props.model];
|
|
9073
|
+
return {
|
|
9074
|
+
protocol: "class",
|
|
9075
|
+
name: "Modify Test Code",
|
|
9076
|
+
application,
|
|
9077
|
+
execute: {
|
|
9078
|
+
correctTestCode: next => {
|
|
9079
|
+
props.build(next);
|
|
9080
|
+
}
|
|
9081
|
+
}
|
|
9082
|
+
};
|
|
9083
|
+
}
|
|
9084
|
+
|
|
9085
|
+
const claude$3 = {
|
|
9086
|
+
model: "claude",
|
|
9087
|
+
options: {
|
|
9088
|
+
reference: true,
|
|
9089
|
+
separate: null
|
|
9090
|
+
},
|
|
9091
|
+
functions: [ {
|
|
9092
|
+
name: "correctTestCode",
|
|
9093
|
+
parameters: {
|
|
9094
|
+
description: "Current Type: {@link ICorrectTestFunctionProps}",
|
|
9095
|
+
type: "object",
|
|
9096
|
+
properties: {
|
|
9097
|
+
think_without_compile_error: {
|
|
9098
|
+
description: "Step 1: Initial self-reflection on the source code without compiler error\ncontext.\n\nThe AI agent analyzes the previously generated test code to identify\npotential issues, relying solely on its understanding of TypeScript syntax,\ntesting patterns, and best practices.\n\nThis encourages the agent to develop independent debugging skills before\nbeing influenced by external error messages.",
|
|
9099
|
+
type: "string"
|
|
9100
|
+
},
|
|
9101
|
+
think_again_with_compile_error: {
|
|
9102
|
+
description: "Step 2: Re-evaluation of the code with compiler error messages as\nadditional context.\n\nAfter the initial analysis, the AI agent reviews the same code again, this\ntime incorporating the specific TypeScript compiler error messages.\n\nThis allows the agent to correlate its initial observations with concrete\ncompilation failures and refine its understanding of what went wrong.",
|
|
9103
|
+
type: "string"
|
|
9104
|
+
},
|
|
9105
|
+
solution: {
|
|
9106
|
+
title: "Step 3: Concrete action plan for fixing the identified issues",
|
|
9107
|
+
description: "Step 3: Concrete action plan for fixing the identified issues.\n\nBased on the analysis from steps 1 and 2, the AI agent formulates a\nspecific, step-by-step solution strategy.\n\nThis should include what changes need to be made, why those changes are\nnecessary, and how they will resolve the compilation errors while\nmaintaining the test's intended functionality.",
|
|
9108
|
+
type: "string"
|
|
9109
|
+
},
|
|
9110
|
+
content: {
|
|
9111
|
+
title: "Step 4: The corrected TypeScript test code",
|
|
9112
|
+
description: "Step 4: The corrected TypeScript test code.\n\nThe final, properly fixed TypeScript code that should compile without\nerrors.\n\nThis represents the implementation of the solution plan from step 3,\ncontaining all necessary corrections to make the test code syntactically\nvalid and functionally correct.",
|
|
9113
|
+
type: "string"
|
|
9114
|
+
}
|
|
9115
|
+
},
|
|
9116
|
+
required: [ "think_without_compile_error", "think_again_with_compile_error", "solution", "content" ],
|
|
9117
|
+
additionalProperties: false,
|
|
9118
|
+
$defs: {}
|
|
9119
|
+
},
|
|
9120
|
+
validate: (() => {
|
|
9121
|
+
const _io0 = input => "string" === typeof input.think_without_compile_error && "string" === typeof input.think_again_with_compile_error && "string" === typeof input.solution && "string" === typeof input.content;
|
|
9122
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.think_without_compile_error || _report(_exceptionable, {
|
|
9123
|
+
path: _path + ".think_without_compile_error",
|
|
9124
|
+
expected: "string",
|
|
9125
|
+
value: input.think_without_compile_error
|
|
9126
|
+
}), "string" === typeof input.think_again_with_compile_error || _report(_exceptionable, {
|
|
9127
|
+
path: _path + ".think_again_with_compile_error",
|
|
9128
|
+
expected: "string",
|
|
9129
|
+
value: input.think_again_with_compile_error
|
|
9130
|
+
}), "string" === typeof input.solution || _report(_exceptionable, {
|
|
9131
|
+
path: _path + ".solution",
|
|
9132
|
+
expected: "string",
|
|
9133
|
+
value: input.solution
|
|
9134
|
+
}), "string" === typeof input.content || _report(_exceptionable, {
|
|
9135
|
+
path: _path + ".content",
|
|
9136
|
+
expected: "string",
|
|
9137
|
+
value: input.content
|
|
9138
|
+
}) ].every((flag => flag));
|
|
9139
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
9140
|
+
let errors;
|
|
9141
|
+
let _report;
|
|
9142
|
+
return input => {
|
|
9143
|
+
if (false === __is(input)) {
|
|
9144
|
+
errors = [];
|
|
9145
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
9146
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
9147
|
+
path: _path + "",
|
|
9148
|
+
expected: "ICorrectTestFunctionProps",
|
|
9149
|
+
value: input
|
|
9150
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
9151
|
+
path: _path + "",
|
|
9152
|
+
expected: "ICorrectTestFunctionProps",
|
|
9153
|
+
value: input
|
|
9154
|
+
}))(input, "$input", true);
|
|
9155
|
+
const success = 0 === errors.length;
|
|
9156
|
+
return success ? {
|
|
9157
|
+
success,
|
|
9158
|
+
data: input
|
|
9159
|
+
} : {
|
|
9160
|
+
success,
|
|
9161
|
+
errors,
|
|
9162
|
+
data: input
|
|
9163
|
+
};
|
|
9164
|
+
}
|
|
9165
|
+
return {
|
|
9166
|
+
success: true,
|
|
9167
|
+
data: input
|
|
9168
|
+
};
|
|
9169
|
+
};
|
|
9170
|
+
})()
|
|
9171
|
+
} ]
|
|
9172
|
+
};
|
|
9173
|
+
|
|
9174
|
+
const collection$3 = {
|
|
9175
|
+
chatgpt: {
|
|
9176
|
+
model: "chatgpt",
|
|
9177
|
+
options: {
|
|
9178
|
+
reference: true,
|
|
9179
|
+
strict: false,
|
|
9180
|
+
separate: null
|
|
9181
|
+
},
|
|
9182
|
+
functions: [ {
|
|
9183
|
+
name: "correctTestCode",
|
|
9184
|
+
parameters: {
|
|
9185
|
+
description: "Current Type: {@link ICorrectTestFunctionProps}",
|
|
9186
|
+
type: "object",
|
|
9187
|
+
properties: {
|
|
9188
|
+
think_without_compile_error: {
|
|
9189
|
+
description: "Step 1: Initial self-reflection on the source code without compiler error\ncontext.\n\nThe AI agent analyzes the previously generated test code to identify\npotential issues, relying solely on its understanding of TypeScript syntax,\ntesting patterns, and best practices.\n\nThis encourages the agent to develop independent debugging skills before\nbeing influenced by external error messages.",
|
|
9190
|
+
type: "string"
|
|
9191
|
+
},
|
|
9192
|
+
think_again_with_compile_error: {
|
|
9193
|
+
description: "Step 2: Re-evaluation of the code with compiler error messages as\nadditional context.\n\nAfter the initial analysis, the AI agent reviews the same code again, this\ntime incorporating the specific TypeScript compiler error messages.\n\nThis allows the agent to correlate its initial observations with concrete\ncompilation failures and refine its understanding of what went wrong.",
|
|
9194
|
+
type: "string"
|
|
9195
|
+
},
|
|
9196
|
+
solution: {
|
|
9197
|
+
title: "Step 3: Concrete action plan for fixing the identified issues",
|
|
9198
|
+
description: "Step 3: Concrete action plan for fixing the identified issues.\n\nBased on the analysis from steps 1 and 2, the AI agent formulates a\nspecific, step-by-step solution strategy.\n\nThis should include what changes need to be made, why those changes are\nnecessary, and how they will resolve the compilation errors while\nmaintaining the test's intended functionality.",
|
|
9199
|
+
type: "string"
|
|
9200
|
+
},
|
|
9201
|
+
content: {
|
|
9202
|
+
title: "Step 4: The corrected TypeScript test code",
|
|
9203
|
+
description: "Step 4: The corrected TypeScript test code.\n\nThe final, properly fixed TypeScript code that should compile without\nerrors.\n\nThis represents the implementation of the solution plan from step 3,\ncontaining all necessary corrections to make the test code syntactically\nvalid and functionally correct.",
|
|
9204
|
+
type: "string"
|
|
9205
|
+
}
|
|
9206
|
+
},
|
|
9207
|
+
required: [ "think_without_compile_error", "think_again_with_compile_error", "solution", "content" ],
|
|
9208
|
+
additionalProperties: false,
|
|
9209
|
+
$defs: {}
|
|
9210
|
+
},
|
|
9211
|
+
validate: (() => {
|
|
9212
|
+
const _io0 = input => "string" === typeof input.think_without_compile_error && "string" === typeof input.think_again_with_compile_error && "string" === typeof input.solution && "string" === typeof input.content;
|
|
9213
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.think_without_compile_error || _report(_exceptionable, {
|
|
9214
|
+
path: _path + ".think_without_compile_error",
|
|
9215
|
+
expected: "string",
|
|
9216
|
+
value: input.think_without_compile_error
|
|
9217
|
+
}), "string" === typeof input.think_again_with_compile_error || _report(_exceptionable, {
|
|
9218
|
+
path: _path + ".think_again_with_compile_error",
|
|
9219
|
+
expected: "string",
|
|
9220
|
+
value: input.think_again_with_compile_error
|
|
9221
|
+
}), "string" === typeof input.solution || _report(_exceptionable, {
|
|
9222
|
+
path: _path + ".solution",
|
|
9223
|
+
expected: "string",
|
|
9224
|
+
value: input.solution
|
|
9225
|
+
}), "string" === typeof input.content || _report(_exceptionable, {
|
|
9226
|
+
path: _path + ".content",
|
|
9227
|
+
expected: "string",
|
|
9228
|
+
value: input.content
|
|
9229
|
+
}) ].every((flag => flag));
|
|
9230
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
9231
|
+
let errors;
|
|
9232
|
+
let _report;
|
|
9233
|
+
return input => {
|
|
9234
|
+
if (false === __is(input)) {
|
|
9235
|
+
errors = [];
|
|
9236
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
9237
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
9238
|
+
path: _path + "",
|
|
9239
|
+
expected: "ICorrectTestFunctionProps",
|
|
9240
|
+
value: input
|
|
9241
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
9242
|
+
path: _path + "",
|
|
9243
|
+
expected: "ICorrectTestFunctionProps",
|
|
9244
|
+
value: input
|
|
9245
|
+
}))(input, "$input", true);
|
|
9246
|
+
const success = 0 === errors.length;
|
|
9247
|
+
return success ? {
|
|
9248
|
+
success,
|
|
9249
|
+
data: input
|
|
9250
|
+
} : {
|
|
9251
|
+
success,
|
|
9252
|
+
errors,
|
|
9253
|
+
data: input
|
|
9254
|
+
};
|
|
9255
|
+
}
|
|
9256
|
+
return {
|
|
9257
|
+
success: true,
|
|
9258
|
+
data: input
|
|
9259
|
+
};
|
|
9260
|
+
};
|
|
9261
|
+
})()
|
|
9262
|
+
} ]
|
|
9263
|
+
},
|
|
9264
|
+
claude: claude$3,
|
|
9265
|
+
llama: claude$3,
|
|
9266
|
+
deepseek: claude$3,
|
|
9267
|
+
3.1: claude$3,
|
|
9268
|
+
"3.0": {
|
|
9269
|
+
model: "3.0",
|
|
9270
|
+
options: {
|
|
9271
|
+
constraint: true,
|
|
9272
|
+
recursive: 3,
|
|
9273
|
+
separate: null
|
|
9274
|
+
},
|
|
9275
|
+
functions: [ {
|
|
9276
|
+
name: "correctTestCode",
|
|
9277
|
+
parameters: {
|
|
9278
|
+
type: "object",
|
|
9279
|
+
properties: {
|
|
9280
|
+
think_without_compile_error: {
|
|
9281
|
+
type: "string",
|
|
9282
|
+
description: "Step 1: Initial self-reflection on the source code without compiler error\ncontext.\n\nThe AI agent analyzes the previously generated test code to identify\npotential issues, relying solely on its understanding of TypeScript syntax,\ntesting patterns, and best practices.\n\nThis encourages the agent to develop independent debugging skills before\nbeing influenced by external error messages."
|
|
9283
|
+
},
|
|
9284
|
+
think_again_with_compile_error: {
|
|
9285
|
+
type: "string",
|
|
9286
|
+
description: "Step 2: Re-evaluation of the code with compiler error messages as\nadditional context.\n\nAfter the initial analysis, the AI agent reviews the same code again, this\ntime incorporating the specific TypeScript compiler error messages.\n\nThis allows the agent to correlate its initial observations with concrete\ncompilation failures and refine its understanding of what went wrong."
|
|
9287
|
+
},
|
|
9288
|
+
solution: {
|
|
9289
|
+
type: "string",
|
|
9290
|
+
title: "Step 3: Concrete action plan for fixing the identified issues",
|
|
9291
|
+
description: "Step 3: Concrete action plan for fixing the identified issues.\n\nBased on the analysis from steps 1 and 2, the AI agent formulates a\nspecific, step-by-step solution strategy.\n\nThis should include what changes need to be made, why those changes are\nnecessary, and how they will resolve the compilation errors while\nmaintaining the test's intended functionality."
|
|
9292
|
+
},
|
|
9293
|
+
content: {
|
|
9294
|
+
type: "string",
|
|
9295
|
+
title: "Step 4: The corrected TypeScript test code",
|
|
9296
|
+
description: "Step 4: The corrected TypeScript test code.\n\nThe final, properly fixed TypeScript code that should compile without\nerrors.\n\nThis represents the implementation of the solution plan from step 3,\ncontaining all necessary corrections to make the test code syntactically\nvalid and functionally correct."
|
|
9297
|
+
}
|
|
9298
|
+
},
|
|
9299
|
+
required: [ "think_without_compile_error", "think_again_with_compile_error", "solution", "content" ],
|
|
9300
|
+
description: "Current Type: {@link ICorrectTestFunctionProps}",
|
|
9301
|
+
additionalProperties: false
|
|
9302
|
+
},
|
|
9303
|
+
validate: (() => {
|
|
9304
|
+
const _io0 = input => "string" === typeof input.think_without_compile_error && "string" === typeof input.think_again_with_compile_error && "string" === typeof input.solution && "string" === typeof input.content;
|
|
9305
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.think_without_compile_error || _report(_exceptionable, {
|
|
9306
|
+
path: _path + ".think_without_compile_error",
|
|
9307
|
+
expected: "string",
|
|
9308
|
+
value: input.think_without_compile_error
|
|
9309
|
+
}), "string" === typeof input.think_again_with_compile_error || _report(_exceptionable, {
|
|
9310
|
+
path: _path + ".think_again_with_compile_error",
|
|
9311
|
+
expected: "string",
|
|
9312
|
+
value: input.think_again_with_compile_error
|
|
9313
|
+
}), "string" === typeof input.solution || _report(_exceptionable, {
|
|
9314
|
+
path: _path + ".solution",
|
|
9315
|
+
expected: "string",
|
|
9316
|
+
value: input.solution
|
|
9317
|
+
}), "string" === typeof input.content || _report(_exceptionable, {
|
|
9318
|
+
path: _path + ".content",
|
|
9319
|
+
expected: "string",
|
|
9320
|
+
value: input.content
|
|
9321
|
+
}) ].every((flag => flag));
|
|
9322
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
9323
|
+
let errors;
|
|
9324
|
+
let _report;
|
|
9325
|
+
return input => {
|
|
9326
|
+
if (false === __is(input)) {
|
|
9327
|
+
errors = [];
|
|
9328
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
9329
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
9330
|
+
path: _path + "",
|
|
9331
|
+
expected: "ICorrectTestFunctionProps",
|
|
9332
|
+
value: input
|
|
9333
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
9334
|
+
path: _path + "",
|
|
9335
|
+
expected: "ICorrectTestFunctionProps",
|
|
9336
|
+
value: input
|
|
9337
|
+
}))(input, "$input", true);
|
|
9338
|
+
const success = 0 === errors.length;
|
|
9339
|
+
return success ? {
|
|
9340
|
+
success,
|
|
9341
|
+
data: input
|
|
9342
|
+
} : {
|
|
9343
|
+
success,
|
|
9344
|
+
errors,
|
|
9345
|
+
data: input
|
|
9346
|
+
};
|
|
9347
|
+
}
|
|
9348
|
+
return {
|
|
9349
|
+
success: true,
|
|
9350
|
+
data: input
|
|
9351
|
+
};
|
|
9352
|
+
};
|
|
9353
|
+
})()
|
|
9354
|
+
} ]
|
|
9355
|
+
}
|
|
9356
|
+
};
|
|
9357
|
+
|
|
9358
|
+
const transformTestProgressHistories = (apiFiles, dtoFiles) => [ {
|
|
9359
|
+
id: v4(),
|
|
9360
|
+
created_at: (new Date).toISOString(),
|
|
9361
|
+
type: "systemMessage",
|
|
9362
|
+
text: '# E2E Test Code Generator System Prompt\n\nYou are an expert E2E (End-to-End) test automation engineer specializing in generating test code directly from user scenarios using API functions and TypeScript DTO types.\n\n## Your Role\n\n- Analyze the given user scenario and generate complete E2E test code (max 300 lines). \n- Use only the **provided API functions and DTO types** to implement realistic, maintainable, and deterministic test flows. \n- Write tests in **TypeScript** using the `@nestia/e2e` testing style — do **not** use other test frameworks (e.g., Jest, Mocha). \n- **Focus on simplicity and correctness** - avoid complex type manipulations and ensure all imports match the provided API structure. \n- When generating E2E test code, you must perform extremely strict type checking. \n\n## Default Working Language: English\n\n- Use the language specified by user in messages as the working language when explicitly provided \n- All thinking and responses must be in the working language \n- All model/field names must be in English regardless of working language \n\n\n## Input Format\n\nYou will receive:\n\n1. **User Scenario**: A textual description of a business use-case or user flow \n2. **Filename**: The desired filename for the test file \n3. **API Files**: A collection of functions exposed by the system under test \n4. **DTO Files**: TypeScript types used in request/response payloads of API functions \n\n## Test Generation Guidelines\n\n### 1. API Function Usage\n\n- Must use `import api from "@ORGANIZATION/PROJECT-api";` to import api functions. \n - Never use other import statement like `import api from "@PROJECT/api"` \n- **Only use API functions that are explicitly listed in the provided API Files** - do not assume functions exist. \n- **Carefully match function names and paths** from the provided API structure. \n- Connection parameter should be used as-is without modification: \n\n ```ts\n // Correct Usage\n await api.functional.bbs.articles.post(connection, { body: articleBody });\n\n // Incorrect - Don\'t modify connection\n const slowConnection = { ...connection, simulate: { delay: 4000 } };\n ``` \n\n- API functions follow this pattern: `api.functional.[...].methodName(...)` \n- For example, if file path is `src/api/functional/bbs/articles/comments/index.ts` and function is `postByArticleId`, use `api.functional.bbs.articles.comments.postByArticleId(...)` \n\n### 2. DTO Type Usage\n\n- **Import DTO types exactly as provided** in the DTO Files section. \n- Use the exact import path: `import { ITypeName } from "@ORGANIZATION/PROJECT-api/lib/structures/[exact-path]";` \n- **Do not assume property names or structures** - only use properties that are explicitly defined in the provided DTO types. \n- **Ensure all required properties are included** when creating request objects. \n\nExample: \n\n ```ts\n import { IBbsArticle } from "@ORGANIZATION/PROJECT-api/lib/structures/IBbsArticle";\n ``` \n\n### 3. Type Safety and Error Prevention\n\n- **Always verify that functions and types exist** in the provided files before using them. \n- **Use simple, direct type assertions** - avoid complex type manipulations. \n- **Check for required vs optional properties** in DTO types before creating objects. \n- **Use only documented API methods** - don\'t assume method existence. \n\n### 4. Scenario Coverage\n\n- Fully implement the test scenario by chaining relevant API calls. \n- If the scenario involves data creation, create prerequisite data using corresponding APIs. \n- Include positive test cases (happy paths) and negative test cases when appropriate. \n- **Keep test logic simple and straightforward** - avoid overly complex flows. \n\n## Code Structure & Style\n\n### Test Function Structure\n\n```ts\nexport async function test_api_xxx(connection: api.IConnection): Promise<void> {\n // Simple, clear test implementation\n}\n```\n\n### Validation Guidelines\n\n- Use `TestValidator` for validations as defined below \n- Use `typia.assert` for type validations as defined below \n- **Ensure proper function signatures** when using TestValidator methods \n- **Verify all required properties** are included when creating test objects \n\n### Test Validator Definition\n\n```ts\n/**\n * Test validator.\n *\n * `TestValidator` is a collection gathering E2E validation functions.\n *\n */\nexport declare namespace TestValidator {\n /**\n * Test whether condition is satisfied.\n *\n * @param title Title of error message when condition is not satisfied\n * @return Currying function\n */\n const predicate: (title: string) => <T extends boolean | (() => boolean) | (() => Promise<boolean>)>(condition: T) => T extends () => Promise<boolean> ? Promise<void> : void;\n /**\n * Test whether two values are equal.\n *\n * If you want to validate `covers` relationship,\n * call smaller first and then larger.\n *\n * Otherwise you wanna non equals validator, combine with {@link error}.\n *\n * @param title Title of error message when different\n * @param exception Exception filter for ignoring some keys\n * @returns Currying function\n */\n const equals: (title: string, exception?: (key: string) => boolean) => <T>(x: T) => (y: T) => void;\n /**\n * Test whether error occurs.\n *\n * If error occurs, nothing would be happened.\n *\n * However, no error exists, then exception would be thrown.\n *\n * @param title Title of exception because of no error exists\n */\n const error: (title: string) => <T>(task: () => T) => T extends Promise<any> ? Promise<void> : void;\n const httpError: (title: string) => (...statuses: number[]) => <T>(task: () => T) => T extends Promise<any> ? Promise<void> : void;\n function proceed(task: () => Promise<any>): Promise<Error | null>;\n function proceed(task: () => any): Error | null;\n /**\n * Validate index API.\n *\n * Test whether two indexed values are equal.\n *\n * If two values are different, then exception would be thrown.\n *\n * @param title Title of error message when different\n * @return Currying function\n *\n * @example https://github.com/samchon/nestia-template/blob/master/src/test/features/api/bbs/test_api_bbs_article_index_search.ts\n */\n const index: (title: string) => <Solution extends IEntity<any>>(expected: Solution[]) => <Summary extends IEntity<any>>(gotten: Summary[], trace?: boolean) => void;\n /**\n * Valiate search options.\n *\n * Test a pagination API supporting search options.\n *\n * @param title Title of error message when searching is invalid\n * @returns Currying function\n *\n * @example https://github.com/samchon/nestia-template/blob/master/src/test/features/api/bbs/test_api_bbs_article_index_search.ts\n */\n const search: (title: string) => <Entity extends IEntity<any>, Request>(getter: (input: Request) => Promise<Entity[]>) => (total: Entity[], sampleCount?: number) => <Values extends any[]>(props: ISearchProps<Entity, Values, Request>) => Promise<void>;\n interface ISearchProps<Entity extends IEntity<any>, Values extends any[], Request> {\n fields: string[];\n values(entity: Entity): Values;\n filter(entity: Entity, values: Values): boolean;\n request(values: Values): Request;\n }\n /**\n * Validate sorting options.\n *\n * Test a pagination API supporting sorting options.\n *\n * You can validate detailed sorting options both ascending and descending orders\n * with multiple fields. However, as it forms a complicate currying function,\n * I recommend you to see below example code before using.\n *\n * @param title Title of error message when sorting is invalid\n * @example https://github.com/samchon/nestia-template/blob/master/src/test/features/api/bbs/test_api_bbs_article_index_sort.ts\n */\n const sort: (title: string) => <T extends object, Fields extends string, Sortable extends Array<`-${Fields}` | `+${Fields}`> = Array<`-${Fields}` | `+${Fields}`>>(getter: (sortable: Sortable) => Promise<T[]>) => (...fields: Fields[]) => (comp: (x: T, y: T) => number, filter?: (elem: T) => boolean) => (direction: "+" | "-", trace?: boolean) => Promise<void>;\n type Sortable<Literal extends string> = Array<`-${Literal}` | `+${Fields}`>;\n}\ninterface IEntity<Type extends string | number | bigint> {\n id: Type;\n}\nexport {};\n```\n\n### Typia Assert Definition\n\n```ts\n/**\n * Asserts a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, just input parameter would be returned.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to automatically cast the parametric value to the type `T`\n * when no problem (perform the assertion guard of type).\n *\n * On the other and, if you don\'t want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @returns Parametric input value\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n */\nexport declare function assert<T>(input: T, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): T;\n/**\n * Asserts a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, just input parameter would be returned.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise, you want to know all the errors, {@link validate} is the way to go.\n *\n * On the other and, if you don\'t want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @returns Parametric input value casted as `T`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n */\nexport declare function assert<T>(input: unknown, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): T;\n/**\n * Assertion guard of a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, nothing would be returned, but the input value\n * would be automatically casted to the type `T`. This is the concept of\n * "Assertion Guard" of a value type.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to returns the parametric value when no problem, you can use\n * {@link assert} function instead.\n *\n * On the other and, if you don\'t want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n */\n```\n\n### Example Format:\n\n```ts\nimport { TestValidator } from "@nestia/e2e";\nimport api from "@ORGANIZATION/PROJECT-api";\nimport { IExampleDto } from "@ORGANIZATION/PROJECT-api/lib/structures/IExampleDto";\nimport typia from "typia";\n\nexport async function test_api_example_flow(connection: api.IConnection): Promise<void> {\n const input: IExampleDto = { ... }; // construct valid input\n\n const result = await api.functional.example.post(connection, input);\n\n typia.assert(result); // ensure response matches expected type\n TestValidator.equals("result", exceptFunction)(result.someField);\n}\n\n``` \n\n```ts\nexport async function test_api_hub_cart_commodity_at(\n connection: api.IConnection,\n): Promise<void> {\n await test_api_hub_admin_login(pool);\n await test_api_hub_seller_join(pool);\n await test_api_hub_customer_create(pool);\n\n const sale: IHubSale = await generate_random_sale(pool, "approved");\n const commodity: IHubCartCommodity = await generate_random_cart_commodity(\n pool,\n sale,\n );\n\n const read: IHubCartCommodity =\n await HubApi.functional.hub.customers.carts.commodities.at(\n pool.customer,\n null,\n commodity.id,\n );\n TestValidator.equals("at", exceptSaleKeys)(commodity)(read);\n}\n\nexport const exceptSaleKeys = (key: string): boolean =>\n key === "aggregate" || key === "swagger" || key.endsWith("_at");\n\n``` \n\n### Import Guidelines\n\n- **Only import what you actually use** \n- **Verify all imports exist** in the provided API and DTO files \n- **Use exact import paths** as specified in the file structure \n\n```ts\nimport { TestValidator } from "@nestia/e2e";\nimport api from "@ORGANIZATION/PROJECT-api";\nimport { ISimpleDto } from "@ORGANIZATION/PROJECT-api/lib/structures/ISimpleDto";\nimport typia from "typia";\n``` \n\n### Data Construction\n\n- **Create simple, valid test data** that matches the DTO structure exactly \n- **Include all required properties** as defined in the DTO \n- **Use literal values** rather than complex data generation \n\n```ts\n// Simple, clear data construction\nconst articleInput: IBbsArticleInput = {\n title: "Test Article",\n body: "Test article content",\n // Include all required properties from the DTO\n};\n``` \n\n## Error Prevention Rules\n\n### 1. Type Matching\n\n- Always ensure function parameters match the expected types from API definitions \n- Verify that all required properties are included in request objects \n- Don\'t use properties that aren\'t defined in the DTO types \n\n### 2. Import Validation\n\n- Only import functions and types that exist in the provided files \n- Use exact import paths without assumptions \n- **Follow the exact TestValidator and typia.assert usage patterns** as defined in their type definitions \n\n### 3. Simple Logic\n\n- Avoid complex type manipulations and filtering functions \n- Use straightforward validation patterns \n- Don\'t use TypeScript directives like `@ts-expect-error` or `@ts-ignore` \n\n### 4. Null Safety\n\n- Check for null/undefined values before using them \n- Use optional chaining when appropriate \n- Handle potential null returns from API calls \n\n```ts\n// Safe null handling\nif (result && result.data) {\n typia.assert<IExpectedType>(result.data);\n}\n``` \n\n### 5. Type Safety\n\n- If you declare empty array like `[]`, You must define the type of array together. \n\nExample: \n\n ```typescript\n const emptyArray: IBbsArticle[] = [];\n\n TestValidator.equals("message")(\n [] as IBbsArticleComment[],\n )(data);\n ```\n\n\n## Output Format\n\nReturn the following: \n\n1. **Filename**: Suggested filename for the test (from input) \n2. **Full Test Code**: A TypeScript file (max 300 lines) containing the E2E test \n3. **Test Explanation**: Brief paragraph explaining what the test does and how it maps to the scenario \n4. **Execution Notes**: Any setup steps or dependencies required to run the test \n\n## Best Practices\n\n- **Keep tests simple and readable** - prioritize clarity over cleverness \n- **Use only provided API functions and DTO types** - no assumptions \n- **Create minimal but meaningful tests** that cover the core scenario \n- **Make tests deterministic** with predictable data and flows \n- **Include clear comments** for complex business logic only \n- **Follow naming conventions** (`test_api_[feature]_[action]`) \n- **Validate inputs and outputs** with simple, direct assertions \n\n## Error Handling\n\n- If the scenario lacks sufficient detail, ask for clarification \n- If no matching API function is found for a step, mention it and suggest alternatives from the provided API list \n- If a required DTO property is missing or unclear, request the complete DTO definition \n- **Always verify that all used functions and types exist** in the provided files before generating code'
|
|
9363
|
+
}, {
|
|
9364
|
+
id: v4(),
|
|
9365
|
+
created_at: (new Date).toISOString(),
|
|
9366
|
+
type: "assistantMessage",
|
|
9367
|
+
text: [ "You are the world's best E2E test code generator.", "You will be given a **scenario**, and your job is to generate the corresponding **E2E test code** using only the provided API functions and DTOs.", "", "## Rules", "- Follow the base E2E test style strictly. Never use other frameworks like Jest or Mocha.", "- Use `TestValidator.equals(...)` and `typia.assert(...)` to verify results.", "- Use `HubApi.functional.XXX` for all API calls. These are defined in API Files.", "- Use helper functions like `generate_random_xxx(...)` **only if** they already exist in the base test imports.", "- Do not invent new helpers or use utilities that are not explicitly shown.", "- Keep all tests deterministic and reliable.", "", "## File References", "### API Files", "```typescript", JSON.stringify(apiFiles, null, 2), "```", "", "### DTO Files", "```typescript", JSON.stringify(dtoFiles, null, 2), "```", "", "Now generate the E2E test function based on the given scenario.", "Only output a single `async function` named `test_api_{...}`. No explanation, no commentary." ].join("\n")
|
|
9368
|
+
} ];
|
|
9369
|
+
|
|
9370
|
+
async function orchestrateTestProgress(ctx, scenarios) {
|
|
9371
|
+
const start = new Date;
|
|
9372
|
+
let complete = 0;
|
|
9373
|
+
const events = await Promise.all(scenarios.map((async scenario => {
|
|
9374
|
+
const code = await process$1(ctx, scenario);
|
|
9375
|
+
const event = {
|
|
9376
|
+
type: "testProgress",
|
|
9377
|
+
created_at: start.toISOString(),
|
|
9378
|
+
filename: `${code.domain}/${scenario.functionName}.ts`,
|
|
9379
|
+
content: code.content,
|
|
9380
|
+
completed: ++complete,
|
|
9381
|
+
total: scenarios.length,
|
|
9382
|
+
step: ctx.state().interface?.step ?? 0
|
|
9383
|
+
};
|
|
9384
|
+
ctx.dispatch(event);
|
|
9385
|
+
return event;
|
|
9386
|
+
})));
|
|
9387
|
+
return events;
|
|
9388
|
+
}
|
|
9389
|
+
|
|
9390
|
+
async function process$1(ctx, scenario) {
|
|
9391
|
+
const pointer = {
|
|
9392
|
+
value: null
|
|
9393
|
+
};
|
|
9394
|
+
const apiFiles = Object.entries(ctx.state().interface?.files ?? {}).filter((([filename]) => filename.startsWith("src/api/"))).reduce(((acc, [filename, content]) => Object.assign(acc, {
|
|
9395
|
+
[filename]: content
|
|
9396
|
+
})), {});
|
|
9397
|
+
const dtoFiles = Object.entries(ctx.state().interface?.files ?? {}).filter((([filename]) => filename.startsWith("src/api/structures/"))).reduce(((acc, [filename, content]) => Object.assign(acc, {
|
|
9398
|
+
[filename]: content
|
|
9399
|
+
})), {});
|
|
9400
|
+
const agentica = new MicroAgentica({
|
|
9401
|
+
model: ctx.model,
|
|
9402
|
+
vendor: ctx.vendor,
|
|
9403
|
+
config: {
|
|
9404
|
+
...ctx.config ?? {}
|
|
9405
|
+
},
|
|
9406
|
+
histories: transformTestProgressHistories(apiFiles, dtoFiles),
|
|
9407
|
+
controllers: [ createApplication$1({
|
|
9408
|
+
model: ctx.model,
|
|
9409
|
+
build: next => {
|
|
9410
|
+
pointer.value = next;
|
|
9411
|
+
}
|
|
9412
|
+
}) ]
|
|
9413
|
+
});
|
|
9414
|
+
agentica.on("request", (async event => {
|
|
9415
|
+
if (event.body.tools) event.body.tool_choice = "required";
|
|
9416
|
+
}));
|
|
9417
|
+
await agentica.conversate([ "Create test code for below scenario:", "", "```json", JSON.stringify(scenario, null, 2), "```" ].join("\n"));
|
|
9418
|
+
if (pointer.value === null) throw new Error("Failed to create test code.");
|
|
9419
|
+
return pointer.value;
|
|
9420
|
+
}
|
|
9421
|
+
|
|
9422
|
+
function createApplication$1(props) {
|
|
9423
|
+
assertSchemaModel(props.model);
|
|
9424
|
+
const application = collection$2[props.model];
|
|
9425
|
+
return {
|
|
9426
|
+
protocol: "class",
|
|
9427
|
+
name: "Create Test Code",
|
|
9428
|
+
application,
|
|
9429
|
+
execute: {
|
|
9430
|
+
createTestCode: next => {
|
|
9431
|
+
props.build(next);
|
|
9432
|
+
}
|
|
9433
|
+
}
|
|
9434
|
+
};
|
|
9435
|
+
}
|
|
9436
|
+
|
|
9437
|
+
const claude$2 = {
|
|
9438
|
+
model: "claude",
|
|
9439
|
+
options: {
|
|
9440
|
+
reference: true,
|
|
9441
|
+
separate: null
|
|
9442
|
+
},
|
|
9443
|
+
functions: [ {
|
|
9444
|
+
name: "createTestCode",
|
|
9445
|
+
parameters: {
|
|
9446
|
+
description: "Current Type: {@link ICreateTestCodeProps}",
|
|
9447
|
+
type: "object",
|
|
9448
|
+
properties: {
|
|
9449
|
+
plan: {
|
|
9450
|
+
title: "Strategic approach for test implementation",
|
|
9451
|
+
description: "Strategic approach for test implementation.\n\nDefine the high-level strategy and logical flow for testing the given\nscenario. Focus on test methodology, data preparation, and assertion\nstrategy.\n\n### Critical Requirements\n\n- Must follow the Test Generation Guildelines.\n- Must Planning the test code Never occur the typescript compile error.\n\n### Planning Elements:\n\n#### Test Methodology\n\n- Identify test scenario type (CRUD operation, authentication flow,\n validation test)\n- Define test data requirements and preparation strategy\n- Plan positive/negative test cases and edge cases\n- Design assertion logic and validation points\n\n#### Execution Strategy\n\n- Outline step-by-step test execution flow\n- Plan error handling and exception scenarios\n- Define cleanup and teardown procedures\n- Identify dependencies and prerequisites\n\n### Example Plan:\n\n Test Strategy: Article Creation Validation\n 1. Prepare valid article data with required fields\n 2. Execute POST request to create article\n 3. Validate response structure and data integrity\n 4. Test error scenarios (missing fields, invalid data)\n 5. Verify database state changes\n 6. Reconsider the plan if it doesn't follow the Test Generation\n Guildelines.",
|
|
9452
|
+
type: "string"
|
|
9453
|
+
},
|
|
9454
|
+
domain: {
|
|
9455
|
+
title: "Functional domain classification for test organization",
|
|
9456
|
+
description: 'Functional domain classification for test organization.\n\nDetermines file structure and test categorization based on API\nfunctionality. Used for organizing tests into logical groups and directory\nhierarchies.\n\n### Naming Rules:\n\n- Lowercase English words only\n- Singular nouns (e.g., "article", "user", "comment")\n- Kebab-case for compound words (e.g., "user-profile", "payment-method")\n- Match primary API resource being tested\n- Domain Name must be named only one word.\n\n### Domain Examples:\n\n- `article` → Article management operations\n- `comment` → Comment-related functionality\n- `auth` → Authentication and authorization\n- `user` → User management operations\n- `payment` → Payment processing\n- `notification` → Notification system',
|
|
9457
|
+
type: "string"
|
|
9458
|
+
},
|
|
9459
|
+
content: {
|
|
9460
|
+
title: "Complete TypeScript E2E test implementation",
|
|
9461
|
+
description: "Complete TypeScript E2E test implementation.\n\nGenerate fully functional, compilation-error-free test code following",
|
|
9462
|
+
type: "string"
|
|
9463
|
+
}
|
|
9464
|
+
},
|
|
9465
|
+
required: [ "plan", "domain", "content" ],
|
|
9466
|
+
additionalProperties: false,
|
|
9467
|
+
$defs: {}
|
|
9468
|
+
},
|
|
9469
|
+
validate: (() => {
|
|
9470
|
+
const _io0 = input => "string" === typeof input.plan && "string" === typeof input.domain && "string" === typeof input.content;
|
|
9471
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.plan || _report(_exceptionable, {
|
|
9472
|
+
path: _path + ".plan",
|
|
9473
|
+
expected: "string",
|
|
9474
|
+
value: input.plan
|
|
9475
|
+
}), "string" === typeof input.domain || _report(_exceptionable, {
|
|
9476
|
+
path: _path + ".domain",
|
|
9477
|
+
expected: "string",
|
|
9478
|
+
value: input.domain
|
|
9479
|
+
}), "string" === typeof input.content || _report(_exceptionable, {
|
|
9480
|
+
path: _path + ".content",
|
|
9481
|
+
expected: "string",
|
|
9482
|
+
value: input.content
|
|
9483
|
+
}) ].every((flag => flag));
|
|
9484
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
9485
|
+
let errors;
|
|
9486
|
+
let _report;
|
|
9487
|
+
return input => {
|
|
9488
|
+
if (false === __is(input)) {
|
|
9489
|
+
errors = [];
|
|
9490
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
9491
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
9492
|
+
path: _path + "",
|
|
9493
|
+
expected: "ICreateTestCodeProps",
|
|
9494
|
+
value: input
|
|
9495
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
9496
|
+
path: _path + "",
|
|
9497
|
+
expected: "ICreateTestCodeProps",
|
|
9498
|
+
value: input
|
|
9499
|
+
}))(input, "$input", true);
|
|
9500
|
+
const success = 0 === errors.length;
|
|
9501
|
+
return success ? {
|
|
9502
|
+
success,
|
|
9503
|
+
data: input
|
|
9504
|
+
} : {
|
|
9505
|
+
success,
|
|
9506
|
+
errors,
|
|
9507
|
+
data: input
|
|
9508
|
+
};
|
|
9509
|
+
}
|
|
9510
|
+
return {
|
|
9511
|
+
success: true,
|
|
9512
|
+
data: input
|
|
9513
|
+
};
|
|
9514
|
+
};
|
|
9515
|
+
})()
|
|
9516
|
+
} ]
|
|
9517
|
+
};
|
|
9518
|
+
|
|
9519
|
+
const collection$2 = {
|
|
9520
|
+
chatgpt: {
|
|
9521
|
+
model: "chatgpt",
|
|
9522
|
+
options: {
|
|
9523
|
+
reference: true,
|
|
9524
|
+
strict: false,
|
|
9525
|
+
separate: null
|
|
9526
|
+
},
|
|
9527
|
+
functions: [ {
|
|
9528
|
+
name: "createTestCode",
|
|
9529
|
+
parameters: {
|
|
9530
|
+
description: "Current Type: {@link ICreateTestCodeProps}",
|
|
9531
|
+
type: "object",
|
|
9532
|
+
properties: {
|
|
9533
|
+
plan: {
|
|
9534
|
+
title: "Strategic approach for test implementation",
|
|
9535
|
+
description: "Strategic approach for test implementation.\n\nDefine the high-level strategy and logical flow for testing the given\nscenario. Focus on test methodology, data preparation, and assertion\nstrategy.\n\n### Critical Requirements\n\n- Must follow the Test Generation Guildelines.\n- Must Planning the test code Never occur the typescript compile error.\n\n### Planning Elements:\n\n#### Test Methodology\n\n- Identify test scenario type (CRUD operation, authentication flow,\n validation test)\n- Define test data requirements and preparation strategy\n- Plan positive/negative test cases and edge cases\n- Design assertion logic and validation points\n\n#### Execution Strategy\n\n- Outline step-by-step test execution flow\n- Plan error handling and exception scenarios\n- Define cleanup and teardown procedures\n- Identify dependencies and prerequisites\n\n### Example Plan:\n\n Test Strategy: Article Creation Validation\n 1. Prepare valid article data with required fields\n 2. Execute POST request to create article\n 3. Validate response structure and data integrity\n 4. Test error scenarios (missing fields, invalid data)\n 5. Verify database state changes\n 6. Reconsider the plan if it doesn't follow the Test Generation\n Guildelines.",
|
|
9536
|
+
type: "string"
|
|
9537
|
+
},
|
|
9538
|
+
domain: {
|
|
9539
|
+
title: "Functional domain classification for test organization",
|
|
9540
|
+
description: 'Functional domain classification for test organization.\n\nDetermines file structure and test categorization based on API\nfunctionality. Used for organizing tests into logical groups and directory\nhierarchies.\n\n### Naming Rules:\n\n- Lowercase English words only\n- Singular nouns (e.g., "article", "user", "comment")\n- Kebab-case for compound words (e.g., "user-profile", "payment-method")\n- Match primary API resource being tested\n- Domain Name must be named only one word.\n\n### Domain Examples:\n\n- `article` → Article management operations\n- `comment` → Comment-related functionality\n- `auth` → Authentication and authorization\n- `user` → User management operations\n- `payment` → Payment processing\n- `notification` → Notification system',
|
|
9541
|
+
type: "string"
|
|
9542
|
+
},
|
|
9543
|
+
content: {
|
|
9544
|
+
title: "Complete TypeScript E2E test implementation",
|
|
9545
|
+
description: "Complete TypeScript E2E test implementation.\n\nGenerate fully functional, compilation-error-free test code following",
|
|
9546
|
+
type: "string"
|
|
9547
|
+
}
|
|
9548
|
+
},
|
|
9549
|
+
required: [ "plan", "domain", "content" ],
|
|
9550
|
+
additionalProperties: false,
|
|
9551
|
+
$defs: {}
|
|
9552
|
+
},
|
|
9553
|
+
validate: (() => {
|
|
9554
|
+
const _io0 = input => "string" === typeof input.plan && "string" === typeof input.domain && "string" === typeof input.content;
|
|
9555
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.plan || _report(_exceptionable, {
|
|
9556
|
+
path: _path + ".plan",
|
|
9557
|
+
expected: "string",
|
|
9558
|
+
value: input.plan
|
|
9559
|
+
}), "string" === typeof input.domain || _report(_exceptionable, {
|
|
9560
|
+
path: _path + ".domain",
|
|
9561
|
+
expected: "string",
|
|
9562
|
+
value: input.domain
|
|
9563
|
+
}), "string" === typeof input.content || _report(_exceptionable, {
|
|
9564
|
+
path: _path + ".content",
|
|
9565
|
+
expected: "string",
|
|
9566
|
+
value: input.content
|
|
9567
|
+
}) ].every((flag => flag));
|
|
9568
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
9569
|
+
let errors;
|
|
9570
|
+
let _report;
|
|
9571
|
+
return input => {
|
|
9572
|
+
if (false === __is(input)) {
|
|
9573
|
+
errors = [];
|
|
9574
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
9575
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
9576
|
+
path: _path + "",
|
|
9577
|
+
expected: "ICreateTestCodeProps",
|
|
9578
|
+
value: input
|
|
9579
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
9580
|
+
path: _path + "",
|
|
9581
|
+
expected: "ICreateTestCodeProps",
|
|
9582
|
+
value: input
|
|
9583
|
+
}))(input, "$input", true);
|
|
9584
|
+
const success = 0 === errors.length;
|
|
9585
|
+
return success ? {
|
|
9586
|
+
success,
|
|
9587
|
+
data: input
|
|
9588
|
+
} : {
|
|
9589
|
+
success,
|
|
9590
|
+
errors,
|
|
9591
|
+
data: input
|
|
9592
|
+
};
|
|
9593
|
+
}
|
|
9594
|
+
return {
|
|
9595
|
+
success: true,
|
|
9596
|
+
data: input
|
|
9597
|
+
};
|
|
9598
|
+
};
|
|
9599
|
+
})()
|
|
9600
|
+
} ]
|
|
9601
|
+
},
|
|
9602
|
+
claude: claude$2,
|
|
9603
|
+
llama: claude$2,
|
|
9604
|
+
deepseek: claude$2,
|
|
9605
|
+
3.1: claude$2,
|
|
9606
|
+
"3.0": {
|
|
9607
|
+
model: "3.0",
|
|
9608
|
+
options: {
|
|
9609
|
+
constraint: true,
|
|
9610
|
+
recursive: 3,
|
|
9611
|
+
separate: null
|
|
9612
|
+
},
|
|
9613
|
+
functions: [ {
|
|
9614
|
+
name: "createTestCode",
|
|
9615
|
+
parameters: {
|
|
9616
|
+
type: "object",
|
|
9617
|
+
properties: {
|
|
9618
|
+
plan: {
|
|
9619
|
+
type: "string",
|
|
9620
|
+
title: "Strategic approach for test implementation",
|
|
9621
|
+
description: "Strategic approach for test implementation.\n\nDefine the high-level strategy and logical flow for testing the given\nscenario. Focus on test methodology, data preparation, and assertion\nstrategy.\n\n### Critical Requirements\n\n- Must follow the Test Generation Guildelines.\n- Must Planning the test code Never occur the typescript compile error.\n\n### Planning Elements:\n\n#### Test Methodology\n\n- Identify test scenario type (CRUD operation, authentication flow,\n validation test)\n- Define test data requirements and preparation strategy\n- Plan positive/negative test cases and edge cases\n- Design assertion logic and validation points\n\n#### Execution Strategy\n\n- Outline step-by-step test execution flow\n- Plan error handling and exception scenarios\n- Define cleanup and teardown procedures\n- Identify dependencies and prerequisites\n\n### Example Plan:\n\n Test Strategy: Article Creation Validation\n 1. Prepare valid article data with required fields\n 2. Execute POST request to create article\n 3. Validate response structure and data integrity\n 4. Test error scenarios (missing fields, invalid data)\n 5. Verify database state changes\n 6. Reconsider the plan if it doesn't follow the Test Generation\n Guildelines."
|
|
9622
|
+
},
|
|
9623
|
+
domain: {
|
|
9624
|
+
type: "string",
|
|
9625
|
+
title: "Functional domain classification for test organization",
|
|
9626
|
+
description: 'Functional domain classification for test organization.\n\nDetermines file structure and test categorization based on API\nfunctionality. Used for organizing tests into logical groups and directory\nhierarchies.\n\n### Naming Rules:\n\n- Lowercase English words only\n- Singular nouns (e.g., "article", "user", "comment")\n- Kebab-case for compound words (e.g., "user-profile", "payment-method")\n- Match primary API resource being tested\n- Domain Name must be named only one word.\n\n### Domain Examples:\n\n- `article` → Article management operations\n- `comment` → Comment-related functionality\n- `auth` → Authentication and authorization\n- `user` → User management operations\n- `payment` → Payment processing\n- `notification` → Notification system'
|
|
9627
|
+
},
|
|
9628
|
+
content: {
|
|
9629
|
+
type: "string",
|
|
9630
|
+
title: "Complete TypeScript E2E test implementation",
|
|
9631
|
+
description: "Complete TypeScript E2E test implementation.\n\nGenerate fully functional, compilation-error-free test code following"
|
|
9632
|
+
}
|
|
9633
|
+
},
|
|
9634
|
+
required: [ "plan", "domain", "content" ],
|
|
9635
|
+
description: "Current Type: {@link ICreateTestCodeProps}",
|
|
9636
|
+
additionalProperties: false
|
|
9637
|
+
},
|
|
9638
|
+
validate: (() => {
|
|
9639
|
+
const _io0 = input => "string" === typeof input.plan && "string" === typeof input.domain && "string" === typeof input.content;
|
|
9640
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.plan || _report(_exceptionable, {
|
|
9641
|
+
path: _path + ".plan",
|
|
9642
|
+
expected: "string",
|
|
9643
|
+
value: input.plan
|
|
9644
|
+
}), "string" === typeof input.domain || _report(_exceptionable, {
|
|
9645
|
+
path: _path + ".domain",
|
|
9646
|
+
expected: "string",
|
|
9647
|
+
value: input.domain
|
|
9648
|
+
}), "string" === typeof input.content || _report(_exceptionable, {
|
|
9649
|
+
path: _path + ".content",
|
|
9650
|
+
expected: "string",
|
|
9651
|
+
value: input.content
|
|
9652
|
+
}) ].every((flag => flag));
|
|
9653
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
9654
|
+
let errors;
|
|
9655
|
+
let _report;
|
|
9656
|
+
return input => {
|
|
9657
|
+
if (false === __is(input)) {
|
|
9658
|
+
errors = [];
|
|
9659
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
9660
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
9661
|
+
path: _path + "",
|
|
9662
|
+
expected: "ICreateTestCodeProps",
|
|
9663
|
+
value: input
|
|
9664
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
9665
|
+
path: _path + "",
|
|
9666
|
+
expected: "ICreateTestCodeProps",
|
|
9667
|
+
value: input
|
|
9668
|
+
}))(input, "$input", true);
|
|
9669
|
+
const success = 0 === errors.length;
|
|
9670
|
+
return success ? {
|
|
9671
|
+
success,
|
|
9672
|
+
data: input
|
|
9673
|
+
} : {
|
|
9674
|
+
success,
|
|
9675
|
+
errors,
|
|
9676
|
+
data: input
|
|
9677
|
+
};
|
|
9678
|
+
}
|
|
9679
|
+
return {
|
|
9680
|
+
success: true,
|
|
9681
|
+
data: input
|
|
9682
|
+
};
|
|
9683
|
+
};
|
|
9684
|
+
})()
|
|
9685
|
+
} ]
|
|
9686
|
+
}
|
|
9687
|
+
};
|
|
9688
|
+
|
|
9689
|
+
const transformTestScenarioHistories = (state, endponits, files) => {
|
|
9690
|
+
if (state.analyze === null) return [ {
|
|
9691
|
+
id: v4(),
|
|
9692
|
+
created_at: (new Date).toISOString(),
|
|
9693
|
+
type: "systemMessage",
|
|
9694
|
+
text: [ "Requirement analysis is not yet completed.", "Don't call the any tool function,", "but say to process the requirement analysis." ].join(" ")
|
|
9695
|
+
} ]; else if (state.prisma === null) return [ {
|
|
9696
|
+
id: v4(),
|
|
9697
|
+
created_at: (new Date).toISOString(),
|
|
9698
|
+
type: "systemMessage",
|
|
9699
|
+
text: [ "Prisma DB schema generation is not yet completed.", "Don't call the any tool function,", "but say to process the Prisma DB schema generation." ].join(" ")
|
|
9700
|
+
} ]; else if (state.analyze.step !== state.prisma.step) return [ {
|
|
9701
|
+
id: v4(),
|
|
9702
|
+
created_at: (new Date).toISOString(),
|
|
9703
|
+
type: "systemMessage",
|
|
9704
|
+
text: [ "Prisma DB schema generation has not been updated", "for the latest requirement analysis.", "Don't call the any tool function,", "but say to re-process the Prisma DB schema generation." ].join(" ")
|
|
9705
|
+
} ]; else if (state.prisma.compiled.type !== "success") return [ {
|
|
9706
|
+
id: v4(),
|
|
9707
|
+
created_at: (new Date).toISOString(),
|
|
9708
|
+
type: "systemMessage",
|
|
9709
|
+
text: [ "Prisma DB schema generation has not been updated", "for the latest requirement analysis.", "Don't call the any tool function,", "but say to re-process the Prisma DB schema generation." ].join(" ")
|
|
9710
|
+
} ]; else if (state.interface === null) return [ {
|
|
9711
|
+
id: v4(),
|
|
9712
|
+
created_at: (new Date).toISOString(),
|
|
9713
|
+
type: "systemMessage",
|
|
9714
|
+
text: [ "Interface generation is not yet completed.", "Don't call the any tool function,", "but say to process the interface generation." ].join(" ")
|
|
9715
|
+
} ];
|
|
9716
|
+
return [ {
|
|
9717
|
+
id: v4(),
|
|
9718
|
+
created_at: (new Date).toISOString(),
|
|
9719
|
+
type: "systemMessage",
|
|
9720
|
+
text: "# System Prompt: User Scenario Generator for API Endpoints\n\n## Role Definition\nYou are a world-class User Experience Analyst and Business Scenario Expert who specializes in analyzing API endpoints to generate comprehensive user scenarios from a pure user perspective. Your scenarios will be used as documentation and comments in test code to help developers understand the real-world user context behind each test.\n\n## Primary Objective\nGenerate all possible scenarios that real users might experience with a single given API endpoint, focusing exclusively on user intentions, motivations, and behaviors rather than technical testing perspectives.\n\n## Core Constraints\n\n### Single Endpoint Limitation\n- Each scenario must be completely achievable using ONLY the provided endpoint\n- Do NOT create scenarios that require multiple API calls or dependencies on other endpoints\n- Each user journey must be self-contained and complete within this single endpoint interaction\n\n### Practicality Constraint for Scenario Quantity\n\n- Do NOT generate an excessive number of test scenarios for trivial endpoints.\n- If the endpoint is a simple read-only operation that returns a static or predictable object (e.g. `{ cpu: number, system: number }`), limit scenarios to those that reflect meaningful variations in user context, not in raw input permutations.\n- Avoid producing multiple user error or edge case scenarios when they provide no additional business insight.\n- Prioritize business relevance over theoretical input diversity.\n- The goal is to maximize scenario value, not quantity.\n\n\n## Scenario Generation Principles\n\n### 1. Pure User-Centric Perspective\n- Focus entirely on what users want to achieve through the API\n- Consider real business contexts and user motivations\n- Emphasize user intent and expected value over technical implementation\n- Write as if documenting actual user stories for product requirements\n\n### 2. Comprehensive Single-Endpoint Coverage\nConsider all the following perspectives when generating scenarios for the single endpoint:\n\n#### A. Happy Path User Journeys\n- Most common and expected user behaviors\n- Standard workflows that lead to successful user outcomes\n- Primary business use cases users perform with this endpoint\n\n#### B. Alternative User Approaches\n- Valid but different ways users might achieve their goals\n- Scenarios using optional parameters or different input combinations\n- Less common but legitimate user behaviors within normal boundaries\n\n#### C. User Error Situations\n- Natural user mistakes with input data (incorrect formats, missing fields)\n- User attempts without proper authentication or authorization\n- User actions that violate business rules or constraints\n- User encounters with system limitations\n\n#### D. Boundary User Behaviors\n- User attempts with extreme values (minimum/maximum limits)\n- User submissions with empty, null, or unusual data\n- User inputs with special characters, long strings, or edge cases\n- User interactions testing system boundaries\n\n#### E. Contextual User Situations\n- User interactions when resources exist vs. don't exist\n- Different user roles attempting the same actions\n- Time-sensitive user scenarios (expired sessions, scheduled operations)\n- User attempts during various system states\n\n### 3. Scenario Writing Format for Test Documentation\nWrite each scenario using the following structure optimized for test code comments:\n\n```\n**Scenario**: [Clear, descriptive title from user perspective]\n\n**User Context**: [Who is the user and why are they performing this action]\n\n**User Goal**: [What the user wants to accomplish]\n\n**User Actions**: [Specific steps the user takes with this endpoint]\n\n**Expected Experience**: [What the user expects to happen and how they'll know it worked]\n\n**Business Value**: [Why this scenario matters to the business]\n\n**Input Test Files**: [The test file names required for combining this scenario. If you have multiple files, connect them with commas.]\n```\n\n## Scenario Generation Checklist for Single Endpoint\n\n### Data Input Perspective\n- [ ] User providing complete, valid data\n- [ ] User missing required fields (intentionally or accidentally)\n- [ ] User sending incorrectly formatted data\n- [ ] User using boundary values (maximum/minimum)\n- [ ] User including special characters or multilingual content\n\n### User Permission Perspective\n- [ ] Users with appropriate permissions\n- [ ] Users with insufficient permissions\n- [ ] Unauthenticated users attempting access\n- [ ] Users with expired authentication\n\n### Resource State Perspective\n- [ ] User interacting when target resource exists\n- [ ] User interacting when target resource doesn't exist\n- [ ] User interacting with resources in various states\n- [ ] User encountering resources modified by others\n\n### User Experience Perspective\n- [ ] Users with realistic data volumes\n- [ ] Users performing time-sensitive operations\n- [ ] Users with different technical skill levels\n- [ ] Users in different business contexts\n\n### Business Context Perspective\n- [ ] Users following standard business processes\n- [ ] Users encountering business rule violations\n- [ ] Users in exceptional business situations\n- [ ] Users with varying business needs\n\n## Output Requirements for Test Documentation\n\nEach scenario must provide sufficient detail for developers to understand:\n\n1. **User Story Context**: Clear understanding of who the user is and their motivation\n2. **Business Justification**: Why this scenario matters for the product\n3. **User Behavior Pattern**: How real users would naturally interact with the endpoint\n4. **Success Criteria**: How users measure successful completion of their goal\n5. **Function Name Guidance**: Clear enough description to derive meaningful test function names\n\n## Quality Standards for Test Code Comments\n\n- Write scenarios that help developers empathize with real users\n- Focus on business value and user outcomes, not technical mechanics\n- Provide enough context that a developer can understand the user's situation\n- Ensure scenarios reflect realistic business situations\n- Make each scenario distinct and valuable for understanding user needs\n- Use language that both technical and non-technical stakeholders can understand\n\n## Guidelines\n\n- Avoid mentioning test code, assertions, or technical implementation details\n- Write purely from the user's perspective using narrative language\n- Create realistic scenarios that reflect actual business situations\n- Ensure scenarios are comprehensive yet practical for a single endpoint\n- Focus on user value and business outcomes\n- Make scenarios detailed enough to understand full user context\n\n## Expected Input\nYou will receive a single API endpoint specification including:\n- HTTP method and endpoint path\n- Request/response schemas\n- Authentication requirements\n- Parameter definitions\n- Business context when available\n\n## Expected Output\nFor the given API endpoint, provide:\n- Categorized user scenarios covering all perspectives mentioned above\n- Each scenario following the specified format for test documentation\n- Scenarios that are complete and achievable with only the single provided endpoint\n- Clear mapping between user intentions and the specific API operation\n- Sufficient detail to understand both user context and business value\n\n## Working Language\n- Default working language: English\n- Use the language specified by user in messages as the working language when explicitly provided\n- All thinking and responses must be in the working language\n- Maintain consistent perspective and tone throughout all scenarios"
|
|
9721
|
+
}, {
|
|
9722
|
+
id: v4(),
|
|
9723
|
+
created_at: (new Date).toISOString(),
|
|
9724
|
+
type: "systemMessage",
|
|
9725
|
+
text: [ "# Result of Analyze Agent", "- The following document contains the user requirements that were extracted through conversations with the user by the Analyze Agent.", "- The database schema was designed based on these requirements, so you may refer to this document when writing test code or reviewing the schema.", "", `## User Request`, "", `- ${state.analyze.reason}`, "", `## Requirement Analysis Report`, "", "```json", JSON.stringify(state.analyze.files), "```" ].join("\n")
|
|
9726
|
+
}, {
|
|
9727
|
+
id: v4(),
|
|
9728
|
+
created_at: (new Date).toISOString(),
|
|
9729
|
+
type: "systemMessage",
|
|
9730
|
+
text: [ "# Result of Prisma Agent", "- Given the following database schema and entity-relationship diagram, write appropriate test code to validate the constraints and relationships defined in the schema. For example, if there is a unique column, include a test that ensures its uniqueness.", "- The test code should strictly adhere to the schema and relationships—no violations of constraints should occur.", "- Use the information from the schema and diagram to design meaningful and accurate test cases.", "", "## Prisma DB Schema", "```json", JSON.stringify(state.prisma.schemas), "```", "", "## Entity Relationship Diagrams", "```json", JSON.stringify(state.prisma.compiled.diagrams), "```" ].join("\n")
|
|
9731
|
+
}, {
|
|
9732
|
+
id: v4(),
|
|
9733
|
+
created_at: (new Date).toISOString(),
|
|
9734
|
+
type: "systemMessage",
|
|
9735
|
+
text: [ "# Result of Interfaced Agent", "- OpenAPI document generation is ready.", "", "Call the provided tool function to generate the user scenarios", "referencing below OpenAPI document.", "", `## OpenAPI Document`, "```json", JSON.stringify(state.interface.document), "```" ].join("\n")
|
|
9736
|
+
}, {
|
|
9737
|
+
id: v4(),
|
|
9738
|
+
created_at: (new Date).toISOString(),
|
|
9739
|
+
type: "systemMessage",
|
|
9740
|
+
text: "# System Prompt: User Scenario Generator for API Endpoints\n\n## Role Definition\nYou are a world-class User Experience Analyst and Business Scenario Expert who specializes in analyzing API endpoints to generate comprehensive user scenarios from a pure user perspective. Your scenarios will be used as documentation and comments in test code to help developers understand the real-world user context behind each test.\n\n## Primary Objective\nGenerate all possible scenarios that real users might experience with a single given API endpoint, focusing exclusively on user intentions, motivations, and behaviors rather than technical testing perspectives.\n\n## Core Constraints\n\n### Single Endpoint Limitation\n- Each scenario must be completely achievable using ONLY the provided endpoint\n- Do NOT create scenarios that require multiple API calls or dependencies on other endpoints\n- Each user journey must be self-contained and complete within this single endpoint interaction\n\n### Practicality Constraint for Scenario Quantity\n\n- Do NOT generate an excessive number of test scenarios for trivial endpoints.\n- If the endpoint is a simple read-only operation that returns a static or predictable object (e.g. `{ cpu: number, system: number }`), limit scenarios to those that reflect meaningful variations in user context, not in raw input permutations.\n- Avoid producing multiple user error or edge case scenarios when they provide no additional business insight.\n- Prioritize business relevance over theoretical input diversity.\n- The goal is to maximize scenario value, not quantity.\n\n\n## Scenario Generation Principles\n\n### 1. Pure User-Centric Perspective\n- Focus entirely on what users want to achieve through the API\n- Consider real business contexts and user motivations\n- Emphasize user intent and expected value over technical implementation\n- Write as if documenting actual user stories for product requirements\n\n### 2. Comprehensive Single-Endpoint Coverage\nConsider all the following perspectives when generating scenarios for the single endpoint:\n\n#### A. Happy Path User Journeys\n- Most common and expected user behaviors\n- Standard workflows that lead to successful user outcomes\n- Primary business use cases users perform with this endpoint\n\n#### B. Alternative User Approaches\n- Valid but different ways users might achieve their goals\n- Scenarios using optional parameters or different input combinations\n- Less common but legitimate user behaviors within normal boundaries\n\n#### C. User Error Situations\n- Natural user mistakes with input data (incorrect formats, missing fields)\n- User attempts without proper authentication or authorization\n- User actions that violate business rules or constraints\n- User encounters with system limitations\n\n#### D. Boundary User Behaviors\n- User attempts with extreme values (minimum/maximum limits)\n- User submissions with empty, null, or unusual data\n- User inputs with special characters, long strings, or edge cases\n- User interactions testing system boundaries\n\n#### E. Contextual User Situations\n- User interactions when resources exist vs. don't exist\n- Different user roles attempting the same actions\n- Time-sensitive user scenarios (expired sessions, scheduled operations)\n- User attempts during various system states\n\n### 3. Scenario Writing Format for Test Documentation\nWrite each scenario using the following structure optimized for test code comments:\n\n```\n**Scenario**: [Clear, descriptive title from user perspective]\n\n**User Context**: [Who is the user and why are they performing this action]\n\n**User Goal**: [What the user wants to accomplish]\n\n**User Actions**: [Specific steps the user takes with this endpoint]\n\n**Expected Experience**: [What the user expects to happen and how they'll know it worked]\n\n**Business Value**: [Why this scenario matters to the business]\n\n**Input Test Files**: [The test file names required for combining this scenario. If you have multiple files, connect them with commas.]\n```\n\n## Scenario Generation Checklist for Single Endpoint\n\n### Data Input Perspective\n- [ ] User providing complete, valid data\n- [ ] User missing required fields (intentionally or accidentally)\n- [ ] User sending incorrectly formatted data\n- [ ] User using boundary values (maximum/minimum)\n- [ ] User including special characters or multilingual content\n\n### User Permission Perspective\n- [ ] Users with appropriate permissions\n- [ ] Users with insufficient permissions\n- [ ] Unauthenticated users attempting access\n- [ ] Users with expired authentication\n\n### Resource State Perspective\n- [ ] User interacting when target resource exists\n- [ ] User interacting when target resource doesn't exist\n- [ ] User interacting with resources in various states\n- [ ] User encountering resources modified by others\n\n### User Experience Perspective\n- [ ] Users with realistic data volumes\n- [ ] Users performing time-sensitive operations\n- [ ] Users with different technical skill levels\n- [ ] Users in different business contexts\n\n### Business Context Perspective\n- [ ] Users following standard business processes\n- [ ] Users encountering business rule violations\n- [ ] Users in exceptional business situations\n- [ ] Users with varying business needs\n\n## Output Requirements for Test Documentation\n\nEach scenario must provide sufficient detail for developers to understand:\n\n1. **User Story Context**: Clear understanding of who the user is and their motivation\n2. **Business Justification**: Why this scenario matters for the product\n3. **User Behavior Pattern**: How real users would naturally interact with the endpoint\n4. **Success Criteria**: How users measure successful completion of their goal\n5. **Function Name Guidance**: Clear enough description to derive meaningful test function names\n\n## Quality Standards for Test Code Comments\n\n- Write scenarios that help developers empathize with real users\n- Focus on business value and user outcomes, not technical mechanics\n- Provide enough context that a developer can understand the user's situation\n- Ensure scenarios reflect realistic business situations\n- Make each scenario distinct and valuable for understanding user needs\n- Use language that both technical and non-technical stakeholders can understand\n\n## Guidelines\n\n- Avoid mentioning test code, assertions, or technical implementation details\n- Write purely from the user's perspective using narrative language\n- Create realistic scenarios that reflect actual business situations\n- Ensure scenarios are comprehensive yet practical for a single endpoint\n- Focus on user value and business outcomes\n- Make scenarios detailed enough to understand full user context\n\n## Expected Input\nYou will receive a single API endpoint specification including:\n- HTTP method and endpoint path\n- Request/response schemas\n- Authentication requirements\n- Parameter definitions\n- Business context when available\n\n## Expected Output\nFor the given API endpoint, provide:\n- Categorized user scenarios covering all perspectives mentioned above\n- Each scenario following the specified format for test documentation\n- Scenarios that are complete and achievable with only the single provided endpoint\n- Clear mapping between user intentions and the specific API operation\n- Sufficient detail to understand both user context and business value\n\n## Working Language\n- Default working language: English\n- Use the language specified by user in messages as the working language when explicitly provided\n- All thinking and responses must be in the working language\n- Maintain consistent perspective and tone throughout all scenarios"
|
|
9741
|
+
}, {
|
|
9742
|
+
id: v4(),
|
|
9743
|
+
created_at: (new Date).toISOString(),
|
|
9744
|
+
type: "systemMessage",
|
|
9745
|
+
text: [ `This is a description of different APIs.`, `Different APIs may have to be called to create one.`, `Check which functions have been developed.`, "```json", JSON.stringify(endponits, null, 2), "```" ].join("\n")
|
|
9746
|
+
}, {
|
|
9747
|
+
id: v4(),
|
|
9748
|
+
created_at: (new Date).toISOString(),
|
|
9749
|
+
type: "systemMessage",
|
|
9750
|
+
text: [ "Below is basically the generated test code,", "which is a test to verify that the API is simply called and successful.", "Since there is already an automatically generated API,", "when a user requests to create a test scenario, two or more APIs must be combined,", "but a test in which the currently given endpoint is the main must be created.", '"Input Test Files" should be selected from the list of files here.', "```json", JSON.stringify(files, null, 2), "```" ].join("\n")
|
|
9751
|
+
} ];
|
|
9752
|
+
};
|
|
9753
|
+
|
|
9754
|
+
async function orchestrateTestScenario(ctx) {
|
|
9755
|
+
const files = Object.entries(ctx.state().interface?.files ?? {}).filter((([filename]) => filename.startsWith("test/features/api/"))).reduce(((acc, [filename, content]) => Object.assign(acc, {
|
|
9756
|
+
[filename]: content
|
|
9757
|
+
})), {});
|
|
9758
|
+
const operations = ctx.state().interface?.document.operations ?? [];
|
|
9759
|
+
const endpoints = operations.map((it => ({
|
|
9760
|
+
method: it.method,
|
|
9761
|
+
path: it.path,
|
|
9762
|
+
summary: it.summary,
|
|
9763
|
+
description: it.description,
|
|
9764
|
+
parameters: it.parameters,
|
|
9765
|
+
requestBody: it.requestBody,
|
|
9766
|
+
responseBody: it.responseBody
|
|
9767
|
+
})));
|
|
9768
|
+
const start = new Date;
|
|
9769
|
+
let completed = 0;
|
|
9770
|
+
const scenarios = await Promise.all(endpoints.map((async (endpoint, i, arr) => {
|
|
9771
|
+
const endponits = arr.filter(((_el, j) => i !== j));
|
|
9772
|
+
const rows = await process(ctx, endpoint, endponits, files);
|
|
9773
|
+
ctx.dispatch({
|
|
9774
|
+
type: "testScenario",
|
|
9775
|
+
scenarios: rows,
|
|
9776
|
+
total: rows.flatMap((el => el.scenarios)).length,
|
|
9777
|
+
step: ctx.state().test?.step ?? 0,
|
|
9778
|
+
completed,
|
|
9779
|
+
created_at: start.toISOString()
|
|
9780
|
+
});
|
|
9781
|
+
return rows;
|
|
9782
|
+
})));
|
|
9783
|
+
return {
|
|
9784
|
+
type: "testScenario",
|
|
9785
|
+
scenarios: scenarios.flat(),
|
|
9786
|
+
total: scenarios.flat().flatMap((el => el.scenarios)).length,
|
|
9787
|
+
step: ctx.state().test?.step ?? 0,
|
|
9788
|
+
completed,
|
|
9789
|
+
created_at: start.toISOString()
|
|
9790
|
+
};
|
|
9791
|
+
}
|
|
9792
|
+
|
|
9793
|
+
async function process(ctx, endpoint, endpoints, files) {
|
|
9794
|
+
const pointer = {
|
|
9795
|
+
value: null
|
|
9796
|
+
};
|
|
9797
|
+
const agentica = new MicroAgentica({
|
|
9798
|
+
model: ctx.model,
|
|
9799
|
+
vendor: ctx.vendor,
|
|
9800
|
+
config: {
|
|
9801
|
+
...ctx.config ?? {
|
|
9802
|
+
locale: "en-US"
|
|
9803
|
+
},
|
|
9804
|
+
systemPrompt: {
|
|
9805
|
+
describe: () => "Answer only 'completion' or 'failure'."
|
|
9806
|
+
}
|
|
9807
|
+
},
|
|
9808
|
+
tokenUsage: ctx.usage(),
|
|
9809
|
+
histories: [ ...transformTestScenarioHistories(ctx.state(), endpoints, files) ],
|
|
9810
|
+
controllers: [ createApplication({
|
|
9811
|
+
model: ctx.model,
|
|
9812
|
+
build: next => {
|
|
9813
|
+
pointer.value = next.scenarios;
|
|
9814
|
+
}
|
|
9815
|
+
}) ]
|
|
9816
|
+
});
|
|
9817
|
+
agentica.on("request", (async event => {
|
|
9818
|
+
if (event.body.tools) event.body.tool_choice = "required";
|
|
9819
|
+
}));
|
|
9820
|
+
await agentica.conversate([ "Make User Scenarios for below endpoint:", "", "```json", JSON.stringify(endpoint, null, 2), "```" ].join("\n"));
|
|
9821
|
+
if (pointer.value === null) throw new Error("Failed to make scenarios.");
|
|
9822
|
+
return pointer.value;
|
|
9823
|
+
}
|
|
9824
|
+
|
|
9825
|
+
function createApplication(props) {
|
|
9826
|
+
assertSchemaModel(props.model);
|
|
9827
|
+
const application = collection$1[props.model];
|
|
9828
|
+
return {
|
|
9829
|
+
protocol: "class",
|
|
9830
|
+
name: "Make User Scenarios",
|
|
9831
|
+
application,
|
|
9832
|
+
execute: {
|
|
9833
|
+
makeScenario: next => {
|
|
9834
|
+
props.build(next);
|
|
9835
|
+
}
|
|
9836
|
+
}
|
|
9837
|
+
};
|
|
9838
|
+
}
|
|
9839
|
+
|
|
9840
|
+
const claude$1 = {
|
|
9841
|
+
model: "claude",
|
|
9842
|
+
options: {
|
|
9843
|
+
reference: true,
|
|
9844
|
+
separate: null
|
|
9845
|
+
},
|
|
9846
|
+
functions: [ {
|
|
9847
|
+
name: "makeScenario",
|
|
9848
|
+
parameters: {
|
|
9849
|
+
description: " Properties containing the endpoints and user scenarios.\n\n------------------------------\n\nCurrent Type: {@link IMakeScenarioProps}",
|
|
9850
|
+
type: "object",
|
|
9851
|
+
properties: {
|
|
9852
|
+
scenarios: {
|
|
9853
|
+
title: "Array of user scenarios",
|
|
9854
|
+
description: "Array of user scenarios.",
|
|
9855
|
+
type: "array",
|
|
9856
|
+
items: {
|
|
9857
|
+
description: "Current Type: {@link AutoBeTest.IScenario}",
|
|
9858
|
+
type: "object",
|
|
9859
|
+
properties: {
|
|
9860
|
+
endpoint: {
|
|
9861
|
+
description: "Target API endpoint for user scenario generation.\n\nThis represents the single API endpoint that will be analyzed to generate\ncomprehensive user scenarios. The endpoint contains all technical\nspecifications needed to understand user interactions, including HTTP\nmethods, paths, parameters, request/response schemas, and authentication\nrequirements.\n\n## Core Purpose\n\n- Serves as the foundation for user-centric scenario generation\n- Contains complete API specification for understanding user capabilities\n- Provides schema constraints for realistic user data generation\n- Defines authentication and permission requirements for user context\n\n## User Scenario Context\n\nThis endpoint information enables generation of scenarios that consider:\n\n- What users can realistically accomplish with this endpoint\n- How users would naturally interact with the API functionality\n- What business value users seek from this endpoint\n- What constraints and limitations users will encounter\n- How authentication affects user access patterns\n- What data formats users need to provide or expect to receive\n\n## Single Endpoint Constraint\n\nEach scenario generated must interact with ONLY this endpoint. Scenarios\nshould not assume or require calls to other endpoints, ensuring each user\njourney is complete and testable in isolation.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
9862
|
+
type: "object",
|
|
9863
|
+
properties: {
|
|
9864
|
+
path: {
|
|
9865
|
+
title: "HTTP path of the API operation",
|
|
9866
|
+
description: "HTTP path of the API operation.\n\nThe URL path for accessing this API operation, using path parameters\nenclosed in curly braces (e.g., `/shoppings/customers/sales/{saleId}`).\n\nIt must be corresponded to the {@link parameters path parameters}.\n\nThe path structure should clearly indicate which database entity this\noperation is manipulating, helping to ensure all entities have\nappropriate API coverage.",
|
|
9867
|
+
type: "string"
|
|
9868
|
+
},
|
|
9869
|
+
method: {
|
|
9870
|
+
title: "HTTP method of the API operation",
|
|
9871
|
+
description: "HTTP method of the API operation.\n\nNote that, if the API operation has {@link requestBody}, method must not\nbe `get`.\n\nAlso, even though the API operation has been designed to only get\ninformation, but it needs complicated request information, it must be\ndefined as `patch` method with {@link requestBody} data specification.\n\n- `get`: get information\n- `patch`: get information with complicated request data\n ({@link requestBody})\n- `post`: create new record\n- `put`: update existing record\n- `delete`: remove record",
|
|
9872
|
+
oneOf: [ {
|
|
9873
|
+
const: "get"
|
|
9874
|
+
}, {
|
|
9875
|
+
const: "post"
|
|
9876
|
+
}, {
|
|
9877
|
+
const: "put"
|
|
9878
|
+
}, {
|
|
9879
|
+
const: "delete"
|
|
9880
|
+
}, {
|
|
9881
|
+
const: "patch"
|
|
9882
|
+
} ]
|
|
9883
|
+
}
|
|
9884
|
+
},
|
|
9885
|
+
required: [ "path", "method" ]
|
|
9886
|
+
},
|
|
9887
|
+
scenarios: {
|
|
9888
|
+
title: "Comprehensive collection of user-centric scenarios for the endpoint",
|
|
9889
|
+
description: "Comprehensive collection of user-centric scenarios for the endpoint.\n\nEach scenario represents a realistic user journey, intention, or\nsituation when interacting with this specific API endpoint. All scenarios\nare written from the user's perspective, focusing on what they want to\nachieve and how they naturally interact with the API functionality.\n\n## Scenario Coverage Framework\n\nThe scenarios must comprehensively cover all user interaction patterns:\n\n### 1. Happy Path User Journeys\n\n- Primary business use cases that users commonly perform\n- Standard workflows leading to successful user outcomes\n- Typical user behaviors with valid inputs and proper permissions\n- Most frequent user intentions and expected interactions\n\n### 2. Alternative User Approaches\n\n- Valid alternative ways users might achieve their goals\n- User scenarios utilizing optional parameters or different input patterns\n- Less common but legitimate user behaviors within normal boundaries\n- User experimentation with available API features\n\n### 3. User Error Situations\n\n- Natural user mistakes with input data (incorrect formats, missing fields)\n- User attempts without proper authentication or authorization\n- User actions that violate business rules or constraints\n- User encounters with system limitations (rate limits, quotas)\n\n### 4. Boundary User Behaviors\n\n- User attempts with extreme values (minimum/maximum limits)\n- User submissions with empty, null, or unusual data\n- User inputs with special characters, long strings, or edge cases\n- User interactions testing system boundaries\n\n### 5. Contextual User Situations\n\n- User interactions when resources exist vs. don't exist\n- Different user roles attempting the same actions\n- Time-sensitive user scenarios (expired sessions, scheduled operations)\n- User attempts during various system states\n\n## User-Centric Quality Standards\n\nEach scenario must:\n\n- Focus entirely on user motivation, context, and expected outcomes\n- Describe realistic business situations users actually encounter\n- Include clear user intent and the value they seek\n- Specify user-provided data and user-expected results\n- Be complete within the single endpoint constraint\n- Provide sufficient context for understanding user behavior patterns\n- Avoid technical implementation details or testing terminology\n\n## Single Endpoint Constraint Application\n\nEvery scenario must:\n\n- Complete the entire user journey using only this one endpoint\n- Not depend on or reference other API endpoints\n- Include all necessary context within the scenario itself\n- Represent a complete, self-contained user interaction\n\n## Business Value Focus\n\nThese user scenarios ensure:\n\n- Understanding of real user needs and behaviors\n- Comprehensive coverage of user interaction patterns\n- Proper handling of user errors and edge cases\n- Appropriate user feedback and experience design\n- Business rule validation from user perspective\n- Security and permission handling for different user contexts",
|
|
9890
|
+
type: "array",
|
|
9891
|
+
items: {
|
|
9892
|
+
description: "Current Type: {@link AutoBeTest.Scenario}",
|
|
9893
|
+
type: "object",
|
|
9894
|
+
properties: {
|
|
9895
|
+
functionName: {
|
|
9896
|
+
title: "Descriptive function name derived from the user scenario",
|
|
9897
|
+
description: "Descriptive function name derived from the user scenario.\n\nThe function name serves as a concise, technical identifier that clearly\nrepresents the specific user scenario being described. It should be\nimmediately understandable and directly correspond to the user situation\nwithout requiring additional context.\n\n## Naming Convention\n\n- Must start with `test_` prefix (mandatory requirement)\n- Use snake_case formatting throughout\n- Include the primary user action (create, get, update, delete, list, etc.)\n- Specify the target resource (user, product, order, profile, etc.)\n- Add scenario-specific context (valid_data, invalid_email, not_found,\n etc.)\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_[user_action]_[resource]_[scenario_context]`\n\nWhere:\n\n- `user_action`: What the user is trying to do\n- `resource`: What the user is interacting with\n- `scenario_context`: The specific situation or condition\n\n## User-Focused Examples\n\n- `test_create_user_profile_with_complete_information` - User providing all\n available profile data\n- `test_retrieve_user_profile_when_profile_exists` - User accessing their\n existing profile\n- `test_update_user_email_with_valid_new_address` - User changing their\n email to a valid new one\n- `test_delete_user_account_when_user_lacks_permission` - User attempting\n account deletion without authorization\n- `test_search_user_profiles_with_pagination_preferences` - User browsing\n profiles with specific pagination\n\n## Clarity Guidelines\n\n- Prioritize clarity over brevity\n- Avoid technical jargon or implementation terms\n- Use terminology that reflects user perspective\n- Ensure the name alone conveys the user's intent\n- Make it understandable to non-technical stakeholders\n- Keep consistent with user scenario description\n\n## Single Endpoint Alignment\n\nFunction names must reflect scenarios that:\n\n- Accomplish user goals through this single endpoint only\n- Don't imply dependency on other API operations\n- Represent complete user interactions",
|
|
9898
|
+
type: "string"
|
|
9899
|
+
},
|
|
9900
|
+
scenario: {
|
|
9901
|
+
description: "Comprehensive user scenario description written from pure user\nperspective.\n\nThis describes a complete user journey, motivation, and expected outcome\nwhen interacting with the API endpoint. The description focuses entirely\non user intent, context, and natural behavior patterns rather than\ntechnical testing considerations.\n\n## User-Centric Writing Approach\n\n- Write as if describing a real person's experience and motivation\n- Focus on business context and user goals, not system functionality\n- Use natural language that business stakeholders would understand\n- Emphasize user value and expected benefits\n- Avoid technical terminology or implementation details\n\n## Required Content Elements\n\nEach scenario description must include:\n\n### 1. User Context and Motivation\n\n- Who is the user (role, background, current situation)\n- Why they need to perform this action (business motivation)\n- What problem they're trying to solve or goal they want to achieve\n- Any relevant background circumstances or constraints\n\n### 2. User Actions and Behavior\n\n- Specific steps the user takes to accomplish their goal\n- What information or data the user provides\n- How the user naturally approaches the interaction\n- Any decision-making process the user goes through\n\n### 3. User Expectations and Desired Outcomes\n\n- What the user expects to happen as a result\n- How the user will know if they were successful\n- What value or benefit the user expects to receive\n- How this fits into their broader workflow or objectives\n\n### 4. Business Impact and Value\n\n- How this scenario relates to business objectives\n- What business processes or workflows this supports\n- Why this user behavior matters to the organization\n- What risks or opportunities this scenario represents\n\n## Single Endpoint Constraint Integration\n\nEach scenario must:\n\n- Represent a complete user journey achievable through this single endpoint\n- Include all necessary context without referencing other API operations\n- Describe user expectations based solely on this endpoint's capabilities\n- Avoid scenarios that would logically require multiple API calls\n\n## Quality and Realism Standards\n\n- Base scenarios on realistic business situations\n- Include specific, concrete details rather than generic descriptions\n- Ensure scenarios reflect actual user behaviors and motivations\n- Make each scenario distinct and valuable for understanding user needs\n- Provide enough detail to understand full context without being verbose\n\n## User-Focused Example Scenarios\n\n- \"A busy project manager needs to quickly create a new team member's user\n account during an onboarding meeting. They have all the necessary\n information readily available and expect the account to be immediately\n active so the new employee can start working right away.\"\n- \"A customer support representative is helping a customer who forgot their\n login credentials. The customer provides their email address, and the\n representative expects to quickly retrieve the associated account\n information to assist with password recovery.\"\n- \"A system administrator discovers that a former employee's account is\n still active after their departure. They need to immediately deactivate\n this account for security purposes and expect confirmation that the\n account can no longer be used to access company resources.\"\n\n## Language and Tone\n\n- Use active voice and present tense when describing user actions\n- Write in a narrative style that tells the user's story\n- Balance professional tone with human context\n- Ensure accessibility for both technical and non-technical readers\n- Maintain consistency in perspective throughout the description",
|
|
9902
|
+
type: "string"
|
|
9903
|
+
}
|
|
9904
|
+
},
|
|
9905
|
+
required: [ "functionName", "scenario" ]
|
|
9906
|
+
}
|
|
9907
|
+
}
|
|
9908
|
+
},
|
|
9909
|
+
required: [ "endpoint", "scenarios" ]
|
|
9910
|
+
}
|
|
9911
|
+
}
|
|
9912
|
+
},
|
|
9913
|
+
required: [ "scenarios" ],
|
|
9914
|
+
additionalProperties: false,
|
|
9915
|
+
$defs: {}
|
|
9916
|
+
},
|
|
9917
|
+
description: "Make user scenarios for the given endpoints.",
|
|
9918
|
+
validate: (() => {
|
|
9919
|
+
const _io0 = input => Array.isArray(input.scenarios) && input.scenarios.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
9920
|
+
const _io1 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && (Array.isArray(input.scenarios) && input.scenarios.every((elem => "object" === typeof elem && null !== elem && _io3(elem))));
|
|
9921
|
+
const _io2 = input => "string" === typeof input.path && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method);
|
|
9922
|
+
const _io3 = input => "string" === typeof input.functionName && "string" === typeof input.scenario;
|
|
9923
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
9924
|
+
path: _path + ".scenarios",
|
|
9925
|
+
expected: "Array<AutoBeTest.IScenario>",
|
|
9926
|
+
value: input.scenarios
|
|
9927
|
+
})) && input.scenarios.map(((elem, _index3) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
9928
|
+
path: _path + ".scenarios[" + _index3 + "]",
|
|
9929
|
+
expected: "AutoBeTest.IScenario",
|
|
9930
|
+
value: elem
|
|
9931
|
+
})) && _vo1(elem, _path + ".scenarios[" + _index3 + "]", _exceptionable) || _report(_exceptionable, {
|
|
9932
|
+
path: _path + ".scenarios[" + _index3 + "]",
|
|
9933
|
+
expected: "AutoBeTest.IScenario",
|
|
9934
|
+
value: elem
|
|
9935
|
+
}))).every((flag => flag)) || _report(_exceptionable, {
|
|
9936
|
+
path: _path + ".scenarios",
|
|
9937
|
+
expected: "Array<AutoBeTest.IScenario>",
|
|
9938
|
+
value: input.scenarios
|
|
9939
|
+
}) ].every((flag => flag));
|
|
9940
|
+
const _vo1 = (input, _path, _exceptionable = true) => [ ("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
9941
|
+
path: _path + ".endpoint",
|
|
9942
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
9943
|
+
value: input.endpoint
|
|
9944
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", _exceptionable) || _report(_exceptionable, {
|
|
9945
|
+
path: _path + ".endpoint",
|
|
9946
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
9947
|
+
value: input.endpoint
|
|
9948
|
+
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
9949
|
+
path: _path + ".scenarios",
|
|
9950
|
+
expected: "Array<AutoBeTest.Scenario>",
|
|
9951
|
+
value: input.scenarios
|
|
9952
|
+
})) && input.scenarios.map(((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
9953
|
+
path: _path + ".scenarios[" + _index4 + "]",
|
|
9954
|
+
expected: "AutoBeTest.Scenario",
|
|
9955
|
+
value: elem
|
|
9956
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index4 + "]", _exceptionable) || _report(_exceptionable, {
|
|
9957
|
+
path: _path + ".scenarios[" + _index4 + "]",
|
|
9958
|
+
expected: "AutoBeTest.Scenario",
|
|
9959
|
+
value: elem
|
|
9960
|
+
}))).every((flag => flag)) || _report(_exceptionable, {
|
|
9961
|
+
path: _path + ".scenarios",
|
|
9962
|
+
expected: "Array<AutoBeTest.Scenario>",
|
|
9963
|
+
value: input.scenarios
|
|
9964
|
+
}) ].every((flag => flag));
|
|
9965
|
+
const _vo2 = (input, _path, _exceptionable = true) => [ "string" === typeof input.path || _report(_exceptionable, {
|
|
9966
|
+
path: _path + ".path",
|
|
9967
|
+
expected: "string",
|
|
9968
|
+
value: input.path
|
|
9969
|
+
}), "get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method || _report(_exceptionable, {
|
|
9970
|
+
path: _path + ".method",
|
|
9971
|
+
expected: '("delete" | "get" | "patch" | "post" | "put")',
|
|
9972
|
+
value: input.method
|
|
9973
|
+
}) ].every((flag => flag));
|
|
9974
|
+
const _vo3 = (input, _path, _exceptionable = true) => [ "string" === typeof input.functionName || _report(_exceptionable, {
|
|
9975
|
+
path: _path + ".functionName",
|
|
9976
|
+
expected: "string",
|
|
9977
|
+
value: input.functionName
|
|
9978
|
+
}), "string" === typeof input.scenario || _report(_exceptionable, {
|
|
9979
|
+
path: _path + ".scenario",
|
|
9980
|
+
expected: "string",
|
|
9981
|
+
value: input.scenario
|
|
9982
|
+
}) ].every((flag => flag));
|
|
9983
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
9984
|
+
let errors;
|
|
9985
|
+
let _report;
|
|
9986
|
+
return input => {
|
|
9987
|
+
if (false === __is(input)) {
|
|
9988
|
+
errors = [];
|
|
9989
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
9990
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
9991
|
+
path: _path + "",
|
|
9992
|
+
expected: "IMakeScenarioProps",
|
|
9993
|
+
value: input
|
|
9994
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
9995
|
+
path: _path + "",
|
|
9996
|
+
expected: "IMakeScenarioProps",
|
|
9997
|
+
value: input
|
|
9998
|
+
}))(input, "$input", true);
|
|
9999
|
+
const success = 0 === errors.length;
|
|
10000
|
+
return success ? {
|
|
10001
|
+
success,
|
|
10002
|
+
data: input
|
|
10003
|
+
} : {
|
|
10004
|
+
success,
|
|
10005
|
+
errors,
|
|
10006
|
+
data: input
|
|
10007
|
+
};
|
|
10008
|
+
}
|
|
10009
|
+
return {
|
|
10010
|
+
success: true,
|
|
10011
|
+
data: input
|
|
10012
|
+
};
|
|
10013
|
+
};
|
|
10014
|
+
})()
|
|
10015
|
+
} ]
|
|
10016
|
+
};
|
|
10017
|
+
|
|
10018
|
+
const collection$1 = {
|
|
10019
|
+
chatgpt: {
|
|
10020
|
+
model: "chatgpt",
|
|
10021
|
+
options: {
|
|
10022
|
+
reference: true,
|
|
10023
|
+
strict: false,
|
|
10024
|
+
separate: null
|
|
10025
|
+
},
|
|
10026
|
+
functions: [ {
|
|
10027
|
+
name: "makeScenario",
|
|
10028
|
+
parameters: {
|
|
10029
|
+
description: " Properties containing the endpoints and user scenarios.\n\n------------------------------\n\nCurrent Type: {@link IMakeScenarioProps}",
|
|
10030
|
+
type: "object",
|
|
10031
|
+
properties: {
|
|
10032
|
+
scenarios: {
|
|
10033
|
+
title: "Array of user scenarios",
|
|
10034
|
+
description: "Array of user scenarios.",
|
|
10035
|
+
type: "array",
|
|
10036
|
+
items: {
|
|
10037
|
+
description: "Current Type: {@link AutoBeTest.IScenario}",
|
|
10038
|
+
type: "object",
|
|
10039
|
+
properties: {
|
|
10040
|
+
endpoint: {
|
|
10041
|
+
description: "Target API endpoint for user scenario generation.\n\nThis represents the single API endpoint that will be analyzed to generate\ncomprehensive user scenarios. The endpoint contains all technical\nspecifications needed to understand user interactions, including HTTP\nmethods, paths, parameters, request/response schemas, and authentication\nrequirements.\n\n## Core Purpose\n\n- Serves as the foundation for user-centric scenario generation\n- Contains complete API specification for understanding user capabilities\n- Provides schema constraints for realistic user data generation\n- Defines authentication and permission requirements for user context\n\n## User Scenario Context\n\nThis endpoint information enables generation of scenarios that consider:\n\n- What users can realistically accomplish with this endpoint\n- How users would naturally interact with the API functionality\n- What business value users seek from this endpoint\n- What constraints and limitations users will encounter\n- How authentication affects user access patterns\n- What data formats users need to provide or expect to receive\n\n## Single Endpoint Constraint\n\nEach scenario generated must interact with ONLY this endpoint. Scenarios\nshould not assume or require calls to other endpoints, ensuring each user\njourney is complete and testable in isolation.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
10042
|
+
type: "object",
|
|
10043
|
+
properties: {
|
|
10044
|
+
path: {
|
|
10045
|
+
title: "HTTP path of the API operation",
|
|
10046
|
+
description: "HTTP path of the API operation.\n\nThe URL path for accessing this API operation, using path parameters\nenclosed in curly braces (e.g., `/shoppings/customers/sales/{saleId}`).\n\nIt must be corresponded to the {@link parameters path parameters}.\n\nThe path structure should clearly indicate which database entity this\noperation is manipulating, helping to ensure all entities have\nappropriate API coverage.",
|
|
10047
|
+
type: "string"
|
|
10048
|
+
},
|
|
10049
|
+
method: {
|
|
10050
|
+
title: "HTTP method of the API operation",
|
|
10051
|
+
description: "HTTP method of the API operation.\n\nNote that, if the API operation has {@link requestBody}, method must not\nbe `get`.\n\nAlso, even though the API operation has been designed to only get\ninformation, but it needs complicated request information, it must be\ndefined as `patch` method with {@link requestBody} data specification.\n\n- `get`: get information\n- `patch`: get information with complicated request data\n ({@link requestBody})\n- `post`: create new record\n- `put`: update existing record\n- `delete`: remove record",
|
|
10052
|
+
type: "string",
|
|
10053
|
+
enum: [ "get", "post", "put", "delete", "patch" ]
|
|
10054
|
+
}
|
|
10055
|
+
},
|
|
10056
|
+
required: [ "path", "method" ]
|
|
10057
|
+
},
|
|
10058
|
+
scenarios: {
|
|
10059
|
+
title: "Comprehensive collection of user-centric scenarios for the endpoint",
|
|
10060
|
+
description: "Comprehensive collection of user-centric scenarios for the endpoint.\n\nEach scenario represents a realistic user journey, intention, or\nsituation when interacting with this specific API endpoint. All scenarios\nare written from the user's perspective, focusing on what they want to\nachieve and how they naturally interact with the API functionality.\n\n## Scenario Coverage Framework\n\nThe scenarios must comprehensively cover all user interaction patterns:\n\n### 1. Happy Path User Journeys\n\n- Primary business use cases that users commonly perform\n- Standard workflows leading to successful user outcomes\n- Typical user behaviors with valid inputs and proper permissions\n- Most frequent user intentions and expected interactions\n\n### 2. Alternative User Approaches\n\n- Valid alternative ways users might achieve their goals\n- User scenarios utilizing optional parameters or different input patterns\n- Less common but legitimate user behaviors within normal boundaries\n- User experimentation with available API features\n\n### 3. User Error Situations\n\n- Natural user mistakes with input data (incorrect formats, missing fields)\n- User attempts without proper authentication or authorization\n- User actions that violate business rules or constraints\n- User encounters with system limitations (rate limits, quotas)\n\n### 4. Boundary User Behaviors\n\n- User attempts with extreme values (minimum/maximum limits)\n- User submissions with empty, null, or unusual data\n- User inputs with special characters, long strings, or edge cases\n- User interactions testing system boundaries\n\n### 5. Contextual User Situations\n\n- User interactions when resources exist vs. don't exist\n- Different user roles attempting the same actions\n- Time-sensitive user scenarios (expired sessions, scheduled operations)\n- User attempts during various system states\n\n## User-Centric Quality Standards\n\nEach scenario must:\n\n- Focus entirely on user motivation, context, and expected outcomes\n- Describe realistic business situations users actually encounter\n- Include clear user intent and the value they seek\n- Specify user-provided data and user-expected results\n- Be complete within the single endpoint constraint\n- Provide sufficient context for understanding user behavior patterns\n- Avoid technical implementation details or testing terminology\n\n## Single Endpoint Constraint Application\n\nEvery scenario must:\n\n- Complete the entire user journey using only this one endpoint\n- Not depend on or reference other API endpoints\n- Include all necessary context within the scenario itself\n- Represent a complete, self-contained user interaction\n\n## Business Value Focus\n\nThese user scenarios ensure:\n\n- Understanding of real user needs and behaviors\n- Comprehensive coverage of user interaction patterns\n- Proper handling of user errors and edge cases\n- Appropriate user feedback and experience design\n- Business rule validation from user perspective\n- Security and permission handling for different user contexts",
|
|
10061
|
+
type: "array",
|
|
10062
|
+
items: {
|
|
10063
|
+
description: "Current Type: {@link AutoBeTest.Scenario}",
|
|
10064
|
+
type: "object",
|
|
10065
|
+
properties: {
|
|
10066
|
+
functionName: {
|
|
10067
|
+
title: "Descriptive function name derived from the user scenario",
|
|
10068
|
+
description: "Descriptive function name derived from the user scenario.\n\nThe function name serves as a concise, technical identifier that clearly\nrepresents the specific user scenario being described. It should be\nimmediately understandable and directly correspond to the user situation\nwithout requiring additional context.\n\n## Naming Convention\n\n- Must start with `test_` prefix (mandatory requirement)\n- Use snake_case formatting throughout\n- Include the primary user action (create, get, update, delete, list, etc.)\n- Specify the target resource (user, product, order, profile, etc.)\n- Add scenario-specific context (valid_data, invalid_email, not_found,\n etc.)\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_[user_action]_[resource]_[scenario_context]`\n\nWhere:\n\n- `user_action`: What the user is trying to do\n- `resource`: What the user is interacting with\n- `scenario_context`: The specific situation or condition\n\n## User-Focused Examples\n\n- `test_create_user_profile_with_complete_information` - User providing all\n available profile data\n- `test_retrieve_user_profile_when_profile_exists` - User accessing their\n existing profile\n- `test_update_user_email_with_valid_new_address` - User changing their\n email to a valid new one\n- `test_delete_user_account_when_user_lacks_permission` - User attempting\n account deletion without authorization\n- `test_search_user_profiles_with_pagination_preferences` - User browsing\n profiles with specific pagination\n\n## Clarity Guidelines\n\n- Prioritize clarity over brevity\n- Avoid technical jargon or implementation terms\n- Use terminology that reflects user perspective\n- Ensure the name alone conveys the user's intent\n- Make it understandable to non-technical stakeholders\n- Keep consistent with user scenario description\n\n## Single Endpoint Alignment\n\nFunction names must reflect scenarios that:\n\n- Accomplish user goals through this single endpoint only\n- Don't imply dependency on other API operations\n- Represent complete user interactions",
|
|
10069
|
+
type: "string"
|
|
10070
|
+
},
|
|
10071
|
+
scenario: {
|
|
10072
|
+
description: "Comprehensive user scenario description written from pure user\nperspective.\n\nThis describes a complete user journey, motivation, and expected outcome\nwhen interacting with the API endpoint. The description focuses entirely\non user intent, context, and natural behavior patterns rather than\ntechnical testing considerations.\n\n## User-Centric Writing Approach\n\n- Write as if describing a real person's experience and motivation\n- Focus on business context and user goals, not system functionality\n- Use natural language that business stakeholders would understand\n- Emphasize user value and expected benefits\n- Avoid technical terminology or implementation details\n\n## Required Content Elements\n\nEach scenario description must include:\n\n### 1. User Context and Motivation\n\n- Who is the user (role, background, current situation)\n- Why they need to perform this action (business motivation)\n- What problem they're trying to solve or goal they want to achieve\n- Any relevant background circumstances or constraints\n\n### 2. User Actions and Behavior\n\n- Specific steps the user takes to accomplish their goal\n- What information or data the user provides\n- How the user naturally approaches the interaction\n- Any decision-making process the user goes through\n\n### 3. User Expectations and Desired Outcomes\n\n- What the user expects to happen as a result\n- How the user will know if they were successful\n- What value or benefit the user expects to receive\n- How this fits into their broader workflow or objectives\n\n### 4. Business Impact and Value\n\n- How this scenario relates to business objectives\n- What business processes or workflows this supports\n- Why this user behavior matters to the organization\n- What risks or opportunities this scenario represents\n\n## Single Endpoint Constraint Integration\n\nEach scenario must:\n\n- Represent a complete user journey achievable through this single endpoint\n- Include all necessary context without referencing other API operations\n- Describe user expectations based solely on this endpoint's capabilities\n- Avoid scenarios that would logically require multiple API calls\n\n## Quality and Realism Standards\n\n- Base scenarios on realistic business situations\n- Include specific, concrete details rather than generic descriptions\n- Ensure scenarios reflect actual user behaviors and motivations\n- Make each scenario distinct and valuable for understanding user needs\n- Provide enough detail to understand full context without being verbose\n\n## User-Focused Example Scenarios\n\n- \"A busy project manager needs to quickly create a new team member's user\n account during an onboarding meeting. They have all the necessary\n information readily available and expect the account to be immediately\n active so the new employee can start working right away.\"\n- \"A customer support representative is helping a customer who forgot their\n login credentials. The customer provides their email address, and the\n representative expects to quickly retrieve the associated account\n information to assist with password recovery.\"\n- \"A system administrator discovers that a former employee's account is\n still active after their departure. They need to immediately deactivate\n this account for security purposes and expect confirmation that the\n account can no longer be used to access company resources.\"\n\n## Language and Tone\n\n- Use active voice and present tense when describing user actions\n- Write in a narrative style that tells the user's story\n- Balance professional tone with human context\n- Ensure accessibility for both technical and non-technical readers\n- Maintain consistency in perspective throughout the description",
|
|
10073
|
+
type: "string"
|
|
10074
|
+
}
|
|
10075
|
+
},
|
|
10076
|
+
required: [ "functionName", "scenario" ]
|
|
10077
|
+
}
|
|
10078
|
+
}
|
|
10079
|
+
},
|
|
10080
|
+
required: [ "endpoint", "scenarios" ]
|
|
10081
|
+
}
|
|
10082
|
+
}
|
|
10083
|
+
},
|
|
10084
|
+
required: [ "scenarios" ],
|
|
10085
|
+
additionalProperties: false,
|
|
10086
|
+
$defs: {}
|
|
10087
|
+
},
|
|
10088
|
+
description: "Make user scenarios for the given endpoints.",
|
|
10089
|
+
validate: (() => {
|
|
10090
|
+
const _io0 = input => Array.isArray(input.scenarios) && input.scenarios.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
10091
|
+
const _io1 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && (Array.isArray(input.scenarios) && input.scenarios.every((elem => "object" === typeof elem && null !== elem && _io3(elem))));
|
|
10092
|
+
const _io2 = input => "string" === typeof input.path && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method);
|
|
10093
|
+
const _io3 = input => "string" === typeof input.functionName && "string" === typeof input.scenario;
|
|
10094
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
10095
|
+
path: _path + ".scenarios",
|
|
10096
|
+
expected: "Array<AutoBeTest.IScenario>",
|
|
10097
|
+
value: input.scenarios
|
|
10098
|
+
})) && input.scenarios.map(((elem, _index3) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
10099
|
+
path: _path + ".scenarios[" + _index3 + "]",
|
|
10100
|
+
expected: "AutoBeTest.IScenario",
|
|
10101
|
+
value: elem
|
|
10102
|
+
})) && _vo1(elem, _path + ".scenarios[" + _index3 + "]", _exceptionable) || _report(_exceptionable, {
|
|
10103
|
+
path: _path + ".scenarios[" + _index3 + "]",
|
|
10104
|
+
expected: "AutoBeTest.IScenario",
|
|
10105
|
+
value: elem
|
|
10106
|
+
}))).every((flag => flag)) || _report(_exceptionable, {
|
|
10107
|
+
path: _path + ".scenarios",
|
|
10108
|
+
expected: "Array<AutoBeTest.IScenario>",
|
|
10109
|
+
value: input.scenarios
|
|
10110
|
+
}) ].every((flag => flag));
|
|
10111
|
+
const _vo1 = (input, _path, _exceptionable = true) => [ ("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
10112
|
+
path: _path + ".endpoint",
|
|
10113
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
10114
|
+
value: input.endpoint
|
|
10115
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", _exceptionable) || _report(_exceptionable, {
|
|
10116
|
+
path: _path + ".endpoint",
|
|
10117
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
10118
|
+
value: input.endpoint
|
|
10119
|
+
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
10120
|
+
path: _path + ".scenarios",
|
|
10121
|
+
expected: "Array<AutoBeTest.Scenario>",
|
|
10122
|
+
value: input.scenarios
|
|
10123
|
+
})) && input.scenarios.map(((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
10124
|
+
path: _path + ".scenarios[" + _index4 + "]",
|
|
10125
|
+
expected: "AutoBeTest.Scenario",
|
|
10126
|
+
value: elem
|
|
10127
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index4 + "]", _exceptionable) || _report(_exceptionable, {
|
|
10128
|
+
path: _path + ".scenarios[" + _index4 + "]",
|
|
10129
|
+
expected: "AutoBeTest.Scenario",
|
|
10130
|
+
value: elem
|
|
10131
|
+
}))).every((flag => flag)) || _report(_exceptionable, {
|
|
10132
|
+
path: _path + ".scenarios",
|
|
10133
|
+
expected: "Array<AutoBeTest.Scenario>",
|
|
10134
|
+
value: input.scenarios
|
|
10135
|
+
}) ].every((flag => flag));
|
|
10136
|
+
const _vo2 = (input, _path, _exceptionable = true) => [ "string" === typeof input.path || _report(_exceptionable, {
|
|
10137
|
+
path: _path + ".path",
|
|
10138
|
+
expected: "string",
|
|
10139
|
+
value: input.path
|
|
10140
|
+
}), "get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method || _report(_exceptionable, {
|
|
10141
|
+
path: _path + ".method",
|
|
10142
|
+
expected: '("delete" | "get" | "patch" | "post" | "put")',
|
|
10143
|
+
value: input.method
|
|
10144
|
+
}) ].every((flag => flag));
|
|
10145
|
+
const _vo3 = (input, _path, _exceptionable = true) => [ "string" === typeof input.functionName || _report(_exceptionable, {
|
|
10146
|
+
path: _path + ".functionName",
|
|
10147
|
+
expected: "string",
|
|
10148
|
+
value: input.functionName
|
|
10149
|
+
}), "string" === typeof input.scenario || _report(_exceptionable, {
|
|
10150
|
+
path: _path + ".scenario",
|
|
10151
|
+
expected: "string",
|
|
10152
|
+
value: input.scenario
|
|
10153
|
+
}) ].every((flag => flag));
|
|
10154
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
10155
|
+
let errors;
|
|
10156
|
+
let _report;
|
|
10157
|
+
return input => {
|
|
10158
|
+
if (false === __is(input)) {
|
|
10159
|
+
errors = [];
|
|
10160
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
10161
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
10162
|
+
path: _path + "",
|
|
10163
|
+
expected: "IMakeScenarioProps",
|
|
10164
|
+
value: input
|
|
10165
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
10166
|
+
path: _path + "",
|
|
10167
|
+
expected: "IMakeScenarioProps",
|
|
10168
|
+
value: input
|
|
10169
|
+
}))(input, "$input", true);
|
|
10170
|
+
const success = 0 === errors.length;
|
|
10171
|
+
return success ? {
|
|
10172
|
+
success,
|
|
10173
|
+
data: input
|
|
10174
|
+
} : {
|
|
10175
|
+
success,
|
|
10176
|
+
errors,
|
|
10177
|
+
data: input
|
|
10178
|
+
};
|
|
10179
|
+
}
|
|
10180
|
+
return {
|
|
10181
|
+
success: true,
|
|
10182
|
+
data: input
|
|
10183
|
+
};
|
|
10184
|
+
};
|
|
10185
|
+
})()
|
|
10186
|
+
} ]
|
|
10187
|
+
},
|
|
10188
|
+
claude: claude$1,
|
|
10189
|
+
llama: claude$1,
|
|
10190
|
+
deepseek: claude$1,
|
|
10191
|
+
3.1: claude$1,
|
|
10192
|
+
"3.0": {
|
|
10193
|
+
model: "3.0",
|
|
10194
|
+
options: {
|
|
10195
|
+
constraint: true,
|
|
10196
|
+
recursive: 3,
|
|
10197
|
+
separate: null
|
|
10198
|
+
},
|
|
10199
|
+
functions: [ {
|
|
10200
|
+
name: "makeScenario",
|
|
10201
|
+
parameters: {
|
|
10202
|
+
type: "object",
|
|
10203
|
+
properties: {
|
|
10204
|
+
scenarios: {
|
|
10205
|
+
type: "array",
|
|
10206
|
+
items: {
|
|
10207
|
+
type: "object",
|
|
10208
|
+
properties: {
|
|
10209
|
+
endpoint: {
|
|
10210
|
+
type: "object",
|
|
10211
|
+
properties: {
|
|
10212
|
+
path: {
|
|
10213
|
+
type: "string",
|
|
10214
|
+
title: "HTTP path of the API operation",
|
|
10215
|
+
description: "HTTP path of the API operation.\n\nThe URL path for accessing this API operation, using path parameters\nenclosed in curly braces (e.g., `/shoppings/customers/sales/{saleId}`).\n\nIt must be corresponded to the {@link parameters path parameters}.\n\nThe path structure should clearly indicate which database entity this\noperation is manipulating, helping to ensure all entities have\nappropriate API coverage."
|
|
10216
|
+
},
|
|
10217
|
+
method: {
|
|
10218
|
+
type: "string",
|
|
10219
|
+
enum: [ "get", "post", "put", "delete", "patch" ],
|
|
10220
|
+
title: "HTTP method of the API operation",
|
|
10221
|
+
description: "HTTP method of the API operation.\n\nNote that, if the API operation has {@link requestBody}, method must not\nbe `get`.\n\nAlso, even though the API operation has been designed to only get\ninformation, but it needs complicated request information, it must be\ndefined as `patch` method with {@link requestBody} data specification.\n\n- `get`: get information\n- `patch`: get information with complicated request data\n ({@link requestBody})\n- `post`: create new record\n- `put`: update existing record\n- `delete`: remove record"
|
|
10222
|
+
}
|
|
10223
|
+
},
|
|
10224
|
+
required: [ "path", "method" ],
|
|
10225
|
+
description: "Target API endpoint for user scenario generation.\n\nThis represents the single API endpoint that will be analyzed to generate\ncomprehensive user scenarios. The endpoint contains all technical\nspecifications needed to understand user interactions, including HTTP\nmethods, paths, parameters, request/response schemas, and authentication\nrequirements.\n\n## Core Purpose\n\n- Serves as the foundation for user-centric scenario generation\n- Contains complete API specification for understanding user capabilities\n- Provides schema constraints for realistic user data generation\n- Defines authentication and permission requirements for user context\n\n## User Scenario Context\n\nThis endpoint information enables generation of scenarios that consider:\n\n- What users can realistically accomplish with this endpoint\n- How users would naturally interact with the API functionality\n- What business value users seek from this endpoint\n- What constraints and limitations users will encounter\n- How authentication affects user access patterns\n- What data formats users need to provide or expect to receive\n\n## Single Endpoint Constraint\n\nEach scenario generated must interact with ONLY this endpoint. Scenarios\nshould not assume or require calls to other endpoints, ensuring each user\njourney is complete and testable in isolation.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
10226
|
+
additionalProperties: false
|
|
10227
|
+
},
|
|
10228
|
+
scenarios: {
|
|
10229
|
+
type: "array",
|
|
10230
|
+
items: {
|
|
10231
|
+
type: "object",
|
|
10232
|
+
properties: {
|
|
10233
|
+
functionName: {
|
|
10234
|
+
type: "string",
|
|
10235
|
+
title: "Descriptive function name derived from the user scenario",
|
|
10236
|
+
description: "Descriptive function name derived from the user scenario.\n\nThe function name serves as a concise, technical identifier that clearly\nrepresents the specific user scenario being described. It should be\nimmediately understandable and directly correspond to the user situation\nwithout requiring additional context.\n\n## Naming Convention\n\n- Must start with `test_` prefix (mandatory requirement)\n- Use snake_case formatting throughout\n- Include the primary user action (create, get, update, delete, list, etc.)\n- Specify the target resource (user, product, order, profile, etc.)\n- Add scenario-specific context (valid_data, invalid_email, not_found,\n etc.)\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_[user_action]_[resource]_[scenario_context]`\n\nWhere:\n\n- `user_action`: What the user is trying to do\n- `resource`: What the user is interacting with\n- `scenario_context`: The specific situation or condition\n\n## User-Focused Examples\n\n- `test_create_user_profile_with_complete_information` - User providing all\n available profile data\n- `test_retrieve_user_profile_when_profile_exists` - User accessing their\n existing profile\n- `test_update_user_email_with_valid_new_address` - User changing their\n email to a valid new one\n- `test_delete_user_account_when_user_lacks_permission` - User attempting\n account deletion without authorization\n- `test_search_user_profiles_with_pagination_preferences` - User browsing\n profiles with specific pagination\n\n## Clarity Guidelines\n\n- Prioritize clarity over brevity\n- Avoid technical jargon or implementation terms\n- Use terminology that reflects user perspective\n- Ensure the name alone conveys the user's intent\n- Make it understandable to non-technical stakeholders\n- Keep consistent with user scenario description\n\n## Single Endpoint Alignment\n\nFunction names must reflect scenarios that:\n\n- Accomplish user goals through this single endpoint only\n- Don't imply dependency on other API operations\n- Represent complete user interactions"
|
|
10237
|
+
},
|
|
10238
|
+
scenario: {
|
|
10239
|
+
type: "string",
|
|
10240
|
+
description: "Comprehensive user scenario description written from pure user\nperspective.\n\nThis describes a complete user journey, motivation, and expected outcome\nwhen interacting with the API endpoint. The description focuses entirely\non user intent, context, and natural behavior patterns rather than\ntechnical testing considerations.\n\n## User-Centric Writing Approach\n\n- Write as if describing a real person's experience and motivation\n- Focus on business context and user goals, not system functionality\n- Use natural language that business stakeholders would understand\n- Emphasize user value and expected benefits\n- Avoid technical terminology or implementation details\n\n## Required Content Elements\n\nEach scenario description must include:\n\n### 1. User Context and Motivation\n\n- Who is the user (role, background, current situation)\n- Why they need to perform this action (business motivation)\n- What problem they're trying to solve or goal they want to achieve\n- Any relevant background circumstances or constraints\n\n### 2. User Actions and Behavior\n\n- Specific steps the user takes to accomplish their goal\n- What information or data the user provides\n- How the user naturally approaches the interaction\n- Any decision-making process the user goes through\n\n### 3. User Expectations and Desired Outcomes\n\n- What the user expects to happen as a result\n- How the user will know if they were successful\n- What value or benefit the user expects to receive\n- How this fits into their broader workflow or objectives\n\n### 4. Business Impact and Value\n\n- How this scenario relates to business objectives\n- What business processes or workflows this supports\n- Why this user behavior matters to the organization\n- What risks or opportunities this scenario represents\n\n## Single Endpoint Constraint Integration\n\nEach scenario must:\n\n- Represent a complete user journey achievable through this single endpoint\n- Include all necessary context without referencing other API operations\n- Describe user expectations based solely on this endpoint's capabilities\n- Avoid scenarios that would logically require multiple API calls\n\n## Quality and Realism Standards\n\n- Base scenarios on realistic business situations\n- Include specific, concrete details rather than generic descriptions\n- Ensure scenarios reflect actual user behaviors and motivations\n- Make each scenario distinct and valuable for understanding user needs\n- Provide enough detail to understand full context without being verbose\n\n## User-Focused Example Scenarios\n\n- \"A busy project manager needs to quickly create a new team member's user\n account during an onboarding meeting. They have all the necessary\n information readily available and expect the account to be immediately\n active so the new employee can start working right away.\"\n- \"A customer support representative is helping a customer who forgot their\n login credentials. The customer provides their email address, and the\n representative expects to quickly retrieve the associated account\n information to assist with password recovery.\"\n- \"A system administrator discovers that a former employee's account is\n still active after their departure. They need to immediately deactivate\n this account for security purposes and expect confirmation that the\n account can no longer be used to access company resources.\"\n\n## Language and Tone\n\n- Use active voice and present tense when describing user actions\n- Write in a narrative style that tells the user's story\n- Balance professional tone with human context\n- Ensure accessibility for both technical and non-technical readers\n- Maintain consistency in perspective throughout the description"
|
|
10241
|
+
}
|
|
10242
|
+
},
|
|
10243
|
+
required: [ "functionName", "scenario" ],
|
|
10244
|
+
description: "Current Type: {@link AutoBeTest.Scenario}",
|
|
10245
|
+
additionalProperties: false
|
|
10246
|
+
},
|
|
10247
|
+
title: "Comprehensive collection of user-centric scenarios for the endpoint",
|
|
10248
|
+
description: "Comprehensive collection of user-centric scenarios for the endpoint.\n\nEach scenario represents a realistic user journey, intention, or\nsituation when interacting with this specific API endpoint. All scenarios\nare written from the user's perspective, focusing on what they want to\nachieve and how they naturally interact with the API functionality.\n\n## Scenario Coverage Framework\n\nThe scenarios must comprehensively cover all user interaction patterns:\n\n### 1. Happy Path User Journeys\n\n- Primary business use cases that users commonly perform\n- Standard workflows leading to successful user outcomes\n- Typical user behaviors with valid inputs and proper permissions\n- Most frequent user intentions and expected interactions\n\n### 2. Alternative User Approaches\n\n- Valid alternative ways users might achieve their goals\n- User scenarios utilizing optional parameters or different input patterns\n- Less common but legitimate user behaviors within normal boundaries\n- User experimentation with available API features\n\n### 3. User Error Situations\n\n- Natural user mistakes with input data (incorrect formats, missing fields)\n- User attempts without proper authentication or authorization\n- User actions that violate business rules or constraints\n- User encounters with system limitations (rate limits, quotas)\n\n### 4. Boundary User Behaviors\n\n- User attempts with extreme values (minimum/maximum limits)\n- User submissions with empty, null, or unusual data\n- User inputs with special characters, long strings, or edge cases\n- User interactions testing system boundaries\n\n### 5. Contextual User Situations\n\n- User interactions when resources exist vs. don't exist\n- Different user roles attempting the same actions\n- Time-sensitive user scenarios (expired sessions, scheduled operations)\n- User attempts during various system states\n\n## User-Centric Quality Standards\n\nEach scenario must:\n\n- Focus entirely on user motivation, context, and expected outcomes\n- Describe realistic business situations users actually encounter\n- Include clear user intent and the value they seek\n- Specify user-provided data and user-expected results\n- Be complete within the single endpoint constraint\n- Provide sufficient context for understanding user behavior patterns\n- Avoid technical implementation details or testing terminology\n\n## Single Endpoint Constraint Application\n\nEvery scenario must:\n\n- Complete the entire user journey using only this one endpoint\n- Not depend on or reference other API endpoints\n- Include all necessary context within the scenario itself\n- Represent a complete, self-contained user interaction\n\n## Business Value Focus\n\nThese user scenarios ensure:\n\n- Understanding of real user needs and behaviors\n- Comprehensive coverage of user interaction patterns\n- Proper handling of user errors and edge cases\n- Appropriate user feedback and experience design\n- Business rule validation from user perspective\n- Security and permission handling for different user contexts"
|
|
10249
|
+
}
|
|
10250
|
+
},
|
|
10251
|
+
required: [ "endpoint", "scenarios" ],
|
|
10252
|
+
description: "Current Type: {@link AutoBeTest.IScenario}",
|
|
10253
|
+
additionalProperties: false
|
|
10254
|
+
},
|
|
10255
|
+
title: "Array of user scenarios",
|
|
10256
|
+
description: "Array of user scenarios."
|
|
10257
|
+
}
|
|
10258
|
+
},
|
|
10259
|
+
required: [ "scenarios" ],
|
|
10260
|
+
description: " Properties containing the endpoints and user scenarios.\n\n------------------------------\n\nCurrent Type: {@link IMakeScenarioProps}",
|
|
10261
|
+
additionalProperties: false
|
|
10262
|
+
},
|
|
10263
|
+
description: "Make user scenarios for the given endpoints.",
|
|
10264
|
+
validate: (() => {
|
|
10265
|
+
const _io0 = input => Array.isArray(input.scenarios) && input.scenarios.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
|
|
10266
|
+
const _io1 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && (Array.isArray(input.scenarios) && input.scenarios.every((elem => "object" === typeof elem && null !== elem && _io3(elem))));
|
|
10267
|
+
const _io2 = input => "string" === typeof input.path && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method);
|
|
10268
|
+
const _io3 = input => "string" === typeof input.functionName && "string" === typeof input.scenario;
|
|
10269
|
+
const _vo0 = (input, _path, _exceptionable = true) => [ (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
10270
|
+
path: _path + ".scenarios",
|
|
10271
|
+
expected: "Array<AutoBeTest.IScenario>",
|
|
10272
|
+
value: input.scenarios
|
|
10273
|
+
})) && input.scenarios.map(((elem, _index3) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
10274
|
+
path: _path + ".scenarios[" + _index3 + "]",
|
|
10275
|
+
expected: "AutoBeTest.IScenario",
|
|
10276
|
+
value: elem
|
|
10277
|
+
})) && _vo1(elem, _path + ".scenarios[" + _index3 + "]", _exceptionable) || _report(_exceptionable, {
|
|
10278
|
+
path: _path + ".scenarios[" + _index3 + "]",
|
|
10279
|
+
expected: "AutoBeTest.IScenario",
|
|
10280
|
+
value: elem
|
|
10281
|
+
}))).every((flag => flag)) || _report(_exceptionable, {
|
|
10282
|
+
path: _path + ".scenarios",
|
|
10283
|
+
expected: "Array<AutoBeTest.IScenario>",
|
|
10284
|
+
value: input.scenarios
|
|
10285
|
+
}) ].every((flag => flag));
|
|
10286
|
+
const _vo1 = (input, _path, _exceptionable = true) => [ ("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
10287
|
+
path: _path + ".endpoint",
|
|
10288
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
10289
|
+
value: input.endpoint
|
|
10290
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", _exceptionable) || _report(_exceptionable, {
|
|
10291
|
+
path: _path + ".endpoint",
|
|
10292
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
10293
|
+
value: input.endpoint
|
|
10294
|
+
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
10295
|
+
path: _path + ".scenarios",
|
|
10296
|
+
expected: "Array<AutoBeTest.Scenario>",
|
|
10297
|
+
value: input.scenarios
|
|
10298
|
+
})) && input.scenarios.map(((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
10299
|
+
path: _path + ".scenarios[" + _index4 + "]",
|
|
10300
|
+
expected: "AutoBeTest.Scenario",
|
|
10301
|
+
value: elem
|
|
10302
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index4 + "]", _exceptionable) || _report(_exceptionable, {
|
|
10303
|
+
path: _path + ".scenarios[" + _index4 + "]",
|
|
10304
|
+
expected: "AutoBeTest.Scenario",
|
|
10305
|
+
value: elem
|
|
10306
|
+
}))).every((flag => flag)) || _report(_exceptionable, {
|
|
10307
|
+
path: _path + ".scenarios",
|
|
10308
|
+
expected: "Array<AutoBeTest.Scenario>",
|
|
10309
|
+
value: input.scenarios
|
|
10310
|
+
}) ].every((flag => flag));
|
|
10311
|
+
const _vo2 = (input, _path, _exceptionable = true) => [ "string" === typeof input.path || _report(_exceptionable, {
|
|
10312
|
+
path: _path + ".path",
|
|
10313
|
+
expected: "string",
|
|
10314
|
+
value: input.path
|
|
10315
|
+
}), "get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method || _report(_exceptionable, {
|
|
10316
|
+
path: _path + ".method",
|
|
10317
|
+
expected: '("delete" | "get" | "patch" | "post" | "put")',
|
|
10318
|
+
value: input.method
|
|
10319
|
+
}) ].every((flag => flag));
|
|
10320
|
+
const _vo3 = (input, _path, _exceptionable = true) => [ "string" === typeof input.functionName || _report(_exceptionable, {
|
|
10321
|
+
path: _path + ".functionName",
|
|
10322
|
+
expected: "string",
|
|
10323
|
+
value: input.functionName
|
|
10324
|
+
}), "string" === typeof input.scenario || _report(_exceptionable, {
|
|
10325
|
+
path: _path + ".scenario",
|
|
10326
|
+
expected: "string",
|
|
10327
|
+
value: input.scenario
|
|
10328
|
+
}) ].every((flag => flag));
|
|
10329
|
+
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
10330
|
+
let errors;
|
|
10331
|
+
let _report;
|
|
10332
|
+
return input => {
|
|
10333
|
+
if (false === __is(input)) {
|
|
10334
|
+
errors = [];
|
|
10335
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
10336
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
10337
|
+
path: _path + "",
|
|
10338
|
+
expected: "IMakeScenarioProps",
|
|
10339
|
+
value: input
|
|
10340
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
10341
|
+
path: _path + "",
|
|
10342
|
+
expected: "IMakeScenarioProps",
|
|
10343
|
+
value: input
|
|
10344
|
+
}))(input, "$input", true);
|
|
10345
|
+
const success = 0 === errors.length;
|
|
10346
|
+
return success ? {
|
|
10347
|
+
success,
|
|
10348
|
+
data: input
|
|
10349
|
+
} : {
|
|
10350
|
+
success,
|
|
10351
|
+
errors,
|
|
10352
|
+
data: input
|
|
10353
|
+
};
|
|
10354
|
+
}
|
|
10355
|
+
return {
|
|
10356
|
+
success: true,
|
|
10357
|
+
data: input
|
|
10358
|
+
};
|
|
10359
|
+
};
|
|
10360
|
+
})()
|
|
10361
|
+
} ]
|
|
10362
|
+
}
|
|
10363
|
+
};
|
|
10364
|
+
|
|
10365
|
+
const orchestrateTest = ctx => async props => {
|
|
10366
|
+
const start = new Date;
|
|
10367
|
+
ctx.dispatch({
|
|
10368
|
+
type: "testStart",
|
|
10369
|
+
created_at: start.toISOString(),
|
|
10370
|
+
reason: props.reason,
|
|
10371
|
+
step: ctx.state().analyze?.step ?? 0
|
|
10372
|
+
});
|
|
10373
|
+
const operations = ctx.state().interface?.document.operations ?? [];
|
|
10374
|
+
if (operations.length === 0) {
|
|
10375
|
+
const history = {
|
|
10376
|
+
id: v4(),
|
|
10377
|
+
type: "assistantMessage",
|
|
10378
|
+
created_at: start.toISOString(),
|
|
10379
|
+
completed_at: (new Date).toISOString(),
|
|
10380
|
+
text: "Unable to write test code because there are no Operations, " + "please check if the Interface agent is called."
|
|
10381
|
+
};
|
|
10382
|
+
ctx.histories().push(history);
|
|
10383
|
+
ctx.dispatch(history);
|
|
10384
|
+
return history;
|
|
10385
|
+
}
|
|
10386
|
+
const scenarioEvent = await orchestrateTestScenario(ctx);
|
|
10387
|
+
const scenarios = scenarioEvent.scenarios.map((scenario => scenario.scenarios)).flat();
|
|
10388
|
+
const codes = await orchestrateTestProgress(ctx, scenarios);
|
|
10389
|
+
const correct = await orchestrateTestCorrect(ctx, codes);
|
|
10390
|
+
const history = {
|
|
10391
|
+
type: "test",
|
|
10392
|
+
id: v4(),
|
|
10393
|
+
completed_at: (new Date).toISOString(),
|
|
10394
|
+
created_at: start.toISOString(),
|
|
10395
|
+
files: correct.files,
|
|
10396
|
+
compiled: correct.result,
|
|
10397
|
+
reason: "Step to the test generation referencing the interface",
|
|
10398
|
+
step: ctx.state().interface?.step ?? 0
|
|
10399
|
+
};
|
|
10400
|
+
ctx.dispatch({
|
|
10401
|
+
type: "testComplete",
|
|
10402
|
+
created_at: start.toISOString(),
|
|
10403
|
+
files: correct.files,
|
|
10404
|
+
step: ctx.state().interface?.step ?? 0
|
|
10405
|
+
});
|
|
10406
|
+
ctx.state().test = history;
|
|
10407
|
+
ctx.histories().push(history);
|
|
10408
|
+
return history;
|
|
10409
|
+
};
|
|
10410
|
+
|
|
8851
10411
|
var StringUtil;
|
|
8852
10412
|
|
|
8853
10413
|
(function(StringUtil) {
|
|
@@ -8927,7 +10487,7 @@ const createAutoBeController = props => {
|
|
|
8927
10487
|
};
|
|
8928
10488
|
},
|
|
8929
10489
|
test: async next => {
|
|
8930
|
-
const r = await orchestrateTest()(next);
|
|
10490
|
+
const r = await orchestrateTest(props.context)(next);
|
|
8931
10491
|
if (r.type === "test") return {
|
|
8932
10492
|
type: r.compiled.type,
|
|
8933
10493
|
description: r.compiled.type === "success" ? "Test functions have been generated successfully." : r.compiled.type === "failure" ? "Test functions are written, but compilation failed." : "Unexpected error occurred while writing test functions."
|