miladyai 2.0.0-alpha.27

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.
Files changed (241) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +7 -0
  2. package/dist/actions/emote.js +64 -0
  3. package/dist/actions/restart.js +81 -0
  4. package/dist/actions/send-message.js +152 -0
  5. package/dist/agent-admin-routes.js +82 -0
  6. package/dist/agent-lifecycle-routes.js +79 -0
  7. package/dist/agent-transfer-routes.js +102 -0
  8. package/dist/api/agent-admin-routes.js +82 -0
  9. package/dist/api/agent-lifecycle-routes.js +79 -0
  10. package/dist/api/agent-transfer-routes.js +102 -0
  11. package/dist/api/apps-hyperscape-routes.js +58 -0
  12. package/dist/api/apps-routes.js +114 -0
  13. package/dist/api/auth-routes.js +56 -0
  14. package/dist/api/autonomy-routes.js +44 -0
  15. package/dist/api/bug-report-routes.js +111 -0
  16. package/dist/api/character-routes.js +195 -0
  17. package/dist/api/cloud-routes.js +330 -0
  18. package/dist/api/cloud-status-routes.js +155 -0
  19. package/dist/api/compat-utils.js +111 -0
  20. package/dist/api/database.js +735 -0
  21. package/dist/api/diagnostics-routes.js +205 -0
  22. package/dist/api/drop-service.js +134 -0
  23. package/dist/api/early-logs.js +86 -0
  24. package/dist/api/http-helpers.js +131 -0
  25. package/dist/api/knowledge-routes.js +534 -0
  26. package/dist/api/memory-bounds.js +71 -0
  27. package/dist/api/models-routes.js +28 -0
  28. package/dist/api/og-tracker.js +36 -0
  29. package/dist/api/permissions-routes.js +109 -0
  30. package/dist/api/plugin-validation.js +198 -0
  31. package/dist/api/provider-switch-config.js +41 -0
  32. package/dist/api/registry-routes.js +86 -0
  33. package/dist/api/registry-service.js +164 -0
  34. package/dist/api/sandbox-routes.js +1112 -0
  35. package/dist/api/server.js +7949 -0
  36. package/dist/api/subscription-routes.js +172 -0
  37. package/dist/api/terminal-run-limits.js +24 -0
  38. package/dist/api/training-routes.js +158 -0
  39. package/dist/api/trajectory-routes.js +300 -0
  40. package/dist/api/trigger-routes.js +246 -0
  41. package/dist/api/twitter-verify.js +134 -0
  42. package/dist/api/tx-service.js +108 -0
  43. package/dist/api/wallet-routes.js +266 -0
  44. package/dist/api/wallet.js +568 -0
  45. package/dist/api/whatsapp-routes.js +182 -0
  46. package/dist/api/zip-utils.js +109 -0
  47. package/dist/apps-hyperscape-routes.js +58 -0
  48. package/dist/apps-routes.js +114 -0
  49. package/dist/ascii.js +20 -0
  50. package/dist/auth/anthropic.js +44 -0
  51. package/dist/auth/apply-stealth.js +41 -0
  52. package/dist/auth/claude-code-stealth.js +78 -0
  53. package/dist/auth/credentials.js +156 -0
  54. package/dist/auth/index.js +5 -0
  55. package/dist/auth/openai-codex.js +66 -0
  56. package/dist/auth/types.js +9 -0
  57. package/dist/auth-routes.js +56 -0
  58. package/dist/autonomy-routes.js +44 -0
  59. package/dist/bug-report-routes.js +111 -0
  60. package/dist/build-info.json +6 -0
  61. package/dist/character-routes.js +195 -0
  62. package/dist/cli/argv.js +63 -0
  63. package/dist/cli/banner.js +34 -0
  64. package/dist/cli/cli-name.js +21 -0
  65. package/dist/cli/cli-utils.js +16 -0
  66. package/dist/cli/git-commit.js +78 -0
  67. package/dist/cli/parse-duration.js +15 -0
  68. package/dist/cli/plugins-cli.js +590 -0
  69. package/dist/cli/profile-utils.js +9 -0
  70. package/dist/cli/profile.js +95 -0
  71. package/dist/cli/program/build-program.js +17 -0
  72. package/dist/cli/program/command-registry.js +23 -0
  73. package/dist/cli/program/help.js +47 -0
  74. package/dist/cli/program/preaction.js +33 -0
  75. package/dist/cli/program/register.config.js +106 -0
  76. package/dist/cli/program/register.configure.js +20 -0
  77. package/dist/cli/program/register.dashboard.js +124 -0
  78. package/dist/cli/program/register.models.js +23 -0
  79. package/dist/cli/program/register.setup.js +36 -0
  80. package/dist/cli/program/register.start.js +22 -0
  81. package/dist/cli/program/register.subclis.js +70 -0
  82. package/dist/cli/program/register.tui.js +163 -0
  83. package/dist/cli/program/register.update.js +154 -0
  84. package/dist/cli/program.js +3 -0
  85. package/dist/cli/run-main.js +37 -0
  86. package/dist/cli/version.js +7 -0
  87. package/dist/cloud/validate-url.js +93 -0
  88. package/dist/cloud-routes.js +330 -0
  89. package/dist/cloud-status-routes.js +155 -0
  90. package/dist/compat-utils.js +111 -0
  91. package/dist/config/config.js +69 -0
  92. package/dist/config/env-vars.js +19 -0
  93. package/dist/config/includes.js +121 -0
  94. package/dist/config/object-utils.js +7 -0
  95. package/dist/config/paths.js +38 -0
  96. package/dist/config/plugin-auto-enable.js +231 -0
  97. package/dist/config/schema.js +864 -0
  98. package/dist/config/telegram-custom-commands.js +76 -0
  99. package/dist/config/zod-schema.agent-runtime.js +519 -0
  100. package/dist/config/zod-schema.core.js +538 -0
  101. package/dist/config/zod-schema.hooks.js +103 -0
  102. package/dist/config/zod-schema.js +488 -0
  103. package/dist/config/zod-schema.providers-core.js +785 -0
  104. package/dist/config/zod-schema.session.js +73 -0
  105. package/dist/core-plugins.js +37 -0
  106. package/dist/custom-actions.js +250 -0
  107. package/dist/database.js +735 -0
  108. package/dist/diagnostics/integration-observability.js +57 -0
  109. package/dist/diagnostics-routes.js +205 -0
  110. package/dist/drop-service.js +134 -0
  111. package/dist/early-logs.js +24 -0
  112. package/dist/eliza.js +2061 -0
  113. package/dist/emotes/catalog.js +271 -0
  114. package/dist/entry.js +40 -0
  115. package/dist/hooks/discovery.js +167 -0
  116. package/dist/hooks/eligibility.js +64 -0
  117. package/dist/hooks/index.js +4 -0
  118. package/dist/hooks/loader.js +147 -0
  119. package/dist/hooks/registry.js +55 -0
  120. package/dist/http-helpers.js +131 -0
  121. package/dist/index.js +49 -0
  122. package/dist/knowledge-routes.js +534 -0
  123. package/dist/memory-bounds.js +71 -0
  124. package/dist/milady-plugin.js +90 -0
  125. package/dist/models-routes.js +28 -0
  126. package/dist/onboarding-names.js +78 -0
  127. package/dist/onboarding-presets.js +922 -0
  128. package/dist/package.json +1 -0
  129. package/dist/permissions-routes.js +109 -0
  130. package/dist/plugin-validation.js +107 -0
  131. package/dist/plugins/whatsapp/actions.js +91 -0
  132. package/dist/plugins/whatsapp/index.js +16 -0
  133. package/dist/plugins/whatsapp/service.js +270 -0
  134. package/dist/provider-switch-config.js +41 -0
  135. package/dist/providers/admin-trust.js +46 -0
  136. package/dist/providers/autonomous-state.js +101 -0
  137. package/dist/providers/session-bridge.js +86 -0
  138. package/dist/providers/session-utils.js +36 -0
  139. package/dist/providers/simple-mode.js +50 -0
  140. package/dist/providers/ui-catalog.js +15 -0
  141. package/dist/providers/workspace-provider.js +93 -0
  142. package/dist/providers/workspace.js +348 -0
  143. package/dist/registry-routes.js +86 -0
  144. package/dist/registry-service.js +164 -0
  145. package/dist/restart.js +40 -0
  146. package/dist/runtime/core-plugins.js +37 -0
  147. package/dist/runtime/custom-actions.js +250 -0
  148. package/dist/runtime/eliza.js +2061 -0
  149. package/dist/runtime/embedding-manager-support.js +185 -0
  150. package/dist/runtime/embedding-manager.js +193 -0
  151. package/dist/runtime/embedding-presets.js +54 -0
  152. package/dist/runtime/embedding-state.js +8 -0
  153. package/dist/runtime/milady-plugin.js +90 -0
  154. package/dist/runtime/onboarding-names.js +78 -0
  155. package/dist/runtime/restart.js +40 -0
  156. package/dist/runtime/version.js +7 -0
  157. package/dist/sandbox-routes.js +1112 -0
  158. package/dist/security/audit-log.js +149 -0
  159. package/dist/security/network-policy.js +70 -0
  160. package/dist/server.js +7949 -0
  161. package/dist/services/agent-export.js +559 -0
  162. package/dist/services/app-manager.js +389 -0
  163. package/dist/services/browser-capture.js +86 -0
  164. package/dist/services/fallback-training-service.js +128 -0
  165. package/dist/services/mcp-marketplace.js +134 -0
  166. package/dist/services/plugin-installer.js +396 -0
  167. package/dist/services/plugin-manager-types.js +15 -0
  168. package/dist/services/registry-client-app-meta.js +144 -0
  169. package/dist/services/registry-client-endpoints.js +166 -0
  170. package/dist/services/registry-client-local.js +271 -0
  171. package/dist/services/registry-client-network.js +93 -0
  172. package/dist/services/registry-client-queries.js +70 -0
  173. package/dist/services/registry-client.js +157 -0
  174. package/dist/services/sandbox-engine.js +511 -0
  175. package/dist/services/sandbox-manager.js +297 -0
  176. package/dist/services/self-updater.js +175 -0
  177. package/dist/services/skill-catalog-client.js +119 -0
  178. package/dist/services/skill-marketplace.js +521 -0
  179. package/dist/services/stream-manager.js +236 -0
  180. package/dist/services/update-checker.js +121 -0
  181. package/dist/services/update-notifier.js +29 -0
  182. package/dist/services/version-compat.js +78 -0
  183. package/dist/services/whatsapp-pairing.js +196 -0
  184. package/dist/shared/ui-catalog-prompt.js +728 -0
  185. package/dist/subscription-routes.js +172 -0
  186. package/dist/terminal/links.js +19 -0
  187. package/dist/terminal/palette.js +14 -0
  188. package/dist/terminal/theme.js +25 -0
  189. package/dist/terminal-run-limits.js +24 -0
  190. package/dist/training-routes.js +158 -0
  191. package/dist/trajectory-routes.js +300 -0
  192. package/dist/trigger-routes.js +246 -0
  193. package/dist/triggers/action.js +218 -0
  194. package/dist/triggers/runtime.js +281 -0
  195. package/dist/triggers/scheduling.js +295 -0
  196. package/dist/triggers/types.js +5 -0
  197. package/dist/tui/components/assistant-message.js +76 -0
  198. package/dist/tui/components/chat-editor.js +34 -0
  199. package/dist/tui/components/embeddings-overlay.js +46 -0
  200. package/dist/tui/components/footer.js +60 -0
  201. package/dist/tui/components/index.js +15 -0
  202. package/dist/tui/components/modal-frame.js +45 -0
  203. package/dist/tui/components/modal-style.js +15 -0
  204. package/dist/tui/components/model-selector.js +70 -0
  205. package/dist/tui/components/pinned-chat-layout.js +46 -0
  206. package/dist/tui/components/plugins-endpoints-tab.js +196 -0
  207. package/dist/tui/components/plugins-installed-tab-view.js +69 -0
  208. package/dist/tui/components/plugins-installed-tab.js +319 -0
  209. package/dist/tui/components/plugins-overlay-catalog.js +81 -0
  210. package/dist/tui/components/plugins-overlay-data-api.js +21 -0
  211. package/dist/tui/components/plugins-overlay-data-shared.js +20 -0
  212. package/dist/tui/components/plugins-overlay-data.js +323 -0
  213. package/dist/tui/components/plugins-overlay.js +117 -0
  214. package/dist/tui/components/plugins-store-tab.js +148 -0
  215. package/dist/tui/components/settings-overlay.js +61 -0
  216. package/dist/tui/components/status-bar.js +64 -0
  217. package/dist/tui/components/tool-execution.js +68 -0
  218. package/dist/tui/components/user-message.js +22 -0
  219. package/dist/tui/eliza-tui-bridge.js +606 -0
  220. package/dist/tui/index.js +370 -0
  221. package/dist/tui/modal-presets.js +33 -0
  222. package/dist/tui/model-spec.js +46 -0
  223. package/dist/tui/sse-parser.js +78 -0
  224. package/dist/tui/theme.js +110 -0
  225. package/dist/tui/titlebar-spinner.js +62 -0
  226. package/dist/tui/tui-app.js +311 -0
  227. package/dist/tui/ws-client.js +215 -0
  228. package/dist/twitter-verify.js +134 -0
  229. package/dist/tx-service.js +108 -0
  230. package/dist/utils/exec-safety.js +17 -0
  231. package/dist/utils/globals.js +20 -0
  232. package/dist/utils/milady-root.js +61 -0
  233. package/dist/utils/number-parsing.js +37 -0
  234. package/dist/version-resolver.js +37 -0
  235. package/dist/version.js +7 -0
  236. package/dist/wallet-routes.js +266 -0
  237. package/dist/wallet.js +568 -0
  238. package/dist/whatsapp-routes.js +182 -0
  239. package/dist/zip-utils.js +109 -0
  240. package/milady.mjs +14 -0
  241. package/package.json +111 -0
@@ -0,0 +1,785 @@
1
+ import { BlockStreamingChunkSchema, BlockStreamingCoalesceSchema, ChannelHeartbeatVisibilitySchema, DmConfigSchema, DmPolicySchema, ExecutableTokenSchema, GroupPolicySchema, MSTeamsReplyStyleSchema, MarkdownConfigSchema, ProviderCommandsSchema, ReplyToModeSchema, RetryConfigSchema, requireOpenAllowFrom } from "./zod-schema.core.js";
2
+ import { ToolPolicySchema } from "./zod-schema.agent-runtime.js";
3
+ import { normalizeTelegramCommandDescription, normalizeTelegramCommandName, resolveTelegramCustomCommands } from "./telegram-custom-commands.js";
4
+ import { z } from "zod";
5
+
6
+ //#region src/config/zod-schema.providers-core.ts
7
+ const ToolPolicyBySenderSchema = z.record(z.string(), ToolPolicySchema).optional();
8
+ const TelegramInlineButtonsScopeSchema = z.enum([
9
+ "off",
10
+ "dm",
11
+ "group",
12
+ "all",
13
+ "allowlist"
14
+ ]);
15
+ const TelegramCapabilitiesSchema = z.union([z.array(z.string()), z.object({ inlineButtons: TelegramInlineButtonsScopeSchema.optional() }).strict()]);
16
+ const TelegramTopicSchema = z.object({
17
+ requireMention: z.boolean().optional(),
18
+ skills: z.array(z.string()).optional(),
19
+ enabled: z.boolean().optional(),
20
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
21
+ systemPrompt: z.string().optional()
22
+ }).strict();
23
+ const TelegramGroupSchema = z.object({
24
+ requireMention: z.boolean().optional(),
25
+ tools: ToolPolicySchema,
26
+ toolsBySender: ToolPolicyBySenderSchema,
27
+ skills: z.array(z.string()).optional(),
28
+ enabled: z.boolean().optional(),
29
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
30
+ systemPrompt: z.string().optional(),
31
+ topics: z.record(z.string(), TelegramTopicSchema.optional()).optional()
32
+ }).strict();
33
+ const TelegramCustomCommandSchema = z.object({
34
+ command: z.string().transform(normalizeTelegramCommandName),
35
+ description: z.string().transform(normalizeTelegramCommandDescription)
36
+ }).strict();
37
+ const validateTelegramCustomCommands = (value, ctx) => {
38
+ if (!value.customCommands || value.customCommands.length === 0) return;
39
+ const { issues } = resolveTelegramCustomCommands({
40
+ commands: value.customCommands,
41
+ checkReserved: false,
42
+ checkDuplicates: false
43
+ });
44
+ for (const issue of issues) ctx.addIssue({
45
+ code: z.ZodIssueCode.custom,
46
+ path: [
47
+ "customCommands",
48
+ issue.index,
49
+ issue.field
50
+ ],
51
+ message: issue.message
52
+ });
53
+ };
54
+ const TelegramAccountSchemaBase = z.object({
55
+ name: z.string().optional(),
56
+ capabilities: TelegramCapabilitiesSchema.optional(),
57
+ markdown: MarkdownConfigSchema,
58
+ enabled: z.boolean().optional(),
59
+ commands: ProviderCommandsSchema,
60
+ customCommands: z.array(TelegramCustomCommandSchema).optional(),
61
+ configWrites: z.boolean().optional(),
62
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
63
+ botToken: z.string().optional(),
64
+ tokenFile: z.string().optional(),
65
+ replyToMode: ReplyToModeSchema.optional(),
66
+ groups: z.record(z.string(), TelegramGroupSchema.optional()).optional(),
67
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
68
+ groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
69
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
70
+ historyLimit: z.number().int().min(0).optional(),
71
+ dmHistoryLimit: z.number().int().min(0).optional(),
72
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
73
+ textChunkLimit: z.number().int().positive().optional(),
74
+ chunkMode: z.enum(["length", "newline"]).optional(),
75
+ blockStreaming: z.boolean().optional(),
76
+ draftChunk: BlockStreamingChunkSchema.optional(),
77
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
78
+ streamMode: z.enum([
79
+ "off",
80
+ "partial",
81
+ "block"
82
+ ]).optional().default("partial"),
83
+ mediaMaxMb: z.number().positive().optional(),
84
+ timeoutSeconds: z.number().int().positive().optional(),
85
+ retry: RetryConfigSchema,
86
+ network: z.object({ autoSelectFamily: z.boolean().optional() }).strict().optional(),
87
+ proxy: z.string().optional(),
88
+ webhookUrl: z.string().optional(),
89
+ webhookSecret: z.string().optional(),
90
+ webhookPath: z.string().optional(),
91
+ actions: z.object({
92
+ reactions: z.boolean().optional(),
93
+ sendMessage: z.boolean().optional(),
94
+ deleteMessage: z.boolean().optional(),
95
+ sticker: z.boolean().optional()
96
+ }).strict().optional(),
97
+ reactionNotifications: z.enum([
98
+ "off",
99
+ "own",
100
+ "all"
101
+ ]).optional(),
102
+ reactionLevel: z.enum([
103
+ "off",
104
+ "ack",
105
+ "minimal",
106
+ "extensive"
107
+ ]).optional(),
108
+ heartbeat: ChannelHeartbeatVisibilitySchema,
109
+ linkPreview: z.boolean().optional()
110
+ }).strict();
111
+ const TelegramAccountSchema = TelegramAccountSchemaBase.superRefine((value, ctx) => {
112
+ requireOpenAllowFrom({
113
+ policy: value.dmPolicy,
114
+ allowFrom: value.allowFrom,
115
+ ctx,
116
+ path: ["allowFrom"],
117
+ message: "channels.telegram.dmPolicy=\"open\" requires channels.telegram.allowFrom to include \"*\""
118
+ });
119
+ validateTelegramCustomCommands(value, ctx);
120
+ });
121
+ const TelegramConfigSchema = TelegramAccountSchemaBase.extend({ accounts: z.record(z.string(), TelegramAccountSchema.optional()).optional() }).superRefine((value, ctx) => {
122
+ requireOpenAllowFrom({
123
+ policy: value.dmPolicy,
124
+ allowFrom: value.allowFrom,
125
+ ctx,
126
+ path: ["allowFrom"],
127
+ message: "channels.telegram.dmPolicy=\"open\" requires channels.telegram.allowFrom to include \"*\""
128
+ });
129
+ validateTelegramCustomCommands(value, ctx);
130
+ const baseWebhookUrl = typeof value.webhookUrl === "string" ? value.webhookUrl.trim() : "";
131
+ const baseWebhookSecret = typeof value.webhookSecret === "string" ? value.webhookSecret.trim() : "";
132
+ if (baseWebhookUrl && !baseWebhookSecret) ctx.addIssue({
133
+ code: z.ZodIssueCode.custom,
134
+ message: "channels.telegram.webhookUrl requires channels.telegram.webhookSecret",
135
+ path: ["webhookSecret"]
136
+ });
137
+ if (!value.accounts) return;
138
+ for (const [accountId, account] of Object.entries(value.accounts)) {
139
+ if (!account) continue;
140
+ if (account.enabled === false) continue;
141
+ if (!(typeof account.webhookUrl === "string" ? account.webhookUrl.trim() : "")) continue;
142
+ if (!(typeof account.webhookSecret === "string" ? account.webhookSecret.trim() : "") && !baseWebhookSecret) ctx.addIssue({
143
+ code: z.ZodIssueCode.custom,
144
+ message: "channels.telegram.accounts.*.webhookUrl requires channels.telegram.webhookSecret or channels.telegram.accounts.*.webhookSecret",
145
+ path: [
146
+ "accounts",
147
+ accountId,
148
+ "webhookSecret"
149
+ ]
150
+ });
151
+ }
152
+ });
153
+ const DiscordDmSchema = z.object({
154
+ enabled: z.boolean().optional(),
155
+ policy: DmPolicySchema.optional().default("pairing"),
156
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
157
+ groupEnabled: z.boolean().optional(),
158
+ groupChannels: z.array(z.union([z.string(), z.number()])).optional()
159
+ }).strict().superRefine((value, ctx) => {
160
+ requireOpenAllowFrom({
161
+ policy: value.policy,
162
+ allowFrom: value.allowFrom,
163
+ ctx,
164
+ path: ["allowFrom"],
165
+ message: "channels.discord.dm.policy=\"open\" requires channels.discord.dm.allowFrom to include \"*\""
166
+ });
167
+ });
168
+ const DiscordGuildChannelSchema = z.object({
169
+ allow: z.boolean().optional(),
170
+ requireMention: z.boolean().optional(),
171
+ tools: ToolPolicySchema,
172
+ toolsBySender: ToolPolicyBySenderSchema,
173
+ skills: z.array(z.string()).optional(),
174
+ enabled: z.boolean().optional(),
175
+ users: z.array(z.union([z.string(), z.number()])).optional(),
176
+ systemPrompt: z.string().optional(),
177
+ autoThread: z.boolean().optional()
178
+ }).strict();
179
+ const DiscordGuildSchema = z.object({
180
+ slug: z.string().optional(),
181
+ requireMention: z.boolean().optional(),
182
+ tools: ToolPolicySchema,
183
+ toolsBySender: ToolPolicyBySenderSchema,
184
+ reactionNotifications: z.enum([
185
+ "off",
186
+ "own",
187
+ "all",
188
+ "allowlist"
189
+ ]).optional(),
190
+ users: z.array(z.union([z.string(), z.number()])).optional(),
191
+ channels: z.record(z.string(), DiscordGuildChannelSchema.optional()).optional()
192
+ }).strict();
193
+ const DiscordAccountSchema = z.object({
194
+ name: z.string().optional(),
195
+ capabilities: z.array(z.string()).optional(),
196
+ markdown: MarkdownConfigSchema,
197
+ enabled: z.boolean().optional(),
198
+ commands: ProviderCommandsSchema,
199
+ configWrites: z.boolean().optional(),
200
+ token: z.string().optional(),
201
+ allowBots: z.boolean().optional(),
202
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
203
+ historyLimit: z.number().int().min(0).optional(),
204
+ dmHistoryLimit: z.number().int().min(0).optional(),
205
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
206
+ textChunkLimit: z.number().int().positive().optional(),
207
+ chunkMode: z.enum(["length", "newline"]).optional(),
208
+ blockStreaming: z.boolean().optional(),
209
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
210
+ maxLinesPerMessage: z.number().int().positive().optional(),
211
+ mediaMaxMb: z.number().positive().optional(),
212
+ retry: RetryConfigSchema,
213
+ actions: z.object({
214
+ reactions: z.boolean().optional(),
215
+ stickers: z.boolean().optional(),
216
+ emojiUploads: z.boolean().optional(),
217
+ stickerUploads: z.boolean().optional(),
218
+ polls: z.boolean().optional(),
219
+ permissions: z.boolean().optional(),
220
+ messages: z.boolean().optional(),
221
+ threads: z.boolean().optional(),
222
+ pins: z.boolean().optional(),
223
+ search: z.boolean().optional(),
224
+ memberInfo: z.boolean().optional(),
225
+ roleInfo: z.boolean().optional(),
226
+ roles: z.boolean().optional(),
227
+ channelInfo: z.boolean().optional(),
228
+ voiceStatus: z.boolean().optional(),
229
+ events: z.boolean().optional(),
230
+ moderation: z.boolean().optional(),
231
+ channels: z.boolean().optional(),
232
+ presence: z.boolean().optional()
233
+ }).strict().optional(),
234
+ replyToMode: ReplyToModeSchema.optional(),
235
+ dm: DiscordDmSchema.optional(),
236
+ guilds: z.record(z.string(), DiscordGuildSchema.optional()).optional(),
237
+ heartbeat: ChannelHeartbeatVisibilitySchema,
238
+ execApprovals: z.object({
239
+ enabled: z.boolean().optional(),
240
+ approvers: z.array(z.union([z.string(), z.number()])).optional(),
241
+ agentFilter: z.array(z.string()).optional(),
242
+ sessionFilter: z.array(z.string()).optional()
243
+ }).strict().optional(),
244
+ intents: z.object({
245
+ presence: z.boolean().optional(),
246
+ guildMembers: z.boolean().optional()
247
+ }).strict().optional(),
248
+ pluralkit: z.object({
249
+ enabled: z.boolean().optional(),
250
+ token: z.string().optional()
251
+ }).strict().optional()
252
+ }).strict();
253
+ const DiscordConfigSchema = DiscordAccountSchema.extend({ accounts: z.record(z.string(), DiscordAccountSchema.optional()).optional() });
254
+ const GoogleChatDmSchema = z.object({
255
+ enabled: z.boolean().optional(),
256
+ policy: DmPolicySchema.optional().default("pairing"),
257
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional()
258
+ }).strict().superRefine((value, ctx) => {
259
+ requireOpenAllowFrom({
260
+ policy: value.policy,
261
+ allowFrom: value.allowFrom,
262
+ ctx,
263
+ path: ["allowFrom"],
264
+ message: "channels.googlechat.dm.policy=\"open\" requires channels.googlechat.dm.allowFrom to include \"*\""
265
+ });
266
+ });
267
+ const GoogleChatGroupSchema = z.object({
268
+ enabled: z.boolean().optional(),
269
+ allow: z.boolean().optional(),
270
+ requireMention: z.boolean().optional(),
271
+ users: z.array(z.union([z.string(), z.number()])).optional(),
272
+ systemPrompt: z.string().optional()
273
+ }).strict();
274
+ const GoogleChatAccountSchema = z.object({
275
+ name: z.string().optional(),
276
+ capabilities: z.array(z.string()).optional(),
277
+ enabled: z.boolean().optional(),
278
+ configWrites: z.boolean().optional(),
279
+ allowBots: z.boolean().optional(),
280
+ requireMention: z.boolean().optional(),
281
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
282
+ groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
283
+ groups: z.record(z.string(), GoogleChatGroupSchema.optional()).optional(),
284
+ serviceAccount: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
285
+ serviceAccountFile: z.string().optional(),
286
+ audienceType: z.enum(["app-url", "project-number"]).optional(),
287
+ audience: z.string().optional(),
288
+ webhookPath: z.string().optional(),
289
+ webhookUrl: z.string().optional(),
290
+ botUser: z.string().optional(),
291
+ historyLimit: z.number().int().min(0).optional(),
292
+ dmHistoryLimit: z.number().int().min(0).optional(),
293
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
294
+ textChunkLimit: z.number().int().positive().optional(),
295
+ chunkMode: z.enum(["length", "newline"]).optional(),
296
+ blockStreaming: z.boolean().optional(),
297
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
298
+ mediaMaxMb: z.number().positive().optional(),
299
+ replyToMode: ReplyToModeSchema.optional(),
300
+ actions: z.object({ reactions: z.boolean().optional() }).strict().optional(),
301
+ dm: GoogleChatDmSchema.optional(),
302
+ typingIndicator: z.enum([
303
+ "none",
304
+ "message",
305
+ "reaction"
306
+ ]).optional()
307
+ }).strict();
308
+ const GoogleChatConfigSchema = GoogleChatAccountSchema.extend({
309
+ accounts: z.record(z.string(), GoogleChatAccountSchema.optional()).optional(),
310
+ defaultAccount: z.string().optional()
311
+ });
312
+ const SlackDmSchema = z.object({
313
+ enabled: z.boolean().optional(),
314
+ policy: DmPolicySchema.optional().default("pairing"),
315
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
316
+ groupEnabled: z.boolean().optional(),
317
+ groupChannels: z.array(z.union([z.string(), z.number()])).optional(),
318
+ replyToMode: ReplyToModeSchema.optional()
319
+ }).strict().superRefine((value, ctx) => {
320
+ requireOpenAllowFrom({
321
+ policy: value.policy,
322
+ allowFrom: value.allowFrom,
323
+ ctx,
324
+ path: ["allowFrom"],
325
+ message: "channels.slack.dm.policy=\"open\" requires channels.slack.dm.allowFrom to include \"*\""
326
+ });
327
+ });
328
+ const SlackChannelSchema = z.object({
329
+ enabled: z.boolean().optional(),
330
+ allow: z.boolean().optional(),
331
+ requireMention: z.boolean().optional(),
332
+ tools: ToolPolicySchema,
333
+ toolsBySender: ToolPolicyBySenderSchema,
334
+ allowBots: z.boolean().optional(),
335
+ users: z.array(z.union([z.string(), z.number()])).optional(),
336
+ skills: z.array(z.string()).optional(),
337
+ systemPrompt: z.string().optional()
338
+ }).strict();
339
+ const SlackThreadSchema = z.object({
340
+ historyScope: z.enum(["thread", "channel"]).optional(),
341
+ inheritParent: z.boolean().optional()
342
+ }).strict();
343
+ const SlackReplyToModeByChatTypeSchema = z.object({
344
+ direct: ReplyToModeSchema.optional(),
345
+ group: ReplyToModeSchema.optional(),
346
+ channel: ReplyToModeSchema.optional()
347
+ }).strict();
348
+ const SlackAccountSchema = z.object({
349
+ name: z.string().optional(),
350
+ mode: z.enum(["socket", "http"]).optional(),
351
+ signingSecret: z.string().optional(),
352
+ webhookPath: z.string().optional(),
353
+ capabilities: z.array(z.string()).optional(),
354
+ markdown: MarkdownConfigSchema,
355
+ enabled: z.boolean().optional(),
356
+ commands: ProviderCommandsSchema,
357
+ configWrites: z.boolean().optional(),
358
+ botToken: z.string().optional(),
359
+ appToken: z.string().optional(),
360
+ userToken: z.string().optional(),
361
+ userTokenReadOnly: z.boolean().optional().default(true),
362
+ allowBots: z.boolean().optional(),
363
+ requireMention: z.boolean().optional(),
364
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
365
+ historyLimit: z.number().int().min(0).optional(),
366
+ dmHistoryLimit: z.number().int().min(0).optional(),
367
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
368
+ textChunkLimit: z.number().int().positive().optional(),
369
+ chunkMode: z.enum(["length", "newline"]).optional(),
370
+ blockStreaming: z.boolean().optional(),
371
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
372
+ mediaMaxMb: z.number().positive().optional(),
373
+ reactionNotifications: z.enum([
374
+ "off",
375
+ "own",
376
+ "all",
377
+ "allowlist"
378
+ ]).optional(),
379
+ reactionAllowlist: z.array(z.union([z.string(), z.number()])).optional(),
380
+ replyToMode: ReplyToModeSchema.optional(),
381
+ replyToModeByChatType: SlackReplyToModeByChatTypeSchema.optional(),
382
+ thread: SlackThreadSchema.optional(),
383
+ actions: z.object({
384
+ reactions: z.boolean().optional(),
385
+ messages: z.boolean().optional(),
386
+ pins: z.boolean().optional(),
387
+ search: z.boolean().optional(),
388
+ permissions: z.boolean().optional(),
389
+ memberInfo: z.boolean().optional(),
390
+ channelInfo: z.boolean().optional(),
391
+ emojiList: z.boolean().optional()
392
+ }).strict().optional(),
393
+ slashCommand: z.object({
394
+ enabled: z.boolean().optional(),
395
+ name: z.string().optional(),
396
+ sessionPrefix: z.string().optional(),
397
+ ephemeral: z.boolean().optional()
398
+ }).strict().optional(),
399
+ dm: SlackDmSchema.optional(),
400
+ channels: z.record(z.string(), SlackChannelSchema.optional()).optional(),
401
+ heartbeat: ChannelHeartbeatVisibilitySchema
402
+ }).strict();
403
+ const SlackConfigSchema = SlackAccountSchema.extend({
404
+ mode: z.enum(["socket", "http"]).optional().default("socket"),
405
+ signingSecret: z.string().optional(),
406
+ webhookPath: z.string().optional().default("/slack/events"),
407
+ accounts: z.record(z.string(), SlackAccountSchema.optional()).optional()
408
+ }).superRefine((value, ctx) => {
409
+ const baseMode = value.mode ?? "socket";
410
+ if (baseMode === "http" && !value.signingSecret) ctx.addIssue({
411
+ code: z.ZodIssueCode.custom,
412
+ message: "channels.slack.mode=\"http\" requires channels.slack.signingSecret",
413
+ path: ["signingSecret"]
414
+ });
415
+ if (!value.accounts) return;
416
+ for (const [accountId, account] of Object.entries(value.accounts)) {
417
+ if (!account) continue;
418
+ if (account.enabled === false) continue;
419
+ if ((account.mode ?? baseMode) !== "http") continue;
420
+ if (!(account.signingSecret ?? value.signingSecret)) ctx.addIssue({
421
+ code: z.ZodIssueCode.custom,
422
+ message: "channels.slack.accounts.*.mode=\"http\" requires channels.slack.signingSecret or channels.slack.accounts.*.signingSecret",
423
+ path: [
424
+ "accounts",
425
+ accountId,
426
+ "signingSecret"
427
+ ]
428
+ });
429
+ }
430
+ });
431
+ const SignalAccountSchemaBase = z.object({
432
+ name: z.string().optional(),
433
+ capabilities: z.array(z.string()).optional(),
434
+ markdown: MarkdownConfigSchema,
435
+ enabled: z.boolean().optional(),
436
+ configWrites: z.boolean().optional(),
437
+ account: z.string().optional(),
438
+ httpUrl: z.string().optional(),
439
+ httpHost: z.string().optional(),
440
+ httpPort: z.number().int().positive().optional(),
441
+ cliPath: ExecutableTokenSchema.optional(),
442
+ autoStart: z.boolean().optional(),
443
+ startupTimeoutMs: z.number().int().min(1e3).max(12e4).optional(),
444
+ receiveMode: z.union([z.literal("on-start"), z.literal("manual")]).optional(),
445
+ ignoreAttachments: z.boolean().optional(),
446
+ ignoreStories: z.boolean().optional(),
447
+ sendReadReceipts: z.boolean().optional(),
448
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
449
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
450
+ groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
451
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
452
+ historyLimit: z.number().int().min(0).optional(),
453
+ dmHistoryLimit: z.number().int().min(0).optional(),
454
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
455
+ textChunkLimit: z.number().int().positive().optional(),
456
+ chunkMode: z.enum(["length", "newline"]).optional(),
457
+ blockStreaming: z.boolean().optional(),
458
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
459
+ mediaMaxMb: z.number().int().positive().optional(),
460
+ reactionNotifications: z.enum([
461
+ "off",
462
+ "own",
463
+ "all",
464
+ "allowlist"
465
+ ]).optional(),
466
+ reactionAllowlist: z.array(z.union([z.string(), z.number()])).optional(),
467
+ actions: z.object({ reactions: z.boolean().optional() }).strict().optional(),
468
+ reactionLevel: z.enum([
469
+ "off",
470
+ "ack",
471
+ "minimal",
472
+ "extensive"
473
+ ]).optional(),
474
+ heartbeat: ChannelHeartbeatVisibilitySchema
475
+ }).strict();
476
+ const SignalAccountSchema = SignalAccountSchemaBase.superRefine((value, ctx) => {
477
+ requireOpenAllowFrom({
478
+ policy: value.dmPolicy,
479
+ allowFrom: value.allowFrom,
480
+ ctx,
481
+ path: ["allowFrom"],
482
+ message: "channels.signal.dmPolicy=\"open\" requires channels.signal.allowFrom to include \"*\""
483
+ });
484
+ });
485
+ const SignalConfigSchema = SignalAccountSchemaBase.extend({ accounts: z.record(z.string(), SignalAccountSchema.optional()).optional() }).superRefine((value, ctx) => {
486
+ requireOpenAllowFrom({
487
+ policy: value.dmPolicy,
488
+ allowFrom: value.allowFrom,
489
+ ctx,
490
+ path: ["allowFrom"],
491
+ message: "channels.signal.dmPolicy=\"open\" requires channels.signal.allowFrom to include \"*\""
492
+ });
493
+ });
494
+ const IMessageAccountSchemaBase = z.object({
495
+ name: z.string().optional(),
496
+ capabilities: z.array(z.string()).optional(),
497
+ markdown: MarkdownConfigSchema,
498
+ enabled: z.boolean().optional(),
499
+ configWrites: z.boolean().optional(),
500
+ cliPath: ExecutableTokenSchema.optional(),
501
+ dbPath: z.string().optional(),
502
+ remoteHost: z.string().optional(),
503
+ service: z.union([
504
+ z.literal("imessage"),
505
+ z.literal("sms"),
506
+ z.literal("auto")
507
+ ]).optional(),
508
+ region: z.string().optional(),
509
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
510
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
511
+ groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
512
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
513
+ historyLimit: z.number().int().min(0).optional(),
514
+ dmHistoryLimit: z.number().int().min(0).optional(),
515
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
516
+ includeAttachments: z.boolean().optional(),
517
+ mediaMaxMb: z.number().int().positive().optional(),
518
+ textChunkLimit: z.number().int().positive().optional(),
519
+ chunkMode: z.enum(["length", "newline"]).optional(),
520
+ blockStreaming: z.boolean().optional(),
521
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
522
+ groups: z.record(z.string(), z.object({
523
+ requireMention: z.boolean().optional(),
524
+ tools: ToolPolicySchema,
525
+ toolsBySender: ToolPolicyBySenderSchema
526
+ }).strict().optional()).optional(),
527
+ heartbeat: ChannelHeartbeatVisibilitySchema
528
+ }).strict();
529
+ const IMessageAccountSchema = IMessageAccountSchemaBase.superRefine((value, ctx) => {
530
+ requireOpenAllowFrom({
531
+ policy: value.dmPolicy,
532
+ allowFrom: value.allowFrom,
533
+ ctx,
534
+ path: ["allowFrom"],
535
+ message: "channels.imessage.dmPolicy=\"open\" requires channels.imessage.allowFrom to include \"*\""
536
+ });
537
+ });
538
+ const IMessageConfigSchema = IMessageAccountSchemaBase.extend({ accounts: z.record(z.string(), IMessageAccountSchema.optional()).optional() }).superRefine((value, ctx) => {
539
+ requireOpenAllowFrom({
540
+ policy: value.dmPolicy,
541
+ allowFrom: value.allowFrom,
542
+ ctx,
543
+ path: ["allowFrom"],
544
+ message: "channels.imessage.dmPolicy=\"open\" requires channels.imessage.allowFrom to include \"*\""
545
+ });
546
+ });
547
+ const BlueBubblesAllowFromEntry = z.union([z.string(), z.number()]);
548
+ const BlueBubblesActionSchema = z.object({
549
+ reactions: z.boolean().optional(),
550
+ edit: z.boolean().optional(),
551
+ unsend: z.boolean().optional(),
552
+ reply: z.boolean().optional(),
553
+ sendWithEffect: z.boolean().optional(),
554
+ renameGroup: z.boolean().optional(),
555
+ setGroupIcon: z.boolean().optional(),
556
+ addParticipant: z.boolean().optional(),
557
+ removeParticipant: z.boolean().optional(),
558
+ leaveGroup: z.boolean().optional(),
559
+ sendAttachment: z.boolean().optional()
560
+ }).strict().optional();
561
+ const BlueBubblesGroupConfigSchema = z.object({
562
+ requireMention: z.boolean().optional(),
563
+ tools: ToolPolicySchema,
564
+ toolsBySender: ToolPolicyBySenderSchema
565
+ }).strict();
566
+ const BlueBubblesAccountSchemaBase = z.object({
567
+ name: z.string().optional(),
568
+ capabilities: z.array(z.string()).optional(),
569
+ markdown: MarkdownConfigSchema,
570
+ configWrites: z.boolean().optional(),
571
+ enabled: z.boolean().optional(),
572
+ serverUrl: z.string().optional(),
573
+ password: z.string().optional(),
574
+ webhookPath: z.string().optional(),
575
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
576
+ allowFrom: z.array(BlueBubblesAllowFromEntry).optional(),
577
+ groupAllowFrom: z.array(BlueBubblesAllowFromEntry).optional(),
578
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
579
+ historyLimit: z.number().int().min(0).optional(),
580
+ dmHistoryLimit: z.number().int().min(0).optional(),
581
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
582
+ textChunkLimit: z.number().int().positive().optional(),
583
+ chunkMode: z.enum(["length", "newline"]).optional(),
584
+ mediaMaxMb: z.number().int().positive().optional(),
585
+ sendReadReceipts: z.boolean().optional(),
586
+ blockStreaming: z.boolean().optional(),
587
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
588
+ groups: z.record(z.string(), BlueBubblesGroupConfigSchema.optional()).optional(),
589
+ heartbeat: ChannelHeartbeatVisibilitySchema
590
+ }).strict();
591
+ const BlueBubblesAccountSchema = BlueBubblesAccountSchemaBase.superRefine((value, ctx) => {
592
+ requireOpenAllowFrom({
593
+ policy: value.dmPolicy,
594
+ allowFrom: value.allowFrom,
595
+ ctx,
596
+ path: ["allowFrom"],
597
+ message: "channels.bluebubbles.accounts.*.dmPolicy=\"open\" requires allowFrom to include \"*\""
598
+ });
599
+ });
600
+ const BlueBubblesConfigSchema = BlueBubblesAccountSchemaBase.extend({
601
+ accounts: z.record(z.string(), BlueBubblesAccountSchema.optional()).optional(),
602
+ actions: BlueBubblesActionSchema
603
+ }).superRefine((value, ctx) => {
604
+ requireOpenAllowFrom({
605
+ policy: value.dmPolicy,
606
+ allowFrom: value.allowFrom,
607
+ ctx,
608
+ path: ["allowFrom"],
609
+ message: "channels.bluebubbles.dmPolicy=\"open\" requires channels.bluebubbles.allowFrom to include \"*\""
610
+ });
611
+ });
612
+ const MSTeamsChannelSchema = z.object({
613
+ requireMention: z.boolean().optional(),
614
+ tools: ToolPolicySchema,
615
+ toolsBySender: ToolPolicyBySenderSchema,
616
+ replyStyle: MSTeamsReplyStyleSchema.optional()
617
+ }).strict();
618
+ const MSTeamsTeamSchema = z.object({
619
+ requireMention: z.boolean().optional(),
620
+ tools: ToolPolicySchema,
621
+ toolsBySender: ToolPolicyBySenderSchema,
622
+ replyStyle: MSTeamsReplyStyleSchema.optional(),
623
+ channels: z.record(z.string(), MSTeamsChannelSchema.optional()).optional()
624
+ }).strict();
625
+ const MSTeamsConfigSchema = z.object({
626
+ enabled: z.boolean().optional(),
627
+ capabilities: z.array(z.string()).optional(),
628
+ markdown: MarkdownConfigSchema,
629
+ configWrites: z.boolean().optional(),
630
+ appId: z.string().optional(),
631
+ appPassword: z.string().optional(),
632
+ tenantId: z.string().optional(),
633
+ webhook: z.object({
634
+ port: z.number().int().positive().optional(),
635
+ path: z.string().optional()
636
+ }).strict().optional(),
637
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
638
+ allowFrom: z.array(z.string()).optional(),
639
+ groupAllowFrom: z.array(z.string()).optional(),
640
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
641
+ textChunkLimit: z.number().int().positive().optional(),
642
+ chunkMode: z.enum(["length", "newline"]).optional(),
643
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
644
+ mediaAllowHosts: z.array(z.string()).optional(),
645
+ mediaAuthAllowHosts: z.array(z.string()).optional(),
646
+ requireMention: z.boolean().optional(),
647
+ historyLimit: z.number().int().min(0).optional(),
648
+ dmHistoryLimit: z.number().int().min(0).optional(),
649
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
650
+ replyStyle: MSTeamsReplyStyleSchema.optional(),
651
+ teams: z.record(z.string(), MSTeamsTeamSchema.optional()).optional(),
652
+ mediaMaxMb: z.number().positive().optional(),
653
+ sharePointSiteId: z.string().optional(),
654
+ heartbeat: ChannelHeartbeatVisibilitySchema
655
+ }).strict().superRefine((value, ctx) => {
656
+ requireOpenAllowFrom({
657
+ policy: value.dmPolicy,
658
+ allowFrom: value.allowFrom,
659
+ ctx,
660
+ path: ["allowFrom"],
661
+ message: "channels.msteams.dmPolicy=\"open\" requires channels.msteams.allowFrom to include \"*\""
662
+ });
663
+ });
664
+ const WhatsAppAccountSchema = z.object({
665
+ name: z.string().optional(),
666
+ capabilities: z.array(z.string()).optional(),
667
+ markdown: MarkdownConfigSchema,
668
+ configWrites: z.boolean().optional(),
669
+ enabled: z.boolean().optional(),
670
+ sendReadReceipts: z.boolean().optional(),
671
+ messagePrefix: z.string().optional(),
672
+ authDir: z.string().optional(),
673
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
674
+ selfChatMode: z.boolean().optional(),
675
+ allowFrom: z.array(z.string()).optional(),
676
+ groupAllowFrom: z.array(z.string()).optional(),
677
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
678
+ historyLimit: z.number().int().min(0).optional(),
679
+ dmHistoryLimit: z.number().int().min(0).optional(),
680
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
681
+ textChunkLimit: z.number().int().positive().optional(),
682
+ chunkMode: z.enum(["length", "newline"]).optional(),
683
+ mediaMaxMb: z.number().int().positive().optional(),
684
+ blockStreaming: z.boolean().optional(),
685
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
686
+ groups: z.record(z.string(), z.object({
687
+ requireMention: z.boolean().optional(),
688
+ tools: ToolPolicySchema,
689
+ toolsBySender: ToolPolicyBySenderSchema
690
+ }).strict().optional()).optional(),
691
+ ackReaction: z.object({
692
+ emoji: z.string().optional(),
693
+ direct: z.boolean().optional().default(true),
694
+ group: z.enum([
695
+ "always",
696
+ "mentions",
697
+ "never"
698
+ ]).optional().default("mentions")
699
+ }).strict().optional(),
700
+ debounceMs: z.number().int().nonnegative().optional().default(0),
701
+ heartbeat: ChannelHeartbeatVisibilitySchema
702
+ }).strict().superRefine((value, ctx) => {
703
+ if (value.dmPolicy !== "open") return;
704
+ if ((value.allowFrom ?? []).map((v) => String(v).trim()).filter(Boolean).includes("*")) return;
705
+ ctx.addIssue({
706
+ code: z.ZodIssueCode.custom,
707
+ path: ["allowFrom"],
708
+ message: "channels.whatsapp.accounts.*.dmPolicy=\"open\" requires allowFrom to include \"*\""
709
+ });
710
+ });
711
+ const WhatsAppConfigSchema = z.object({
712
+ accounts: z.record(z.string(), WhatsAppAccountSchema.optional()).optional(),
713
+ capabilities: z.array(z.string()).optional(),
714
+ markdown: MarkdownConfigSchema,
715
+ configWrites: z.boolean().optional(),
716
+ sendReadReceipts: z.boolean().optional(),
717
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
718
+ messagePrefix: z.string().optional(),
719
+ selfChatMode: z.boolean().optional(),
720
+ allowFrom: z.array(z.string()).optional(),
721
+ groupAllowFrom: z.array(z.string()).optional(),
722
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
723
+ historyLimit: z.number().int().min(0).optional(),
724
+ dmHistoryLimit: z.number().int().min(0).optional(),
725
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
726
+ textChunkLimit: z.number().int().positive().optional(),
727
+ chunkMode: z.enum(["length", "newline"]).optional(),
728
+ mediaMaxMb: z.number().int().positive().optional().default(50),
729
+ blockStreaming: z.boolean().optional(),
730
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
731
+ actions: z.object({
732
+ reactions: z.boolean().optional(),
733
+ sendMessage: z.boolean().optional(),
734
+ polls: z.boolean().optional()
735
+ }).strict().optional(),
736
+ groups: z.record(z.string(), z.object({
737
+ requireMention: z.boolean().optional(),
738
+ tools: ToolPolicySchema,
739
+ toolsBySender: ToolPolicyBySenderSchema
740
+ }).strict().optional()).optional(),
741
+ ackReaction: z.object({
742
+ emoji: z.string().optional(),
743
+ direct: z.boolean().optional().default(true),
744
+ group: z.enum([
745
+ "always",
746
+ "mentions",
747
+ "never"
748
+ ]).optional().default("mentions")
749
+ }).strict().optional(),
750
+ debounceMs: z.number().int().nonnegative().optional().default(0),
751
+ heartbeat: ChannelHeartbeatVisibilitySchema
752
+ }).strict().superRefine((value, ctx) => {
753
+ if (value.dmPolicy !== "open") return;
754
+ if ((value.allowFrom ?? []).map((v) => String(v).trim()).filter(Boolean).includes("*")) return;
755
+ ctx.addIssue({
756
+ code: z.ZodIssueCode.custom,
757
+ path: ["allowFrom"],
758
+ message: "channels.whatsapp.dmPolicy=\"open\" requires channels.whatsapp.allowFrom to include \"*\""
759
+ });
760
+ });
761
+ const TwitterConfigSchema = z.object({
762
+ enabled: z.boolean().optional(),
763
+ apiKey: z.string().optional(),
764
+ apiSecretKey: z.string().optional(),
765
+ accessToken: z.string().optional(),
766
+ accessTokenSecret: z.string().optional(),
767
+ postEnable: z.boolean().optional().default(true),
768
+ postImmediately: z.boolean().optional().default(false),
769
+ postIntervalMin: z.number().int().positive().optional().default(90),
770
+ postIntervalMax: z.number().int().positive().optional().default(180),
771
+ postIntervalVariance: z.number().min(0).max(1).optional().default(.1),
772
+ searchEnable: z.boolean().optional().default(false),
773
+ autoRespondMentions: z.boolean().optional().default(true),
774
+ enableActionProcessing: z.boolean().optional().default(true),
775
+ timelineAlgorithm: z.enum(["weighted", "latest"]).optional().default("weighted"),
776
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
777
+ dryRun: z.boolean().optional().default(false),
778
+ retryLimit: z.number().int().positive().optional().default(3),
779
+ pollInterval: z.number().int().positive().optional().default(120),
780
+ maxTweetLength: z.number().int().positive().optional().default(4e3),
781
+ configWrites: z.boolean().optional()
782
+ }).strict();
783
+
784
+ //#endregion
785
+ export { BlueBubblesConfigSchema, DiscordConfigSchema, GoogleChatConfigSchema, IMessageConfigSchema, MSTeamsConfigSchema, SignalConfigSchema, SlackConfigSchema, TelegramConfigSchema, TwitterConfigSchema, WhatsAppConfigSchema };