@faapi/faapi 5.0.1 → 5.2.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 +152 -68
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.js +152 -68
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-DnJuuvq-.d.ts → routeTypes-Bm--uTbm.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/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AppRegistries, R as RouteManifest, F as FaapiContext, C as CorsOptions, H as HelmetOptions, L as LoggerOptions, a as FaapiMiddleware, I as InjectorMap, T as ToolMetadata, b as AgentCore, c as AgentMetadata, W as WsRouteManifest } from './routeTypes-
|
|
2
|
-
export { d as AgentHandleFactory, e as AgentHandleStore, f as AgentPathMeta, g as AgentRegistry, h as AgentToolDescriptor, i as FaapiContextConfig, j as FailOptions, k as Injector, l as RouteInfo, m as RouteInputSchema, n as RouteOutputSchema, o as RouteParamSchema, S as SkillRegistry, p as SseEvent, q as SseWriter, r as ToolCore, s as ToolPathMeta, t as ToolRegistry, u as cors, v as createAppRegistries, w as helmet, x as logger } from './routeTypes-
|
|
1
|
+
import { A as AppRegistries, R as RouteManifest, F as FaapiContext, C as CorsOptions, H as HelmetOptions, L as LoggerOptions, a as FaapiMiddleware, I as InjectorMap, T as ToolMetadata, b as AgentCore, c as AgentMetadata, W as WsRouteManifest } from './routeTypes-Bm--uTbm.js';
|
|
2
|
+
export { d as AgentHandleFactory, e as AgentHandleStore, f as AgentPathMeta, g as AgentRegistry, h as AgentToolDescriptor, i as FaapiContextConfig, j as FailOptions, k as Injector, l as RouteInfo, m as RouteInputSchema, n as RouteOutputSchema, o as RouteParamSchema, S as SkillRegistry, p as SseEvent, q as SseWriter, r as ToolCore, s as ToolPathMeta, t as ToolRegistry, u as cors, v as createAppRegistries, w as helmet, x as logger } from './routeTypes-Bm--uTbm.js';
|
|
3
3
|
import * as node_http from 'node:http';
|
|
4
4
|
import { Server, IncomingMessage, ServerResponse } from 'node:http';
|
|
5
5
|
import { Socket } from 'node:net';
|
|
@@ -781,8 +781,12 @@ declare class SchemaExtractionError extends Error {
|
|
|
781
781
|
*
|
|
782
782
|
* 所有抛错点应优先使用此工厂——错误无行号时,几百行的类型文件只能靠
|
|
783
783
|
* 类型名肉眼定位;解析 lib.d.ts 类型别名时还会出现错误文本与文件上下文错位
|
|
784
|
+
*
|
|
785
|
+
* `sourceFile` 可选:未触达 checker 的纯语法遍历路径(binder 未运行)没有
|
|
786
|
+
* parent 指针,`node.getSourceFile()` 返回 undefined,此时调用方需显式传入
|
|
787
|
+
* `program.getSourceFile(filePath)` 的结果以携带位置。
|
|
784
788
|
*/
|
|
785
|
-
static at(node: ts.Node, typeText: string, reason: string): SchemaExtractionError;
|
|
789
|
+
static at(node: ts.Node, typeText: string, reason: string, sourceFile?: ts.SourceFile): SchemaExtractionError;
|
|
786
790
|
}
|
|
787
791
|
/**
|
|
788
792
|
* 运行时类型描述
|
package/dist/index.js
CHANGED
|
@@ -848,15 +848,19 @@ var init_resolveTypeNode = __esm({
|
|
|
848
848
|
*
|
|
849
849
|
* 所有抛错点应优先使用此工厂——错误无行号时,几百行的类型文件只能靠
|
|
850
850
|
* 类型名肉眼定位;解析 lib.d.ts 类型别名时还会出现错误文本与文件上下文错位
|
|
851
|
+
*
|
|
852
|
+
* `sourceFile` 可选:未触达 checker 的纯语法遍历路径(binder 未运行)没有
|
|
853
|
+
* parent 指针,`node.getSourceFile()` 返回 undefined,此时调用方需显式传入
|
|
854
|
+
* `program.getSourceFile(filePath)` 的结果以携带位置。
|
|
851
855
|
*/
|
|
852
|
-
static at(node, typeText, reason) {
|
|
853
|
-
const
|
|
854
|
-
if (!
|
|
856
|
+
static at(node, typeText, reason, sourceFile) {
|
|
857
|
+
const sf = sourceFile ?? node.getSourceFile();
|
|
858
|
+
if (!sf) {
|
|
855
859
|
return new _SchemaExtractionError(typeText, reason);
|
|
856
860
|
}
|
|
857
|
-
const { line, character } =
|
|
861
|
+
const { line, character } = sf.getLineAndCharacterOfPosition(node.getStart(sf));
|
|
858
862
|
return new _SchemaExtractionError(typeText, reason, void 0, {
|
|
859
|
-
file:
|
|
863
|
+
file: sf.fileName,
|
|
860
864
|
line: line + 1,
|
|
861
865
|
column: character + 1
|
|
862
866
|
});
|
|
@@ -5085,37 +5089,35 @@ import path17 from "path";
|
|
|
5085
5089
|
|
|
5086
5090
|
// src/ast/extractAgentMetadata.ts
|
|
5087
5091
|
import ts9 from "typescript";
|
|
5092
|
+
init_resolveTypeNode();
|
|
5088
5093
|
function extractAgentMetadata(program, filePath, pathMeta) {
|
|
5089
5094
|
const sourceFile = program.getSourceFile(filePath);
|
|
5090
5095
|
if (!sourceFile) return null;
|
|
5091
5096
|
const configFound = findConfigExport(sourceFile);
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5097
|
+
if (!configFound) {
|
|
5098
|
+
throw SchemaExtractionError.at(
|
|
5099
|
+
sourceFile,
|
|
5100
|
+
"config.systemPrompt",
|
|
5101
|
+
"agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF09",
|
|
5102
|
+
sourceFile
|
|
5103
|
+
);
|
|
5104
|
+
}
|
|
5105
|
+
if (!configFound.objectLiteral) {
|
|
5106
|
+
throw SchemaExtractionError.at(
|
|
5107
|
+
configFound.jsDocOwner,
|
|
5108
|
+
"config",
|
|
5109
|
+
"\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",
|
|
5110
|
+
sourceFile
|
|
5111
|
+
);
|
|
5112
|
+
}
|
|
5113
|
+
const objectLiteral = configFound.objectLiteral;
|
|
5114
|
+
const jsDoc = getJSDocFromNode(configFound.jsDocOwner);
|
|
5104
5115
|
const description = extractDescription(jsDoc);
|
|
5105
5116
|
const agentNameOverride = extractJSDocTagValue(jsDoc, "agent");
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
let maxTurns;
|
|
5111
|
-
if (objectLiteral) {
|
|
5112
|
-
const fields = extractConfigFields(objectLiteral);
|
|
5113
|
-
systemPrompt = fields.systemPrompt;
|
|
5114
|
-
tools = fields.tools;
|
|
5115
|
-
agents = fields.agents;
|
|
5116
|
-
model = fields.model;
|
|
5117
|
-
maxTurns = fields.maxTurns;
|
|
5118
|
-
}
|
|
5117
|
+
const { systemPrompt, tools, agents, model, maxTurns } = extractConfigFields(
|
|
5118
|
+
objectLiteral,
|
|
5119
|
+
sourceFile
|
|
5120
|
+
);
|
|
5119
5121
|
return {
|
|
5120
5122
|
name: agentNameOverride ?? pathMeta.name,
|
|
5121
5123
|
description,
|
|
@@ -5140,8 +5142,9 @@ function findConfigExport(sourceFile) {
|
|
|
5140
5142
|
if (ts9.isObjectLiteralExpression(decl.initializer)) {
|
|
5141
5143
|
result = { jsDocOwner: node, objectLiteral: decl.initializer };
|
|
5142
5144
|
} else if (ts9.isArrowFunction(decl.initializer)) {
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
+
result = { jsDocOwner: node, objectLiteral: getReturnObjectLiteral(decl.initializer) };
|
|
5146
|
+
} else {
|
|
5147
|
+
result = { jsDocOwner: node, objectLiteral: null };
|
|
5145
5148
|
}
|
|
5146
5149
|
}
|
|
5147
5150
|
}
|
|
@@ -5152,27 +5155,6 @@ function findConfigExport(sourceFile) {
|
|
|
5152
5155
|
});
|
|
5153
5156
|
return result;
|
|
5154
5157
|
}
|
|
5155
|
-
function findRunExport(sourceFile) {
|
|
5156
|
-
let result = null;
|
|
5157
|
-
ts9.forEachChild(sourceFile, (node) => {
|
|
5158
|
-
if (result) return;
|
|
5159
|
-
if (ts9.isFunctionDeclaration(node) && hasExportModifier(node) && node.name?.text === "run") {
|
|
5160
|
-
result = node;
|
|
5161
|
-
return;
|
|
5162
|
-
}
|
|
5163
|
-
if (ts9.isVariableStatement(node) && hasExportModifier(node)) {
|
|
5164
|
-
for (const decl of node.declarationList.declarations) {
|
|
5165
|
-
if (result) break;
|
|
5166
|
-
const nameText = ts9.isIdentifier(decl.name) ? decl.name.text : "";
|
|
5167
|
-
if (nameText !== "run" || !decl.initializer) continue;
|
|
5168
|
-
if (ts9.isArrowFunction(decl.initializer) || ts9.isFunctionExpression(decl.initializer)) {
|
|
5169
|
-
result = node;
|
|
5170
|
-
}
|
|
5171
|
-
}
|
|
5172
|
-
}
|
|
5173
|
-
});
|
|
5174
|
-
return result;
|
|
5175
|
-
}
|
|
5176
5158
|
function getReturnObjectLiteral(fn) {
|
|
5177
5159
|
const body = fn.body;
|
|
5178
5160
|
if (!body) return null;
|
|
@@ -5188,31 +5170,60 @@ function getReturnObjectLiteral(fn) {
|
|
|
5188
5170
|
}
|
|
5189
5171
|
return null;
|
|
5190
5172
|
}
|
|
5191
|
-
function extractConfigFields(objLit) {
|
|
5192
|
-
|
|
5173
|
+
function extractConfigFields(objLit, sourceFile) {
|
|
5174
|
+
let systemPrompt;
|
|
5175
|
+
let tools;
|
|
5176
|
+
let agents;
|
|
5177
|
+
let model;
|
|
5178
|
+
let maxTurns;
|
|
5193
5179
|
for (const prop of objLit.properties) {
|
|
5194
|
-
if (
|
|
5180
|
+
if (ts9.isSpreadAssignment(prop)) continue;
|
|
5181
|
+
if (!ts9.isPropertyAssignment(prop)) {
|
|
5182
|
+
throw SchemaExtractionError.at(
|
|
5183
|
+
prop,
|
|
5184
|
+
"config",
|
|
5185
|
+
"\u4EC5\u652F\u6301 key: value \u5C5E\u6027\u5F62\u5F0F\uFF08\u4E0D\u652F\u6301 shorthand/\u65B9\u6CD5/getter\uFF09",
|
|
5186
|
+
sourceFile
|
|
5187
|
+
);
|
|
5188
|
+
}
|
|
5195
5189
|
const propName = getPropertyName(prop.name);
|
|
5196
|
-
if (!propName)
|
|
5190
|
+
if (!propName) {
|
|
5191
|
+
throw SchemaExtractionError.at(prop.name, "config", "\u4E0D\u652F\u6301 computed \u5C5E\u6027\u540D", sourceFile);
|
|
5192
|
+
}
|
|
5197
5193
|
switch (propName) {
|
|
5198
5194
|
case "systemPrompt":
|
|
5199
|
-
|
|
5195
|
+
systemPrompt = requireStringValue(prop, "systemPrompt", sourceFile);
|
|
5200
5196
|
break;
|
|
5201
5197
|
case "tools":
|
|
5202
|
-
|
|
5198
|
+
tools = requireStringArrayValue(prop, "tools", sourceFile);
|
|
5203
5199
|
break;
|
|
5204
5200
|
case "agents":
|
|
5205
|
-
|
|
5201
|
+
agents = requireStringArrayValue(prop, "agents", sourceFile);
|
|
5206
5202
|
break;
|
|
5207
5203
|
case "model":
|
|
5208
|
-
|
|
5204
|
+
model = requireStringValue(prop, "model", sourceFile);
|
|
5209
5205
|
break;
|
|
5210
5206
|
case "maxTurns":
|
|
5211
|
-
|
|
5207
|
+
maxTurns = requireNumberValue(prop, "maxTurns", sourceFile);
|
|
5212
5208
|
break;
|
|
5209
|
+
default:
|
|
5210
|
+
throw SchemaExtractionError.at(
|
|
5211
|
+
prop,
|
|
5212
|
+
`config.${propName}`,
|
|
5213
|
+
"\u672A\u77E5 config \u5B57\u6BB5\u2014\u2014\u4EC5\u652F\u6301 systemPrompt / tools / agents / model / maxTurns",
|
|
5214
|
+
sourceFile
|
|
5215
|
+
);
|
|
5213
5216
|
}
|
|
5214
5217
|
}
|
|
5215
|
-
|
|
5218
|
+
if (systemPrompt === void 0) {
|
|
5219
|
+
throw SchemaExtractionError.at(
|
|
5220
|
+
objLit,
|
|
5221
|
+
"config.systemPrompt",
|
|
5222
|
+
"agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF09",
|
|
5223
|
+
sourceFile
|
|
5224
|
+
);
|
|
5225
|
+
}
|
|
5226
|
+
return { systemPrompt, tools, agents, model, maxTurns };
|
|
5216
5227
|
}
|
|
5217
5228
|
function getPropertyName(name) {
|
|
5218
5229
|
if (ts9.isIdentifier(name)) return name.text;
|
|
@@ -5220,9 +5231,52 @@ function getPropertyName(name) {
|
|
|
5220
5231
|
return null;
|
|
5221
5232
|
}
|
|
5222
5233
|
function extractStringValue(expr) {
|
|
5223
|
-
if (
|
|
5234
|
+
if (isStringLikeLiteral(expr)) return expr.text;
|
|
5235
|
+
if (ts9.isBinaryExpression(expr) && expr.operatorToken.kind === ts9.SyntaxKind.PlusToken) {
|
|
5236
|
+
const left = extractStringValue(expr.left);
|
|
5237
|
+
if (left === void 0) return void 0;
|
|
5238
|
+
const right = extractStringValue(expr.right);
|
|
5239
|
+
if (right === void 0) return void 0;
|
|
5240
|
+
return left + right;
|
|
5241
|
+
}
|
|
5224
5242
|
return void 0;
|
|
5225
5243
|
}
|
|
5244
|
+
function requireStringValue(prop, fieldName, sourceFile) {
|
|
5245
|
+
const value = extractStringValue(prop.initializer);
|
|
5246
|
+
if (value === void 0) {
|
|
5247
|
+
throw SchemaExtractionError.at(
|
|
5248
|
+
prop.initializer,
|
|
5249
|
+
`config.${fieldName}`,
|
|
5250
|
+
"\u4EC5\u652F\u6301\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF08\u542B\u63D2\u503C\u7684\u6A21\u677F\u5B57\u7B26\u4E32/\u53D8\u91CF\u5F15\u7528/\u6570\u5B57\u65E0\u6CD5\u9759\u6001\u6C42\u503C\u4E3A\u5B57\u7B26\u4E32\uFF09",
|
|
5251
|
+
sourceFile
|
|
5252
|
+
);
|
|
5253
|
+
}
|
|
5254
|
+
return value;
|
|
5255
|
+
}
|
|
5256
|
+
function requireStringArrayValue(prop, fieldName, sourceFile) {
|
|
5257
|
+
const value = extractStringArrayValue(prop.initializer);
|
|
5258
|
+
if (value === void 0) {
|
|
5259
|
+
throw SchemaExtractionError.at(
|
|
5260
|
+
prop.initializer,
|
|
5261
|
+
`config.${fieldName}`,
|
|
5262
|
+
"\u4EC5\u652F\u6301\u5168\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u6570\u7EC4\uFF08\u5143\u7D20\u4E3A\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF09",
|
|
5263
|
+
sourceFile
|
|
5264
|
+
);
|
|
5265
|
+
}
|
|
5266
|
+
return value;
|
|
5267
|
+
}
|
|
5268
|
+
function requireNumberValue(prop, fieldName, sourceFile) {
|
|
5269
|
+
const value = extractNumberValue(prop.initializer);
|
|
5270
|
+
if (value === void 0) {
|
|
5271
|
+
throw SchemaExtractionError.at(
|
|
5272
|
+
prop.initializer,
|
|
5273
|
+
`config.${fieldName}`,
|
|
5274
|
+
"\u4EC5\u652F\u6301\u6570\u5B57\u5B57\u9762\u91CF",
|
|
5275
|
+
sourceFile
|
|
5276
|
+
);
|
|
5277
|
+
}
|
|
5278
|
+
return value;
|
|
5279
|
+
}
|
|
5226
5280
|
function extractNumberValue(expr) {
|
|
5227
5281
|
if (ts9.isNumericLiteral(expr)) {
|
|
5228
5282
|
const num = Number(expr.text);
|
|
@@ -5230,12 +5284,16 @@ function extractNumberValue(expr) {
|
|
|
5230
5284
|
}
|
|
5231
5285
|
return void 0;
|
|
5232
5286
|
}
|
|
5287
|
+
function isStringLikeLiteral(node) {
|
|
5288
|
+
return ts9.isStringLiteral(node) || ts9.isNoSubstitutionTemplateLiteral(node);
|
|
5289
|
+
}
|
|
5233
5290
|
function extractStringArrayValue(expr) {
|
|
5234
5291
|
if (!ts9.isArrayLiteralExpression(expr)) return void 0;
|
|
5235
5292
|
const values = [];
|
|
5236
5293
|
for (const element of expr.elements) {
|
|
5237
|
-
|
|
5238
|
-
|
|
5294
|
+
const value = extractStringValue(element);
|
|
5295
|
+
if (value === void 0) return void 0;
|
|
5296
|
+
values.push(value);
|
|
5239
5297
|
}
|
|
5240
5298
|
return values;
|
|
5241
5299
|
}
|
|
@@ -5276,6 +5334,28 @@ function hydrateAgents(manifest) {
|
|
|
5276
5334
|
maxTurns: a.maxTurns ?? void 0
|
|
5277
5335
|
}));
|
|
5278
5336
|
}
|
|
5337
|
+
function validateAgentList(metadata) {
|
|
5338
|
+
const names = /* @__PURE__ */ new Map();
|
|
5339
|
+
for (const a of metadata) {
|
|
5340
|
+
const prev = names.get(a.name);
|
|
5341
|
+
if (prev) {
|
|
5342
|
+
throw new Error(
|
|
5343
|
+
`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`
|
|
5344
|
+
);
|
|
5345
|
+
}
|
|
5346
|
+
names.set(a.name, a.filePath);
|
|
5347
|
+
}
|
|
5348
|
+
for (const a of metadata) {
|
|
5349
|
+
for (const ref of a.agents ?? []) {
|
|
5350
|
+
if (!names.has(ref)) {
|
|
5351
|
+
const available = [...names.keys()].join(", ") || "\u65E0";
|
|
5352
|
+
throw new Error(
|
|
5353
|
+
`agent "${a.name}" \u7684 agents \u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684 agent: "${ref}"\uFF08\u6E05\u5355\u4E2D\u53EF\u7528: ${available}\uFF09`
|
|
5354
|
+
);
|
|
5355
|
+
}
|
|
5356
|
+
}
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5279
5359
|
async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
5280
5360
|
const metadata = [];
|
|
5281
5361
|
const programByFile = createPrograms(agents.map((m) => path17.resolve(rootDir, m.filePath)));
|
|
@@ -5287,10 +5367,14 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
|
5287
5367
|
filePath: manifest.filePath,
|
|
5288
5368
|
hasRun: manifest.hasRun
|
|
5289
5369
|
});
|
|
5290
|
-
if (result) {
|
|
5291
|
-
|
|
5370
|
+
if (!result) {
|
|
5371
|
+
throw new Error(
|
|
5372
|
+
`agent "${manifest.name}" \u6E90\u6587\u4EF6\u4E0D\u5728 Program \u4E2D: ${manifest.filePath}\u2014\u2014\u65E0\u6CD5\u751F\u6210\u6E05\u5355`
|
|
5373
|
+
);
|
|
5292
5374
|
}
|
|
5375
|
+
metadata.push(result);
|
|
5293
5376
|
}
|
|
5377
|
+
validateAgentList(metadata);
|
|
5294
5378
|
const serialized = serializeAgents(metadata, dist);
|
|
5295
5379
|
const agentsPath = path17.resolve(rootDir, dist, AGENTS_FILE);
|
|
5296
5380
|
await writeAgentsModule(serialized, agentsPath);
|