@faapi/faapi 6.28.0 → 6.30.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 +37 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +16 -20
- package/dist/index.js +36 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -480,15 +480,6 @@ interface AgentConfig {
|
|
|
480
480
|
* 详见 `@faapi/agent` 的 [trace](../../agent/src/trace.md) 文档。
|
|
481
481
|
*/
|
|
482
482
|
enableTracing?: boolean;
|
|
483
|
-
/**
|
|
484
|
-
* 执行守卫(authHooks,见 @faapi/agent 的 authHooks 文档)
|
|
485
|
-
*
|
|
486
|
-
* 每次 tool / sub-agent 执行前调用(`agent.x` 名称为 sub-agent 递归)。
|
|
487
|
-
* 三种返回:`void` 放行;`{ error }` 拒绝(不执行,error 回传 LLM 调整策略);
|
|
488
|
-
* `{ args }` 改写后放行(多租户场景强制注入可信值,不信 LLM 传入的标识参数)。
|
|
489
|
-
*
|
|
490
|
-
* 典型用法:中间件解析 `ctx.workspace` 后在此校验/强制改写 `args.workspaceId`。
|
|
491
|
-
*/
|
|
492
483
|
/**
|
|
493
484
|
* 发送给 LLM 的历史 token 预算(近似估算,未设置 = 不裁剪)
|
|
494
485
|
*
|
|
@@ -498,7 +489,20 @@ interface AgentConfig {
|
|
|
498
489
|
* reactLoop 文档历史裁剪章节。
|
|
499
490
|
*/
|
|
500
491
|
maxHistoryTokens?: number;
|
|
501
|
-
|
|
492
|
+
/**
|
|
493
|
+
* 执行守卫(authHooks,见 @faapi/agent 的 authHooks 文档)
|
|
494
|
+
*
|
|
495
|
+
* 每次 tool / sub-agent 执行前调用(`agent-x` 派发名称为 sub-agent 递归)。
|
|
496
|
+
* 三种返回:`void` 放行;`{ error }` 拒绝(不执行,error 回传 LLM 调整策略);
|
|
497
|
+
* `{ args }` 改写后放行(多租户场景强制注入可信值,不信 LLM 传入的标识参数)。
|
|
498
|
+
*
|
|
499
|
+
* ctx 为请求上下文透传(`Partial<FaapiContext>`,框架零读取):HTTP 请求是完整
|
|
500
|
+
* ctx,任务内组装 Agent 时业务方显式传窄对象(如鉴权硬闸需要的
|
|
501
|
+
* `{ currentUserId }`),编程式直调为 undefined。
|
|
502
|
+
*
|
|
503
|
+
* 典型用法:中间件解析 `ctx.workspace` 后在此校验/强制改写 `args.workspaceId`。
|
|
504
|
+
*/
|
|
505
|
+
beforeToolCall?: (name: string, args: Record<string, unknown>, ctx: Partial<FaapiContext> | undefined) => void | {
|
|
502
506
|
error: string;
|
|
503
507
|
} | {
|
|
504
508
|
args: Record<string, unknown>;
|
|
@@ -507,7 +511,7 @@ interface AgentConfig {
|
|
|
507
511
|
* 审计钩子(authHooks):tool / sub-agent 成功返回后调用,返回值忽略。
|
|
508
512
|
* 用于日志/审计/计量;异常路径不调用。
|
|
509
513
|
*/
|
|
510
|
-
afterToolCall?: (name: string, args: Record<string, unknown>, result: unknown, ctx: FaapiContext | undefined) => void;
|
|
514
|
+
afterToolCall?: (name: string, args: Record<string, unknown>, result: unknown, ctx: Partial<FaapiContext> | undefined) => void;
|
|
511
515
|
/**
|
|
512
516
|
* 可见性过滤(authHooks):LLM 可见 tools 清单组装完成后调用,
|
|
513
517
|
* 返回过滤后的数组(含 agent-as-tool 项)。每次 agent.run / stream 生效——
|
|
@@ -523,7 +527,7 @@ interface AgentConfig {
|
|
|
523
527
|
description?: string;
|
|
524
528
|
parameters?: Record<string, unknown>;
|
|
525
529
|
};
|
|
526
|
-
}>, ctx: FaapiContext | undefined) => Array<{
|
|
530
|
+
}>, ctx: Partial<FaapiContext> | undefined) => Array<{
|
|
527
531
|
type: 'function';
|
|
528
532
|
function: {
|
|
529
533
|
name: string;
|
|
@@ -1684,14 +1688,6 @@ interface AppBase {
|
|
|
1684
1688
|
* 业务方定位任意产物文件时与 rootDir 配合使用。
|
|
1685
1689
|
*/
|
|
1686
1690
|
dist: string;
|
|
1687
|
-
/**
|
|
1688
|
-
* 运行时资源根目录绝对路径(<rootDir>/<dist>/resources)
|
|
1689
|
-
*
|
|
1690
|
-
* `src/resources/` 经 dev/build 复制进产物后的位置,业务方
|
|
1691
|
-
* `path.join(app.resourcesDir, 'prompts/foo.md')` 后自行读取。
|
|
1692
|
-
* 源码无 `src/resources/` 目录时路径仍指向约定位置(读文件由业务方容错)。
|
|
1693
|
-
*/
|
|
1694
|
-
resourcesDir: string;
|
|
1695
1691
|
/** 任务队列客户端(入队/查询;app 实例级,close 时随队列停机) */
|
|
1696
1692
|
tasks: TaskClient;
|
|
1697
1693
|
/** 启动 HTTP server,打印路由表,执行 onReady 钩子 */
|
package/dist/index.js
CHANGED
|
@@ -2864,6 +2864,34 @@ var CONCURRENCY_RE = new RegExp(`(?:^|\\n)\\s*concurrency:\\s*${NUM_LITERAL}`);
|
|
|
2864
2864
|
var RETRIES_RE = new RegExp(`(?:^|\\n)\\s*retries:\\s*${NUM_LITERAL}`);
|
|
2865
2865
|
var TIMEOUT_MS_RE = new RegExp(`(?:^|\\n)\\s*timeoutMs:\\s*${NUM_LITERAL}`);
|
|
2866
2866
|
var GRACE_MS_RE = new RegExp(`(?:^|\\n)\\s*graceMs:\\s*${NUM_LITERAL}`);
|
|
2867
|
+
var NUMERIC_META_FIELDS = ["concurrency", "retries", "timeoutMs", "graceMs"];
|
|
2868
|
+
var STRING_META_FIELDS = ["cron"];
|
|
2869
|
+
var ALL_META_FIELDS = [...NUMERIC_META_FIELDS, ...STRING_META_FIELDS];
|
|
2870
|
+
function detectIgnoredMetaFields(source, strictHit) {
|
|
2871
|
+
const declared = /* @__PURE__ */ new Set();
|
|
2872
|
+
for (const line of source.split("\n")) {
|
|
2873
|
+
const trimmed = line.trim();
|
|
2874
|
+
if (trimmed.startsWith("//")) continue;
|
|
2875
|
+
for (const field of ALL_META_FIELDS) {
|
|
2876
|
+
if (new RegExp(`\\b${field}\\s*:`).test(trimmed)) declared.add(field);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
return ALL_META_FIELDS.filter((field) => declared.has(field) && !strictHit[field]);
|
|
2880
|
+
}
|
|
2881
|
+
function warnIgnoredMetaFields(name, fields) {
|
|
2882
|
+
for (const field of fields) {
|
|
2883
|
+
if (STRING_META_FIELDS.includes(field)) {
|
|
2884
|
+
console.warn(
|
|
2885
|
+
`[faapi] Task "${name}" declares "${field}" but its value is not a string literal \u2014 the declaration was ignored and the task will not be cron-scheduled. Meta values are extracted from source code without importing it, so only literal values are recognized: use a quoted literal (cron: '0 3 * * *'), not an expression or a dynamic value.`
|
|
2886
|
+
);
|
|
2887
|
+
} else {
|
|
2888
|
+
const consequence = field === "timeoutMs" ? " and the task will run in-process with no timeout" : "";
|
|
2889
|
+
console.warn(
|
|
2890
|
+
`[faapi] Task "${name}" declares "${field}" but its value is not a numeric literal \u2014 the declaration was ignored${consequence}. Meta values are extracted from source code without importing it, so only literal values are recognized (underscores allowed, e.g. 1_800_000); expressions like 30 * 60_000 or dynamic values are not supported.`
|
|
2891
|
+
);
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2867
2895
|
function parseNumericLiteral(raw) {
|
|
2868
2896
|
return Number(raw.replace(/_/g, ""));
|
|
2869
2897
|
}
|
|
@@ -2925,6 +2953,14 @@ async function scanTasks(rootDir, patterns) {
|
|
|
2925
2953
|
manifest.timeoutMs = value;
|
|
2926
2954
|
}
|
|
2927
2955
|
if (graceMs !== void 0) manifest.graceMs = parseNumericLiteral(graceMs);
|
|
2956
|
+
const strictHit = {
|
|
2957
|
+
cron: cron !== void 0,
|
|
2958
|
+
concurrency: concurrency !== void 0,
|
|
2959
|
+
retries: retries !== void 0,
|
|
2960
|
+
timeoutMs: timeoutMs !== void 0,
|
|
2961
|
+
graceMs: graceMs !== void 0
|
|
2962
|
+
};
|
|
2963
|
+
warnIgnoredMetaFields(name, detectIgnoredMetaFields(source, strictHit));
|
|
2928
2964
|
tasks.push(manifest);
|
|
2929
2965
|
}
|
|
2930
2966
|
return tasks.sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -7603,7 +7639,6 @@ async function createAppBase(options) {
|
|
|
7603
7639
|
wsRoutes,
|
|
7604
7640
|
rootDir,
|
|
7605
7641
|
dist,
|
|
7606
|
-
resourcesDir,
|
|
7607
7642
|
tasks: taskQueue,
|
|
7608
7643
|
async listen(listenPort) {
|
|
7609
7644
|
const envPort = process.env.PORT ? Number(process.env.PORT) : void 0;
|