@faapi/faapi 5.0.0 → 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/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-DG0eL3l5.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-DG0eL3l5.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\u6216\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\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\u6216\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\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,45 @@ function getPropertyName(name) {
|
|
|
5220
5231
|
return null;
|
|
5221
5232
|
}
|
|
5222
5233
|
function extractStringValue(expr) {
|
|
5223
|
-
if (
|
|
5234
|
+
if (isStringLikeLiteral(expr)) return expr.text;
|
|
5224
5235
|
return void 0;
|
|
5225
5236
|
}
|
|
5237
|
+
function requireStringValue(prop, fieldName, sourceFile) {
|
|
5238
|
+
const value = extractStringValue(prop.initializer);
|
|
5239
|
+
if (value === void 0) {
|
|
5240
|
+
throw SchemaExtractionError.at(
|
|
5241
|
+
prop.initializer,
|
|
5242
|
+
`config.${fieldName}`,
|
|
5243
|
+
"\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",
|
|
5244
|
+
sourceFile
|
|
5245
|
+
);
|
|
5246
|
+
}
|
|
5247
|
+
return value;
|
|
5248
|
+
}
|
|
5249
|
+
function requireStringArrayValue(prop, fieldName, sourceFile) {
|
|
5250
|
+
const value = extractStringArrayValue(prop.initializer);
|
|
5251
|
+
if (value === void 0) {
|
|
5252
|
+
throw SchemaExtractionError.at(
|
|
5253
|
+
prop.initializer,
|
|
5254
|
+
`config.${fieldName}`,
|
|
5255
|
+
"\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",
|
|
5256
|
+
sourceFile
|
|
5257
|
+
);
|
|
5258
|
+
}
|
|
5259
|
+
return value;
|
|
5260
|
+
}
|
|
5261
|
+
function requireNumberValue(prop, fieldName, sourceFile) {
|
|
5262
|
+
const value = extractNumberValue(prop.initializer);
|
|
5263
|
+
if (value === void 0) {
|
|
5264
|
+
throw SchemaExtractionError.at(
|
|
5265
|
+
prop.initializer,
|
|
5266
|
+
`config.${fieldName}`,
|
|
5267
|
+
"\u4EC5\u652F\u6301\u6570\u5B57\u5B57\u9762\u91CF",
|
|
5268
|
+
sourceFile
|
|
5269
|
+
);
|
|
5270
|
+
}
|
|
5271
|
+
return value;
|
|
5272
|
+
}
|
|
5226
5273
|
function extractNumberValue(expr) {
|
|
5227
5274
|
if (ts9.isNumericLiteral(expr)) {
|
|
5228
5275
|
const num = Number(expr.text);
|
|
@@ -5230,11 +5277,14 @@ function extractNumberValue(expr) {
|
|
|
5230
5277
|
}
|
|
5231
5278
|
return void 0;
|
|
5232
5279
|
}
|
|
5280
|
+
function isStringLikeLiteral(node) {
|
|
5281
|
+
return ts9.isStringLiteral(node) || ts9.isNoSubstitutionTemplateLiteral(node);
|
|
5282
|
+
}
|
|
5233
5283
|
function extractStringArrayValue(expr) {
|
|
5234
5284
|
if (!ts9.isArrayLiteralExpression(expr)) return void 0;
|
|
5235
5285
|
const values = [];
|
|
5236
5286
|
for (const element of expr.elements) {
|
|
5237
|
-
if (!
|
|
5287
|
+
if (!isStringLikeLiteral(element)) return void 0;
|
|
5238
5288
|
values.push(element.text);
|
|
5239
5289
|
}
|
|
5240
5290
|
return values;
|
|
@@ -5276,6 +5326,28 @@ function hydrateAgents(manifest) {
|
|
|
5276
5326
|
maxTurns: a.maxTurns ?? void 0
|
|
5277
5327
|
}));
|
|
5278
5328
|
}
|
|
5329
|
+
function validateAgentList(metadata) {
|
|
5330
|
+
const names = /* @__PURE__ */ new Map();
|
|
5331
|
+
for (const a of metadata) {
|
|
5332
|
+
const prev = names.get(a.name);
|
|
5333
|
+
if (prev) {
|
|
5334
|
+
throw new Error(
|
|
5335
|
+
`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`
|
|
5336
|
+
);
|
|
5337
|
+
}
|
|
5338
|
+
names.set(a.name, a.filePath);
|
|
5339
|
+
}
|
|
5340
|
+
for (const a of metadata) {
|
|
5341
|
+
for (const ref of a.agents ?? []) {
|
|
5342
|
+
if (!names.has(ref)) {
|
|
5343
|
+
const available = [...names.keys()].join(", ") || "\u65E0";
|
|
5344
|
+
throw new Error(
|
|
5345
|
+
`agent "${a.name}" \u7684 agents \u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684 agent: "${ref}"\uFF08\u6E05\u5355\u4E2D\u53EF\u7528: ${available}\uFF09`
|
|
5346
|
+
);
|
|
5347
|
+
}
|
|
5348
|
+
}
|
|
5349
|
+
}
|
|
5350
|
+
}
|
|
5279
5351
|
async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
5280
5352
|
const metadata = [];
|
|
5281
5353
|
const programByFile = createPrograms(agents.map((m) => path17.resolve(rootDir, m.filePath)));
|
|
@@ -5287,10 +5359,14 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
|
5287
5359
|
filePath: manifest.filePath,
|
|
5288
5360
|
hasRun: manifest.hasRun
|
|
5289
5361
|
});
|
|
5290
|
-
if (result) {
|
|
5291
|
-
|
|
5362
|
+
if (!result) {
|
|
5363
|
+
throw new Error(
|
|
5364
|
+
`agent "${manifest.name}" \u6E90\u6587\u4EF6\u4E0D\u5728 Program \u4E2D: ${manifest.filePath}\u2014\u2014\u65E0\u6CD5\u751F\u6210\u6E05\u5355`
|
|
5365
|
+
);
|
|
5292
5366
|
}
|
|
5367
|
+
metadata.push(result);
|
|
5293
5368
|
}
|
|
5369
|
+
validateAgentList(metadata);
|
|
5294
5370
|
const serialized = serializeAgents(metadata, dist);
|
|
5295
5371
|
const agentsPath = path17.resolve(rootDir, dist, AGENTS_FILE);
|
|
5296
5372
|
await writeAgentsModule(serialized, agentsPath);
|