botmux 2.33.0 → 2.34.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/README.en.md +12 -1
- package/README.md +45 -1
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +11 -0
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/cli/bots-list-output.d.ts +21 -0
- package/dist/cli/bots-list-output.d.ts.map +1 -0
- package/dist/cli/bots-list-output.js +23 -0
- package/dist/cli/bots-list-output.js.map +1 -0
- package/dist/cli/workflow.d.ts +13 -0
- package/dist/cli/workflow.d.ts.map +1 -0
- package/dist/cli/workflow.js +781 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/cli.js +69 -14
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +219 -6
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/session-manager.d.ts +6 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +22 -12
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/worker-pool.d.ts +13 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +100 -6
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +884 -3
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/auth.d.ts +36 -0
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +22 -0
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/web/app.js +20 -1
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +356 -0
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/workflow-catalog.d.ts +2 -0
- package/dist/dashboard/web/workflow-catalog.d.ts.map +1 -0
- package/dist/dashboard/web/workflow-catalog.js +323 -0
- package/dist/dashboard/web/workflow-catalog.js.map +1 -0
- package/dist/dashboard/web/workflows.d.ts +2 -0
- package/dist/dashboard/web/workflows.d.ts.map +1 -0
- package/dist/dashboard/web/workflows.js +1618 -0
- package/dist/dashboard/web/workflows.js.map +1 -0
- package/dist/dashboard/workflow-api.d.ts +23 -0
- package/dist/dashboard/workflow-api.d.ts.map +1 -0
- package/dist/dashboard/workflow-api.js +463 -0
- package/dist/dashboard/workflow-api.js.map +1 -0
- package/dist/dashboard-web/app.js +494 -199
- package/dist/dashboard-web/index.html +1 -0
- package/dist/dashboard-web/style.css +160 -6
- package/dist/dashboard-web/terminal-replay.html +227 -0
- package/dist/dashboard.js +29 -12
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +12 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +12 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +3 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +27 -1
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +19 -2
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +21 -2
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/workflow-card-handler.d.ts +50 -0
- package/dist/im/lark/workflow-card-handler.d.ts.map +1 -0
- package/dist/im/lark/workflow-card-handler.js +152 -0
- package/dist/im/lark/workflow-card-handler.js.map +1 -0
- package/dist/im/lark/workflow-cards.d.ts +46 -0
- package/dist/im/lark/workflow-cards.d.ts.map +1 -0
- package/dist/im/lark/workflow-cards.js +226 -0
- package/dist/im/lark/workflow-cards.js.map +1 -0
- package/dist/im/lark/workflow-progress-card.d.ts +76 -0
- package/dist/im/lark/workflow-progress-card.d.ts.map +1 -0
- package/dist/im/lark/workflow-progress-card.js +279 -0
- package/dist/im/lark/workflow-progress-card.js.map +1 -0
- package/dist/im/lark/workflow-slash-command.d.ts +92 -0
- package/dist/im/lark/workflow-slash-command.d.ts.map +1 -0
- package/dist/im/lark/workflow-slash-command.js +185 -0
- package/dist/im/lark/workflow-slash-command.js.map +1 -0
- package/dist/services/group-creator.d.ts.map +1 -1
- package/dist/services/group-creator.js +17 -4
- package/dist/services/group-creator.js.map +1 -1
- package/dist/services/groups-store.d.ts +11 -0
- package/dist/services/groups-store.d.ts.map +1 -1
- package/dist/services/groups-store.js +26 -0
- package/dist/services/groups-store.js.map +1 -1
- package/dist/services/jsonl-cursor.d.ts +12 -0
- package/dist/services/jsonl-cursor.d.ts.map +1 -0
- package/dist/services/jsonl-cursor.js +45 -0
- package/dist/services/jsonl-cursor.js.map +1 -0
- package/dist/services/schedule-store.d.ts +35 -0
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +108 -1
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +399 -0
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cli-usage-limit.d.ts.map +1 -1
- package/dist/utils/cli-usage-limit.js +4 -0
- package/dist/utils/cli-usage-limit.js.map +1 -1
- package/dist/worker.js +118 -14
- package/dist/worker.js.map +1 -1
- package/dist/workflows/attempt-resume.d.ts +114 -0
- package/dist/workflows/attempt-resume.d.ts.map +1 -0
- package/dist/workflows/attempt-resume.js +385 -0
- package/dist/workflows/attempt-resume.js.map +1 -0
- package/dist/workflows/attempt-terminal.d.ts +21 -0
- package/dist/workflows/attempt-terminal.d.ts.map +1 -0
- package/dist/workflows/attempt-terminal.js +7 -0
- package/dist/workflows/attempt-terminal.js.map +1 -0
- package/dist/workflows/blob.d.ts +27 -0
- package/dist/workflows/blob.d.ts.map +1 -0
- package/dist/workflows/blob.js +39 -0
- package/dist/workflows/blob.js.map +1 -0
- package/dist/workflows/cancel-run.d.ts +45 -0
- package/dist/workflows/cancel-run.d.ts.map +1 -0
- package/dist/workflows/cancel-run.js +99 -0
- package/dist/workflows/cancel-run.js.map +1 -0
- package/dist/workflows/cancel.d.ts +111 -0
- package/dist/workflows/cancel.d.ts.map +1 -0
- package/dist/workflows/cancel.js +120 -0
- package/dist/workflows/cancel.js.map +1 -0
- package/dist/workflows/catalog.d.ts +60 -0
- package/dist/workflows/catalog.d.ts.map +1 -0
- package/dist/workflows/catalog.js +119 -0
- package/dist/workflows/catalog.js.map +1 -0
- package/dist/workflows/cold-attach.d.ts +30 -0
- package/dist/workflows/cold-attach.d.ts.map +1 -0
- package/dist/workflows/cold-attach.js +40 -0
- package/dist/workflows/cold-attach.js.map +1 -0
- package/dist/workflows/cold-scan.d.ts +21 -0
- package/dist/workflows/cold-scan.d.ts.map +1 -0
- package/dist/workflows/cold-scan.js +70 -0
- package/dist/workflows/cold-scan.js.map +1 -0
- package/dist/workflows/daemon-spawn.d.ts +117 -0
- package/dist/workflows/daemon-spawn.d.ts.map +1 -0
- package/dist/workflows/daemon-spawn.js +551 -0
- package/dist/workflows/daemon-spawn.js.map +1 -0
- package/dist/workflows/definition.d.ts +1309 -0
- package/dist/workflows/definition.d.ts.map +1 -0
- package/dist/workflows/definition.js +334 -0
- package/dist/workflows/definition.js.map +1 -0
- package/dist/workflows/effect-input.d.ts +4 -0
- package/dist/workflows/effect-input.d.ts.map +1 -0
- package/dist/workflows/effect-input.js +18 -0
- package/dist/workflows/effect-input.js.map +1 -0
- package/dist/workflows/events/append.d.ts +77 -0
- package/dist/workflows/events/append.d.ts.map +1 -0
- package/dist/workflows/events/append.js +214 -0
- package/dist/workflows/events/append.js.map +1 -0
- package/dist/workflows/events/idempotency.d.ts +77 -0
- package/dist/workflows/events/idempotency.d.ts.map +1 -0
- package/dist/workflows/events/idempotency.js +116 -0
- package/dist/workflows/events/idempotency.js.map +1 -0
- package/dist/workflows/events/index.d.ts +7 -0
- package/dist/workflows/events/index.d.ts.map +1 -0
- package/dist/workflows/events/index.js +7 -0
- package/dist/workflows/events/index.js.map +1 -0
- package/dist/workflows/events/payloads.d.ts +917 -0
- package/dist/workflows/events/payloads.d.ts.map +1 -0
- package/dist/workflows/events/payloads.js +337 -0
- package/dist/workflows/events/payloads.js.map +1 -0
- package/dist/workflows/events/replay.d.ts +238 -0
- package/dist/workflows/events/replay.d.ts.map +1 -0
- package/dist/workflows/events/replay.js +608 -0
- package/dist/workflows/events/replay.js.map +1 -0
- package/dist/workflows/events/schema.d.ts +5242 -0
- package/dist/workflows/events/schema.d.ts.map +1 -0
- package/dist/workflows/events/schema.js +295 -0
- package/dist/workflows/events/schema.js.map +1 -0
- package/dist/workflows/events/types.d.ts +34 -0
- package/dist/workflows/events/types.d.ts.map +1 -0
- package/dist/workflows/events/types.js +2 -0
- package/dist/workflows/events/types.js.map +1 -0
- package/dist/workflows/fanout.d.ts +36 -0
- package/dist/workflows/fanout.d.ts.map +1 -0
- package/dist/workflows/fanout.js +114 -0
- package/dist/workflows/fanout.js.map +1 -0
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +41 -0
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/botmux-schedule.js +121 -0
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -0
- package/dist/workflows/hostExecutors/feishu-im.d.ts +12 -0
- package/dist/workflows/hostExecutors/feishu-im.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/feishu-im.js +49 -0
- package/dist/workflows/hostExecutors/feishu-im.js.map +1 -0
- package/dist/workflows/hostExecutors/feishu-reply.d.ts +24 -0
- package/dist/workflows/hostExecutors/feishu-reply.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/feishu-reply.js +88 -0
- package/dist/workflows/hostExecutors/feishu-reply.js.map +1 -0
- package/dist/workflows/hostExecutors/feishu-send.d.ts +23 -0
- package/dist/workflows/hostExecutors/feishu-send.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/feishu-send.js +124 -0
- package/dist/workflows/hostExecutors/feishu-send.js.map +1 -0
- package/dist/workflows/hostExecutors/index.d.ts +8 -0
- package/dist/workflows/hostExecutors/index.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/index.js +8 -0
- package/dist/workflows/hostExecutors/index.js.map +1 -0
- package/dist/workflows/hostExecutors/protocol.d.ts +42 -0
- package/dist/workflows/hostExecutors/protocol.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/protocol.js +181 -0
- package/dist/workflows/hostExecutors/protocol.js.map +1 -0
- package/dist/workflows/hostExecutors/registry.d.ts +10 -0
- package/dist/workflows/hostExecutors/registry.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/registry.js +36 -0
- package/dist/workflows/hostExecutors/registry.js.map +1 -0
- package/dist/workflows/hostExecutors/types.d.ts +78 -0
- package/dist/workflows/hostExecutors/types.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/types.js +2 -0
- package/dist/workflows/hostExecutors/types.js.map +1 -0
- package/dist/workflows/loader.d.ts +16 -0
- package/dist/workflows/loader.d.ts.map +1 -0
- package/dist/workflows/loader.js +56 -0
- package/dist/workflows/loader.js.map +1 -0
- package/dist/workflows/loop.d.ts +50 -0
- package/dist/workflows/loop.d.ts.map +1 -0
- package/dist/workflows/loop.js +350 -0
- package/dist/workflows/loop.js.map +1 -0
- package/dist/workflows/ops-projection.d.ts +168 -0
- package/dist/workflows/ops-projection.d.ts.map +1 -0
- package/dist/workflows/ops-projection.js +707 -0
- package/dist/workflows/ops-projection.js.map +1 -0
- package/dist/workflows/orchestrator.d.ts +107 -0
- package/dist/workflows/orchestrator.d.ts.map +1 -0
- package/dist/workflows/orchestrator.js +197 -0
- package/dist/workflows/orchestrator.js.map +1 -0
- package/dist/workflows/output-binding.d.ts +70 -0
- package/dist/workflows/output-binding.d.ts.map +1 -0
- package/dist/workflows/output-binding.js +265 -0
- package/dist/workflows/output-binding.js.map +1 -0
- package/dist/workflows/params.d.ts +61 -0
- package/dist/workflows/params.d.ts.map +1 -0
- package/dist/workflows/params.js +195 -0
- package/dist/workflows/params.js.map +1 -0
- package/dist/workflows/resume.d.ts +263 -0
- package/dist/workflows/resume.d.ts.map +1 -0
- package/dist/workflows/resume.js +808 -0
- package/dist/workflows/resume.js.map +1 -0
- package/dist/workflows/run-id.d.ts +2 -0
- package/dist/workflows/run-id.d.ts.map +1 -0
- package/dist/workflows/run-id.js +7 -0
- package/dist/workflows/run-id.js.map +1 -0
- package/dist/workflows/run-init.d.ts +48 -0
- package/dist/workflows/run-init.d.ts.map +1 -0
- package/dist/workflows/run-init.js +99 -0
- package/dist/workflows/run-init.js.map +1 -0
- package/dist/workflows/runs-dir.d.ts +4 -0
- package/dist/workflows/runs-dir.d.ts.map +1 -0
- package/dist/workflows/runs-dir.js +15 -0
- package/dist/workflows/runs-dir.js.map +1 -0
- package/dist/workflows/runtime.d.ts +211 -0
- package/dist/workflows/runtime.d.ts.map +1 -0
- package/dist/workflows/runtime.js +594 -0
- package/dist/workflows/runtime.js.map +1 -0
- package/dist/workflows/spawn-bot.d.ts +165 -0
- package/dist/workflows/spawn-bot.d.ts.map +1 -0
- package/dist/workflows/spawn-bot.js +215 -0
- package/dist/workflows/spawn-bot.js.map +1 -0
- package/dist/workflows/system.d.ts +49 -0
- package/dist/workflows/system.d.ts.map +1 -0
- package/dist/workflows/system.js +48 -0
- package/dist/workflows/system.js.map +1 -0
- package/dist/workflows/trigger-run.d.ts +70 -0
- package/dist/workflows/trigger-run.d.ts.map +1 -0
- package/dist/workflows/trigger-run.js +88 -0
- package/dist/workflows/trigger-run.js.map +1 -0
- package/dist/workflows/wait.d.ts +120 -0
- package/dist/workflows/wait.d.ts.map +1 -0
- package/dist/workflows/wait.js +181 -0
- package/dist/workflows/wait.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createTask, getTask, IdempotencyConflictError, } from '../../services/schedule-store.js';
|
|
3
|
+
const ParsedScheduleSchema = z.object({
|
|
4
|
+
kind: z.enum(['once', 'interval', 'cron']),
|
|
5
|
+
runAt: z.string().optional(),
|
|
6
|
+
minutes: z.number().optional(),
|
|
7
|
+
expr: z.string().optional(),
|
|
8
|
+
display: z.string(),
|
|
9
|
+
});
|
|
10
|
+
const ScheduleInputSchema = z.object({
|
|
11
|
+
name: z.string().min(1),
|
|
12
|
+
schedule: z.string().min(1),
|
|
13
|
+
parsed: ParsedScheduleSchema,
|
|
14
|
+
prompt: z.string(),
|
|
15
|
+
workingDir: z.string().min(1),
|
|
16
|
+
chatId: z.string().min(1),
|
|
17
|
+
rootMessageId: z.string().optional(),
|
|
18
|
+
scope: z.enum(['thread', 'chat']).optional(),
|
|
19
|
+
larkAppId: z.string().optional(),
|
|
20
|
+
repeat: z.object({ times: z.number().int().nonnegative().nullable() }).optional(),
|
|
21
|
+
deliver: z.enum(['origin', 'local']).optional(),
|
|
22
|
+
});
|
|
23
|
+
export function parseScheduleInput(input) {
|
|
24
|
+
return ScheduleInputSchema.parse(input);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* `botmux-schedule` hostExecutor. Calls `schedule-store.createTask`
|
|
28
|
+
* passing the runtime-derived `idempotencyKey` as the deterministic
|
|
29
|
+
* task id; schedule-store applies create-or-return-identical semantics
|
|
30
|
+
* (Step 5).
|
|
31
|
+
*
|
|
32
|
+
* Provider TTL is effectively infinite for schedule (the task entry
|
|
33
|
+
* lives until removed), so dangling effectAttempted reconcile uses
|
|
34
|
+
* readOnlyLookup (`getTask(idempotencyKey)`) — no TTL boundary.
|
|
35
|
+
*/
|
|
36
|
+
export const botmuxScheduleExecutor = {
|
|
37
|
+
provider: 'botmux-schedule',
|
|
38
|
+
idempotencyTtlMs: Number.MAX_SAFE_INTEGER,
|
|
39
|
+
canonicalInput(input) {
|
|
40
|
+
// Mirrors schedule-store's `canonicalScheduleInput`. Keeping them in
|
|
41
|
+
// sync is critical: if they diverge, two callers can produce the
|
|
42
|
+
// same idempotencyKey but disagree on canonicality and trip the
|
|
43
|
+
// IdempotencyConflict path on every retry.
|
|
44
|
+
return {
|
|
45
|
+
name: input.name,
|
|
46
|
+
schedule: input.schedule,
|
|
47
|
+
parsed: {
|
|
48
|
+
kind: input.parsed.kind,
|
|
49
|
+
runAt: input.parsed.runAt,
|
|
50
|
+
minutes: input.parsed.minutes,
|
|
51
|
+
expr: input.parsed.expr,
|
|
52
|
+
},
|
|
53
|
+
prompt: input.prompt,
|
|
54
|
+
workingDir: input.workingDir,
|
|
55
|
+
chatId: input.chatId,
|
|
56
|
+
rootMessageId: input.rootMessageId,
|
|
57
|
+
scope: input.scope,
|
|
58
|
+
larkAppId: input.larkAppId,
|
|
59
|
+
repeat: input.repeat ? { times: input.repeat.times } : undefined,
|
|
60
|
+
deliver: input.deliver ?? 'origin',
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
async invoke(input, idempotencyKey) {
|
|
64
|
+
const task = createTask({
|
|
65
|
+
id: idempotencyKey,
|
|
66
|
+
name: input.name,
|
|
67
|
+
schedule: input.schedule,
|
|
68
|
+
parsed: input.parsed,
|
|
69
|
+
prompt: input.prompt,
|
|
70
|
+
workingDir: input.workingDir,
|
|
71
|
+
chatId: input.chatId,
|
|
72
|
+
rootMessageId: input.rootMessageId,
|
|
73
|
+
scope: input.scope,
|
|
74
|
+
larkAppId: input.larkAppId,
|
|
75
|
+
repeat: input.repeat ? { times: input.repeat.times, completed: 0 } : undefined,
|
|
76
|
+
deliver: input.deliver,
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
output: { taskId: task.id },
|
|
80
|
+
externalRefs: { taskId: task.id },
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
classifyError(err) {
|
|
84
|
+
if (err instanceof IdempotencyConflictError) {
|
|
85
|
+
return {
|
|
86
|
+
errorCode: 'IdempotencyConflict',
|
|
87
|
+
errorClass: 'fatal',
|
|
88
|
+
errorMessage: err.message,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
export const botmuxScheduleReconciler = {
|
|
95
|
+
provider: 'botmux-schedule',
|
|
96
|
+
// Schedule reconciler doesn't load effect input (idempotencyKey is
|
|
97
|
+
// self-sufficient), so the resume-side hash guard never fires. We
|
|
98
|
+
// still expose `canonicalInput` for interface uniformity — anyone
|
|
99
|
+
// re-using the reconciler in a context that DOES load sidecars (e.g.
|
|
100
|
+
// future ScheduleStore variants requiring body verification) gets the
|
|
101
|
+
// same check for free.
|
|
102
|
+
canonicalInput(input) {
|
|
103
|
+
return botmuxScheduleExecutor.canonicalInput(input);
|
|
104
|
+
},
|
|
105
|
+
async readOnlyLookup(idempotencyKey) {
|
|
106
|
+
const task = getTask(idempotencyKey);
|
|
107
|
+
if (!task) {
|
|
108
|
+
return {
|
|
109
|
+
found: false,
|
|
110
|
+
evidence: { source: 'getTask', returned: 'undefined' },
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const externalRefs = { taskId: task.id };
|
|
114
|
+
return {
|
|
115
|
+
found: true,
|
|
116
|
+
externalRefs,
|
|
117
|
+
evidence: { source: 'getTask', externalRefs },
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=botmux-schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"botmux-schedule.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/botmux-schedule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,UAAU,EACV,OAAO,EACP,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AA6B1C,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;IACjF,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAyD;IAC1F,QAAQ,EAAE,iBAAiB;IAC3B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;IAEzC,cAAc,CAAC,KAAK;QAClB,sEAAsE;QACtE,iEAAiE;QACjE,gEAAgE;QAChE,2CAA2C;QAC3C,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE;gBACN,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI;gBACvB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK;gBACzB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;gBAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI;aACxB;YACD,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS;YAChE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,QAAQ;SACnC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc;QAChC,MAAM,IAAI,GAAG,UAAU,CAAC;YACtB,EAAE,EAAE,cAAc;YAClB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;YAC9E,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;YAC3B,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;SAClC,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,GAAG;QACf,IAAI,GAAG,YAAY,wBAAwB,EAAE,CAAC;YAC5C,OAAO;gBACL,SAAS,EAAE,qBAAqB;gBAChC,UAAU,EAAE,OAAO;gBACnB,YAAY,EAAE,GAAG,CAAC,OAAO;aAC1B,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAuB;IAC1D,QAAQ,EAAE,iBAAiB;IAE3B,mEAAmE;IACnE,mEAAmE;IACnE,kEAAkE;IAClE,qEAAqE;IACrE,sEAAsE;IACtE,uBAAuB;IACvB,cAAc,CAAC,KAAK;QAClB,OAAO,sBAAsB,CAAC,cAAc,CAAC,KAAsB,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,cAAc;QACjC,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;aACvD,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QACzC,OAAO;YACL,KAAK,EAAE,IAAI;YACX,YAAY;YACZ,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE;SAC9C,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ProviderReconciler } from '../resume.js';
|
|
2
|
+
/**
|
|
3
|
+
* Single Feishu IM provider reconciler.
|
|
4
|
+
*
|
|
5
|
+
* `effectAttempted.provider` is intentionally `feishu-im` for both
|
|
6
|
+
* `feishu-send` and `feishu-reply` because Feishu's idempotency surface
|
|
7
|
+
* is the IM uuid field. The executor id identifies the author-facing
|
|
8
|
+
* operation; resume only sees the provider, so it dispatches by the
|
|
9
|
+
* recovered effect input shape.
|
|
10
|
+
*/
|
|
11
|
+
export declare const feishuImReconciler: ProviderReconciler;
|
|
12
|
+
//# sourceMappingURL=feishu-im.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu-im.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-im.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAoChC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { feishuReplyReconciler } from './feishu-reply.js';
|
|
2
|
+
import { feishuSendReconciler } from './feishu-send.js';
|
|
3
|
+
/**
|
|
4
|
+
* Single Feishu IM provider reconciler.
|
|
5
|
+
*
|
|
6
|
+
* `effectAttempted.provider` is intentionally `feishu-im` for both
|
|
7
|
+
* `feishu-send` and `feishu-reply` because Feishu's idempotency surface
|
|
8
|
+
* is the IM uuid field. The executor id identifies the author-facing
|
|
9
|
+
* operation; resume only sees the provider, so it dispatches by the
|
|
10
|
+
* recovered effect input shape.
|
|
11
|
+
*/
|
|
12
|
+
export const feishuImReconciler = {
|
|
13
|
+
provider: 'feishu-im',
|
|
14
|
+
requiresEffectInput: true,
|
|
15
|
+
canonicalInput(input) {
|
|
16
|
+
// The hash guard in resume needs to canonicalize via the SAME shape
|
|
17
|
+
// the original executor used. Dispatch by input discriminator —
|
|
18
|
+
// identical logic to idempotentSubmit's routing.
|
|
19
|
+
if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'rootMessageId')) {
|
|
20
|
+
return feishuReplyReconciler.canonicalInput(input);
|
|
21
|
+
}
|
|
22
|
+
if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'chatId')) {
|
|
23
|
+
return feishuSendReconciler.canonicalInput(input);
|
|
24
|
+
}
|
|
25
|
+
// Unknown shape: return the input verbatim so the recomputed hash
|
|
26
|
+
// ends up SHA-stable but different from the original; the guard
|
|
27
|
+
// surfaces this as a mismatch rather than swallowing it.
|
|
28
|
+
return input;
|
|
29
|
+
},
|
|
30
|
+
async idempotentSubmit(idempotencyKey, input) {
|
|
31
|
+
if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'rootMessageId')) {
|
|
32
|
+
return feishuReplyReconciler.idempotentSubmit(idempotencyKey, input);
|
|
33
|
+
}
|
|
34
|
+
if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'chatId')) {
|
|
35
|
+
return feishuSendReconciler.idempotentSubmit(idempotencyKey, input);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
errorCode: 'InputValidationFailed',
|
|
40
|
+
errorClass: 'manual',
|
|
41
|
+
errorMessage: "Feishu IM effect input must include either 'chatId' (send) or 'rootMessageId' (reply)",
|
|
42
|
+
evidence: { source: 'idempotentSubmit', reason: 'unknown_feishu_im_input' },
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
function isRecord(value) {
|
|
47
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=feishu-im.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu-im.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-im.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAuB;IACpD,QAAQ,EAAE,WAAW;IACrB,mBAAmB,EAAE,IAAI;IAEzB,cAAc,CAAC,KAAK;QAClB,oEAAoE;QACpE,iEAAiE;QACjE,iDAAiD;QACjD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;YACpF,OAAO,qBAAqB,CAAC,cAAe,CAAC,KAAK,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC7E,OAAO,oBAAoB,CAAC,cAAe,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,kEAAkE;QAClE,gEAAgE;QAChE,yDAAyD;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,cAAc,EAAE,KAAK;QAC1C,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;YACpF,OAAO,qBAAqB,CAAC,gBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC7E,OAAO,oBAAoB,CAAC,gBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,SAAS,EAAE,uBAAuB;YAClC,UAAU,EAAE,QAAQ;YACpB,YAAY,EACV,uFAAuF;YACzF,QAAQ,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,yBAAyB,EAAE;SAC5E,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProviderReconciler } from '../resume.js';
|
|
2
|
+
import type { SideEffectingExecutor } from './types.js';
|
|
3
|
+
export type FeishuReplyInput = {
|
|
4
|
+
larkAppId: string;
|
|
5
|
+
/** Parent message id (om_xxx) being replied to. */
|
|
6
|
+
rootMessageId: string;
|
|
7
|
+
content: string;
|
|
8
|
+
msgType?: string;
|
|
9
|
+
replyInThread?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type FeishuReplyOutput = {
|
|
12
|
+
messageId: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function parseFeishuReplyInput(input: unknown): FeishuReplyInput;
|
|
15
|
+
/**
|
|
16
|
+
* `feishu-reply` is similar to `feishu-send` but the canonical input
|
|
17
|
+
* additionally pins `rootMessageId` — spike Test 3c proved that Feishu
|
|
18
|
+
* uuid dedupe IGNORES `parent_id` mismatches, so we must lock the parent
|
|
19
|
+
* into the inputHash; otherwise a retry against a different parent would
|
|
20
|
+
* silently land on the original parent.
|
|
21
|
+
*/
|
|
22
|
+
export declare const feishuReplyExecutor: SideEffectingExecutor<FeishuReplyInput, FeishuReplyOutput>;
|
|
23
|
+
export declare const feishuReplyReconciler: ProviderReconciler;
|
|
24
|
+
//# sourceMappingURL=feishu-reply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu-reply.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-reply.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAUF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAEtE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CA8B1F,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,kBAsCnC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { replyMessage } from '../../im/lark/client.js';
|
|
3
|
+
import { PROVIDER_TTL_MS } from '../events/schema.js';
|
|
4
|
+
import { classifyFeishuError } from './feishu-send.js';
|
|
5
|
+
const FeishuReplyInputSchema = z.object({
|
|
6
|
+
larkAppId: z.string().min(1),
|
|
7
|
+
rootMessageId: z.string().min(1),
|
|
8
|
+
content: z.string(),
|
|
9
|
+
msgType: z.string().min(1).optional(),
|
|
10
|
+
replyInThread: z.boolean().optional(),
|
|
11
|
+
}).strict();
|
|
12
|
+
export function parseFeishuReplyInput(input) {
|
|
13
|
+
return FeishuReplyInputSchema.parse(input);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* `feishu-reply` is similar to `feishu-send` but the canonical input
|
|
17
|
+
* additionally pins `rootMessageId` — spike Test 3c proved that Feishu
|
|
18
|
+
* uuid dedupe IGNORES `parent_id` mismatches, so we must lock the parent
|
|
19
|
+
* into the inputHash; otherwise a retry against a different parent would
|
|
20
|
+
* silently land on the original parent.
|
|
21
|
+
*/
|
|
22
|
+
export const feishuReplyExecutor = {
|
|
23
|
+
provider: 'feishu-im',
|
|
24
|
+
idempotencyTtlMs: PROVIDER_TTL_MS['feishu-im'],
|
|
25
|
+
canonicalInput(input) {
|
|
26
|
+
return {
|
|
27
|
+
root_message_id: input.rootMessageId,
|
|
28
|
+
msg_type: input.msgType ?? 'text',
|
|
29
|
+
content: input.content,
|
|
30
|
+
reply_in_thread: input.replyInThread ?? false,
|
|
31
|
+
larkAppId: input.larkAppId,
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
async invoke(input, idempotencyKey) {
|
|
35
|
+
const messageId = await replyMessage(input.larkAppId, input.rootMessageId, input.content, input.msgType ?? 'text', input.replyInThread ?? false, idempotencyKey);
|
|
36
|
+
return {
|
|
37
|
+
output: { messageId },
|
|
38
|
+
externalRefs: { messageId },
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
classifyError: classifyFeishuError,
|
|
42
|
+
};
|
|
43
|
+
export const feishuReplyReconciler = {
|
|
44
|
+
provider: 'feishu-im',
|
|
45
|
+
requiresEffectInput: true,
|
|
46
|
+
canonicalInput(input) {
|
|
47
|
+
return feishuReplyExecutor.canonicalInput(input);
|
|
48
|
+
},
|
|
49
|
+
async idempotentSubmit(idempotencyKey, input) {
|
|
50
|
+
let parsed;
|
|
51
|
+
try {
|
|
52
|
+
parsed = parseFeishuReplyInput(input);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
return {
|
|
56
|
+
ok: false,
|
|
57
|
+
errorCode: 'InputValidationFailed',
|
|
58
|
+
errorClass: 'manual',
|
|
59
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
60
|
+
evidence: { source: 'idempotentSubmit', reason: 'invalid_effect_input' },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const { externalRefs } = await feishuReplyExecutor.invoke(parsed, idempotencyKey);
|
|
65
|
+
return {
|
|
66
|
+
ok: true,
|
|
67
|
+
externalRefs,
|
|
68
|
+
evidence: { source: 'idempotentSubmit', externalRefs },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
const classification = classifyFeishuError(err) ?? defaultFeishuClassification(err);
|
|
73
|
+
return {
|
|
74
|
+
ok: false,
|
|
75
|
+
...classification,
|
|
76
|
+
evidence: { source: 'idempotentSubmit' },
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
function defaultFeishuClassification(err) {
|
|
82
|
+
return {
|
|
83
|
+
errorCode: 'UnknownProviderError',
|
|
84
|
+
errorClass: 'manual',
|
|
85
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=feishu-reply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu-reply.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-reply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ProviderReconciler } from '../resume.js';
|
|
2
|
+
import type { ExecutorErrorClassification, SideEffectingExecutor } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Input for the `feishu-send` hostExecutor. Mirrors the surface area of
|
|
5
|
+
* `client.sendMessage`; the canonical hash covers every field that
|
|
6
|
+
* participates in the external effect (spike report §1.5 / events doc
|
|
7
|
+
* v0.1.2 §3.2).
|
|
8
|
+
*/
|
|
9
|
+
export type FeishuSendInput = {
|
|
10
|
+
larkAppId: string;
|
|
11
|
+
chatId: string;
|
|
12
|
+
content: string;
|
|
13
|
+
/** Defaults to 'text'. */
|
|
14
|
+
msgType?: string;
|
|
15
|
+
};
|
|
16
|
+
export type FeishuSendOutput = {
|
|
17
|
+
messageId: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function parseFeishuSendInput(input: unknown): FeishuSendInput;
|
|
20
|
+
export declare const feishuSendExecutor: SideEffectingExecutor<FeishuSendInput, FeishuSendOutput>;
|
|
21
|
+
export declare const feishuSendReconciler: ProviderReconciler;
|
|
22
|
+
export declare function classifyFeishuError(err: unknown): ExecutorErrorClassification | null;
|
|
23
|
+
//# sourceMappingURL=feishu-send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu-send.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-send.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AASF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAEpE;AAED,eAAO,MAAM,kBAAkB,EAAE,qBAAqB,CAAC,eAAe,EAAE,gBAAgB,CAqCvF,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,kBAsClC,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,2BAA2B,GAAG,IAAI,CAuCpF"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { sendMessage, MessageWithdrawnError } from '../../im/lark/client.js';
|
|
3
|
+
import { PROVIDER_TTL_MS } from '../events/schema.js';
|
|
4
|
+
const FeishuSendInputSchema = z.object({
|
|
5
|
+
larkAppId: z.string().min(1),
|
|
6
|
+
chatId: z.string().min(1),
|
|
7
|
+
content: z.string(),
|
|
8
|
+
msgType: z.string().min(1).optional(),
|
|
9
|
+
}).strict();
|
|
10
|
+
export function parseFeishuSendInput(input) {
|
|
11
|
+
return FeishuSendInputSchema.parse(input);
|
|
12
|
+
}
|
|
13
|
+
export const feishuSendExecutor = {
|
|
14
|
+
provider: 'feishu-im',
|
|
15
|
+
idempotencyTtlMs: PROVIDER_TTL_MS['feishu-im'],
|
|
16
|
+
canonicalInput(input) {
|
|
17
|
+
return {
|
|
18
|
+
// receive_id + receive_id_type fully identify the destination. We
|
|
19
|
+
// pin receive_id_type to 'chat_id' because that's all
|
|
20
|
+
// `client.sendMessage` supports today; future variants would extend
|
|
21
|
+
// this canonical shape.
|
|
22
|
+
receive_id: input.chatId,
|
|
23
|
+
receive_id_type: 'chat_id',
|
|
24
|
+
msg_type: input.msgType ?? 'text',
|
|
25
|
+
content: input.content,
|
|
26
|
+
// larkAppId is part of "who sends" — different bots writing the
|
|
27
|
+
// same content to the same chat are distinct effects.
|
|
28
|
+
larkAppId: input.larkAppId,
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
async invoke(input, idempotencyKey) {
|
|
32
|
+
const messageId = await sendMessage(input.larkAppId, input.chatId, input.content, input.msgType ?? 'text', idempotencyKey);
|
|
33
|
+
return {
|
|
34
|
+
output: { messageId },
|
|
35
|
+
externalRefs: { messageId },
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
classifyError(err) {
|
|
39
|
+
return classifyFeishuError(err);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export const feishuSendReconciler = {
|
|
43
|
+
provider: 'feishu-im',
|
|
44
|
+
requiresEffectInput: true,
|
|
45
|
+
canonicalInput(input) {
|
|
46
|
+
return feishuSendExecutor.canonicalInput(input);
|
|
47
|
+
},
|
|
48
|
+
async idempotentSubmit(idempotencyKey, input) {
|
|
49
|
+
let parsed;
|
|
50
|
+
try {
|
|
51
|
+
parsed = parseFeishuSendInput(input);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return {
|
|
55
|
+
ok: false,
|
|
56
|
+
errorCode: 'InputValidationFailed',
|
|
57
|
+
errorClass: 'manual',
|
|
58
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
59
|
+
evidence: { source: 'idempotentSubmit', reason: 'invalid_effect_input' },
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const { externalRefs } = await feishuSendExecutor.invoke(parsed, idempotencyKey);
|
|
64
|
+
return {
|
|
65
|
+
ok: true,
|
|
66
|
+
externalRefs,
|
|
67
|
+
evidence: { source: 'idempotentSubmit', externalRefs },
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
const classification = classifyFeishuError(err) ?? defaultFeishuClassification(err);
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
...classification,
|
|
75
|
+
evidence: { source: 'idempotentSubmit' },
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
// ─── Error classification (shared with feishu-reply) ────────────────────────
|
|
81
|
+
export function classifyFeishuError(err) {
|
|
82
|
+
if (err instanceof MessageWithdrawnError) {
|
|
83
|
+
return {
|
|
84
|
+
errorCode: 'UnknownProviderError',
|
|
85
|
+
// Withdrawn message means the parent or target is gone — the user
|
|
86
|
+
// would need to retarget (effectively manual). Could be refined
|
|
87
|
+
// to a dedicated WithdrawnTarget code later.
|
|
88
|
+
errorClass: 'manual',
|
|
89
|
+
errorMessage: err.message,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (err instanceof Error) {
|
|
93
|
+
const status = err?.response?.status ?? err?.status;
|
|
94
|
+
const code = err?.response?.data?.code ?? err?.code;
|
|
95
|
+
// Rate-limited
|
|
96
|
+
if (status === 429 || code === 99991663 /* feishu rate-limited */) {
|
|
97
|
+
return {
|
|
98
|
+
errorCode: 'ProviderRateLimited',
|
|
99
|
+
errorClass: 'retryable',
|
|
100
|
+
errorMessage: err.message,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// Generic network — connection refused / DNS / 5xx
|
|
104
|
+
if (status >= 500 ||
|
|
105
|
+
/ECONNREFUSED|ETIMEDOUT|EHOSTUNREACH|ENOTFOUND|getaddrinfo/i.test(err.message)) {
|
|
106
|
+
return {
|
|
107
|
+
errorCode: 'NetworkError',
|
|
108
|
+
errorClass: 'retryable',
|
|
109
|
+
errorMessage: err.message,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Unknown — fall through to protocol default (UnknownProviderError /
|
|
114
|
+
// manual) by returning null.
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
function defaultFeishuClassification(err) {
|
|
118
|
+
return {
|
|
119
|
+
errorCode: 'UnknownProviderError',
|
|
120
|
+
errorClass: 'manual',
|
|
121
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=feishu-send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu-send.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAyBtD,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC,MAAM,EAAE,CAAC;AAEZ,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,OAAO,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAA6D;IAC1F,QAAQ,EAAE,WAAW;IACrB,gBAAgB,EAAE,eAAe,CAAC,WAAW,CAAC;IAE9C,cAAc,CAAC,KAAK;QAClB,OAAO;YACL,mEAAmE;YACnE,sDAAsD;YACtD,oEAAoE;YACpE,wBAAwB;YACxB,UAAU,EAAE,KAAK,CAAC,MAAM;YACxB,eAAe,EAAE,SAAS;YAC1B,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM;YACjC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,gEAAgE;YAChE,sDAAsD;YACtD,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc;QAChC,MAAM,SAAS,GAAG,MAAM,WAAW,CACjC,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,IAAI,MAAM,EACvB,cAAc,CACf,CAAC;QACF,OAAO;YACL,MAAM,EAAE,EAAE,SAAS,EAAE;YACrB,YAAY,EAAE,EAAE,SAAS,EAAE;SAC5B,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,GAAG;QACf,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAuB;IACtD,QAAQ,EAAE,WAAW;IACrB,mBAAmB,EAAE,IAAI;IAEzB,cAAc,CAAC,KAAK;QAClB,OAAO,kBAAkB,CAAC,cAAc,CAAC,KAAwB,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,cAAc,EAAE,KAAK;QAC1C,IAAI,MAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,SAAS,EAAE,uBAAuB;gBAClC,UAAU,EAAE,QAAQ;gBACpB,YAAY,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC9D,QAAQ,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,sBAAsB,EAAE;aACzE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACjF,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,YAAY;gBACZ,QAAQ,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE;aACvD,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,cAAc,GAAG,mBAAmB,CAAC,GAAG,CAAC,IAAI,2BAA2B,CAAC,GAAG,CAAC,CAAC;YACpF,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,GAAG,cAAc;gBACjB,QAAQ,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;aACzC,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC;AAEF,+EAA+E;AAE/E,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;QACzC,OAAO;YACL,SAAS,EAAE,sBAAsB;YACjC,kEAAkE;YAClE,iEAAiE;YACjE,6CAA6C;YAC7C,UAAU,EAAE,QAAQ;YACpB,YAAY,EAAE,GAAG,CAAC,OAAO;SAC1B,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAI,GAAW,EAAE,QAAQ,EAAE,MAAM,IAAK,GAAW,EAAE,MAAM,CAAC;QACtE,MAAM,IAAI,GAAI,GAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,IAAK,GAAW,EAAE,IAAI,CAAC;QAEtE,eAAe;QACf,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,KAAK,QAAQ,CAAC,yBAAyB,EAAE,CAAC;YAClE,OAAO;gBACL,SAAS,EAAE,qBAAqB;gBAChC,UAAU,EAAE,WAAW;gBACvB,YAAY,EAAE,GAAG,CAAC,OAAO;aAC1B,CAAC;QACJ,CAAC;QACD,mDAAmD;QACnD,IACE,MAAM,IAAI,GAAG;YACb,4DAA4D,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAC9E,CAAC;YACD,OAAO;gBACL,SAAS,EAAE,cAAc;gBACzB,UAAU,EAAE,WAAW;gBACvB,YAAY,EAAE,GAAG,CAAC,OAAO;aAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IACD,qEAAqE;IACrE,6BAA6B;IAC7B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,2BAA2B,CAAC,GAAY;IAC/C,OAAO;QACL,SAAS,EAAE,sBAAsB;QACjC,UAAU,EAAE,QAAQ;QACpB,YAAY,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;KAC/D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './protocol.js';
|
|
3
|
+
export * from './feishu-send.js';
|
|
4
|
+
export * from './feishu-reply.js';
|
|
5
|
+
export * from './feishu-im.js';
|
|
6
|
+
export * from './botmux-schedule.js';
|
|
7
|
+
export * from './registry.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './protocol.js';
|
|
3
|
+
export * from './feishu-send.js';
|
|
4
|
+
export * from './feishu-reply.js';
|
|
5
|
+
export * from './feishu-im.js';
|
|
6
|
+
export * from './botmux-schedule.js';
|
|
7
|
+
export * from './registry.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ActivityFailedEvent, ActivitySucceededEvent } from '../events/types.js';
|
|
2
|
+
import type { ExecutorErrorClassification, HostExecutorContext, SideEffectingExecutor } from './types.js';
|
|
3
|
+
export type SideEffectingResult<Output> = {
|
|
4
|
+
ok: true;
|
|
5
|
+
event: ActivitySucceededEvent;
|
|
6
|
+
output: Output;
|
|
7
|
+
externalRefs: Record<string, unknown>;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
event: ActivityFailedEvent;
|
|
11
|
+
error: ExecutorErrorClassification;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Drive the side-effecting protocol for one attempt (events doc v0.1.2
|
|
15
|
+
* §2.3, §4.3). Writes three events in order:
|
|
16
|
+
*
|
|
17
|
+
* 1. `effectAttempted` — written **before** invoking the provider so a
|
|
18
|
+
* crash mid-call leaves a dangling intent that resume can reconcile.
|
|
19
|
+
* 2. provider invocation (via `executor.invoke`).
|
|
20
|
+
* 3. `activitySucceeded` OR `activityFailed` — terminal event for this
|
|
21
|
+
* attempt; carries `externalRefs` on success or classified error on
|
|
22
|
+
* failure.
|
|
23
|
+
*
|
|
24
|
+
* The protocol does NOT write `attemptCreated/leaseSigned/activityRunning`
|
|
25
|
+
* — those are the scheduler/worker layer's responsibility. This function
|
|
26
|
+
* assumes the caller has already advanced the activity to `running`.
|
|
27
|
+
*
|
|
28
|
+
* The protocol does NOT do retry/backoff — that's the scheduler's job
|
|
29
|
+
* (Step 7+). A failed invocation is reported via `ok: false` and the
|
|
30
|
+
* caller decides whether to spawn a new `attemptCreated`.
|
|
31
|
+
*
|
|
32
|
+
* Idempotency contract:
|
|
33
|
+
* - `idempotencyKey` is deterministic per attempt (5-tuple hash), so
|
|
34
|
+
* re-running the same attempt with the same input produces the same
|
|
35
|
+
* uuid → Feishu/schedule provider returns the original ref.
|
|
36
|
+
* - `inputHash` is recorded for the resume path to detect attempt
|
|
37
|
+
* mutability violations (Step 7). This function doesn't enforce
|
|
38
|
+
* immutability across calls — Step 7 reads recorded inputHash and
|
|
39
|
+
* fails if a future attempt re-derives a different one.
|
|
40
|
+
*/
|
|
41
|
+
export declare function executeSideEffect<I, O>(ctx: HostExecutorContext, input: I, executor: SideEffectingExecutor<I, O>): Promise<SideEffectingResult<O>>;
|
|
42
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/protocol.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAI1G,MAAM,MAAM,mBAAmB,CAAC,MAAM,IAClC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,sBAAsB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAClG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,2BAA2B,CAAA;CAAE,CAAC;AAIlF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAC1C,GAAG,EAAE,mBAAmB,EACxB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,GACpC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAwFjC"}
|