enya-agent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/.env.example +20 -0
  2. package/.github/workflows/ci.yml +70 -0
  3. package/.github/workflows/publish.yml +250 -0
  4. package/.gitmodules +3 -0
  5. package/Cargo.lock +3584 -0
  6. package/Cargo.toml +97 -0
  7. package/crates/enact/Cargo.toml +27 -0
  8. package/crates/enact/src/lib.rs +60 -0
  9. package/crates/enact-a2a/Cargo.toml +25 -0
  10. package/crates/enact-a2a/src/lib.rs +411 -0
  11. package/crates/enact-channels/Cargo.toml +64 -0
  12. package/crates/enact-channels/examples/README.md +80 -0
  13. package/crates/enact-channels/examples/channel_bot.rs +169 -0
  14. package/crates/enact-channels/examples/telegram-echo.rs +34 -0
  15. package/crates/enact-channels/examples/whatsapp-echo.rs +142 -0
  16. package/crates/enact-channels/src/config.rs +213 -0
  17. package/crates/enact-channels/src/lib.rs +25 -0
  18. package/crates/enact-channels/src/runtime.rs +237 -0
  19. package/crates/enact-channels/src/security/mod.rs +5 -0
  20. package/crates/enact-channels/src/security/pairing.rs +205 -0
  21. package/crates/enact-channels/src/teams.rs +601 -0
  22. package/crates/enact-channels/src/telegram.rs +2833 -0
  23. package/crates/enact-channels/src/traits.rs +200 -0
  24. package/crates/enact-channels/src/webhook.rs +262 -0
  25. package/crates/enact-channels/src/whatsapp.rs +310 -0
  26. package/crates/enact-cli/Cargo.toml +40 -0
  27. package/crates/enact-cli/src/commands/doctor.rs +62 -0
  28. package/crates/enact-cli/src/commands/mod.rs +3 -0
  29. package/crates/enact-cli/src/commands/run.rs +69 -0
  30. package/crates/enact-cli/src/commands/serve.rs +81 -0
  31. package/crates/enact-cli/src/config.rs +2 -0
  32. package/crates/enact-cli/src/main.rs +79 -0
  33. package/crates/enact-config/Cargo.toml +36 -0
  34. package/crates/enact-config/ENV_VAR_MAPPING.md +135 -0
  35. package/crates/enact-config/QUICK_REFERENCE.md +92 -0
  36. package/crates/enact-config/README.md +107 -0
  37. package/crates/enact-config/TESTING.md +161 -0
  38. package/crates/enact-config/examples/test-env-vars.rs +100 -0
  39. package/crates/enact-config/src/config.rs +399 -0
  40. package/crates/enact-config/src/encrypted_store.rs +211 -0
  41. package/crates/enact-config/src/lib.rs +298 -0
  42. package/crates/enact-config/src/secrets.rs +149 -0
  43. package/crates/enact-config/src/sync.rs +260 -0
  44. package/crates/enact-config/test-env-vars.sh +34 -0
  45. package/crates/enact-config/tests/README.md +99 -0
  46. package/crates/enact-config/tests/config_integration_test.rs +202 -0
  47. package/crates/enact-config/tests/security_test.rs +140 -0
  48. package/crates/enact-context/Cargo.toml +41 -0
  49. package/crates/enact-context/src/budget.rs +314 -0
  50. package/crates/enact-context/src/calibrator.rs +535 -0
  51. package/crates/enact-context/src/compactor.rs +392 -0
  52. package/crates/enact-context/src/condenser.rs +826 -0
  53. package/crates/enact-context/src/lib.rs +94 -0
  54. package/crates/enact-context/src/segment.rs +238 -0
  55. package/crates/enact-context/src/step_context.rs +645 -0
  56. package/crates/enact-context/src/token_counter.rs +148 -0
  57. package/crates/enact-context/src/window.rs +372 -0
  58. package/crates/enact-core/Cargo.toml +42 -0
  59. package/crates/enact-core/README.md +98 -0
  60. package/crates/enact-core/src/background/executor.rs +524 -0
  61. package/crates/enact-core/src/background/mod.rs +48 -0
  62. package/crates/enact-core/src/background/target_binding.rs +390 -0
  63. package/crates/enact-core/src/background/trigger.rs +511 -0
  64. package/crates/enact-core/src/callable/callable.rs +152 -0
  65. package/crates/enact-core/src/callable/composite.rs +817 -0
  66. package/crates/enact-core/src/callable/graph.rs +104 -0
  67. package/crates/enact-core/src/callable/llm.rs +211 -0
  68. package/crates/enact-core/src/callable/mod.rs +64 -0
  69. package/crates/enact-core/src/callable/registry.rs +206 -0
  70. package/crates/enact-core/src/context/execution_context.rs +757 -0
  71. package/crates/enact-core/src/context/invocation.rs +99 -0
  72. package/crates/enact-core/src/context/mod.rs +50 -0
  73. package/crates/enact-core/src/context/tenant.rs +175 -0
  74. package/crates/enact-core/src/context/trace.rs +127 -0
  75. package/crates/enact-core/src/flow/conditional.rs +293 -0
  76. package/crates/enact-core/src/flow/mod.rs +43 -0
  77. package/crates/enact-core/src/flow/parallel.rs +437 -0
  78. package/crates/enact-core/src/flow/repeat.rs +534 -0
  79. package/crates/enact-core/src/flow/sequential.rs +248 -0
  80. package/crates/enact-core/src/graph/checkpoint.rs +79 -0
  81. package/crates/enact-core/src/graph/checkpoint_store.rs +76 -0
  82. package/crates/enact-core/src/graph/compiled.rs +189 -0
  83. package/crates/enact-core/src/graph/edge.rs +59 -0
  84. package/crates/enact-core/src/graph/graph_schema.rs +218 -0
  85. package/crates/enact-core/src/graph/loader.rs +155 -0
  86. package/crates/enact-core/src/graph/mod.rs +18 -0
  87. package/crates/enact-core/src/graph/node/function.rs +49 -0
  88. package/crates/enact-core/src/graph/node/mod.rs +48 -0
  89. package/crates/enact-core/src/graph/schema.rs +62 -0
  90. package/crates/enact-core/src/inbox/message.rs +405 -0
  91. package/crates/enact-core/src/inbox/mod.rs +31 -0
  92. package/crates/enact-core/src/inbox/store.rs +355 -0
  93. package/crates/enact-core/src/kernel/artifact/filesystem.rs +546 -0
  94. package/crates/enact-core/src/kernel/artifact/metadata.rs +283 -0
  95. package/crates/enact-core/src/kernel/artifact/mod.rs +27 -0
  96. package/crates/enact-core/src/kernel/artifact/store.rs +427 -0
  97. package/crates/enact-core/src/kernel/enforcement.rs +1315 -0
  98. package/crates/enact-core/src/kernel/error.rs +1200 -0
  99. package/crates/enact-core/src/kernel/event.rs +1394 -0
  100. package/crates/enact-core/src/kernel/execution_model.rs +831 -0
  101. package/crates/enact-core/src/kernel/execution_state.rs +189 -0
  102. package/crates/enact-core/src/kernel/execution_strategy.rs +117 -0
  103. package/crates/enact-core/src/kernel/ids.rs +2086 -0
  104. package/crates/enact-core/src/kernel/interrupt.rs +125 -0
  105. package/crates/enact-core/src/kernel/kernel.rs +1283 -0
  106. package/crates/enact-core/src/kernel/mod.rs +205 -0
  107. package/crates/enact-core/src/kernel/persistence/event_store.rs +270 -0
  108. package/crates/enact-core/src/kernel/persistence/message_store.rs +908 -0
  109. package/crates/enact-core/src/kernel/persistence/mod.rs +102 -0
  110. package/crates/enact-core/src/kernel/persistence/state_store.rs +228 -0
  111. package/crates/enact-core/src/kernel/persistence/vector_store.rs +299 -0
  112. package/crates/enact-core/src/kernel/reducer.rs +808 -0
  113. package/crates/enact-core/src/kernel/replay.rs +153 -0
  114. package/crates/enact-core/src/lib.rs +413 -0
  115. package/crates/enact-core/src/memory/episodic.rs +0 -0
  116. package/crates/enact-core/src/memory/mod.rs +6 -0
  117. package/crates/enact-core/src/memory/semantic.rs +0 -0
  118. package/crates/enact-core/src/memory/trait.rs +0 -0
  119. package/crates/enact-core/src/memory/vector_db.rs +0 -0
  120. package/crates/enact-core/src/memory/working.rs +0 -0
  121. package/crates/enact-core/src/policy/execution_policy.rs +292 -0
  122. package/crates/enact-core/src/policy/filters.rs +458 -0
  123. package/crates/enact-core/src/policy/input_processor.rs +407 -0
  124. package/crates/enact-core/src/policy/long_running.rs +134 -0
  125. package/crates/enact-core/src/policy/mod.rs +193 -0
  126. package/crates/enact-core/src/policy/pii_input.rs +274 -0
  127. package/crates/enact-core/src/policy/tenant_policy.rs +453 -0
  128. package/crates/enact-core/src/policy/tool_policy.rs +407 -0
  129. package/crates/enact-core/src/providers/mod.rs +63 -0
  130. package/crates/enact-core/src/providers/trait.rs +292 -0
  131. package/crates/enact-core/src/runner/callbacks.rs +6 -0
  132. package/crates/enact-core/src/runner/execution_runner.rs +476 -0
  133. package/crates/enact-core/src/runner/loop.rs +117 -0
  134. package/crates/enact-core/src/runner/mod.rs +58 -0
  135. package/crates/enact-core/src/runner/protected_runner.rs +280 -0
  136. package/crates/enact-core/src/signal/inmemory.rs +231 -0
  137. package/crates/enact-core/src/signal/mod.rs +108 -0
  138. package/crates/enact-core/src/streaming/event_logger.rs +195 -0
  139. package/crates/enact-core/src/streaming/event_stream.rs +1423 -0
  140. package/crates/enact-core/src/streaming/mod.rs +108 -0
  141. package/crates/enact-core/src/streaming/pause_cancel.rs +0 -0
  142. package/crates/enact-core/src/streaming/protected_emitter.rs +173 -0
  143. package/crates/enact-core/src/streaming/protection/context.rs +136 -0
  144. package/crates/enact-core/src/streaming/protection/encryption.rs +289 -0
  145. package/crates/enact-core/src/streaming/protection/mod.rs +43 -0
  146. package/crates/enact-core/src/streaming/protection/pii_protection.rs +243 -0
  147. package/crates/enact-core/src/streaming/protection/processor.rs +166 -0
  148. package/crates/enact-core/src/streaming/sse.rs +0 -0
  149. package/crates/enact-core/src/telemetry/exporter.rs +0 -0
  150. package/crates/enact-core/src/telemetry/init.rs +0 -0
  151. package/crates/enact-core/src/telemetry/mod.rs +49 -0
  152. package/crates/enact-core/src/telemetry/spans.rs +245 -0
  153. package/crates/enact-core/src/tool/agent_tool.rs +177 -0
  154. package/crates/enact-core/src/tool/browser/mod.rs +0 -0
  155. package/crates/enact-core/src/tool/browser/webdriver.rs +0 -0
  156. package/crates/enact-core/src/tool/cost.rs +247 -0
  157. package/crates/enact-core/src/tool/discovery.rs +0 -0
  158. package/crates/enact-core/src/tool/dispatcher.rs +347 -0
  159. package/crates/enact-core/src/tool/filesystem.rs +231 -0
  160. package/crates/enact-core/src/tool/function.rs +99 -0
  161. package/crates/enact-core/src/tool/git.rs +162 -0
  162. package/crates/enact-core/src/tool/http.rs +214 -0
  163. package/crates/enact-core/src/tool/mcp/client.rs +0 -0
  164. package/crates/enact-core/src/tool/mcp/mod.rs +0 -0
  165. package/crates/enact-core/src/tool/mod.rs +51 -0
  166. package/crates/enact-core/src/tool/reasoning/debugging.rs +0 -0
  167. package/crates/enact-core/src/tool/reasoning/mcts.rs +0 -0
  168. package/crates/enact-core/src/tool/reasoning/mod.rs +0 -0
  169. package/crates/enact-core/src/tool/reasoning/sequential.rs +0 -0
  170. package/crates/enact-core/src/tool/sandbox/dagger.rs +0 -0
  171. package/crates/enact-core/src/tool/sandbox/mod.rs +0 -0
  172. package/crates/enact-core/src/tool/shell.rs +147 -0
  173. package/crates/enact-core/src/tool/trait.rs +33 -0
  174. package/crates/enact-core/src/tool/web_search.rs +277 -0
  175. package/crates/enact-core/src/util/config.rs +0 -0
  176. package/crates/enact-core/src/util/errors.rs +0 -0
  177. package/crates/enact-core/src/util/mod.rs +6 -0
  178. package/crates/enact-core/tests/airgapped_e2e_test.rs +291 -0
  179. package/crates/enact-core/tests/e2e_agentic_loop.rs +119 -0
  180. package/crates/enact-core/tests/e2e_test.rs +259 -0
  181. package/crates/enact-core/tests/graph_test.rs +130 -0
  182. package/crates/enact-core/tests/stream_event_id_validation.rs +435 -0
  183. package/crates/enact-cron/Cargo.toml +28 -0
  184. package/crates/enact-cron/src/lib.rs +44 -0
  185. package/crates/enact-cron/src/schedule.rs +156 -0
  186. package/crates/enact-cron/src/store.rs +589 -0
  187. package/crates/enact-cron/src/types.rs +148 -0
  188. package/crates/enact-gateway/Cargo.toml +31 -0
  189. package/crates/enact-gateway/README.md +30 -0
  190. package/crates/enact-gateway/examples/whatsapp-gateway-runner-mock.rs +59 -0
  191. package/crates/enact-gateway/examples/whatsapp-gateway.rs +42 -0
  192. package/crates/enact-gateway/src/lib.rs +582 -0
  193. package/crates/enact-mcp/Cargo.toml +24 -0
  194. package/crates/enact-mcp/src/lib.rs +178 -0
  195. package/crates/enact-memory/Cargo.toml +25 -0
  196. package/crates/enact-memory/src/backend.rs +20 -0
  197. package/crates/enact-memory/src/chunker.rs +230 -0
  198. package/crates/enact-memory/src/embeddings.rs +221 -0
  199. package/crates/enact-memory/src/lib.rs +67 -0
  200. package/crates/enact-memory/src/markdown.rs +127 -0
  201. package/crates/enact-memory/src/none.rs +61 -0
  202. package/crates/enact-memory/src/sqlite.rs +276 -0
  203. package/crates/enact-memory/src/traits.rs +65 -0
  204. package/crates/enact-memory/src/vector.rs +198 -0
  205. package/crates/enact-oauth/Cargo.toml +27 -0
  206. package/crates/enact-oauth/src/lib.rs +584 -0
  207. package/crates/enact-observability/Cargo.toml +22 -0
  208. package/crates/enact-observability/src/lib.rs +197 -0
  209. package/crates/enact-providers/Cargo.toml +33 -0
  210. package/crates/enact-providers/examples/hello-agent.rs +33 -0
  211. package/crates/enact-providers/src/anthropic.rs +182 -0
  212. package/crates/enact-providers/src/azure.rs +96 -0
  213. package/crates/enact-providers/src/bridge.rs +221 -0
  214. package/crates/enact-providers/src/gemini.rs +227 -0
  215. package/crates/enact-providers/src/http.rs +78 -0
  216. package/crates/enact-providers/src/lib.rs +53 -0
  217. package/crates/enact-providers/src/openai_compatible.rs +167 -0
  218. package/crates/enact-providers/src/openrouter.rs +33 -0
  219. package/crates/enact-runner/Cargo.toml +24 -0
  220. package/crates/enact-runner/README.md +76 -0
  221. package/crates/enact-runner/src/compaction.rs +225 -0
  222. package/crates/enact-runner/src/config.rs +118 -0
  223. package/crates/enact-runner/src/lib.rs +63 -0
  224. package/crates/enact-runner/src/loop_driver.rs +414 -0
  225. package/crates/enact-runner/src/parser.rs +421 -0
  226. package/crates/enact-runner/src/retry.rs +262 -0
  227. package/crates/enact-runner/tests/integration.rs +278 -0
  228. package/crates/enact-security/Cargo.toml +22 -0
  229. package/crates/enact-security/src/audit.rs +375 -0
  230. package/crates/enact-security/src/lib.rs +37 -0
  231. package/crates/enact-security/src/policy.rs +406 -0
  232. package/crates/enact-skills/Cargo.toml +25 -0
  233. package/crates/enact-skills/src/lib.rs +506 -0
  234. package/crates/enact-tools/Cargo.toml +22 -0
  235. package/crates/enact-tools/src/file_read.rs +166 -0
  236. package/crates/enact-tools/src/file_write.rs +216 -0
  237. package/crates/enact-tools/src/git_operations.rs +513 -0
  238. package/crates/enact-tools/src/http_request.rs +417 -0
  239. package/crates/enact-tools/src/lib.rs +104 -0
  240. package/crates/enact-tools/src/security.rs +227 -0
  241. package/crates/enact-tools/src/shell.rs +191 -0
  242. package/crates/enact-tools/src/traits.rs +159 -0
  243. package/docs/Makefile +74 -0
  244. package/docs/config.toml +62 -0
  245. package/docs/content/_index.md +174 -0
  246. package/docs/content/a2a/_index.md +431 -0
  247. package/docs/content/api/_index.md +323 -0
  248. package/docs/content/channels/_index.md +160 -0
  249. package/docs/content/channels/teams.md +205 -0
  250. package/docs/content/channels/telegram.md +182 -0
  251. package/docs/content/channels/webhook.md +423 -0
  252. package/docs/content/channels/whatsapp.md +240 -0
  253. package/docs/content/cli/_index.md +261 -0
  254. package/docs/content/concepts/_index.md +273 -0
  255. package/docs/content/configuration/_index.md +241 -0
  256. package/docs/content/cron/_index.md +248 -0
  257. package/docs/content/developers/_index.md +278 -0
  258. package/docs/content/getting-started/_index.md +180 -0
  259. package/docs/content/installation/_index.md +186 -0
  260. package/docs/content/installation/uninstall.md +101 -0
  261. package/docs/content/installation/updating.md +120 -0
  262. package/docs/content/mcp/_index.md +215 -0
  263. package/docs/content/memory/_index.md +163 -0
  264. package/docs/content/oauth/_index.md +515 -0
  265. package/docs/content/providers/_index.md +206 -0
  266. package/docs/content/roadmap/_index.md +199 -0
  267. package/docs/content/security/_index.md +219 -0
  268. package/docs/content/skills/_index.md +228 -0
  269. package/docs/content/tools/_index.md +485 -0
  270. package/docs/content/troubleshooting/_index.md +259 -0
  271. package/docs/content/yaml-schema/_index.md +294 -0
  272. package/docs/static/giallo-dark.css +91 -0
  273. package/docs/static/giallo-light.css +91 -0
  274. package/docs/themes/tanuki/.github/workflows/deploy.yml +44 -0
  275. package/docs/themes/tanuki/LICENSE +21 -0
  276. package/docs/themes/tanuki/README.md +166 -0
  277. package/docs/themes/tanuki/examples/blog/config.toml +58 -0
  278. package/docs/themes/tanuki/examples/blog/content/_index.md +4 -0
  279. package/docs/themes/tanuki/examples/blog/content/about.md +33 -0
  280. package/docs/themes/tanuki/examples/blog/content/blog/_index.md +7 -0
  281. package/docs/themes/tanuki/examples/blog/content/blog/api-design-best-practices.md +245 -0
  282. package/docs/themes/tanuki/examples/blog/content/blog/building-accessible-websites.md +147 -0
  283. package/docs/themes/tanuki/examples/blog/content/blog/css-grid-vs-flexbox.md +165 -0
  284. package/docs/themes/tanuki/examples/blog/content/blog/customizing-catppuccin-colors.md +137 -0
  285. package/docs/themes/tanuki/examples/blog/content/blog/dark-mode-best-practices.md +82 -0
  286. package/docs/themes/tanuki/examples/blog/content/blog/docker-essentials.md +301 -0
  287. package/docs/themes/tanuki/examples/blog/content/blog/getting-started-with-zola.md +129 -0
  288. package/docs/themes/tanuki/examples/blog/content/blog/git-workflow-for-content.md +112 -0
  289. package/docs/themes/tanuki/examples/blog/content/blog/introduction-to-webassembly.md +183 -0
  290. package/docs/themes/tanuki/examples/blog/content/blog/modern-javascript-features.md +234 -0
  291. package/docs/themes/tanuki/examples/blog/content/blog/testing-strategies.md +311 -0
  292. package/docs/themes/tanuki/examples/blog/content/blog/typography-for-developers.md +104 -0
  293. package/docs/themes/tanuki/examples/blog/content/blog/welcome-to-tanuki.md +67 -0
  294. package/docs/themes/tanuki/examples/blog/content/blog/why-static-sites.md +85 -0
  295. package/docs/themes/tanuki/examples/blog/content/projects.md +64 -0
  296. package/docs/themes/tanuki/examples/book/config.toml +17 -0
  297. package/docs/themes/tanuki/examples/book/content/_index.md +12 -0
  298. package/docs/themes/tanuki/examples/book/content/chapter-1.md +90 -0
  299. package/docs/themes/tanuki/examples/book/content/chapter-2.md +143 -0
  300. package/docs/themes/tanuki/examples/book/content/chapter-3.md +217 -0
  301. package/docs/themes/tanuki/examples/book/content/chapter-4.md +224 -0
  302. package/docs/themes/tanuki/examples/book/content/chapter-5.md +297 -0
  303. package/docs/themes/tanuki/examples/book/content/print.md +6 -0
  304. package/docs/themes/tanuki/examples/docs/config.toml +28 -0
  305. package/docs/themes/tanuki/examples/docs/content/_index.md +20 -0
  306. package/docs/themes/tanuki/examples/docs/content/components.md +156 -0
  307. package/docs/themes/tanuki/examples/docs/content/configuration.md +94 -0
  308. package/docs/themes/tanuki/examples/docs/content/customization.md +202 -0
  309. package/docs/themes/tanuki/examples/docs/content/deployment.md +204 -0
  310. package/docs/themes/tanuki/examples/docs/content/installation.md +59 -0
  311. package/docs/themes/tanuki/examples/docs/content/print.md +6 -0
  312. package/docs/themes/tanuki/examples/docs/static/img/tanuki-icon.avif +0 -0
  313. package/docs/themes/tanuki/examples/index.html +2104 -0
  314. package/docs/themes/tanuki/mise.toml +108 -0
  315. package/docs/themes/tanuki/sass/base/_catppuccin.scss +164 -0
  316. package/docs/themes/tanuki/sass/base/_fonts.scss +64 -0
  317. package/docs/themes/tanuki/sass/base/_reset.scss +152 -0
  318. package/docs/themes/tanuki/sass/base/_typography.scss +523 -0
  319. package/docs/themes/tanuki/sass/components/_buttons.scss +209 -0
  320. package/docs/themes/tanuki/sass/components/_code.scss +457 -0
  321. package/docs/themes/tanuki/sass/components/_landing.scss +633 -0
  322. package/docs/themes/tanuki/sass/components/_layout.scss +294 -0
  323. package/docs/themes/tanuki/sass/components/_navigation.scss +1200 -0
  324. package/docs/themes/tanuki/sass/components/_print.scss +237 -0
  325. package/docs/themes/tanuki/sass/components/_search.scss +224 -0
  326. package/docs/themes/tanuki/sass/components/_sidebar.scss +473 -0
  327. package/docs/themes/tanuki/sass/components/_theme-toggle.scss +186 -0
  328. package/docs/themes/tanuki/sass/modes/_blog.scss +366 -0
  329. package/docs/themes/tanuki/sass/modes/_product.scss +875 -0
  330. package/docs/themes/tanuki/sass/modes/_raskell.scss +1696 -0
  331. package/docs/themes/tanuki/sass/patterns/_buttons.scss +183 -0
  332. package/docs/themes/tanuki/sass/patterns/_cards.scss +144 -0
  333. package/docs/themes/tanuki/sass/patterns/_index.scss +9 -0
  334. package/docs/themes/tanuki/sass/patterns/_lists.scss +259 -0
  335. package/docs/themes/tanuki/sass/patterns/_sections.scss +243 -0
  336. package/docs/themes/tanuki/sass/style.scss +47 -0
  337. package/docs/themes/tanuki/sass/tokens/_colors.scss +139 -0
  338. package/docs/themes/tanuki/sass/tokens/_spacing.scss +100 -0
  339. package/docs/themes/tanuki/sass/tokens/_typography.scss +186 -0
  340. package/docs/themes/tanuki/screenshot.png +0 -0
  341. package/docs/themes/tanuki/sentinel.kdl +59 -0
  342. package/docs/themes/tanuki/static/elasticlunr.min.js +10 -0
  343. package/docs/themes/tanuki/static/fonts/GEIST-LICENSE.txt +92 -0
  344. package/docs/themes/tanuki/static/fonts/Geist-Variable.woff2 +0 -0
  345. package/docs/themes/tanuki/static/fonts/GeistMono-Variable.woff2 +0 -0
  346. package/docs/themes/tanuki/static/img/tanuki-icon.avif +0 -0
  347. package/docs/themes/tanuki/static/img/tanuki-icon.png +0 -0
  348. package/docs/themes/tanuki/static/js/anchors.js +18 -0
  349. package/docs/themes/tanuki/static/js/app.js +274 -0
  350. package/docs/themes/tanuki/static/js/code.js +394 -0
  351. package/docs/themes/tanuki/static/js/navigation.js +778 -0
  352. package/docs/themes/tanuki/static/js/scroll-to-top.js +33 -0
  353. package/docs/themes/tanuki/static/js/search-raskell.js +240 -0
  354. package/docs/themes/tanuki/static/js/search.js +215 -0
  355. package/docs/themes/tanuki/static/js/theme.js +169 -0
  356. package/docs/themes/tanuki/static/syntax-dark.css +151 -0
  357. package/docs/themes/tanuki/static/syntax-light.css +151 -0
  358. package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm.js +486 -0
  359. package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm_bg.wasm +0 -0
  360. package/docs/themes/tanuki/templates/404.html +52 -0
  361. package/docs/themes/tanuki/templates/base.html +428 -0
  362. package/docs/themes/tanuki/templates/blog.html +66 -0
  363. package/docs/themes/tanuki/templates/home.html +108 -0
  364. package/docs/themes/tanuki/templates/index.html +178 -0
  365. package/docs/themes/tanuki/templates/landing.html +168 -0
  366. package/docs/themes/tanuki/templates/macros/nav.html +128 -0
  367. package/docs/themes/tanuki/templates/macros/posts.html +101 -0
  368. package/docs/themes/tanuki/templates/macros/ui.html +159 -0
  369. package/docs/themes/tanuki/templates/page.html +135 -0
  370. package/docs/themes/tanuki/templates/partials/footer.html +38 -0
  371. package/docs/themes/tanuki/templates/partials/header.html +366 -0
  372. package/docs/themes/tanuki/templates/partials/nav-buttons.html +55 -0
  373. package/docs/themes/tanuki/templates/partials/nav-overlay.html +81 -0
  374. package/docs/themes/tanuki/templates/partials/page-toc-panel.html +43 -0
  375. package/docs/themes/tanuki/templates/partials/search.html +52 -0
  376. package/docs/themes/tanuki/templates/partials/sidebar.html +107 -0
  377. package/docs/themes/tanuki/templates/partials/theme-toggle.html +35 -0
  378. package/docs/themes/tanuki/templates/partials/toc-overlay.html +146 -0
  379. package/docs/themes/tanuki/templates/partials/version-picker.html +38 -0
  380. package/docs/themes/tanuki/templates/print.html +244 -0
  381. package/docs/themes/tanuki/templates/section.html +186 -0
  382. package/docs/themes/tanuki/templates/taxonomy_list.html +18 -0
  383. package/docs/themes/tanuki/templates/taxonomy_single.html +31 -0
  384. package/docs/themes/tanuki/theme.toml +58 -0
  385. package/examples/hello-agent.rs +55 -0
  386. package/package.json +36 -0
  387. package/proto/config.proto +60 -0
  388. package/proto/events.proto +0 -0
  389. package/proto/runtime.proto +215 -0
@@ -0,0 +1,323 @@
1
+ +++
2
+ title = "API Reference"
3
+ weight = 6
4
+ sort_by = "weight"
5
+ +++
6
+
7
+ # API Reference
8
+
9
+ HTTP Gateway and Rust library API for Enact.
10
+
11
+ ## Status
12
+
13
+ | API | Status |
14
+ |-----|--------|
15
+ | HTTP Gateway | ✅ Complete |
16
+ | WhatsApp Webhook | ✅ Complete |
17
+ | Rust Library API | ✅ Complete |
18
+ | gRPC API | 🚧 Future |
19
+ | WebSocket Streaming | 🚧 Future |
20
+
21
+ ## HTTP Gateway
22
+
23
+ The gateway is started with `enact serve` and provides webhook endpoints for channels.
24
+
25
+ ### Starting the Gateway
26
+
27
+ ```bash
28
+ ./target/release/enact serve --http-port 8080
29
+ ```
30
+
31
+ ### Endpoints
32
+
33
+ | Endpoint | Method | Description |
34
+ |----------|--------|-------------|
35
+ | `/health` | GET | Health check |
36
+ | `/webhook/whatsapp` | GET | WhatsApp verification |
37
+ | `/webhook/whatsapp` | POST | WhatsApp messages |
38
+
39
+ ---
40
+
41
+ ## GET /health
42
+
43
+ Health check endpoint.
44
+
45
+ **Request:**
46
+ ```bash
47
+ curl http://localhost:8080/health
48
+ ```
49
+
50
+ **Response:**
51
+ ```json
52
+ {"status": "ok"}
53
+ ```
54
+
55
+ ---
56
+
57
+ ## GET /webhook/whatsapp
58
+
59
+ WhatsApp webhook verification for Meta's challenge-response.
60
+
61
+ **Request (from Meta):**
62
+ ```
63
+ GET /webhook/whatsapp?hub.mode=subscribe&hub.verify_token=YOUR_TOKEN&hub.challenge=CHALLENGE_STRING
64
+ ```
65
+
66
+ **Response:**
67
+ - `200 OK` with challenge string if token matches
68
+ - `403 Forbidden` if token doesn't match
69
+
70
+ ---
71
+
72
+ ## POST /webhook/whatsapp
73
+
74
+ Process incoming WhatsApp messages.
75
+
76
+ **Request (from Meta):**
77
+ ```json
78
+ {
79
+ "entry": [{
80
+ "changes": [{
81
+ "value": {
82
+ "messages": [{
83
+ "from": "+1234567890",
84
+ "text": {"body": "Hello!"},
85
+ "id": "wamid.xxx",
86
+ "timestamp": "1234567890"
87
+ }]
88
+ }
89
+ }]
90
+ }]
91
+ }
92
+ ```
93
+
94
+ **Headers:**
95
+ - `X-Hub-Signature-256`: HMAC signature (if `WHATSAPP_APP_SECRET` is configured)
96
+ - `X-Idempotency-Key`: Optional, for deduplication
97
+
98
+ **Response:**
99
+ ```json
100
+ {"status": "ok", "processed": 1}
101
+ ```
102
+
103
+ **Response (duplicate):**
104
+ ```json
105
+ {"status": "duplicate_ignored"}
106
+ ```
107
+
108
+ **Response (rate limited):**
109
+ ```json
110
+ {"error": "rate limit exceeded"}
111
+ ```
112
+ Status: `429 Too Many Requests`
113
+
114
+ **Response (invalid signature):**
115
+ ```json
116
+ {"error": "invalid signature"}
117
+ ```
118
+ Status: `401 Unauthorized`
119
+
120
+ ---
121
+
122
+ ## Gateway Features
123
+
124
+ ### Rate Limiting
125
+
126
+ - **Algorithm**: Sliding window
127
+ - **Default**: 120 requests/minute per client IP
128
+ - **Max tracked clients**: 10,000
129
+
130
+ ### Idempotency
131
+
132
+ - **TTL**: 5 minutes
133
+ - **Key source**: `X-Idempotency-Key` header or SHA-256 of body
134
+ - **Max tracked keys**: 10,000
135
+
136
+ ### Request Limits
137
+
138
+ - **Max body size**: 64KB
139
+ - **Request timeout**: 30 seconds
140
+
141
+ ### Signature Verification
142
+
143
+ When `WHATSAPP_APP_SECRET` is set:
144
+ - Validates `X-Hub-Signature-256` header
145
+ - Rejects requests with invalid signatures
146
+
147
+ ---
148
+
149
+ ## Gateway Configuration
150
+
151
+ ```rust
152
+ pub struct GatewayConfig {
153
+ pub host: String, // default: "0.0.0.0"
154
+ pub port: u16, // default: 8080
155
+ pub webhook_rate_limit_per_minute: u32, // default: 120
156
+ pub max_rate_limit_keys: usize, // default: 10,000
157
+ pub idempotency_ttl_secs: u64, // default: 300
158
+ pub idempotency_max_keys: usize, // default: 10,000
159
+ pub trust_forwarded_headers: bool, // default: false
160
+ }
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Rust Library API
166
+
167
+ ### Core Types
168
+
169
+ #### Callable
170
+
171
+ The main trait for agent implementations:
172
+
173
+ ```rust
174
+ #[async_trait]
175
+ pub trait Callable: Send + Sync {
176
+ fn name(&self) -> &str;
177
+ async fn run(&self, input: &str) -> anyhow::Result<String>;
178
+ }
179
+ ```
180
+
181
+ #### LlmCallable
182
+
183
+ LLM-powered callable:
184
+
185
+ ```rust
186
+ use enact_core::callable::LlmCallable;
187
+ use enact_providers::OpenAICompatible;
188
+
189
+ let provider = Arc::new(OpenAICompatible::new(
190
+ "https://api.openai.com",
191
+ "gpt-4o-mini",
192
+ Some(api_key),
193
+ ));
194
+
195
+ let callable = LlmCallable::with_provider(
196
+ "my-agent",
197
+ "You are a helpful assistant.",
198
+ provider,
199
+ );
200
+ ```
201
+
202
+ #### DefaultAgentRunner
203
+
204
+ Executes callables with retry/compaction:
205
+
206
+ ```rust
207
+ use enact_runner::{DefaultAgentRunner, LoopOutcome};
208
+
209
+ let mut runner = DefaultAgentRunner::default_new();
210
+ let outcome = runner.run(&callable, "Hello!").await?;
211
+
212
+ match outcome {
213
+ LoopOutcome::Completed(output) => println!("{}", output),
214
+ LoopOutcome::MaxIterationsReached { last_output, .. } => { /* ... */ },
215
+ LoopOutcome::Cancelled => { /* ... */ },
216
+ LoopOutcome::TimedOut { elapsed_secs } => { /* ... */ },
217
+ }
218
+ ```
219
+
220
+ ### Channel Trait
221
+
222
+ ```rust
223
+ #[async_trait]
224
+ pub trait Channel: Send + Sync {
225
+ fn channel_id(&self) -> &str;
226
+ fn channel_type(&self) -> ChannelType;
227
+ async fn receive(&self) -> Result<IncomingMessage>;
228
+ async fn send(&self, message: OutgoingMessage) -> Result<MessageId>;
229
+ async fn run(&self) -> Result<()>;
230
+ }
231
+ ```
232
+
233
+ ### Provider Trait
234
+
235
+ ```rust
236
+ #[async_trait]
237
+ pub trait ModelProvider: Send + Sync {
238
+ async fn complete(&self, request: ChatRequest) -> Result<ChatResponse>;
239
+ fn requires_network(&self) -> bool { true }
240
+ }
241
+ ```
242
+
243
+ ### InboundResponder
244
+
245
+ For custom message handling in the gateway:
246
+
247
+ ```rust
248
+ #[async_trait]
249
+ pub trait InboundResponder: Send + Sync {
250
+ async fn handle(&self, message: &ChannelMessage) -> anyhow::Result<Option<String>>;
251
+ }
252
+ ```
253
+
254
+ Built-in implementations:
255
+ - `EchoResponder` - Echoes messages back
256
+ - `RunnerResponder` - Routes through `DefaultAgentRunner`
257
+
258
+ ---
259
+
260
+ ## Usage Examples
261
+
262
+ ### Basic Agent Execution
263
+
264
+ ```rust
265
+ use enact_core::callable::LlmCallable;
266
+ use enact_providers::OpenAICompatible;
267
+ use enact_runner::DefaultAgentRunner;
268
+ use std::sync::Arc;
269
+
270
+ #[tokio::main]
271
+ async fn main() -> anyhow::Result<()> {
272
+ let api_key = std::env::var("OPENAI_API_KEY")?;
273
+
274
+ let provider = Arc::new(OpenAICompatible::new(
275
+ "https://api.openai.com",
276
+ "gpt-4o-mini",
277
+ Some(api_key),
278
+ ));
279
+
280
+ let callable = LlmCallable::with_provider(
281
+ "assistant",
282
+ "You are a helpful assistant.",
283
+ provider,
284
+ );
285
+
286
+ let mut runner = DefaultAgentRunner::default_new();
287
+ let outcome = runner.run(&callable, "What is Rust?").await?;
288
+
289
+ println!("{:?}", outcome);
290
+ Ok(())
291
+ }
292
+ ```
293
+
294
+ ### Custom Gateway Handler
295
+
296
+ ```rust
297
+ use enact_gateway::{GatewayConfig, GatewayState, InboundResponder, serve};
298
+ use enact_channels::WhatsAppChannel;
299
+ use async_trait::async_trait;
300
+
301
+ struct MyResponder;
302
+
303
+ #[async_trait]
304
+ impl InboundResponder for MyResponder {
305
+ async fn handle(&self, message: &ChannelMessage) -> anyhow::Result<Option<String>> {
306
+ Ok(Some(format!("Got: {}", message.content)))
307
+ }
308
+ }
309
+
310
+ #[tokio::main]
311
+ async fn main() -> anyhow::Result<()> {
312
+ let channel = Arc::new(WhatsAppChannel::new(/* ... */));
313
+ let config = GatewayConfig::default();
314
+ let state = GatewayState::new(
315
+ channel,
316
+ Some("app_secret".to_string()),
317
+ Arc::new(MyResponder),
318
+ &config,
319
+ );
320
+
321
+ serve(config, state).await
322
+ }
323
+ ```
@@ -0,0 +1,160 @@
1
+ +++
2
+ title = "Channels"
3
+ weight = 6
4
+ sort_by = "weight"
5
+ +++
6
+
7
+ # Channels
8
+
9
+ Enact supports deploying agents to multiple messaging platforms.
10
+
11
+ ## Supported Channels
12
+
13
+ | Channel | Status | Description |
14
+ |---------|--------|-------------|
15
+ | [Telegram](/channels/telegram/) | ✅ Implemented | Bot API integration |
16
+ | [Teams](/channels/teams/) | ✅ Implemented | Microsoft Teams bot |
17
+ | [WhatsApp](/channels/whatsapp/) | ✅ Implemented | Meta Business API |
18
+ | [Webhook](/channels/webhook/) | ✅ Implemented | Generic HTTP webhooks |
19
+ | Discord | ❌ Not Planned | Discord bot (skip) |
20
+ | Slack | ❌ Not Planned | Slack app (skip) |
21
+
22
+ ## Architecture
23
+
24
+ ```
25
+ ┌──────────────────────────────────────────────────────────────┐
26
+ │ Messaging Platforms │
27
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
28
+ │ │ Telegram │ │ Teams │ │ WhatsApp │ │ Discord │ │
29
+ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
30
+ └───────┼─────────────┼─────────────┼─────────────┼───────────┘
31
+ │ │ │ │
32
+ └─────────────┴──────┬──────┴─────────────┘
33
+
34
+ ┌────────▼────────┐
35
+ │ Channel Trait │
36
+ │ receive() │
37
+ │ send() │
38
+ │ run() │
39
+ └────────┬────────┘
40
+
41
+ ┌────────▼────────┐
42
+ │ Agent Runtime │
43
+ │ (enact-core) │
44
+ └─────────────────┘
45
+ ```
46
+
47
+ ## Channel Trait
48
+
49
+ All channels implement the `Channel` trait:
50
+
51
+ ```rust
52
+ #[async_trait]
53
+ pub trait Channel: Send + Sync {
54
+ /// Unique channel identifier
55
+ fn channel_id(&self) -> &str;
56
+
57
+ /// Channel type (telegram, teams, whatsapp)
58
+ fn channel_type(&self) -> ChannelType;
59
+
60
+ /// Receive incoming message
61
+ async fn receive(&self) -> Result<IncomingMessage>;
62
+
63
+ /// Send outgoing message
64
+ async fn send(&self, message: OutgoingMessage) -> Result<MessageId>;
65
+
66
+ /// Run the channel event loop
67
+ async fn run(&self) -> Result<()>;
68
+ }
69
+ ```
70
+
71
+ ## Configuration
72
+
73
+ Each channel requires specific credentials in `.env`:
74
+
75
+ ```bash
76
+ # Telegram
77
+ TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
78
+
79
+ # Teams
80
+ TEAMS_APP_ID=...
81
+ TEAMS_APP_SECRET=...
82
+ TEAMS_TENANT_ID=...
83
+
84
+ # WhatsApp
85
+ WHATSAPP_PHONE_NUMBER_ID=...
86
+ WHATSAPP_ACCESS_TOKEN=...
87
+ WHATSAPP_WEBHOOK_VERIFY_TOKEN=...
88
+ ```
89
+
90
+ ## Using Channels (Rust API)
91
+
92
+ ```rust
93
+ use enact_channels::telegram::TelegramChannel;
94
+ use enact_channels::ChannelConfig;
95
+
96
+ // Create channel
97
+ let config = ChannelConfig::from_env()?;
98
+ let telegram = TelegramChannel::new(config)?;
99
+
100
+ // Run channel (blocking)
101
+ telegram.run().await?;
102
+ ```
103
+
104
+ ## Multi-Channel Deployment (🚧 Future)
105
+
106
+ Run multiple channels simultaneously:
107
+
108
+ ```rust
109
+ use enact_channels::{telegram, teams, whatsapp};
110
+ use tokio::join;
111
+
112
+ let tg = telegram::TelegramChannel::new(config)?;
113
+ let ms = teams::TeamsChannel::new(config)?;
114
+ let wa = whatsapp::WhatsAppChannel::new(config)?;
115
+
116
+ // Run all channels concurrently
117
+ join!(tg.run(), ms.run(), wa.run());
118
+ ```
119
+
120
+ ## Channel-Specific Features
121
+
122
+ ### Telegram
123
+ - Inline keyboards
124
+ - Media support (photos, documents)
125
+ - Bot commands
126
+ - Group chat support
127
+
128
+ ### Teams
129
+ - Adaptive cards
130
+ - SSO authentication
131
+ - Proactive messaging
132
+ - Meeting integration (🚧)
133
+
134
+ ### WhatsApp
135
+ - Interactive messages
136
+ - Message templates
137
+ - Media messages
138
+ - Business API features
139
+
140
+ ## Security
141
+
142
+ Each channel has security features in `enact-channels/src/security/`:
143
+
144
+ - **Rate limiting**: Prevent abuse
145
+ - **User allowlists**: Restrict access
146
+ - **Message validation**: Verify message integrity
147
+ - **Webhook verification**: Validate incoming webhooks
148
+
149
+ ```rust
150
+ use enact_channels::security::{RateLimiter, AllowList};
151
+
152
+ let limiter = RateLimiter::new(10, Duration::from_secs(60)); // 10 msg/min
153
+ let allowlist = AllowList::from_users(vec!["+1234567890"]);
154
+ ```
155
+
156
+ ## Next Steps
157
+
158
+ - [Telegram Setup](/channels/telegram/)
159
+ - [Teams Setup](/channels/teams/)
160
+ - [WhatsApp Setup](/channels/whatsapp/)
@@ -0,0 +1,205 @@
1
+ +++
2
+ title = "Microsoft Teams"
3
+ weight = 2
4
+ +++
5
+
6
+ # Microsoft Teams Channel
7
+
8
+ Deploy your Enact agent to Microsoft Teams.
9
+
10
+ ## Status
11
+
12
+ | Feature | Status |
13
+ |---------|--------|
14
+ | Bot Framework Integration | ✅ Implemented |
15
+ | Text Messages | ✅ Implemented |
16
+ | Adaptive Cards | ✅ Implemented |
17
+ | SSO Authentication | 🚧 Partial |
18
+ | Proactive Messaging | ✅ Implemented |
19
+ | Meeting Integration | 🚧 Future |
20
+
21
+ ## Setup
22
+
23
+ ### 1. Register Azure AD Application
24
+
25
+ 1. Go to [Azure Portal](https://portal.azure.com)
26
+ 2. Navigate to Azure Active Directory > App registrations
27
+ 3. Click "New registration"
28
+ 4. Configure:
29
+ - Name: Your bot name
30
+ - Supported account types: Multitenant
31
+ 5. Note the **Application (client) ID**
32
+
33
+ ### 2. Create Client Secret
34
+
35
+ 1. In your app, go to "Certificates & secrets"
36
+ 2. Click "New client secret"
37
+ 3. Copy the secret value immediately
38
+
39
+ ### 3. Register with Bot Framework
40
+
41
+ 1. Go to [Bot Framework Portal](https://dev.botframework.com/bots/new)
42
+ 2. Fill in bot details
43
+ 3. Use your Azure AD App ID
44
+ 4. Add the Teams channel
45
+
46
+ ### 4. Configure Environment
47
+
48
+ ```bash
49
+ # .env
50
+ TEAMS_APP_ID=your-azure-ad-app-id
51
+ TEAMS_APP_SECRET=your-client-secret
52
+ TEAMS_TENANT_ID=your-tenant-id # or "common" for multi-tenant
53
+ ```
54
+
55
+ ### 5. Run Channel (Rust API)
56
+
57
+ ```rust
58
+ use enact_channels::teams::{TeamsChannel, TeamsConfig};
59
+
60
+ #[tokio::main]
61
+ async fn main() -> anyhow::Result<()> {
62
+ let config = TeamsConfig {
63
+ app_id: std::env::var("TEAMS_APP_ID")?,
64
+ app_secret: std::env::var("TEAMS_APP_SECRET")?,
65
+ tenant_id: std::env::var("TEAMS_TENANT_ID")?,
66
+ ..Default::default()
67
+ };
68
+
69
+ let channel = TeamsChannel::new(config)?;
70
+ channel.run().await?;
71
+
72
+ Ok(())
73
+ }
74
+ ```
75
+
76
+ ## Configuration Options
77
+
78
+ ```rust
79
+ pub struct TeamsConfig {
80
+ /// Azure AD Application ID
81
+ pub app_id: String,
82
+
83
+ /// Azure AD Client Secret
84
+ pub app_secret: String,
85
+
86
+ /// Tenant ID or "common"
87
+ pub tenant_id: String,
88
+
89
+ /// Service URL for Bot Framework
90
+ pub service_url: String,
91
+
92
+ /// Enable proactive messaging
93
+ pub enable_proactive: bool,
94
+ }
95
+ ```
96
+
97
+ ## Features
98
+
99
+ ### Adaptive Cards
100
+
101
+ ```rust
102
+ use enact_channels::teams::AdaptiveCard;
103
+
104
+ let card = AdaptiveCard::new()
105
+ .add_text_block("Welcome!", true)
106
+ .add_text_block("Choose an action:")
107
+ .add_action_set(vec![
108
+ Action::submit("Run Query", "action_query"),
109
+ Action::submit("Get Help", "action_help"),
110
+ ]);
111
+
112
+ channel.send(OutgoingMessage {
113
+ conversation_id: message.conversation_id,
114
+ attachments: vec![card.into()],
115
+ ..Default::default()
116
+ }).await?;
117
+ ```
118
+
119
+ ### Handling Card Actions
120
+
121
+ ```rust
122
+ match message.message_type {
123
+ MessageType::CardAction(action) => {
124
+ match action.verb.as_str() {
125
+ "action_query" => { /* Handle query */ }
126
+ "action_help" => { /* Handle help */ }
127
+ _ => {}
128
+ }
129
+ }
130
+ _ => {}
131
+ }
132
+ ```
133
+
134
+ ### Proactive Messaging
135
+
136
+ Send messages without user prompting:
137
+
138
+ ```rust
139
+ // Store conversation reference
140
+ let conv_ref = message.conversation_reference();
141
+ store_reference(user_id, conv_ref).await;
142
+
143
+ // Later, send proactive message
144
+ channel.send_proactive(
145
+ stored_conv_ref,
146
+ "Reminder: Your task is due!",
147
+ ).await?;
148
+ ```
149
+
150
+ ## App Manifest
151
+
152
+ Create `manifest.json` for Teams:
153
+
154
+ ```json
155
+ {
156
+ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
157
+ "manifestVersion": "1.16",
158
+ "version": "1.0.0",
159
+ "id": "your-app-id",
160
+ "packageName": "com.yourcompany.enact",
161
+ "developer": {
162
+ "name": "Your Company",
163
+ "websiteUrl": "https://yourcompany.com",
164
+ "privacyUrl": "https://yourcompany.com/privacy",
165
+ "termsOfUseUrl": "https://yourcompany.com/terms"
166
+ },
167
+ "name": {
168
+ "short": "Enact Bot",
169
+ "full": "Enact AI Assistant"
170
+ },
171
+ "description": {
172
+ "short": "AI-powered assistant",
173
+ "full": "Enact AI Assistant for Teams"
174
+ },
175
+ "bots": [
176
+ {
177
+ "botId": "your-bot-id",
178
+ "scopes": ["personal", "team", "groupchat"]
179
+ }
180
+ ]
181
+ }
182
+ ```
183
+
184
+ ## Security
185
+
186
+ ### Tenant Restriction
187
+
188
+ Restrict to specific tenants:
189
+
190
+ ```rust
191
+ let config = TeamsConfig {
192
+ tenant_id: "your-specific-tenant-id".to_string(),
193
+ ..Default::default()
194
+ };
195
+ ```
196
+
197
+ ### User Validation
198
+
199
+ Validate users before processing:
200
+
201
+ ```rust
202
+ if !allowed_users.contains(&message.user_id) {
203
+ return Err(ChannelError::Unauthorized);
204
+ }
205
+ ```