redis-iris 0.1.0a1__tar.gz

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 (237) hide show
  1. redis_iris-0.1.0a1/.autorc +90 -0
  2. redis_iris-0.1.0a1/.github/dependabot.yml +20 -0
  3. redis_iris-0.1.0a1/.github/workflows/auto-release.yml +257 -0
  4. redis_iris-0.1.0a1/.github/workflows/ci.yml +107 -0
  5. redis_iris-0.1.0a1/.github/workflows/docs.yml +49 -0
  6. redis_iris-0.1.0a1/.github/workflows/integration.yml +60 -0
  7. redis_iris-0.1.0a1/.github/workflows/publish.yml +82 -0
  8. redis_iris-0.1.0a1/.gitignore +36 -0
  9. redis_iris-0.1.0a1/AGENTS.md +53 -0
  10. redis_iris-0.1.0a1/CONTRIBUTING.md +148 -0
  11. redis_iris-0.1.0a1/Formula/redis-iris.rb +22 -0
  12. redis_iris-0.1.0a1/LICENSE +21 -0
  13. redis_iris-0.1.0a1/PACKAGE_EVOLUTION_PLAN.md +122 -0
  14. redis_iris-0.1.0a1/PKG-INFO +154 -0
  15. redis_iris-0.1.0a1/README.md +129 -0
  16. redis_iris-0.1.0a1/RELEASE_PIPELINE_PLAN.md +181 -0
  17. redis_iris-0.1.0a1/Taskfile.yml +49 -0
  18. redis_iris-0.1.0a1/config.example.toml +14 -0
  19. redis_iris-0.1.0a1/docs/assets/favicon.png +0 -0
  20. redis_iris-0.1.0a1/docs/assets/redis-logo-script-red.svg +11 -0
  21. redis_iris-0.1.0a1/docs/assets/redis-logo-script.svg +11 -0
  22. redis_iris-0.1.0a1/docs/core/agent-memory.md +204 -0
  23. redis_iris-0.1.0a1/docs/core/context-retriever.md +137 -0
  24. redis_iris-0.1.0a1/docs/core/errors.md +27 -0
  25. redis_iris-0.1.0a1/docs/core/index.md +40 -0
  26. redis_iris-0.1.0a1/docs/core/iris.md +24 -0
  27. redis_iris-0.1.0a1/docs/core/playbook.md +175 -0
  28. redis_iris-0.1.0a1/docs/index.md +48 -0
  29. redis_iris-0.1.0a1/docs/skills/add-agent-memory/SKILL.md +132 -0
  30. redis_iris-0.1.0a1/docs/skills/add-context-retriever/SKILL.md +98 -0
  31. redis_iris-0.1.0a1/docs/skills/add-playbook/SKILL.md +169 -0
  32. redis_iris-0.1.0a1/docs/skills/add-redis-iris/SKILL.md +60 -0
  33. redis_iris-0.1.0a1/docs/skills/index.md +61 -0
  34. redis_iris-0.1.0a1/docs/stylesheets/redis-brand.css +91 -0
  35. redis_iris-0.1.0a1/docs/user_guides/answer-from-approved-policy.md +136 -0
  36. redis_iris-0.1.0a1/docs/user_guides/configuration.md +97 -0
  37. redis_iris-0.1.0a1/docs/user_guides/index.md +20 -0
  38. redis_iris-0.1.0a1/docs/user_guides/live-account-data.md +133 -0
  39. redis_iris-0.1.0a1/docs/user_guides/one-support-turn.md +126 -0
  40. redis_iris-0.1.0a1/docs/user_guides/playbook-cli.md +613 -0
  41. redis_iris-0.1.0a1/docs/user_guides/remember-customers.md +143 -0
  42. redis_iris-0.1.0a1/docs/user_guides/set-up-agent-memory.md +88 -0
  43. redis_iris-0.1.0a1/docs/user_guides/set-up-playbook.md +94 -0
  44. redis_iris-0.1.0a1/examples/.env.example +32 -0
  45. redis_iris-0.1.0a1/examples/01_plug_in_agent_memory.md +260 -0
  46. redis_iris-0.1.0a1/examples/01_plug_in_agent_memory.py +261 -0
  47. redis_iris-0.1.0a1/examples/02_publish_policy_with_playbook.md +223 -0
  48. redis_iris-0.1.0a1/examples/02_publish_policy_with_playbook.py +221 -0
  49. redis_iris-0.1.0a1/examples/03_live_accounts_with_context_retriever.md +188 -0
  50. redis_iris-0.1.0a1/examples/03_live_accounts_with_context_retriever.py +188 -0
  51. redis_iris-0.1.0a1/examples/04_one_support_turn.md +147 -0
  52. redis_iris-0.1.0a1/examples/04_one_support_turn.py +149 -0
  53. redis_iris-0.1.0a1/examples/README.md +144 -0
  54. redis_iris-0.1.0a1/examples/example/__init__.py +63 -0
  55. redis_iris-0.1.0a1/examples/example/data/accounts.jsonl +4 -0
  56. redis_iris-0.1.0a1/examples/example/data/customers.jsonl +3 -0
  57. redis_iris-0.1.0a1/examples/example/data/faqs/card-replacement.json +8 -0
  58. redis_iris-0.1.0a1/examples/example/data/faqs/dispute-charge.json +8 -0
  59. redis_iris-0.1.0a1/examples/example/data/faqs/overdraft-fee-refund.json +8 -0
  60. redis_iris-0.1.0a1/examples/example/data/faqs/overdraft-fee.json +8 -0
  61. redis_iris-0.1.0a1/examples/example/data/faqs/routing-number.json +8 -0
  62. redis_iris-0.1.0a1/examples/example/data/memories.jsonl +4 -0
  63. redis_iris-0.1.0a1/examples/example/data/skills/dispute-intake/.iris-playbook.json +5 -0
  64. redis_iris-0.1.0a1/examples/example/data/skills/dispute-intake/SKILL.md +13 -0
  65. redis_iris-0.1.0a1/examples/example/data/transactions.jsonl +11 -0
  66. redis_iris-0.1.0a1/examples/example/langgraph_glue.py +245 -0
  67. redis_iris-0.1.0a1/examples/example/models.py +68 -0
  68. redis_iris-0.1.0a1/examples/example/turn.py +119 -0
  69. redis_iris-0.1.0a1/examples/local/context-retriever.ports.yaml +30 -0
  70. redis_iris-0.1.0a1/examples/local/memory.env.yaml +15 -0
  71. redis_iris-0.1.0a1/examples/local/playbook.openai.yaml +20 -0
  72. redis_iris-0.1.0a1/examples/maintain.py +853 -0
  73. redis_iris-0.1.0a1/examples/playbook_cli.sh +23 -0
  74. redis_iris-0.1.0a1/examples/setup_meridian.py +188 -0
  75. redis_iris-0.1.0a1/examples/spec.md +209 -0
  76. redis_iris-0.1.0a1/examples/ui/.gitignore +3 -0
  77. redis_iris-0.1.0a1/examples/ui/.oxfmtrc.json +13 -0
  78. redis_iris-0.1.0a1/examples/ui/.oxlintrc.json +43 -0
  79. redis_iris-0.1.0a1/examples/ui/index.html +12 -0
  80. redis_iris-0.1.0a1/examples/ui/package-lock.json +4853 -0
  81. redis_iris-0.1.0a1/examples/ui/package.json +45 -0
  82. redis_iris-0.1.0a1/examples/ui/server.py +208 -0
  83. redis_iris-0.1.0a1/examples/ui/src/App.tsx +5 -0
  84. redis_iris-0.1.0a1/examples/ui/src/api/client.ts +79 -0
  85. redis_iris-0.1.0a1/examples/ui/src/api/queryKeys.ts +12 -0
  86. redis_iris-0.1.0a1/examples/ui/src/api/types.ts +84 -0
  87. redis_iris-0.1.0a1/examples/ui/src/main.tsx +24 -0
  88. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/MeridianScreen/MeridianScreen.style.ts +30 -0
  89. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/MeridianScreen/MeridianScreen.tsx +43 -0
  90. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/OperatorPanel.style.ts +9 -0
  91. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/OperatorPanel.tsx +25 -0
  92. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/MemoryOwnerCard/MemoryOwnerCard.style.ts +37 -0
  93. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/MemoryOwnerCard/MemoryOwnerCard.tsx +92 -0
  94. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/PlaybookEntriesCard/PlaybookEntriesCard.style.ts +41 -0
  95. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/PlaybookEntriesCard/PlaybookEntriesCard.tsx +130 -0
  96. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/PlaybookEntriesCard/PlaybookEntriesCard.types.ts +6 -0
  97. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/RetrieverStatusCard/RetrieverStatusCard.style.ts +13 -0
  98. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/RetrieverStatusCard/RetrieverStatusCard.tsx +36 -0
  99. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/StackStatusCard/StackStatusCard.style.ts +13 -0
  100. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/StackStatusCard/StackStatusCard.tsx +39 -0
  101. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/SupportChatPanel.style.ts +17 -0
  102. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/SupportChatPanel.tsx +56 -0
  103. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/SupportChatPanel.types.ts +5 -0
  104. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatComposer/ChatComposer.style.ts +12 -0
  105. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatComposer/ChatComposer.tsx +48 -0
  106. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatComposer/ChatComposer.types.ts +5 -0
  107. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.style.ts +24 -0
  108. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.test.tsx +37 -0
  109. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.tsx +25 -0
  110. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.types.ts +6 -0
  111. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/TurnEvidencePanel.style.ts +9 -0
  112. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/TurnEvidencePanel.tsx +43 -0
  113. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/TurnEvidencePanel.types.ts +5 -0
  114. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/MemoryEvidenceList/MemoryEvidenceList.style.ts +19 -0
  115. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/MemoryEvidenceList/MemoryEvidenceList.tsx +28 -0
  116. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/MemoryEvidenceList/MemoryEvidenceList.types.ts +5 -0
  117. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/PolicyEvidenceList/PolicyEvidenceList.style.ts +19 -0
  118. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/PolicyEvidenceList/PolicyEvidenceList.tsx +29 -0
  119. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/PolicyEvidenceList/PolicyEvidenceList.types.ts +5 -0
  120. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/TransactionsTable/TransactionsTable.style.ts +27 -0
  121. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/TransactionsTable/TransactionsTable.tsx +38 -0
  122. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/TransactionsTable/TransactionsTable.types.ts +5 -0
  123. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useConfigQuery/useConfigQuery.ts +7 -0
  124. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useEraseMemoryMutation/useEraseMemoryMutation.ts +20 -0
  125. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useMemoryOwnerQuery/useMemoryOwnerQuery.ts +8 -0
  126. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/usePlaybookEntriesQuery/usePlaybookEntriesQuery.ts +8 -0
  127. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/usePlaybookVersionsQuery/usePlaybookVersionsQuery.ts +13 -0
  128. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/usePublishVersionMutation/usePublishVersionMutation.ts +23 -0
  129. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useReseedMemoryMutation/useReseedMemoryMutation.ts +19 -0
  130. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useRetrieverQuery/useRetrieverQuery.ts +8 -0
  131. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useStackQuery/useStackQuery.ts +10 -0
  132. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useTurnMutation/useTurnMutation.ts +19 -0
  133. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useWithdrawEntryMutation/useWithdrawEntryMutation.ts +23 -0
  134. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/types/chat.ts +7 -0
  135. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/utils/formatScore/formatScore.test.ts +11 -0
  136. redis_iris-0.1.0a1/examples/ui/src/screens/meridian/utils/formatScore/formatScore.ts +3 -0
  137. redis_iris-0.1.0a1/examples/ui/src/styled.d.ts +9 -0
  138. redis_iris-0.1.0a1/examples/ui/src/test/setup-tests.ts +26 -0
  139. redis_iris-0.1.0a1/examples/ui/src/theme/ResponsiveRem/ResponsiveRem.ts +21 -0
  140. redis_iris-0.1.0a1/examples/ui/src/theme/ThemeProvider/ThemeProvider.tsx +22 -0
  141. redis_iris-0.1.0a1/examples/ui/src/theme/ThemeProvider/ThemeProvider.types.ts +5 -0
  142. redis_iris-0.1.0a1/examples/ui/src/utils/formatAmount/formatAmount.test.ts +15 -0
  143. redis_iris-0.1.0a1/examples/ui/src/utils/formatAmount/formatAmount.ts +7 -0
  144. redis_iris-0.1.0a1/examples/ui/src/utils/formatDate/formatDate.test.ts +13 -0
  145. redis_iris-0.1.0a1/examples/ui/src/utils/formatDate/formatDate.ts +5 -0
  146. redis_iris-0.1.0a1/examples/ui/src/vite-env.d.ts +1 -0
  147. redis_iris-0.1.0a1/examples/ui/tsconfig.app.json +25 -0
  148. redis_iris-0.1.0a1/examples/ui/tsconfig.json +4 -0
  149. redis_iris-0.1.0a1/examples/ui/tsconfig.node.json +17 -0
  150. redis_iris-0.1.0a1/examples/ui/vite.config.ts +42 -0
  151. redis_iris-0.1.0a1/mkdocs.yml +134 -0
  152. redis_iris-0.1.0a1/mkdocs_hooks.py +20 -0
  153. redis_iris-0.1.0a1/pyproject.toml +129 -0
  154. redis_iris-0.1.0a1/src/redis_iris/__init__.py +21 -0
  155. redis_iris-0.1.0a1/src/redis_iris/__main__.py +6 -0
  156. redis_iris-0.1.0a1/src/redis_iris/_settings.py +30 -0
  157. redis_iris-0.1.0a1/src/redis_iris/agent_memory/__init__.py +43 -0
  158. redis_iris-0.1.0a1/src/redis_iris/agent_memory/_wire.py +47 -0
  159. redis_iris-0.1.0a1/src/redis_iris/agent_memory/conversation.py +81 -0
  160. redis_iris-0.1.0a1/src/redis_iris/agent_memory/hooks.py +55 -0
  161. redis_iris-0.1.0a1/src/redis_iris/agent_memory/ids.py +27 -0
  162. redis_iris-0.1.0a1/src/redis_iris/agent_memory/memory.py +309 -0
  163. redis_iris-0.1.0a1/src/redis_iris/agent_memory/settings.py +66 -0
  164. redis_iris-0.1.0a1/src/redis_iris/agent_memory/values.py +66 -0
  165. redis_iris-0.1.0a1/src/redis_iris/cli/__init__.py +1 -0
  166. redis_iris-0.1.0a1/src/redis_iris/cli/__main__.py +6 -0
  167. redis_iris-0.1.0a1/src/redis_iris/cli/core/__init__.py +1 -0
  168. redis_iris-0.1.0a1/src/redis_iris/cli/core/branding.py +22 -0
  169. redis_iris-0.1.0a1/src/redis_iris/cli/core/config.py +95 -0
  170. redis_iris-0.1.0a1/src/redis_iris/cli/core/errors.py +65 -0
  171. redis_iris-0.1.0a1/src/redis_iris/cli/core/logging.py +12 -0
  172. redis_iris-0.1.0a1/src/redis_iris/cli/core/output.py +43 -0
  173. redis_iris-0.1.0a1/src/redis_iris/cli/core/registry.py +122 -0
  174. redis_iris-0.1.0a1/src/redis_iris/cli/main.py +69 -0
  175. redis_iris-0.1.0a1/src/redis_iris/cli/services/__init__.py +1 -0
  176. redis_iris-0.1.0a1/src/redis_iris/cli/services/agent_memory/__init__.py +1 -0
  177. redis_iris-0.1.0a1/src/redis_iris/cli/services/agent_memory/client.py +189 -0
  178. redis_iris-0.1.0a1/src/redis_iris/cli/services/agent_memory/commands.py +231 -0
  179. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/__init__.py +1 -0
  180. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/apply.py +349 -0
  181. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/client.py +764 -0
  182. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/commands.py +1806 -0
  183. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/config.py +80 -0
  184. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/evidence.py +103 -0
  185. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/exporting.py +260 -0
  186. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/faq_lifecycle.py +376 -0
  187. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/faqs.py +314 -0
  188. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/output.py +194 -0
  189. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/planner.py +401 -0
  190. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/progress.py +134 -0
  191. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/service.py +448 -0
  192. redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/skills.py +622 -0
  193. redis_iris-0.1.0a1/src/redis_iris/context_retriever/__init__.py +32 -0
  194. redis_iris-0.1.0a1/src/redis_iris/context_retriever/provisioning.py +31 -0
  195. redis_iris-0.1.0a1/src/redis_iris/context_retriever/results.py +57 -0
  196. redis_iris-0.1.0a1/src/redis_iris/context_retriever/retriever.py +189 -0
  197. redis_iris-0.1.0a1/src/redis_iris/context_retriever/settings.py +63 -0
  198. redis_iris-0.1.0a1/src/redis_iris/errors.py +23 -0
  199. redis_iris-0.1.0a1/src/redis_iris/integrations/__init__.py +5 -0
  200. redis_iris-0.1.0a1/src/redis_iris/integrations/langgraph.py +105 -0
  201. redis_iris-0.1.0a1/src/redis_iris/iris.py +74 -0
  202. redis_iris-0.1.0a1/src/redis_iris/playbook/__init__.py +33 -0
  203. redis_iris-0.1.0a1/src/redis_iris/playbook/_wire.py +68 -0
  204. redis_iris-0.1.0a1/src/redis_iris/playbook/filters.py +11 -0
  205. redis_iris-0.1.0a1/src/redis_iris/playbook/hooks.py +120 -0
  206. redis_iris-0.1.0a1/src/redis_iris/playbook/playbook.py +180 -0
  207. redis_iris-0.1.0a1/src/redis_iris/playbook/settings.py +64 -0
  208. redis_iris-0.1.0a1/src/redis_iris/playbook/values.py +65 -0
  209. redis_iris-0.1.0a1/src/redis_iris/py.typed +1 -0
  210. redis_iris-0.1.0a1/tests/agent_memory/__init__.py +1 -0
  211. redis_iris-0.1.0a1/tests/agent_memory/test_commands.py +264 -0
  212. redis_iris-0.1.0a1/tests/integrations/__init__.py +0 -0
  213. redis_iris-0.1.0a1/tests/integrations/test_langgraph.py +149 -0
  214. redis_iris-0.1.0a1/tests/playbook/__init__.py +1 -0
  215. redis_iris-0.1.0a1/tests/playbook/conftest.py +34 -0
  216. redis_iris-0.1.0a1/tests/playbook/integration/__init__.py +1 -0
  217. redis_iris-0.1.0a1/tests/playbook/integration/conftest.py +173 -0
  218. redis_iris-0.1.0a1/tests/playbook/integration/test_cli_lifecycle.py +737 -0
  219. redis_iris-0.1.0a1/tests/playbook/test_client.py +631 -0
  220. redis_iris-0.1.0a1/tests/playbook/test_command_values.py +206 -0
  221. redis_iris-0.1.0a1/tests/playbook/test_commands.py +461 -0
  222. redis_iris-0.1.0a1/tests/playbook/test_config.py +67 -0
  223. redis_iris-0.1.0a1/tests/playbook/test_domain_output.py +130 -0
  224. redis_iris-0.1.0a1/tests/playbook/test_evidence_commands.py +365 -0
  225. redis_iris-0.1.0a1/tests/playbook/test_exporting.py +345 -0
  226. redis_iris-0.1.0a1/tests/playbook/test_faqs.py +388 -0
  227. redis_iris-0.1.0a1/tests/playbook/test_planner_apply.py +334 -0
  228. redis_iris-0.1.0a1/tests/playbook/test_progress.py +60 -0
  229. redis_iris-0.1.0a1/tests/playbook/test_proposal_commands.py +244 -0
  230. redis_iris-0.1.0a1/tests/playbook/test_service_commands.py +336 -0
  231. redis_iris-0.1.0a1/tests/playbook/test_skills.py +331 -0
  232. redis_iris-0.1.0a1/tests/test_config.py +58 -0
  233. redis_iris-0.1.0a1/tests/test_iris.py +570 -0
  234. redis_iris-0.1.0a1/tests/test_main.py +84 -0
  235. redis_iris-0.1.0a1/tests/test_output.py +47 -0
  236. redis_iris-0.1.0a1/tests/test_registry.py +69 -0
  237. redis_iris-0.1.0a1/uv.lock +3255 -0
@@ -0,0 +1,90 @@
1
+ {
2
+ "plugins": [
3
+ "git-tag",
4
+ "conventional-commits",
5
+ "released"
6
+ ],
7
+ "owner": "redis",
8
+ "repo": "redis-iris",
9
+ "onlyPublishWithReleaseLabel": true,
10
+ "labels": [
11
+ {
12
+ "name": "auto:major",
13
+ "changelogTitle": "💥 Breaking Change",
14
+ "description": "Increment the major version when merged",
15
+ "releaseType": "major",
16
+ "color": "#C5000B",
17
+ "overwrite": true
18
+ },
19
+ {
20
+ "name": "auto:minor",
21
+ "changelogTitle": "🚀 Enhancement",
22
+ "description": "Increment the minor version when merged",
23
+ "releaseType": "minor",
24
+ "color": "#F1A60E",
25
+ "overwrite": true
26
+ },
27
+ {
28
+ "name": "auto:patch",
29
+ "changelogTitle": "🐛 Bug Fix",
30
+ "description": "Increment the patch version when merged",
31
+ "releaseType": "patch",
32
+ "color": "#870048",
33
+ "overwrite": true
34
+ },
35
+ {
36
+ "name": "auto:skip-release",
37
+ "description": "Preserve the current version when merged",
38
+ "releaseType": "skip",
39
+ "color": "#bf5416",
40
+ "overwrite": true
41
+ },
42
+ {
43
+ "name": "auto:release",
44
+ "description": "Create a release when this PR is merged",
45
+ "releaseType": "release",
46
+ "color": "#007f70",
47
+ "overwrite": true
48
+ },
49
+ {
50
+ "name": "auto:internal",
51
+ "changelogTitle": "🏠 Internal",
52
+ "description": "Changes only affect the internal API",
53
+ "releaseType": "none",
54
+ "color": "#696969",
55
+ "overwrite": true
56
+ },
57
+ {
58
+ "name": "auto:documentation",
59
+ "changelogTitle": "📝 Documentation",
60
+ "description": "Changes only affect the documentation",
61
+ "releaseType": "none",
62
+ "color": "#cfd3d7",
63
+ "overwrite": true
64
+ },
65
+ {
66
+ "name": "auto:tests",
67
+ "changelogTitle": "🧪 Tests",
68
+ "description": "Add or improve existing tests",
69
+ "releaseType": "none",
70
+ "color": "#ffd3cc",
71
+ "overwrite": true
72
+ },
73
+ {
74
+ "name": "auto:dependencies",
75
+ "changelogTitle": "🔩 Dependency Updates",
76
+ "description": "Update one or more dependencies version",
77
+ "releaseType": "none",
78
+ "color": "#8732bc",
79
+ "overwrite": true
80
+ },
81
+ {
82
+ "name": "auto:ci",
83
+ "changelogTitle": "CI/CD Changes",
84
+ "description": "Updates to CI/CD workflows and processes",
85
+ "releaseType": "none",
86
+ "color": "#E5A3DD",
87
+ "overwrite": true
88
+ }
89
+ ]
90
+ }
@@ -0,0 +1,20 @@
1
+ # Opens a PR here whenever an Iris product SDK publishes a new version to PyPI.
2
+ # Dependabot bumps the exact pin in pyproject.toml and regenerates uv.lock.
3
+ # Scoped to the product SDKs only; one grouped PR per day covers all of them.
4
+ # ponytail: daily polling, not a push from iris-sdks; add a repository_dispatch
5
+ # receiver if same-hour bumps ever matter (releases here are manual anyway).
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: uv
9
+ directory: /
10
+ schedule:
11
+ interval: daily
12
+ allow:
13
+ - dependency-name: redis-agent-*
14
+ - dependency-name: langcache
15
+ - dependency-name: redis-context-retriever
16
+ groups:
17
+ iris-sdks:
18
+ patterns: ["*"]
19
+ # Changelog grouping for the Auto Release workflow; does not trigger a release.
20
+ labels: ["auto:dependencies"]
@@ -0,0 +1,257 @@
1
+ name: Auto Release
2
+
3
+ # BOILERPLATE, NOT YET ACTIVE. Ported from redis-developer/sql-redis so the
4
+ # label-driven release is ready when the alpha series ends. Until then releases
5
+ # are manual through publish.yml, and this workflow runs only on dispatch.
6
+ #
7
+ # To activate: add `push: { branches: [main] }` under `on:`, delete publish.yml,
8
+ # and make sure [project].version is semver (`0.1.0`, not `0.1.0a1`; `auto`
9
+ # bumps semver and cannot parse PEP 440 suffixes).
10
+ #
11
+ # How it works once active: every push to main runs the gate; the release job
12
+ # runs only when the merged PR carries the `auto:release` label. Intuit `auto`
13
+ # picks the bump from the `auto:major` / `auto:minor` / `auto:patch` labels
14
+ # (see .autorc), writes it into pyproject.toml and uv.lock, commits with
15
+ # [skip ci], tags, and writes GitHub release notes. The built distribution is
16
+ # then checked with twine and uploaded to PyPI with REDIS_IRIS_PYPI_TOKEN.
17
+ # `first_release=true` publishes the committed version as-is (bootstrap, recovery).
18
+
19
+ on:
20
+ workflow_dispatch:
21
+ inputs:
22
+ first_release:
23
+ description: "Bootstrap: publish the version currently in pyproject.toml. Bypasses the auto:release label gate and skips version bumping. Use only for the first release or manual recovery."
24
+ type: boolean
25
+ default: false
26
+
27
+ permissions:
28
+ contents: write
29
+ issues: write
30
+ pull-requests: write
31
+
32
+ concurrency:
33
+ group: auto-release-${{ github.ref }}
34
+ cancel-in-progress: false
35
+
36
+ env:
37
+ PYTHON_VERSION: "3.11"
38
+ AUTO_VERSION: "11.3.6"
39
+ RELEASE_BOT_NAME: "github-actions[bot]"
40
+ RELEASE_BOT_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com"
41
+
42
+ jobs:
43
+ gate:
44
+ name: Gate on merged PR label
45
+ runs-on: ubuntu-latest
46
+ # Prevent infinite loops from the bot's "chore(release)" commit.
47
+ if: github.actor != 'github-actions[bot]'
48
+ outputs:
49
+ should_release: ${{ steps.find_pr.outputs.should_release }}
50
+ pr_number: ${{ steps.find_pr.outputs.pr_number }}
51
+ steps:
52
+ - name: Find merged PR and check labels
53
+ id: find_pr
54
+ uses: actions/github-script@v7
55
+ env:
56
+ FIRST_RELEASE: ${{ github.event.inputs.first_release }}
57
+ with:
58
+ script: |
59
+ // Manual bootstrap: bypass the PR label check entirely.
60
+ if (context.eventName === 'workflow_dispatch' && process.env.FIRST_RELEASE === 'true') {
61
+ core.notice('Manual first_release=true; bypassing PR label check.');
62
+ core.setOutput('should_release', 'true');
63
+ core.setOutput('pr_number', '');
64
+ return;
65
+ }
66
+ const { owner, repo } = context.repo;
67
+ const sha = context.sha;
68
+ const maxAttempts = 6;
69
+ let pulls;
70
+ // GitHub can briefly lag in associating a merge commit with its PR, so retry.
71
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
72
+ pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({
73
+ owner, repo, commit_sha: sha,
74
+ });
75
+ if (pulls.data.length) break;
76
+ if (attempt < maxAttempts) {
77
+ await new Promise((r) => setTimeout(r, 10000));
78
+ }
79
+ }
80
+ if (!pulls.data || !pulls.data.length) {
81
+ core.notice(`No PR associated with ${sha}. Not releasing.`);
82
+ core.setOutput('should_release', 'false');
83
+ core.setOutput('pr_number', '');
84
+ return;
85
+ }
86
+ const pr = pulls.data.find((p) => p.merged_at && p.base?.ref === 'main') ?? pulls.data[0];
87
+ const labels = (pr.labels || []).map((l) => l.name);
88
+ const should = labels.includes('auto:release');
89
+ core.setOutput('pr_number', String(pr.number));
90
+ core.setOutput('should_release', should ? 'true' : 'false');
91
+ core.notice(`PR #${pr.number} labels: ${labels.join(', ')}`);
92
+ core.notice(`should_release=${should}`);
93
+
94
+ release:
95
+ name: Tag, release, and publish
96
+ runs-on: ubuntu-latest
97
+ needs: gate
98
+ if: needs.gate.outputs.should_release == 'true'
99
+ env:
100
+ # 'true' for manual bootstrap runs; 'false' or empty otherwise.
101
+ FIRST_RELEASE: ${{ github.event.inputs.first_release || 'false' }}
102
+ steps:
103
+ - name: Checkout
104
+ uses: actions/checkout@v4
105
+ with:
106
+ ref: main
107
+ fetch-depth: 0
108
+ fetch-tags: true
109
+ # RELEASE_PAT (a PAT with repo + workflow scopes) lets the bot push to
110
+ # protected branches and trigger other workflows. Falls back to
111
+ # GITHUB_TOKEN for repos without branch protection.
112
+ token: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
113
+
114
+ - name: Install uv
115
+ uses: astral-sh/setup-uv@v6
116
+ with:
117
+ enable-cache: true
118
+ python-version: ${{ env.PYTHON_VERSION }}
119
+
120
+ - name: Install auto
121
+ run: |
122
+ set -euo pipefail
123
+ curl -L "https://github.com/intuit/auto/releases/download/v${AUTO_VERSION}/auto-linux.gz" -o auto-linux.gz
124
+ gunzip auto-linux.gz
125
+ chmod +x auto-linux
126
+ sudo mv auto-linux /usr/local/bin/auto
127
+ auto --version
128
+
129
+ - name: Check publishing token is configured
130
+ env:
131
+ PYPI_TOKEN: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
132
+ run: |
133
+ if [ -z "$PYPI_TOKEN" ]; then
134
+ echo "::error::Configure the REDIS_IRIS_PYPI_TOKEN Actions secret."
135
+ exit 1
136
+ fi
137
+
138
+ - name: Install locked environment
139
+ run: uv sync --locked --all-groups
140
+
141
+ - name: Sanity build (pre-tag)
142
+ run: uv build --no-sources
143
+
144
+ - name: Capture previous tag
145
+ id: previous_tag
146
+ run: |
147
+ set -euo pipefail
148
+ echo "tag=$(git describe --tags --abbrev=0 2>/dev/null || echo '')" >> "$GITHUB_OUTPUT"
149
+
150
+ - name: Resolve next version (auto)
151
+ id: resolve_version
152
+ if: env.FIRST_RELEASE != 'true'
153
+ env:
154
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
155
+ run: |
156
+ set -euo pipefail
157
+ RAW_VERSION="$(auto shipit --name "${RELEASE_BOT_NAME}" --email "${RELEASE_BOT_EMAIL}" --dry-run --quiet | tail -n1 | tr -d '\r')"
158
+ VERSION="${RAW_VERSION#v}"
159
+ if [ -z "$VERSION" ]; then
160
+ echo "Could not resolve release version from auto."
161
+ exit 1
162
+ fi
163
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
164
+ echo "Resolved version: $VERSION"
165
+
166
+ - name: Apply version to pyproject.toml and uv.lock
167
+ if: env.FIRST_RELEASE != 'true'
168
+ run: |
169
+ set -euo pipefail
170
+ VERSION="${{ steps.resolve_version.outputs.version }}"
171
+ sed -i "s/^version = \".*\"$/version = \"${VERSION}\"/" pyproject.toml
172
+ grep '^version = ' pyproject.toml
173
+ # uv.lock records the project's own version; CI syncs with --locked.
174
+ uv lock
175
+
176
+ - name: Commit version bump
177
+ if: env.FIRST_RELEASE != 'true'
178
+ env:
179
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
180
+ run: |
181
+ set -euo pipefail
182
+ if git diff --quiet -- pyproject.toml uv.lock; then
183
+ echo "No version change to commit."
184
+ else
185
+ git config user.name "${RELEASE_BOT_NAME}"
186
+ git config user.email "${RELEASE_BOT_EMAIL}"
187
+ git add pyproject.toml uv.lock
188
+ # [skip ci] avoids re-running this workflow on the bot's own commit.
189
+ git commit -m "chore(release): v${{ steps.resolve_version.outputs.version }} [skip ci]"
190
+ git push origin HEAD:main
191
+ fi
192
+
193
+ - name: Read final version from pyproject.toml
194
+ id: final_version
195
+ run: |
196
+ set -euo pipefail
197
+ VERSION="$(grep -E '^version = ' pyproject.toml | head -1 | sed -E 's/version = "([^"]+)".*/\1/')"
198
+ if [ -z "$VERSION" ]; then
199
+ echo "Could not read version from pyproject.toml"
200
+ exit 1
201
+ fi
202
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
203
+ echo "Final version: $VERSION"
204
+
205
+ - name: Capture release commit SHA
206
+ id: release_commit
207
+ run: |
208
+ set -euo pipefail
209
+ echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
210
+
211
+ - name: Create labels (idempotent)
212
+ env:
213
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
214
+ run: auto create-labels
215
+
216
+ - name: Create and push tag
217
+ run: |
218
+ set -euo pipefail
219
+ TAG="v${{ steps.final_version.outputs.version }}"
220
+ TARGET_SHA="${{ steps.release_commit.outputs.sha }}"
221
+ if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
222
+ EXISTING_SHA="$(git rev-list -n1 "$TAG")"
223
+ if [ "$EXISTING_SHA" = "$TARGET_SHA" ]; then
224
+ echo "Tag $TAG already exists at $TARGET_SHA. Skipping."
225
+ exit 0
226
+ fi
227
+ echo "Tag $TAG exists at $EXISTING_SHA but expected $TARGET_SHA."
228
+ exit 1
229
+ fi
230
+ git tag "$TAG" "$TARGET_SHA"
231
+ git push origin "$TAG"
232
+
233
+ - name: Build final artifacts
234
+ run: |
235
+ set -euo pipefail
236
+ rm -rf dist
237
+ uv build --no-sources
238
+ uv run --no-sync twine check --strict dist/*
239
+
240
+ - name: Create GitHub release with auto notes
241
+ env:
242
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
243
+ run: |
244
+ set -euo pipefail
245
+ args=(--to "${{ steps.release_commit.outputs.sha }}" --use-version "v${{ steps.final_version.outputs.version }}")
246
+ if [ -n "${{ steps.previous_tag.outputs.tag }}" ]; then
247
+ args=(--from "${{ steps.previous_tag.outputs.tag }}" "${args[@]}")
248
+ fi
249
+ auto release "${args[@]}"
250
+ gh release upload "v${{ steps.final_version.outputs.version }}" dist/* --clobber
251
+
252
+ - name: Publish to PyPI
253
+ uses: pypa/gh-action-pypi-publish@release/v1 # maintainer-recommended rolling ref: a SHA pin has no prebuilt ghcr image (manifest unknown)
254
+ with:
255
+ user: __token__
256
+ password: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
257
+ attestations: false
@@ -0,0 +1,107 @@
1
+ name: CI
2
+
3
+ on:
4
+ workflow_call:
5
+ outputs:
6
+ version:
7
+ description: Validated distribution version
8
+ value: ${{ jobs.build-and-install.outputs.version }}
9
+ prerelease:
10
+ description: Whether the distribution is a prerelease
11
+ value: ${{ jobs.build-and-install.outputs.prerelease }}
12
+ workflow_dispatch:
13
+ pull_request:
14
+ push:
15
+ branches: [main]
16
+
17
+ concurrency:
18
+ # A reusable workflow inherits its caller's github.workflow. Keep this
19
+ # distinct from the publish workflow's concurrency group.
20
+ group: ci-${{ github.workflow }}-${{ github.ref }}
21
+ cancel-in-progress: true
22
+
23
+ permissions:
24
+ contents: read
25
+
26
+ jobs:
27
+ quality:
28
+ name: Quality (Python ${{ matrix.python-version }})
29
+ runs-on: ubuntu-latest
30
+ timeout-minutes: 10
31
+ strategy:
32
+ fail-fast: false
33
+ matrix:
34
+ python-version: ["3.11", "3.12", "3.13"]
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: astral-sh/setup-uv@v6
38
+ with:
39
+ enable-cache: true
40
+ python-version: ${{ matrix.python-version }}
41
+ - run: uv sync --locked --all-groups --python ${{ matrix.python-version }}
42
+ - run: uv run ruff format --check .
43
+ - run: uv run ruff check .
44
+ - run: uv run mypy
45
+ - run: uv run pytest -m "not integration"
46
+
47
+ build-and-install:
48
+ name: Build and install distribution
49
+ runs-on: ubuntu-latest
50
+ timeout-minutes: 10
51
+ outputs:
52
+ version: ${{ steps.metadata.outputs.version }}
53
+ prerelease: ${{ steps.metadata.outputs.prerelease }}
54
+ steps:
55
+ - uses: actions/checkout@v4
56
+ - uses: astral-sh/setup-uv@v6
57
+ with:
58
+ python-version: "3.11"
59
+ - run: uv sync --locked --all-groups
60
+ - name: Validate release metadata
61
+ id: metadata
62
+ run: |
63
+ uv run --locked python - <<'PY'
64
+ import os
65
+ import tomllib
66
+ from packaging.version import Version
67
+
68
+ with open("pyproject.toml", "rb") as source:
69
+ project = tomllib.load(source)["project"]
70
+ version = Version(project["version"])
71
+ assert project["name"] == "redis-iris", "Unexpected distribution name"
72
+ assert str(version) == project["version"], "Use a canonical Python version"
73
+ assert version.local is None, "Local versions cannot be published to PyPI"
74
+ with open(os.environ["GITHUB_OUTPUT"], "a") as output:
75
+ output.write(f"version={version}\n")
76
+ output.write(f"prerelease={str(version.is_prerelease).lower()}\n")
77
+ PY
78
+ - run: uv build --no-sources
79
+ - run: uv run --locked twine check --strict dist/*
80
+ - run: uv venv --python 3.11 /tmp/iris-cli-venv
81
+ - run: uv pip install --python /tmp/iris-cli-venv/bin/python dist/*.whl
82
+ - run: uv pip check --python /tmp/iris-cli-venv/bin/python
83
+ - name: Verify installed distribution version
84
+ env:
85
+ EXPECTED_VERSION: ${{ steps.metadata.outputs.version }}
86
+ run: |
87
+ cd "$RUNNER_TEMP"
88
+ /tmp/iris-cli-venv/bin/python - <<'PY'
89
+ import os
90
+ import subprocess
91
+ from importlib.metadata import version
92
+ assert version("redis-iris") == os.environ["EXPECTED_VERSION"]
93
+ actual = subprocess.check_output(
94
+ ["/tmp/iris-cli-venv/bin/iris", "--version"], text=True
95
+ ).strip()
96
+ assert actual == f"iris, version {os.environ['EXPECTED_VERSION']}"
97
+ PY
98
+ - run: /tmp/iris-cli-venv/bin/iris --help
99
+ - run: /tmp/iris-cli-venv/bin/iris playbook --help
100
+ - run: /tmp/iris-cli-venv/bin/python -m redis_iris --help
101
+ - run: /tmp/iris-cli-venv/bin/python -m redis_iris.cli --help
102
+ - uses: actions/upload-artifact@v4
103
+ with:
104
+ name: redis-iris-dist
105
+ path: dist/*
106
+ if-no-files-found: error
107
+ overwrite: true
@@ -0,0 +1,49 @@
1
+ name: Deploy docs to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths: ["docs/**", "mkdocs.yml", "src/redis_iris/**"]
7
+ pull_request:
8
+ paths: ["docs/**", "mkdocs.yml", "src/redis_iris/**"]
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ concurrency:
15
+ group: pages-${{ github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ env:
19
+ DISABLE_MKDOCS_2_WARNING: "true"
20
+
21
+ jobs:
22
+ build:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: astral-sh/setup-uv@v6
27
+ with:
28
+ python-version: "3.12"
29
+ # Docs tooling only: mkdocstrings reads src/ statically, so product SDKs
30
+ # (including the path-sourced Context Retriever client) are not installed.
31
+ - run: uv sync --only-group docs
32
+ - run: uv run --no-sync mkdocs build --strict
33
+ - uses: actions/upload-pages-artifact@v3
34
+ with:
35
+ path: site
36
+
37
+ deploy:
38
+ if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
39
+ needs: build
40
+ runs-on: ubuntu-latest
41
+ permissions:
42
+ pages: write
43
+ id-token: write
44
+ environment:
45
+ name: github-pages
46
+ url: ${{ steps.deployment.outputs.page_url }}
47
+ steps:
48
+ - id: deployment
49
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,60 @@
1
+ name: Manual integration
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ # The suite creates and deletes shared remote resources. Serialize runs so that
7
+ # two manually requested runs cannot interfere with each other.
8
+ concurrency:
9
+ group: playbook-integration
10
+ cancel-in-progress: false
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ playbook:
17
+ name: Playbook lifecycle
18
+ runs-on: ubuntu-latest
19
+ timeout-minutes: 30
20
+ environment: playbook-integration
21
+ env:
22
+ IRIS_PLAYBOOK_TEST_CONTROL_URL: ${{ vars.IRIS_PLAYBOOK_TEST_CONTROL_URL }}
23
+ IRIS_PLAYBOOK_TEST_DATA_URL: ${{ vars.IRIS_PLAYBOOK_TEST_DATA_URL }}
24
+ IRIS_PLAYBOOK_TEST_IDENTITY_URL: ${{ vars.IRIS_PLAYBOOK_TEST_IDENTITY_URL }}
25
+ IRIS_PLAYBOOK_TEST_CONTROL_TOKEN: ${{ secrets.IRIS_PLAYBOOK_TEST_CONTROL_TOKEN }}
26
+ IRIS_PLAYBOOK_TEST_IDENTITY_TOKEN: ${{ secrets.IRIS_PLAYBOOK_TEST_IDENTITY_TOKEN }}
27
+ IRIS_PLAYBOOK_TEST_EMBEDDING_PROVIDER: ${{ vars.IRIS_PLAYBOOK_TEST_EMBEDDING_PROVIDER }}
28
+ IRIS_PLAYBOOK_TEST_EMBEDDING_MODEL: ${{ vars.IRIS_PLAYBOOK_TEST_EMBEDDING_MODEL }}
29
+ IRIS_PLAYBOOK_TEST_EMBEDDING_DIMENSIONS: ${{ vars.IRIS_PLAYBOOK_TEST_EMBEDDING_DIMENSIONS }}
30
+ steps:
31
+ - name: Validate integration configuration
32
+ shell: bash
33
+ run: |
34
+ required=(
35
+ IRIS_PLAYBOOK_TEST_CONTROL_URL
36
+ IRIS_PLAYBOOK_TEST_DATA_URL
37
+ IRIS_PLAYBOOK_TEST_IDENTITY_URL
38
+ IRIS_PLAYBOOK_TEST_CONTROL_TOKEN
39
+ IRIS_PLAYBOOK_TEST_IDENTITY_TOKEN
40
+ IRIS_PLAYBOOK_TEST_EMBEDDING_PROVIDER
41
+ IRIS_PLAYBOOK_TEST_EMBEDDING_MODEL
42
+ IRIS_PLAYBOOK_TEST_EMBEDDING_DIMENSIONS
43
+ )
44
+ missing=()
45
+ for name in "${required[@]}"; do
46
+ if [[ -z "${!name:-}" ]]; then
47
+ missing+=("$name")
48
+ fi
49
+ done
50
+ if (( ${#missing[@]} )); then
51
+ printf 'Missing integration configuration: %s\n' "${missing[*]}" >&2
52
+ exit 1
53
+ fi
54
+ - uses: actions/checkout@v4
55
+ - uses: astral-sh/setup-uv@v6
56
+ with:
57
+ enable-cache: true
58
+ python-version: "3.13"
59
+ - run: uv sync --locked --all-groups --python 3.13
60
+ - run: task test:integration
@@ -0,0 +1,82 @@
1
+ name: Publish Redis Iris
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ concurrency:
10
+ group: publish-redis-iris
11
+ cancel-in-progress: false
12
+
13
+ jobs:
14
+ check:
15
+ if: github.ref == 'refs/heads/main'
16
+ uses: ./.github/workflows/ci.yml
17
+
18
+ publish:
19
+ name: Publish to PyPI
20
+ needs: check
21
+ if: github.ref == 'refs/heads/main'
22
+ runs-on: ubuntu-latest
23
+ timeout-minutes: 10
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ with:
27
+ ref: ${{ github.sha }}
28
+ fetch-depth: 0
29
+ persist-credentials: false
30
+ - name: Reject an existing release tag
31
+ env:
32
+ RELEASE_TAG: v${{ needs.check.outputs.version }}
33
+ run: |
34
+ if git show-ref --verify --quiet "refs/tags/$RELEASE_TAG"; then
35
+ echo "::error::Release tag already exists. Bump the version before publishing."
36
+ exit 1
37
+ fi
38
+ - name: Check publishing token is configured
39
+ env:
40
+ PYPI_TOKEN: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
41
+ run: |
42
+ if [ -z "$PYPI_TOKEN" ]; then
43
+ echo "::error::Configure the REDIS_IRIS_PYPI_TOKEN Actions secret."
44
+ exit 1
45
+ fi
46
+ - uses: actions/download-artifact@v4
47
+ with:
48
+ name: redis-iris-dist
49
+ path: dist
50
+ - name: Publish tested distributions
51
+ uses: pypa/gh-action-pypi-publish@release/v1 # maintainer-recommended rolling ref: a SHA pin has no prebuilt ghcr image (manifest unknown)
52
+ with:
53
+ user: __token__
54
+ password: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
55
+ attestations: false
56
+
57
+ release:
58
+ name: Create GitHub Release
59
+ needs: [check, publish]
60
+ runs-on: ubuntu-latest
61
+ timeout-minutes: 5
62
+ permissions:
63
+ contents: write
64
+ steps:
65
+ - uses: actions/download-artifact@v4
66
+ with:
67
+ name: redis-iris-dist
68
+ path: dist
69
+ - name: Create tag and release at the tested commit
70
+ env:
71
+ GH_TOKEN: ${{ github.token }}
72
+ GH_REPO: ${{ github.repository }}
73
+ RELEASE_TAG: v${{ needs.check.outputs.version }}
74
+ PRERELEASE: ${{ needs.check.outputs.prerelease }}
75
+ RELEASE_COMMIT: ${{ github.sha }}
76
+ run: |
77
+ args=(--repo "$GH_REPO" --target "$RELEASE_COMMIT"
78
+ --title "Redis Iris $RELEASE_TAG" --generate-notes)
79
+ if [ "$PRERELEASE" = true ]; then
80
+ args+=(--prerelease --latest=false)
81
+ fi
82
+ gh release create "$RELEASE_TAG" dist/* "${args[@]}"