@ai-setting/roy-agent-core 1.7.85 → 1.7.89
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/config/index.js +7 -7
- package/dist/env/agent/agent-component.d.ts +1 -1
- package/dist/env/agent/agent-component.js +13 -12
- package/dist/env/agent/index.js +13 -12
- package/dist/env/agent/types.d.ts +14 -0
- package/dist/env/commands/index.js +7 -7
- package/dist/env/context/index.js +3 -3
- package/dist/env/debug/index.js +7 -7
- package/dist/env/error-reply.js +1 -1
- package/dist/env/event-source/event-source-handlers.d.ts +18 -2
- package/dist/env/event-source/event-source-handlers.js +26 -21
- package/dist/env/event-source/event-store.js +2 -2
- package/dist/env/event-source/index.js +25 -22
- package/dist/env/event-source/timer-handler.d.ts +98 -0
- package/dist/env/event-source/types.d.ts +53 -1
- package/dist/env/event-source/wecom-card-action-handler.d.ts +235 -3
- package/dist/env/event-source/wecom-card-builder.d.ts +207 -1
- package/dist/env/event-source/wecom-cli-handler.d.ts +25 -0
- package/dist/{shared/@ai-setting/roy-agent-core-vyr6svt6.js → env/event-source/wecom-respond-registry.js} +8 -6
- package/dist/env/event-source/wecom-session-card-sender.d.ts +135 -0
- package/dist/env/event-source/wecom-session-card-sender.js +153 -0
- package/dist/env/hook/index.js +5 -5
- package/dist/env/index.js +50 -45
- package/dist/env/llm/index.js +9 -8
- package/dist/env/log-trace/index.js +7 -7
- package/dist/env/log-trace/trace-filters.d.ts +6 -1
- package/dist/env/mcp/index.js +7 -7
- package/dist/env/memory/index.js +7 -7
- package/dist/env/plugin/index.js +7 -7
- package/dist/env/prompt/index.js +8 -8
- package/dist/env/prompt/prompts-index.d.ts +1 -1
- package/dist/env/session/group-session-link.d.ts +99 -0
- package/dist/env/session/index.js +11 -10
- package/dist/env/session/session-component.d.ts +89 -0
- package/dist/env/session/storage/index.js +5 -4
- package/dist/env/session/types.d.ts +10 -0
- package/dist/env/skill/index.js +7 -7
- package/dist/env/task/backend/index.d.ts +3 -0
- package/dist/env/task/backend/index.js +151 -3
- package/dist/env/task/backend/remote-task-port.d.ts +85 -0
- package/dist/env/task/backend/types.d.ts +5 -0
- package/dist/env/task/delegate/delegate-channel-hint.d.ts +39 -0
- package/dist/env/task/delegate/delegate-tool.d.ts +71 -6
- package/dist/env/task/delegate/delegate-tool.js +11 -9
- package/dist/env/task/delegate/index.js +8 -8
- package/dist/env/task/index.d.ts +1 -1
- package/dist/env/task/index.js +34 -18
- package/dist/env/task/mcp/index.js +4 -4
- package/dist/env/task/plugins/card-subject.d.ts +117 -0
- package/dist/env/task/plugins/index.js +19 -17
- package/dist/env/task/plugins/lark-card-action-handler.d.ts +261 -6
- package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +501 -0
- package/dist/env/task/plugins/lark-card-patch-notifier.js +12 -2
- package/dist/env/task/plugins/lark-card-state-store.d.ts +60 -0
- package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +45 -0
- package/dist/env/task/plugins/sub-session-activity.d.ts +415 -0
- package/dist/env/task/plugins/wecom-session-card-store.d.ts +134 -0
- package/dist/env/task/plugins/wecom-session-card-store.js +23 -0
- package/dist/env/task/plugins/wecom-task-notify-plugin.d.ts +40 -0
- package/dist/env/task/storage/index.d.ts +1 -0
- package/dist/env/task/storage/index.js +24 -4
- package/dist/env/task/storage/migrations/006_add_task_owner.d.ts +24 -0
- package/dist/env/task/storage/remote-task-store.d.ts +186 -0
- package/dist/env/task/task-component.d.ts +7 -0
- package/dist/env/task/tools/index.js +4 -4
- package/dist/env/task/tools/task-types.d.ts +7 -0
- package/dist/env/task/types.d.ts +17 -0
- package/dist/env/tool/built-in/index.js +6 -4
- package/dist/env/tool/index.js +14 -10
- package/dist/env/tool/types.d.ts +25 -0
- package/dist/env/tool/validator.d.ts +8 -0
- package/dist/env/workflow/engine/index.js +12 -12
- package/dist/env/workflow/hooks/index.js +7 -7
- package/dist/env/workflow/index.js +24 -23
- package/dist/env/workflow/nodes/index.js +2 -2
- package/dist/env/workflow/plugins/index.js +10 -8
- package/dist/env/workflow/service/index.js +2 -2
- package/dist/env/workflow/storage/index.js +3 -3
- package/dist/env/workflow/tools/index.js +16 -15
- package/dist/env/workflow/utils/index.js +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +71 -60
- package/dist/shared/@ai-setting/{roy-agent-core-q813vafd.js → roy-agent-core-05z35shp.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-dc9zq75z.js → roy-agent-core-0crmsc12.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-7dd0s3xb.js → roy-agent-core-0n1wwndq.js} +1027 -14
- package/dist/shared/@ai-setting/{roy-agent-core-cha0jc7n.js → roy-agent-core-0sbmdz8d.js} +137 -16
- package/dist/shared/@ai-setting/{roy-agent-core-87942bw4.js → roy-agent-core-1mhyh4c5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-v6vr6za7.js → roy-agent-core-1vv4fx15.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-nwbfepba.js → roy-agent-core-3e040tc5.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-418zc9ha.js +288 -0
- package/dist/shared/@ai-setting/{roy-agent-core-qk9hd89p.js → roy-agent-core-49qcpqwg.js} +54 -19
- package/dist/shared/@ai-setting/{roy-agent-core-xf6z96qy.js → roy-agent-core-4b38m749.js} +818 -346
- package/dist/shared/@ai-setting/{roy-agent-core-r5wt1h3c.js → roy-agent-core-4fkxy2gv.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-na18zwj0.js → roy-agent-core-4t3yskp8.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-d1n4jbza.js → roy-agent-core-5dhvfgaw.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-5pr4zp88.js → roy-agent-core-5kzhaap1.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qq96p0tj.js → roy-agent-core-5s2t8z00.js} +22 -1
- package/dist/shared/@ai-setting/{roy-agent-core-6rh8k6ba.js → roy-agent-core-6gj1hc5z.js} +7 -7
- package/dist/shared/@ai-setting/{roy-agent-core-g8htfwxj.js → roy-agent-core-7f10p7m2.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-h21gngxf.js → roy-agent-core-7yh5wps0.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-efkjyh69.js → roy-agent-core-9710zwwz.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-rykf7c04.js → roy-agent-core-9c565frx.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-vffccgf6.js → roy-agent-core-9cen1jvg.js} +18 -7
- package/dist/shared/@ai-setting/{roy-agent-core-fghc2m8z.js → roy-agent-core-aa8kv18f.js} +34 -2
- package/dist/shared/@ai-setting/roy-agent-core-age3qseb.js +177 -0
- package/dist/shared/@ai-setting/{roy-agent-core-7bpj859q.js → roy-agent-core-azyz78ky.js} +7 -7
- package/dist/shared/@ai-setting/{roy-agent-core-264qexac.js → roy-agent-core-b7h39vrc.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-dqxec05w.js → roy-agent-core-bjtc9d35.js} +2 -2
- package/dist/shared/@ai-setting/roy-agent-core-c4ec7k0p.js +426 -0
- package/dist/shared/@ai-setting/{roy-agent-core-ddyk1rc0.js → roy-agent-core-cre2y2ct.js} +160 -4
- package/dist/shared/@ai-setting/{roy-agent-core-tr3ep81v.js → roy-agent-core-d6zdbgtc.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-0qyrk5k0.js → roy-agent-core-ds6qzmf8.js} +14 -5
- package/dist/shared/@ai-setting/{roy-agent-core-p6ks90tb.js → roy-agent-core-dvec4nn2.js} +6 -6
- package/dist/shared/@ai-setting/{roy-agent-core-cgtq6427.js → roy-agent-core-e08bvpaq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-12n08pg5.js → roy-agent-core-e69qxdyy.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-xcp8vwax.js → roy-agent-core-fepm835e.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-6j02sbee.js → roy-agent-core-fhg03v43.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-dvtg4sn0.js → roy-agent-core-g8yr733d.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-m3vjepzz.js → roy-agent-core-h1e1fm9b.js} +38 -202
- package/dist/shared/@ai-setting/{roy-agent-core-c2gbt68e.js → roy-agent-core-h83zdsrq.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-tk98f92b.js → roy-agent-core-k3gcvybs.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-b31v3qpv.js → roy-agent-core-k3h8t4q1.js} +992 -212
- package/dist/shared/@ai-setting/{roy-agent-core-pgvcf91v.js → roy-agent-core-m39v7qpx.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-ezvpreqz.js → roy-agent-core-m66ysky0.js} +54 -6
- package/dist/shared/@ai-setting/{roy-agent-core-begm7ytz.js → roy-agent-core-m7d1t3db.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-tm1mxttk.js → roy-agent-core-mf5p38yf.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-83bewqx8.js → roy-agent-core-mvh0td7p.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-ze5cqpf2.js → roy-agent-core-mx855td4.js} +17 -38
- package/dist/shared/@ai-setting/{roy-agent-core-0dh8npnz.js → roy-agent-core-n197medr.js} +13 -13
- package/dist/shared/@ai-setting/{roy-agent-core-cmprygrp.js → roy-agent-core-nqkfkpf4.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-7cbpmk4q.js → roy-agent-core-p31ftgq9.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-1v4g0d4x.js → roy-agent-core-rm7seqwb.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-ax9e9szb.js → roy-agent-core-smf94h73.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-acj8ag08.js → roy-agent-core-tjnabyvq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qqaak24r.js → roy-agent-core-tkpp1ba0.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-dkrvmjsh.js → roy-agent-core-tpm1dd1g.js} +23 -15
- package/dist/shared/@ai-setting/{roy-agent-core-ed233k5z.js → roy-agent-core-v1n0106v.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-zxz5fkwj.js → roy-agent-core-v6yshv0z.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mcy5apay.js → roy-agent-core-vf9sp6s3.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-xvt7kf7p.js → roy-agent-core-w9ryeg2p.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-es203w7p.js → roy-agent-core-wqs6yypq.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-wxrkcb17.js +56 -0
- package/dist/shared/@ai-setting/{roy-agent-core-0snm5hc5.js → roy-agent-core-y6shd91r.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-9vxh6f8h.js → roy-agent-core-y7fqtzk2.js} +7 -7
- package/dist/shared/@ai-setting/{roy-agent-core-cpcd24n2.js → roy-agent-core-yet36q5k.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-3fh1f7s7.js → roy-agent-core-yfpnkc4z.js} +5 -5
- package/dist/shared/@ai-setting/roy-agent-core-zhwcje5a.js +352 -0
- package/package.json +9 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/env/tool/validator.ts
|
|
2
|
+
import { ZodError } from "zod";
|
|
3
|
+
var REASON_REQUIRED_CONFIG_KEY = "tool.reason.required";
|
|
4
|
+
var moduleLevelReasonRequired = true;
|
|
5
|
+
var configComponentRef = null;
|
|
6
|
+
function setToolReasonConfigComponent(component) {
|
|
7
|
+
configComponentRef = component;
|
|
8
|
+
}
|
|
9
|
+
function isToolReasonRequired() {
|
|
10
|
+
if (configComponentRef) {
|
|
11
|
+
const v = configComponentRef.get(REASON_REQUIRED_CONFIG_KEY);
|
|
12
|
+
if (typeof v === "boolean")
|
|
13
|
+
return v;
|
|
14
|
+
if (typeof v === "string")
|
|
15
|
+
return v !== "false";
|
|
16
|
+
}
|
|
17
|
+
return moduleLevelReasonRequired;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class ToolValidator {
|
|
21
|
+
async validate(tool, args) {
|
|
22
|
+
if (isToolReasonRequired()) {
|
|
23
|
+
const reason = args?.["reason"];
|
|
24
|
+
if (typeof reason !== "string" || reason.trim() === "") {
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
error: `Missing or empty required parameter 'reason' for tool '${tool.name}': ` + `provide a one-sentence explanation of why you are calling this tool.`
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const parsed = await tool.parameters.parseAsync(args);
|
|
33
|
+
return {
|
|
34
|
+
success: true,
|
|
35
|
+
data: parsed
|
|
36
|
+
};
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (error instanceof ZodError) {
|
|
39
|
+
const errorMessage = tool.formatValidationError ? tool.formatValidationError(error) : this.formatError(error);
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: `Invalid arguments for tool '${tool.name}': ${errorMessage}`
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
success: false,
|
|
47
|
+
error: `Validation error: ${error}`
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
formatError(error) {
|
|
52
|
+
return error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { setToolReasonConfigComponent, isToolReasonRequired, ToolValidator };
|
|
@@ -439,7 +439,7 @@ subSessionId: sub-session-xyz
|
|
|
439
439
|
| session 规模 | 建议处置 |
|
|
440
440
|
|---|---|
|
|
441
441
|
| **小**(超限比例 < 30%,消息数不多) | 直接 \`compact_session\` → 压缩成功后用 \`sub_session_id\` 续跑 |
|
|
442
|
-
| **大**(超限比例很高 / 消息数很多) | \`compact_session\` **可能要跑很久甚至撞 120s 工具超时** → **不要在同一个 session
|
|
442
|
+
| **大**(超限比例很高 / 消息数很多) | \`compact_session\` **可能要跑很久甚至撞 120s 工具超时** → **不要在同一个 session 上死磕**,走下面的**兜底路径**(压缩复查 → 仍无效才开新 session)+ 明确列出「已完成项 / 断点 / 小目标」 |
|
|
443
443
|
|
|
444
444
|
**为什么必须先评估**(实测数据):
|
|
445
445
|
|
|
@@ -474,7 +474,7 @@ const r = await compact_session({ session_id: "sub-session-xyz" });
|
|
|
474
474
|
2. **再检查一次**该 session 的**消息数 / checkpoint** —— \`compact_session\` 成功会返回 \`checkpointId\`,也可以用 session 相关工具确认消息是否已被 archived
|
|
475
475
|
3. 再决定走哪条路:
|
|
476
476
|
- **压缩其实成功了** → 用 \`sub_session_id\` 续跑(上下文已经变小,安全)
|
|
477
|
-
- **压缩确实没生效** →
|
|
477
|
+
- **压缩确实没生效** → 才走下面的兜底路径(换新 session)
|
|
478
478
|
|
|
479
479
|
**第 3 步:带同一个 \`sub_session_id\` 续跑**
|
|
480
480
|
|
|
@@ -502,9 +502,9 @@ delegate_task({
|
|
|
502
502
|
|
|
503
503
|
\`\`\`typescript
|
|
504
504
|
delegate_task({
|
|
505
|
-
description: "
|
|
505
|
+
description: "接续工作(上下文已超限,压缩复查后仍不可救,换新 session)",
|
|
506
506
|
prompt: "【已完成】... \\n【断点】... \\n【小目标】... \\n【相关文件路径】... \\n【已知结论】...",
|
|
507
|
-
//
|
|
507
|
+
sub_session_id: "sub-session-xyz", // ⚠️ 兜底路径:仅在 compact_session 也无效时才省略
|
|
508
508
|
});
|
|
509
509
|
\`\`\`
|
|
510
510
|
|
|
@@ -512,9 +512,9 @@ delegate_task({
|
|
|
512
512
|
|
|
513
513
|
#### ❌ 反模式警示
|
|
514
514
|
|
|
515
|
-
- ❌
|
|
516
|
-
- ❌ **不要在压缩失败时反复用同一个 session 续跑** —— 同样的超限会再发生一次,徒增 token 消耗。压缩失败就走"
|
|
517
|
-
- ❌ **不要在 session 规模很大时死磕 \`compact_session\`** —— 先按第 0 步评估,message
|
|
515
|
+
- ❌ **不要从头重新委托** —— 不传 \`sub_session_id\` 直接 \`delegate_task\` 是**最后手段**,只在旧 session 上下文已确认不可救(compact_session 后仍超限 / 迭代上限且无可复用断点)时才允许。其余情况一律带 \`sub_session_id\` 续跑(不传才会丢掉全部上下文,前面的调研和代码全白做,还可能重复踩已解决过的坑)。
|
|
516
|
+
- ❌ **不要在压缩失败时反复用同一个 session 续跑** —— 同样的超限会再发生一次,徒增 token 消耗。压缩失败就走"换新 session(不传 \`sub_session_id\`)+ 明确列出已完成项/断点/小目标"的兜底路径。
|
|
517
|
+
- ❌ **不要在 session 规模很大时死磕 \`compact_session\`** —— 先按第 0 步评估,message 数很多就走兜底路径(压缩复查 → 仍无效才换新 session)。
|
|
518
518
|
- ❌ **不要用 \`compact_session\` 压缩当前会话自己** —— 工具会直接拒绝(自毁)。
|
|
519
519
|
- ❌ **不要压缩还在 running/pending 的后台任务** —— 先 \`stop_task\`。
|
|
520
520
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
init_context
|
|
3
|
-
} from "./roy-agent-core-
|
|
3
|
+
} from "./roy-agent-core-tkpp1ba0.js";
|
|
4
4
|
import {
|
|
5
5
|
getEnvContext
|
|
6
|
-
} from "./roy-agent-core-
|
|
6
|
+
} from "./roy-agent-core-p31ftgq9.js";
|
|
7
7
|
import {
|
|
8
8
|
__esm
|
|
9
9
|
} from "./roy-agent-core-fs0mn2jk.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentComponentAdapter,
|
|
3
3
|
init_agent_component_adapter
|
|
4
|
-
} from "./roy-agent-core-
|
|
4
|
+
} from "./roy-agent-core-bjtc9d35.js";
|
|
5
5
|
import"./roy-agent-core-1db4vpc6.js";
|
|
6
6
|
import"./roy-agent-core-mkc3zshb.js";
|
|
7
|
-
import"./roy-agent-core-
|
|
8
|
-
import"./roy-agent-core-
|
|
9
|
-
import"./roy-agent-core-
|
|
10
|
-
import"./roy-agent-core-
|
|
7
|
+
import"./roy-agent-core-yet36q5k.js";
|
|
8
|
+
import"./roy-agent-core-tkpp1ba0.js";
|
|
9
|
+
import"./roy-agent-core-p31ftgq9.js";
|
|
10
|
+
import"./roy-agent-core-5s2t8z00.js";
|
|
11
11
|
import"./roy-agent-core-7f7t9wwp.js";
|
|
12
12
|
import"./roy-agent-core-85xyctnb.js";
|
|
13
13
|
import"./roy-agent-core-fs0mn2jk.js";
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger,
|
|
3
|
+
init_logger
|
|
4
|
+
} from "./roy-agent-core-7f7t9wwp.js";
|
|
5
|
+
|
|
6
|
+
// src/env/task/storage/remote-task-store.ts
|
|
7
|
+
init_logger();
|
|
8
|
+
|
|
9
|
+
class RemoteTaskStoreError extends Error {
|
|
10
|
+
endpoint;
|
|
11
|
+
cause;
|
|
12
|
+
constructor(message, endpoint, cause) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.endpoint = endpoint;
|
|
15
|
+
this.cause = cause;
|
|
16
|
+
this.name = new.target.name;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class RemoteAuthError extends RemoteTaskStoreError {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class RemoteIdempotencyConflictError extends RemoteTaskStoreError {
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class RemoteBatchBusyError extends RemoteTaskStoreError {
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class RemoteProtocolError extends RemoteTaskStoreError {
|
|
30
|
+
}
|
|
31
|
+
var WRITE_METHODS = new Set([
|
|
32
|
+
"createTask",
|
|
33
|
+
"updateTask",
|
|
34
|
+
"deleteTask",
|
|
35
|
+
"createOperation",
|
|
36
|
+
"updateOperation",
|
|
37
|
+
"deleteOperation",
|
|
38
|
+
"createTag",
|
|
39
|
+
"deleteTag",
|
|
40
|
+
"addTagsToTask",
|
|
41
|
+
"removeTagsFromTask",
|
|
42
|
+
"updateTaskTags"
|
|
43
|
+
]);
|
|
44
|
+
var REMOTE_TASK_STORE_METHODS = [
|
|
45
|
+
"createTask",
|
|
46
|
+
"getTask",
|
|
47
|
+
"updateTask",
|
|
48
|
+
"deleteTask",
|
|
49
|
+
"listTasks",
|
|
50
|
+
"getTaskIdBySessionId",
|
|
51
|
+
"getTaskIdsBySessionId",
|
|
52
|
+
"createOperation",
|
|
53
|
+
"getOperation",
|
|
54
|
+
"updateOperation",
|
|
55
|
+
"deleteOperation",
|
|
56
|
+
"listOperations",
|
|
57
|
+
"listOperationsFresh",
|
|
58
|
+
"invalidateOperationsCache",
|
|
59
|
+
"createTag",
|
|
60
|
+
"getTag",
|
|
61
|
+
"getTagByName",
|
|
62
|
+
"listTags",
|
|
63
|
+
"searchTags",
|
|
64
|
+
"deleteTag",
|
|
65
|
+
"addTagsToTask",
|
|
66
|
+
"removeTagsFromTask",
|
|
67
|
+
"getTagsForTask",
|
|
68
|
+
"getTaskIdsByTags",
|
|
69
|
+
"updateTaskTags",
|
|
70
|
+
"searchTasksByKeywords",
|
|
71
|
+
"findSimilarTasksByKeywords",
|
|
72
|
+
"getTaskTree",
|
|
73
|
+
"getChildTasks",
|
|
74
|
+
"findSimilarTasks",
|
|
75
|
+
"searchTasks",
|
|
76
|
+
"findTasksByContextValue"
|
|
77
|
+
];
|
|
78
|
+
var REMOTE_PROTOCOL_MAJOR = 1;
|
|
79
|
+
function trimTrailingNullish(args) {
|
|
80
|
+
let end = args.length;
|
|
81
|
+
while (end > 0) {
|
|
82
|
+
const v = args[end - 1];
|
|
83
|
+
if (v === null || v === undefined)
|
|
84
|
+
end -= 1;
|
|
85
|
+
else
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
return end === args.length ? args : args.slice(0, end);
|
|
89
|
+
}
|
|
90
|
+
var defaultLog = createLogger("task-remote");
|
|
91
|
+
|
|
92
|
+
class RemoteTaskStore {
|
|
93
|
+
endpoint;
|
|
94
|
+
authToken;
|
|
95
|
+
timeoutMs;
|
|
96
|
+
maxRetries;
|
|
97
|
+
retryBaseDelayMs;
|
|
98
|
+
fetchImpl;
|
|
99
|
+
log;
|
|
100
|
+
stats = { handshakes: 0, requests: 0, retries: 0 };
|
|
101
|
+
handshake;
|
|
102
|
+
closed = false;
|
|
103
|
+
constructor(options) {
|
|
104
|
+
if (!options?.endpoint) {
|
|
105
|
+
throw new Error("[RemoteTaskStore] endpoint is required (task.storage.endpoint)");
|
|
106
|
+
}
|
|
107
|
+
this.endpoint = options.endpoint.replace(/\/+$/, "");
|
|
108
|
+
this.authToken = options.authToken;
|
|
109
|
+
this.timeoutMs = options.timeoutMs ?? 5000;
|
|
110
|
+
this.maxRetries = options.maxRetries ?? 3;
|
|
111
|
+
this.retryBaseDelayMs = options.retryBaseDelayMs ?? 200;
|
|
112
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
113
|
+
this.log = options.log ?? defaultLog;
|
|
114
|
+
}
|
|
115
|
+
getStats() {
|
|
116
|
+
return { ...this.stats };
|
|
117
|
+
}
|
|
118
|
+
ensureOpen() {
|
|
119
|
+
if (this.closed) {
|
|
120
|
+
throw new RemoteTaskStoreError(`RemoteTaskStore is closed (endpoint=${this.endpoint})`, this.endpoint);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async ensureHandshake() {
|
|
124
|
+
if (!this.handshake) {
|
|
125
|
+
this.handshake = this.doHandshake().catch((e) => {
|
|
126
|
+
this.handshake = undefined;
|
|
127
|
+
throw e;
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return this.handshake;
|
|
131
|
+
}
|
|
132
|
+
async doHandshake() {
|
|
133
|
+
this.ensureOpen();
|
|
134
|
+
let res;
|
|
135
|
+
try {
|
|
136
|
+
res = await this.fetchWithTimeout(`${this.endpoint}/version`, { method: "GET" });
|
|
137
|
+
} catch (e) {
|
|
138
|
+
throw new RemoteTaskStoreError(`Cannot reach task-service at ${this.endpoint} (/version): ` + `${e instanceof Error ? e.message : String(e)}. ` + `Start it (systemctl --user start roy-task-service) or set task.storage.endpoint correctly. ` + `No local fallback is performed by design.`, this.endpoint, e);
|
|
139
|
+
}
|
|
140
|
+
if (!res.ok) {
|
|
141
|
+
throw new RemoteProtocolError(`task-service /version returned HTTP ${res.status} (endpoint=${this.endpoint})`, this.endpoint);
|
|
142
|
+
}
|
|
143
|
+
const body = await res.json().catch(() => ({}));
|
|
144
|
+
const major = body?.protocol?.major;
|
|
145
|
+
if (typeof major !== "number") {
|
|
146
|
+
throw new RemoteProtocolError(`task-service /version response has no protocol.major (endpoint=${this.endpoint})`, this.endpoint);
|
|
147
|
+
}
|
|
148
|
+
if (major !== REMOTE_PROTOCOL_MAJOR) {
|
|
149
|
+
throw new RemoteProtocolError(`Protocol mismatch: client speaks store-major ${REMOTE_PROTOCOL_MAJOR}, ` + `task-service speaks ${major} (endpoint=${this.endpoint}). Upgrade one side.`, this.endpoint);
|
|
150
|
+
}
|
|
151
|
+
this.stats.handshakes += 1;
|
|
152
|
+
}
|
|
153
|
+
async fetchWithTimeout(url, init) {
|
|
154
|
+
const controller = new AbortController;
|
|
155
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
156
|
+
try {
|
|
157
|
+
return await this.fetchImpl(url, { ...init, signal: controller.signal });
|
|
158
|
+
} finally {
|
|
159
|
+
clearTimeout(timer);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
isRetryableStatus(status) {
|
|
163
|
+
return status === 503 || status === 502 || status === 504 || status >= 500;
|
|
164
|
+
}
|
|
165
|
+
async call(method, rawArgs) {
|
|
166
|
+
this.ensureOpen();
|
|
167
|
+
await this.ensureHandshake();
|
|
168
|
+
const args = trimTrailingNullish(rawArgs);
|
|
169
|
+
const idempotencyKey = WRITE_METHODS.has(method) ? `${method}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}` : undefined;
|
|
170
|
+
let lastError;
|
|
171
|
+
for (let attempt = 0;attempt <= this.maxRetries; attempt++) {
|
|
172
|
+
if (attempt > 0) {
|
|
173
|
+
this.stats.retries += 1;
|
|
174
|
+
const backoff = this.retryBaseDelayMs * 2 ** (attempt - 1);
|
|
175
|
+
this.log.debug?.(`[RemoteTaskStore] retry ${attempt}/${this.maxRetries} ${method} in ${backoff}ms`);
|
|
176
|
+
await new Promise((r) => setTimeout(r, backoff));
|
|
177
|
+
}
|
|
178
|
+
const headers = { "content-type": "application/json" };
|
|
179
|
+
if (this.authToken)
|
|
180
|
+
headers.authorization = `Bearer ${this.authToken}`;
|
|
181
|
+
if (idempotencyKey)
|
|
182
|
+
headers["idempotency-key"] = idempotencyKey;
|
|
183
|
+
this.stats.requests += 1;
|
|
184
|
+
let res;
|
|
185
|
+
try {
|
|
186
|
+
res = await this.fetchWithTimeout(`${this.endpoint}/store/${method}`, {
|
|
187
|
+
method: "POST",
|
|
188
|
+
headers,
|
|
189
|
+
body: JSON.stringify({ args })
|
|
190
|
+
});
|
|
191
|
+
} catch (e) {
|
|
192
|
+
lastError = e;
|
|
193
|
+
if (attempt === this.maxRetries) {
|
|
194
|
+
throw new RemoteTaskStoreError(`task-service request failed: ${method} (endpoint=${this.endpoint}) after ` + `${attempt + 1} attempts: ${e instanceof Error ? e.message : String(e)}. ` + `No local fallback is performed by design.`, this.endpoint, e);
|
|
195
|
+
}
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (res.ok) {
|
|
199
|
+
const text = await res.text();
|
|
200
|
+
if (!text)
|
|
201
|
+
return;
|
|
202
|
+
try {
|
|
203
|
+
return JSON.parse(text);
|
|
204
|
+
} catch (e) {
|
|
205
|
+
throw new RemoteTaskStoreError(`task-service returned non-JSON for ${method} (endpoint=${this.endpoint})`, this.endpoint, e);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const body = await res.json().catch(() => null);
|
|
209
|
+
const code = body?.error?.code ?? "";
|
|
210
|
+
const detail = body?.error?.message ?? `HTTP ${res.status}`;
|
|
211
|
+
if (res.status === 401) {
|
|
212
|
+
throw new RemoteAuthError(`task-service rejected the request (401 ${code}): ${detail}. ` + `Check task.storage.authToken against the service's TASK_AUTH_TOKEN ` + `(endpoint=${this.endpoint}).`, this.endpoint);
|
|
213
|
+
}
|
|
214
|
+
if (res.status === 409 && code === "IDEMPOTENCY_CONFLICT") {
|
|
215
|
+
throw new RemoteIdempotencyConflictError(`task-service idempotency conflict for ${method}: ${detail} (endpoint=${this.endpoint})`, this.endpoint);
|
|
216
|
+
}
|
|
217
|
+
if (res.status === 404 && code === "METHOD_NOT_FOUND") {
|
|
218
|
+
throw new RemoteProtocolError(`task-service does not implement ${method}() — service is older than this client ` + `(endpoint=${this.endpoint}). deploy a newer task-service.`, this.endpoint);
|
|
219
|
+
}
|
|
220
|
+
if (res.status === 400) {
|
|
221
|
+
throw new RemoteTaskStoreError(`task-service rejected ${method} payload (400 ${code}): ${detail} (endpoint=${this.endpoint})`, this.endpoint);
|
|
222
|
+
}
|
|
223
|
+
if (res.status === 503 && code === "BUSY") {
|
|
224
|
+
lastError = new RemoteBatchBusyError(`sqlite backend busy for ${method}: a batch transaction holds the single shared ` + `connection; retried ${this.maxRetries} times without success (endpoint=${this.endpoint}). ` + `Retry after the batch completes.`, this.endpoint);
|
|
225
|
+
if (attempt === this.maxRetries)
|
|
226
|
+
throw lastError;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (this.isRetryableStatus(res.status)) {
|
|
230
|
+
lastError = new RemoteTaskStoreError(`task-service error for ${method} (HTTP ${res.status} ${code}): ${detail} ` + `(endpoint=${this.endpoint})`, this.endpoint);
|
|
231
|
+
if (attempt === this.maxRetries)
|
|
232
|
+
throw lastError;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
throw new RemoteTaskStoreError(`task-service rejected ${method} (HTTP ${res.status} ${code}): ${detail} ` + `(endpoint=${this.endpoint})`, this.endpoint);
|
|
236
|
+
}
|
|
237
|
+
throw new RemoteTaskStoreError(`task-service call ${method} exhausted retries (endpoint=${this.endpoint}): ` + `${lastError instanceof Error ? lastError.message : String(lastError)}`, this.endpoint, lastError);
|
|
238
|
+
}
|
|
239
|
+
createTask(options) {
|
|
240
|
+
return this.call("createTask", [options]);
|
|
241
|
+
}
|
|
242
|
+
async getTask(id) {
|
|
243
|
+
const task = await this.call("getTask", [id]);
|
|
244
|
+
return task ?? undefined;
|
|
245
|
+
}
|
|
246
|
+
async updateTask(id, options) {
|
|
247
|
+
const task = await this.call("updateTask", [id, options]);
|
|
248
|
+
return task ?? undefined;
|
|
249
|
+
}
|
|
250
|
+
deleteTask(id) {
|
|
251
|
+
return this.call("deleteTask", [id]);
|
|
252
|
+
}
|
|
253
|
+
listTasks(options) {
|
|
254
|
+
return this.call("listTasks", [options]);
|
|
255
|
+
}
|
|
256
|
+
async getTaskIdBySessionId(sessionId) {
|
|
257
|
+
const id = await this.call("getTaskIdBySessionId", [sessionId]);
|
|
258
|
+
return id ?? undefined;
|
|
259
|
+
}
|
|
260
|
+
getTaskIdsBySessionId(sessionId) {
|
|
261
|
+
return this.call("getTaskIdsBySessionId", [sessionId]);
|
|
262
|
+
}
|
|
263
|
+
createOperation(options) {
|
|
264
|
+
return this.call("createOperation", [options]);
|
|
265
|
+
}
|
|
266
|
+
async getOperation(id) {
|
|
267
|
+
const op = await this.call("getOperation", [id]);
|
|
268
|
+
return op ?? undefined;
|
|
269
|
+
}
|
|
270
|
+
async updateOperation(id, updates) {
|
|
271
|
+
const op = await this.call("updateOperation", [id, updates]);
|
|
272
|
+
return op ?? undefined;
|
|
273
|
+
}
|
|
274
|
+
deleteOperation(id) {
|
|
275
|
+
return this.call("deleteOperation", [id]);
|
|
276
|
+
}
|
|
277
|
+
listOperations(options) {
|
|
278
|
+
return this.call("listOperations", [options]);
|
|
279
|
+
}
|
|
280
|
+
listOperationsFresh(options) {
|
|
281
|
+
return this.call("listOperationsFresh", [options]);
|
|
282
|
+
}
|
|
283
|
+
invalidateOperationsCache(taskId) {
|
|
284
|
+
this.call("invalidateOperationsCache", [taskId]).catch((e) => {
|
|
285
|
+
this.log.warn?.(`[RemoteTaskStore] invalidateOperationsCache(${taskId}) failed: ` + `${e instanceof Error ? e.message : String(e)}`);
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
createTag(name) {
|
|
289
|
+
return this.call("createTag", [name]);
|
|
290
|
+
}
|
|
291
|
+
async getTag(id) {
|
|
292
|
+
const tag = await this.call("getTag", [id]);
|
|
293
|
+
return tag ?? undefined;
|
|
294
|
+
}
|
|
295
|
+
async getTagByName(name) {
|
|
296
|
+
const tag = await this.call("getTagByName", [name]);
|
|
297
|
+
return tag ?? undefined;
|
|
298
|
+
}
|
|
299
|
+
listTags(options) {
|
|
300
|
+
return this.call("listTags", [options]);
|
|
301
|
+
}
|
|
302
|
+
searchTags(options) {
|
|
303
|
+
return this.call("searchTags", [options]);
|
|
304
|
+
}
|
|
305
|
+
deleteTag(id) {
|
|
306
|
+
return this.call("deleteTag", [id]);
|
|
307
|
+
}
|
|
308
|
+
async addTagsToTask(taskId, tagIds) {
|
|
309
|
+
await this.call("addTagsToTask", [taskId, tagIds]);
|
|
310
|
+
}
|
|
311
|
+
async removeTagsFromTask(taskId, tagIds) {
|
|
312
|
+
await this.call("removeTagsFromTask", [taskId, tagIds]);
|
|
313
|
+
}
|
|
314
|
+
getTagsForTask(taskId) {
|
|
315
|
+
return this.call("getTagsForTask", [taskId]);
|
|
316
|
+
}
|
|
317
|
+
getTaskIdsByTags(tagNames) {
|
|
318
|
+
return this.call("getTaskIdsByTags", [tagNames]);
|
|
319
|
+
}
|
|
320
|
+
async updateTaskTags(taskId, tagNames) {
|
|
321
|
+
await this.call("updateTaskTags", [taskId, tagNames]);
|
|
322
|
+
}
|
|
323
|
+
searchTasksByKeywords(keywords, options) {
|
|
324
|
+
return this.call("searchTasksByKeywords", [keywords, options]);
|
|
325
|
+
}
|
|
326
|
+
findSimilarTasksByKeywords(keywords, options) {
|
|
327
|
+
return this.call("findSimilarTasksByKeywords", [keywords, options]);
|
|
328
|
+
}
|
|
329
|
+
getTaskTree(taskId, depth) {
|
|
330
|
+
return this.call("getTaskTree", [taskId, depth]);
|
|
331
|
+
}
|
|
332
|
+
getChildTasks(taskId, options) {
|
|
333
|
+
return this.call("getChildTasks", [taskId, options]);
|
|
334
|
+
}
|
|
335
|
+
findSimilarTasks(taskId, limit) {
|
|
336
|
+
return this.call("findSimilarTasks", [taskId, limit]);
|
|
337
|
+
}
|
|
338
|
+
searchTasks(query, limit) {
|
|
339
|
+
return this.call("searchTasks", [query, limit]);
|
|
340
|
+
}
|
|
341
|
+
findTasksByContextValue(value, limit) {
|
|
342
|
+
return this.call("findTasksByContextValue", [value, limit]);
|
|
343
|
+
}
|
|
344
|
+
close() {
|
|
345
|
+
this.closed = true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function createRemoteTaskStore(options) {
|
|
349
|
+
return new RemoteTaskStore(options);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export { RemoteTaskStoreError, RemoteAuthError, RemoteIdempotencyConflictError, RemoteBatchBusyError, RemoteProtocolError, REMOTE_TASK_STORE_METHODS, REMOTE_PROTOCOL_MAJOR, RemoteTaskStore, createRemoteTaskStore };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-setting/roy-agent-core",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.89",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core SDK for roy-agent - Environment, Components, Tools, Sessions, Tasks",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -72,6 +72,14 @@
|
|
|
72
72
|
"types": "./dist/env/event-source/wecom-respond-registry.d.ts",
|
|
73
73
|
"default": "./dist/env/event-source/wecom-respond-registry.js"
|
|
74
74
|
},
|
|
75
|
+
"./env/event-source/wecom-session-card-sender": {
|
|
76
|
+
"import": "./dist/env/event-source/wecom-session-card-sender.js",
|
|
77
|
+
"types": "./dist/env/event-source/wecom-session-card-sender.d.ts"
|
|
78
|
+
},
|
|
79
|
+
"./env/task/plugins/wecom-session-card-store": {
|
|
80
|
+
"import": "./dist/env/task/plugins/wecom-session-card-store.js",
|
|
81
|
+
"types": "./dist/env/task/plugins/wecom-session-card-store.d.ts"
|
|
82
|
+
},
|
|
75
83
|
"./env/event-source/idempotency-key": {
|
|
76
84
|
"import": "./dist/env/event-source/idempotency-key.js",
|
|
77
85
|
"types": "./dist/env/event-source/idempotency-key.d.ts",
|