@faapi/faapi 5.0.1 → 5.1.0
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/dist/cli/index.js +143 -67
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.js +143 -67
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-DnJuuvq-.d.ts → routeTypes-DG0eL3l5.d.ts} +5 -5
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +9 -5
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1929,15 +1929,19 @@ var init_resolveTypeNode = __esm({
|
|
|
1929
1929
|
*
|
|
1930
1930
|
* 所有抛错点应优先使用此工厂——错误无行号时,几百行的类型文件只能靠
|
|
1931
1931
|
* 类型名肉眼定位;解析 lib.d.ts 类型别名时还会出现错误文本与文件上下文错位
|
|
1932
|
+
*
|
|
1933
|
+
* `sourceFile` 可选:未触达 checker 的纯语法遍历路径(binder 未运行)没有
|
|
1934
|
+
* parent 指针,`node.getSourceFile()` 返回 undefined,此时调用方需显式传入
|
|
1935
|
+
* `program.getSourceFile(filePath)` 的结果以携带位置。
|
|
1932
1936
|
*/
|
|
1933
|
-
static at(node, typeText, reason) {
|
|
1934
|
-
const
|
|
1935
|
-
if (!
|
|
1937
|
+
static at(node, typeText, reason, sourceFile) {
|
|
1938
|
+
const sf = sourceFile ?? node.getSourceFile();
|
|
1939
|
+
if (!sf) {
|
|
1936
1940
|
return new _SchemaExtractionError(typeText, reason);
|
|
1937
1941
|
}
|
|
1938
|
-
const { line, character } =
|
|
1942
|
+
const { line, character } = sf.getLineAndCharacterOfPosition(node.getStart(sf));
|
|
1939
1943
|
return new _SchemaExtractionError(typeText, reason, void 0, {
|
|
1940
|
-
file:
|
|
1944
|
+
file: sf.fileName,
|
|
1941
1945
|
line: line + 1,
|
|
1942
1946
|
column: character + 1
|
|
1943
1947
|
});
|
|
@@ -3006,33 +3010,30 @@ function extractAgentMetadata(program, filePath, pathMeta) {
|
|
|
3006
3010
|
const sourceFile = program.getSourceFile(filePath);
|
|
3007
3011
|
if (!sourceFile) return null;
|
|
3008
3012
|
const configFound = findConfigExport(sourceFile);
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3013
|
+
if (!configFound) {
|
|
3014
|
+
throw SchemaExtractionError.at(
|
|
3015
|
+
sourceFile,
|
|
3016
|
+
"config.systemPrompt",
|
|
3017
|
+
"agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u6216\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\uFF09",
|
|
3018
|
+
sourceFile
|
|
3019
|
+
);
|
|
3020
|
+
}
|
|
3021
|
+
if (!configFound.objectLiteral) {
|
|
3022
|
+
throw SchemaExtractionError.at(
|
|
3023
|
+
configFound.jsDocOwner,
|
|
3024
|
+
"config",
|
|
3025
|
+
"\u4EC5\u652F\u6301\u5BF9\u8C61\u5B57\u9762\u91CF\u3001\u7BAD\u5934\u51FD\u6570\u8FD4\u56DE\u5BF9\u8C61\u5B57\u9762\u91CF\u6216\u51FD\u6570\u8FD4\u56DE\u5BF9\u8C61\u5B57\u9762\u91CF",
|
|
3026
|
+
sourceFile
|
|
3027
|
+
);
|
|
3028
|
+
}
|
|
3029
|
+
const objectLiteral = configFound.objectLiteral;
|
|
3030
|
+
const jsDoc = getJSDocFromNode(configFound.jsDocOwner);
|
|
3021
3031
|
const description = extractDescription(jsDoc);
|
|
3022
3032
|
const agentNameOverride = extractJSDocTagValue(jsDoc, "agent");
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
let maxTurns;
|
|
3028
|
-
if (objectLiteral) {
|
|
3029
|
-
const fields = extractConfigFields(objectLiteral);
|
|
3030
|
-
systemPrompt = fields.systemPrompt;
|
|
3031
|
-
tools = fields.tools;
|
|
3032
|
-
agents = fields.agents;
|
|
3033
|
-
model = fields.model;
|
|
3034
|
-
maxTurns = fields.maxTurns;
|
|
3035
|
-
}
|
|
3033
|
+
const { systemPrompt, tools, agents, model, maxTurns } = extractConfigFields(
|
|
3034
|
+
objectLiteral,
|
|
3035
|
+
sourceFile
|
|
3036
|
+
);
|
|
3036
3037
|
return {
|
|
3037
3038
|
name: agentNameOverride ?? pathMeta.name,
|
|
3038
3039
|
description,
|
|
@@ -3057,8 +3058,9 @@ function findConfigExport(sourceFile) {
|
|
|
3057
3058
|
if (ts9.isObjectLiteralExpression(decl.initializer)) {
|
|
3058
3059
|
result = { jsDocOwner: node, objectLiteral: decl.initializer };
|
|
3059
3060
|
} else if (ts9.isArrowFunction(decl.initializer)) {
|
|
3060
|
-
|
|
3061
|
-
|
|
3061
|
+
result = { jsDocOwner: node, objectLiteral: getReturnObjectLiteral(decl.initializer) };
|
|
3062
|
+
} else {
|
|
3063
|
+
result = { jsDocOwner: node, objectLiteral: null };
|
|
3062
3064
|
}
|
|
3063
3065
|
}
|
|
3064
3066
|
}
|
|
@@ -3069,27 +3071,6 @@ function findConfigExport(sourceFile) {
|
|
|
3069
3071
|
});
|
|
3070
3072
|
return result;
|
|
3071
3073
|
}
|
|
3072
|
-
function findRunExport(sourceFile) {
|
|
3073
|
-
let result = null;
|
|
3074
|
-
ts9.forEachChild(sourceFile, (node) => {
|
|
3075
|
-
if (result) return;
|
|
3076
|
-
if (ts9.isFunctionDeclaration(node) && hasExportModifier(node) && node.name?.text === "run") {
|
|
3077
|
-
result = node;
|
|
3078
|
-
return;
|
|
3079
|
-
}
|
|
3080
|
-
if (ts9.isVariableStatement(node) && hasExportModifier(node)) {
|
|
3081
|
-
for (const decl of node.declarationList.declarations) {
|
|
3082
|
-
if (result) break;
|
|
3083
|
-
const nameText = ts9.isIdentifier(decl.name) ? decl.name.text : "";
|
|
3084
|
-
if (nameText !== "run" || !decl.initializer) continue;
|
|
3085
|
-
if (ts9.isArrowFunction(decl.initializer) || ts9.isFunctionExpression(decl.initializer)) {
|
|
3086
|
-
result = node;
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
|
-
}
|
|
3090
|
-
});
|
|
3091
|
-
return result;
|
|
3092
|
-
}
|
|
3093
3074
|
function getReturnObjectLiteral(fn) {
|
|
3094
3075
|
const body = fn.body;
|
|
3095
3076
|
if (!body) return null;
|
|
@@ -3105,31 +3086,60 @@ function getReturnObjectLiteral(fn) {
|
|
|
3105
3086
|
}
|
|
3106
3087
|
return null;
|
|
3107
3088
|
}
|
|
3108
|
-
function extractConfigFields(objLit) {
|
|
3109
|
-
|
|
3089
|
+
function extractConfigFields(objLit, sourceFile) {
|
|
3090
|
+
let systemPrompt;
|
|
3091
|
+
let tools;
|
|
3092
|
+
let agents;
|
|
3093
|
+
let model;
|
|
3094
|
+
let maxTurns;
|
|
3110
3095
|
for (const prop of objLit.properties) {
|
|
3111
|
-
if (
|
|
3096
|
+
if (ts9.isSpreadAssignment(prop)) continue;
|
|
3097
|
+
if (!ts9.isPropertyAssignment(prop)) {
|
|
3098
|
+
throw SchemaExtractionError.at(
|
|
3099
|
+
prop,
|
|
3100
|
+
"config",
|
|
3101
|
+
"\u4EC5\u652F\u6301 key: value \u5C5E\u6027\u5F62\u5F0F\uFF08\u4E0D\u652F\u6301 shorthand/\u65B9\u6CD5/getter\uFF09",
|
|
3102
|
+
sourceFile
|
|
3103
|
+
);
|
|
3104
|
+
}
|
|
3112
3105
|
const propName = getPropertyName(prop.name);
|
|
3113
|
-
if (!propName)
|
|
3106
|
+
if (!propName) {
|
|
3107
|
+
throw SchemaExtractionError.at(prop.name, "config", "\u4E0D\u652F\u6301 computed \u5C5E\u6027\u540D", sourceFile);
|
|
3108
|
+
}
|
|
3114
3109
|
switch (propName) {
|
|
3115
3110
|
case "systemPrompt":
|
|
3116
|
-
|
|
3111
|
+
systemPrompt = requireStringValue(prop, "systemPrompt", sourceFile);
|
|
3117
3112
|
break;
|
|
3118
3113
|
case "tools":
|
|
3119
|
-
|
|
3114
|
+
tools = requireStringArrayValue(prop, "tools", sourceFile);
|
|
3120
3115
|
break;
|
|
3121
3116
|
case "agents":
|
|
3122
|
-
|
|
3117
|
+
agents = requireStringArrayValue(prop, "agents", sourceFile);
|
|
3123
3118
|
break;
|
|
3124
3119
|
case "model":
|
|
3125
|
-
|
|
3120
|
+
model = requireStringValue(prop, "model", sourceFile);
|
|
3126
3121
|
break;
|
|
3127
3122
|
case "maxTurns":
|
|
3128
|
-
|
|
3123
|
+
maxTurns = requireNumberValue(prop, "maxTurns", sourceFile);
|
|
3129
3124
|
break;
|
|
3125
|
+
default:
|
|
3126
|
+
throw SchemaExtractionError.at(
|
|
3127
|
+
prop,
|
|
3128
|
+
`config.${propName}`,
|
|
3129
|
+
"\u672A\u77E5 config \u5B57\u6BB5\u2014\u2014\u4EC5\u652F\u6301 systemPrompt / tools / agents / model / maxTurns",
|
|
3130
|
+
sourceFile
|
|
3131
|
+
);
|
|
3130
3132
|
}
|
|
3131
3133
|
}
|
|
3132
|
-
|
|
3134
|
+
if (systemPrompt === void 0) {
|
|
3135
|
+
throw SchemaExtractionError.at(
|
|
3136
|
+
objLit,
|
|
3137
|
+
"config.systemPrompt",
|
|
3138
|
+
"agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u6216\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\uFF09",
|
|
3139
|
+
sourceFile
|
|
3140
|
+
);
|
|
3141
|
+
}
|
|
3142
|
+
return { systemPrompt, tools, agents, model, maxTurns };
|
|
3133
3143
|
}
|
|
3134
3144
|
function getPropertyName(name) {
|
|
3135
3145
|
if (ts9.isIdentifier(name)) return name.text;
|
|
@@ -3137,9 +3147,45 @@ function getPropertyName(name) {
|
|
|
3137
3147
|
return null;
|
|
3138
3148
|
}
|
|
3139
3149
|
function extractStringValue(expr) {
|
|
3140
|
-
if (
|
|
3150
|
+
if (isStringLikeLiteral(expr)) return expr.text;
|
|
3141
3151
|
return void 0;
|
|
3142
3152
|
}
|
|
3153
|
+
function requireStringValue(prop, fieldName, sourceFile) {
|
|
3154
|
+
const value = extractStringValue(prop.initializer);
|
|
3155
|
+
if (value === void 0) {
|
|
3156
|
+
throw SchemaExtractionError.at(
|
|
3157
|
+
prop.initializer,
|
|
3158
|
+
`config.${fieldName}`,
|
|
3159
|
+
"\u4EC5\u652F\u6301\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u6216\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\uFF08\u542B\u63D2\u503C\u7684\u6A21\u677F\u5B57\u7B26\u4E32/\u53D8\u91CF\u5F15\u7528\u65E0\u6CD5\u9759\u6001\u6C42\u503C\uFF09",
|
|
3160
|
+
sourceFile
|
|
3161
|
+
);
|
|
3162
|
+
}
|
|
3163
|
+
return value;
|
|
3164
|
+
}
|
|
3165
|
+
function requireStringArrayValue(prop, fieldName, sourceFile) {
|
|
3166
|
+
const value = extractStringArrayValue(prop.initializer);
|
|
3167
|
+
if (value === void 0) {
|
|
3168
|
+
throw SchemaExtractionError.at(
|
|
3169
|
+
prop.initializer,
|
|
3170
|
+
`config.${fieldName}`,
|
|
3171
|
+
"\u4EC5\u652F\u6301\u5168\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u6570\u7EC4\uFF08\u5143\u7D20\u4E3A\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u6216\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\uFF09",
|
|
3172
|
+
sourceFile
|
|
3173
|
+
);
|
|
3174
|
+
}
|
|
3175
|
+
return value;
|
|
3176
|
+
}
|
|
3177
|
+
function requireNumberValue(prop, fieldName, sourceFile) {
|
|
3178
|
+
const value = extractNumberValue(prop.initializer);
|
|
3179
|
+
if (value === void 0) {
|
|
3180
|
+
throw SchemaExtractionError.at(
|
|
3181
|
+
prop.initializer,
|
|
3182
|
+
`config.${fieldName}`,
|
|
3183
|
+
"\u4EC5\u652F\u6301\u6570\u5B57\u5B57\u9762\u91CF",
|
|
3184
|
+
sourceFile
|
|
3185
|
+
);
|
|
3186
|
+
}
|
|
3187
|
+
return value;
|
|
3188
|
+
}
|
|
3143
3189
|
function extractNumberValue(expr) {
|
|
3144
3190
|
if (ts9.isNumericLiteral(expr)) {
|
|
3145
3191
|
const num = Number(expr.text);
|
|
@@ -3147,11 +3193,14 @@ function extractNumberValue(expr) {
|
|
|
3147
3193
|
}
|
|
3148
3194
|
return void 0;
|
|
3149
3195
|
}
|
|
3196
|
+
function isStringLikeLiteral(node) {
|
|
3197
|
+
return ts9.isStringLiteral(node) || ts9.isNoSubstitutionTemplateLiteral(node);
|
|
3198
|
+
}
|
|
3150
3199
|
function extractStringArrayValue(expr) {
|
|
3151
3200
|
if (!ts9.isArrayLiteralExpression(expr)) return void 0;
|
|
3152
3201
|
const values = [];
|
|
3153
3202
|
for (const element of expr.elements) {
|
|
3154
|
-
if (!
|
|
3203
|
+
if (!isStringLikeLiteral(element)) return void 0;
|
|
3155
3204
|
values.push(element.text);
|
|
3156
3205
|
}
|
|
3157
3206
|
return values;
|
|
@@ -3160,6 +3209,7 @@ var init_extractAgentMetadata = __esm({
|
|
|
3160
3209
|
"src/ast/extractAgentMetadata.ts"() {
|
|
3161
3210
|
"use strict";
|
|
3162
3211
|
init_jsDocMetadata();
|
|
3212
|
+
init_resolveTypeNode();
|
|
3163
3213
|
}
|
|
3164
3214
|
});
|
|
3165
3215
|
|
|
@@ -3197,6 +3247,28 @@ function hydrateAgents(manifest) {
|
|
|
3197
3247
|
maxTurns: a.maxTurns ?? void 0
|
|
3198
3248
|
}));
|
|
3199
3249
|
}
|
|
3250
|
+
function validateAgentList(metadata) {
|
|
3251
|
+
const names = /* @__PURE__ */ new Map();
|
|
3252
|
+
for (const a of metadata) {
|
|
3253
|
+
const prev = names.get(a.name);
|
|
3254
|
+
if (prev) {
|
|
3255
|
+
throw new Error(
|
|
3256
|
+
`agent \u540D\u91CD\u590D: "${a.name}"\uFF08${prev} \u4E0E ${a.filePath} \u51B2\u7A81\u2014\u2014\u76EE\u5F55\u63A8\u5BFC\u540D\u6216 @agent \u8986\u76D6\u540D\u649E\u540D\uFF09`
|
|
3257
|
+
);
|
|
3258
|
+
}
|
|
3259
|
+
names.set(a.name, a.filePath);
|
|
3260
|
+
}
|
|
3261
|
+
for (const a of metadata) {
|
|
3262
|
+
for (const ref of a.agents ?? []) {
|
|
3263
|
+
if (!names.has(ref)) {
|
|
3264
|
+
const available = [...names.keys()].join(", ") || "\u65E0";
|
|
3265
|
+
throw new Error(
|
|
3266
|
+
`agent "${a.name}" \u7684 agents \u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684 agent: "${ref}"\uFF08\u6E05\u5355\u4E2D\u53EF\u7528: ${available}\uFF09`
|
|
3267
|
+
);
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3200
3272
|
async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
3201
3273
|
const metadata = [];
|
|
3202
3274
|
const programByFile = createPrograms(agents.map((m) => path15.resolve(rootDir, m.filePath)));
|
|
@@ -3208,10 +3280,14 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
|
3208
3280
|
filePath: manifest.filePath,
|
|
3209
3281
|
hasRun: manifest.hasRun
|
|
3210
3282
|
});
|
|
3211
|
-
if (result) {
|
|
3212
|
-
|
|
3283
|
+
if (!result) {
|
|
3284
|
+
throw new Error(
|
|
3285
|
+
`agent "${manifest.name}" \u6E90\u6587\u4EF6\u4E0D\u5728 Program \u4E2D: ${manifest.filePath}\u2014\u2014\u65E0\u6CD5\u751F\u6210\u6E05\u5355`
|
|
3286
|
+
);
|
|
3213
3287
|
}
|
|
3288
|
+
metadata.push(result);
|
|
3214
3289
|
}
|
|
3290
|
+
validateAgentList(metadata);
|
|
3215
3291
|
const serialized = serializeAgents(metadata, dist);
|
|
3216
3292
|
const agentsPath = path15.resolve(rootDir, dist, AGENTS_FILE);
|
|
3217
3293
|
await writeAgentsModule(serialized, agentsPath);
|