julee 0.1.6__tar.gz → 0.1.8__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 (296) hide show
  1. {julee-0.1.6/src/julee.egg-info → julee-0.1.8}/PKG-INFO +1 -1
  2. {julee-0.1.6 → julee-0.1.8}/pyproject.toml +1 -1
  3. {julee-0.1.6 → julee-0.1.8}/src/julee/__init__.py +1 -1
  4. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/apps/worker/pipelines.py +3 -1
  5. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/apps/worker/test_pipelines.py +3 -0
  6. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly_specification/knowledge_service_query.py +1 -1
  7. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly_specification/tests/test_knowledge_service_query.py +3 -3
  8. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/extract_assemble_data.py +11 -54
  9. julee-0.1.8/src/julee/domain/use_cases/pointable_json_schema.py +102 -0
  10. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/tests/test_extract_assemble_data.py +143 -2
  11. julee-0.1.8/src/julee/domain/use_cases/tests/test_pointable_json_schema.py +451 -0
  12. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/validate_document.py +2 -0
  13. {julee-0.1.6 → julee-0.1.8}/src/julee/fixtures/knowledge_service_queries.yaml +4 -4
  14. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/anthropic/knowledge_service.py +53 -6
  15. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +143 -0
  16. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/factory.py +2 -0
  17. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/knowledge_service.py +5 -0
  18. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/memory/knowledge_service.py +28 -4
  19. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/memory/test_knowledge_service.py +1 -1
  20. {julee-0.1.6 → julee-0.1.8}/src/julee/util/temporal/decorators.py +4 -4
  21. {julee-0.1.6 → julee-0.1.8}/src/julee/util/tests/test_decorators.py +1 -1
  22. {julee-0.1.6 → julee-0.1.8/src/julee.egg-info}/PKG-INFO +1 -1
  23. {julee-0.1.6 → julee-0.1.8}/src/julee.egg-info/SOURCES.txt +2 -0
  24. {julee-0.1.6 → julee-0.1.8}/LICENSE +0 -0
  25. {julee-0.1.6 → julee-0.1.8}/MANIFEST.in +0 -0
  26. {julee-0.1.6 → julee-0.1.8}/README.md +0 -0
  27. {julee-0.1.6 → julee-0.1.8}/setup.cfg +0 -0
  28. {julee-0.1.6 → julee-0.1.8}/src/julee/api/__init__.py +0 -0
  29. {julee-0.1.6 → julee-0.1.8}/src/julee/api/app.py +0 -0
  30. {julee-0.1.6 → julee-0.1.8}/src/julee/api/dependencies.py +0 -0
  31. {julee-0.1.6 → julee-0.1.8}/src/julee/api/requests.py +0 -0
  32. {julee-0.1.6 → julee-0.1.8}/src/julee/api/responses.py +0 -0
  33. {julee-0.1.6 → julee-0.1.8}/src/julee/api/routers/__init__.py +0 -0
  34. {julee-0.1.6 → julee-0.1.8}/src/julee/api/routers/assembly_specifications.py +0 -0
  35. {julee-0.1.6 → julee-0.1.8}/src/julee/api/routers/documents.py +0 -0
  36. {julee-0.1.6 → julee-0.1.8}/src/julee/api/routers/knowledge_service_configs.py +0 -0
  37. {julee-0.1.6 → julee-0.1.8}/src/julee/api/routers/knowledge_service_queries.py +0 -0
  38. {julee-0.1.6 → julee-0.1.8}/src/julee/api/routers/system.py +0 -0
  39. {julee-0.1.6 → julee-0.1.8}/src/julee/api/routers/workflows.py +0 -0
  40. {julee-0.1.6 → julee-0.1.8}/src/julee/api/services/__init__.py +0 -0
  41. {julee-0.1.6 → julee-0.1.8}/src/julee/api/services/system_initialization.py +0 -0
  42. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/__init__.py +0 -0
  43. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/routers/__init__.py +0 -0
  44. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/routers/test_assembly_specifications.py +0 -0
  45. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/routers/test_documents.py +0 -0
  46. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/routers/test_knowledge_service_configs.py +0 -0
  47. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/routers/test_knowledge_service_queries.py +0 -0
  48. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/routers/test_system.py +0 -0
  49. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/routers/test_workflows.py +0 -0
  50. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/test_app.py +0 -0
  51. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/test_dependencies.py +0 -0
  52. {julee-0.1.6 → julee-0.1.8}/src/julee/api/tests/test_requests.py +0 -0
  53. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/__init__.py +0 -0
  54. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/__init__.py +0 -0
  55. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/apps/__init__.py +0 -0
  56. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/apps/worker/__init__.py +0 -0
  57. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/domain/__init__.py +0 -0
  58. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/domain/models/__init__.py +0 -0
  59. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/domain/models/polling_config.py +0 -0
  60. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/domain/services/__init__.py +0 -0
  61. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/domain/services/poller.py +0 -0
  62. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/__init__.py +0 -0
  63. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/services/__init__.py +0 -0
  64. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/services/polling/__init__.py +0 -0
  65. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/services/polling/http/__init__.py +0 -0
  66. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/services/polling/http/http_poller_service.py +0 -0
  67. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/temporal/__init__.py +0 -0
  68. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/temporal/activities.py +0 -0
  69. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/temporal/activity_names.py +0 -0
  70. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/temporal/manager.py +0 -0
  71. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/infrastructure/temporal/proxies.py +0 -0
  72. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/__init__.py +0 -0
  73. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/__init__.py +0 -0
  74. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/infrastructure/__init__.py +0 -0
  75. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/infrastructure/services/__init__.py +0 -0
  76. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/infrastructure/services/polling/__init__.py +0 -0
  77. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/infrastructure/services/polling/http/__init__.py +0 -0
  78. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/infrastructure/services/polling/http/test_http_poller_service.py +0 -0
  79. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/infrastructure/temporal/__init__.py +0 -0
  80. {julee-0.1.6 → julee-0.1.8}/src/julee/contrib/polling/tests/unit/infrastructure/temporal/test_manager.py +0 -0
  81. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/__init__.py +0 -0
  82. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/__init__.py +0 -0
  83. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/config.py +0 -0
  84. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/__init__.py +0 -0
  85. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/__init__.py +0 -0
  86. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/accelerator.py +0 -0
  87. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/app.py +0 -0
  88. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/code_info.py +0 -0
  89. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/epic.py +0 -0
  90. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/integration.py +0 -0
  91. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/journey.py +0 -0
  92. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/persona.py +0 -0
  93. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/models/story.py +0 -0
  94. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/__init__.py +0 -0
  95. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/accelerator.py +0 -0
  96. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/app.py +0 -0
  97. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/base.py +0 -0
  98. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/code_info.py +0 -0
  99. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/epic.py +0 -0
  100. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/integration.py +0 -0
  101. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/journey.py +0 -0
  102. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/repositories/story.py +0 -0
  103. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/use_cases/__init__.py +0 -0
  104. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/use_cases/derive_personas.py +0 -0
  105. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/use_cases/resolve_accelerator_references.py +0 -0
  106. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/use_cases/resolve_app_references.py +0 -0
  107. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/domain/use_cases/resolve_story_references.py +0 -0
  108. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/parsers/__init__.py +0 -0
  109. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/parsers/ast.py +0 -0
  110. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/parsers/gherkin.py +0 -0
  111. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/parsers/yaml.py +0 -0
  112. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/__init__.py +0 -0
  113. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/__init__.py +0 -0
  114. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/accelerator.py +0 -0
  115. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/app.py +0 -0
  116. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/base.py +0 -0
  117. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/code_info.py +0 -0
  118. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/epic.py +0 -0
  119. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/integration.py +0 -0
  120. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/journey.py +0 -0
  121. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/repositories/memory/story.py +0 -0
  122. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/__init__.py +0 -0
  123. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/adapters.py +0 -0
  124. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/context.py +0 -0
  125. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/__init__.py +0 -0
  126. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/accelerator.py +0 -0
  127. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/app.py +0 -0
  128. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/base.py +0 -0
  129. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/epic.py +0 -0
  130. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/integration.py +0 -0
  131. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/journey.py +0 -0
  132. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/persona.py +0 -0
  133. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/directives/story.py +0 -0
  134. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/event_handlers/__init__.py +0 -0
  135. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/event_handlers/builder_inited.py +0 -0
  136. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_read.py +0 -0
  137. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_resolved.py +0 -0
  138. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/event_handlers/env_purge_doc.py +0 -0
  139. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/sphinx/initialization.py +0 -0
  140. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/__init__.py +0 -0
  141. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/conftest.py +0 -0
  142. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/__init__.py +0 -0
  143. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/__init__.py +0 -0
  144. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_accelerator.py +0 -0
  145. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_app.py +0 -0
  146. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_code_info.py +0 -0
  147. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_epic.py +0 -0
  148. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_integration.py +0 -0
  149. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_journey.py +0 -0
  150. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_persona.py +0 -0
  151. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/models/test_story.py +0 -0
  152. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/use_cases/__init__.py +0 -0
  153. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/use_cases/test_derive_personas.py +0 -0
  154. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_accelerator_references.py +0 -0
  155. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_app_references.py +0 -0
  156. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_story_references.py +0 -0
  157. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/integration/__init__.py +0 -0
  158. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/parsers/__init__.py +0 -0
  159. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/parsers/test_ast.py +0 -0
  160. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/parsers/test_gherkin.py +0 -0
  161. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/parsers/test_yaml.py +0 -0
  162. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/__init__.py +0 -0
  163. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_accelerator.py +0 -0
  164. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_app.py +0 -0
  165. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_base.py +0 -0
  166. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_code_info.py +0 -0
  167. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_epic.py +0 -0
  168. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_integration.py +0 -0
  169. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_journey.py +0 -0
  170. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/repositories/test_story.py +0 -0
  171. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/sphinx/__init__.py +0 -0
  172. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/sphinx/directives/__init__.py +0 -0
  173. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/sphinx/directives/test_base.py +0 -0
  174. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/sphinx/test_adapters.py +0 -0
  175. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/tests/sphinx/test_context.py +0 -0
  176. {julee-0.1.6 → julee-0.1.8}/src/julee/docs/sphinx_hcd/utils.py +0 -0
  177. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/__init__.py +0 -0
  178. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/__init__.py +0 -0
  179. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly/__init__.py +0 -0
  180. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly/assembly.py +0 -0
  181. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly/tests/__init__.py +0 -0
  182. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly/tests/factories.py +0 -0
  183. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly/tests/test_assembly.py +0 -0
  184. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly_specification/__init__.py +0 -0
  185. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly_specification/assembly_specification.py +0 -0
  186. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly_specification/tests/__init__.py +0 -0
  187. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly_specification/tests/factories.py +0 -0
  188. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/assembly_specification/tests/test_assembly_specification.py +0 -0
  189. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/custom_fields/__init__.py +0 -0
  190. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/custom_fields/content_stream.py +0 -0
  191. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/custom_fields/tests/__init__.py +0 -0
  192. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/custom_fields/tests/test_custom_fields.py +0 -0
  193. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/document/__init__.py +0 -0
  194. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/document/document.py +0 -0
  195. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/document/tests/__init__.py +0 -0
  196. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/document/tests/factories.py +0 -0
  197. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/document/tests/test_document.py +0 -0
  198. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/knowledge_service_config/__init__.py +0 -0
  199. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/knowledge_service_config/knowledge_service_config.py +0 -0
  200. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/policy/__init__.py +0 -0
  201. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/policy/document_policy_validation.py +0 -0
  202. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/policy/policy.py +0 -0
  203. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/policy/tests/__init__.py +0 -0
  204. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/policy/tests/factories.py +0 -0
  205. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/policy/tests/test_document_policy_validation.py +0 -0
  206. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/models/policy/tests/test_policy.py +0 -0
  207. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/__init__.py +0 -0
  208. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/assembly.py +0 -0
  209. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/assembly_specification.py +0 -0
  210. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/base.py +0 -0
  211. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/document.py +0 -0
  212. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/document_policy_validation.py +0 -0
  213. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/knowledge_service_config.py +0 -0
  214. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/knowledge_service_query.py +0 -0
  215. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/repositories/policy.py +0 -0
  216. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/__init__.py +0 -0
  217. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/decorators.py +0 -0
  218. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/initialize_system_data.py +0 -0
  219. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/tests/__init__.py +0 -0
  220. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/tests/test_initialize_system_data.py +0 -0
  221. {julee-0.1.6 → julee-0.1.8}/src/julee/domain/use_cases/tests/test_validate_document.py +0 -0
  222. {julee-0.1.6 → julee-0.1.8}/src/julee/fixtures/documents.yaml +0 -0
  223. {julee-0.1.6 → julee-0.1.8}/src/julee/fixtures/knowledge_service_configs.yaml +0 -0
  224. {julee-0.1.6 → julee-0.1.8}/src/julee/maintenance/__init__.py +0 -0
  225. {julee-0.1.6 → julee-0.1.8}/src/julee/maintenance/release.py +0 -0
  226. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/__init__.py +0 -0
  227. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/__init__.py +0 -0
  228. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/assembly.py +0 -0
  229. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/assembly_specification.py +0 -0
  230. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/base.py +0 -0
  231. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/document.py +0 -0
  232. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/document_policy_validation.py +0 -0
  233. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/knowledge_service_config.py +0 -0
  234. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/knowledge_service_query.py +0 -0
  235. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/policy.py +0 -0
  236. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/tests/__init__.py +0 -0
  237. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/tests/test_document.py +0 -0
  238. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/tests/test_document_policy_validation.py +0 -0
  239. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/memory/tests/test_policy.py +0 -0
  240. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/__init__.py +0 -0
  241. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/assembly.py +0 -0
  242. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/assembly_specification.py +0 -0
  243. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/client.py +0 -0
  244. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/document.py +0 -0
  245. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/document_policy_validation.py +0 -0
  246. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/knowledge_service_config.py +0 -0
  247. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/knowledge_service_query.py +0 -0
  248. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/policy.py +0 -0
  249. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/__init__.py +0 -0
  250. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/fake_client.py +0 -0
  251. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_assembly.py +0 -0
  252. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_assembly_specification.py +0 -0
  253. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_client_protocol.py +0 -0
  254. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_document.py +0 -0
  255. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_document_policy_validation.py +0 -0
  256. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_knowledge_service_config.py +0 -0
  257. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_knowledge_service_query.py +0 -0
  258. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/minio/tests/test_policy.py +0 -0
  259. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/temporal/__init__.py +0 -0
  260. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/temporal/activities.py +0 -0
  261. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/temporal/activity_names.py +0 -0
  262. {julee-0.1.6 → julee-0.1.8}/src/julee/repositories/temporal/proxies.py +0 -0
  263. {julee-0.1.6 → julee-0.1.8}/src/julee/services/__init__.py +0 -0
  264. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/__init__.py +0 -0
  265. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/anthropic/__init__.py +0 -0
  266. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/memory/__init__.py +0 -0
  267. {julee-0.1.6 → julee-0.1.8}/src/julee/services/knowledge_service/test_factory.py +0 -0
  268. {julee-0.1.6 → julee-0.1.8}/src/julee/services/temporal/__init__.py +0 -0
  269. {julee-0.1.6 → julee-0.1.8}/src/julee/services/temporal/activities.py +0 -0
  270. {julee-0.1.6 → julee-0.1.8}/src/julee/services/temporal/activity_names.py +0 -0
  271. {julee-0.1.6 → julee-0.1.8}/src/julee/services/temporal/proxies.py +0 -0
  272. {julee-0.1.6 → julee-0.1.8}/src/julee/util/__init__.py +0 -0
  273. {julee-0.1.6 → julee-0.1.8}/src/julee/util/domain.py +0 -0
  274. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/__init__.py +0 -0
  275. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/minio/__init__.py +0 -0
  276. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/minio/file_storage.py +0 -0
  277. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/temporal/__init__.py +0 -0
  278. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/temporal/client_proxies/file_storage.py +0 -0
  279. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/temporal/data_converter.py +0 -0
  280. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/temporal/minio_file_storage.py +0 -0
  281. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/temporal/proxies/__init__.py +0 -0
  282. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repos/temporal/proxies/file_storage.py +0 -0
  283. {julee-0.1.6 → julee-0.1.8}/src/julee/util/repositories.py +0 -0
  284. {julee-0.1.6 → julee-0.1.8}/src/julee/util/temporal/__init__.py +0 -0
  285. {julee-0.1.6 → julee-0.1.8}/src/julee/util/temporal/activities.py +0 -0
  286. {julee-0.1.6 → julee-0.1.8}/src/julee/util/tests/__init__.py +0 -0
  287. {julee-0.1.6 → julee-0.1.8}/src/julee/util/validation/__init__.py +0 -0
  288. {julee-0.1.6 → julee-0.1.8}/src/julee/util/validation/repository.py +0 -0
  289. {julee-0.1.6 → julee-0.1.8}/src/julee/util/validation/type_guards.py +0 -0
  290. {julee-0.1.6 → julee-0.1.8}/src/julee/worker.py +0 -0
  291. {julee-0.1.6 → julee-0.1.8}/src/julee/workflows/__init__.py +0 -0
  292. {julee-0.1.6 → julee-0.1.8}/src/julee/workflows/extract_assemble.py +0 -0
  293. {julee-0.1.6 → julee-0.1.8}/src/julee/workflows/validate_document.py +0 -0
  294. {julee-0.1.6 → julee-0.1.8}/src/julee.egg-info/dependency_links.txt +0 -0
  295. {julee-0.1.6 → julee-0.1.8}/src/julee.egg-info/requires.txt +0 -0
  296. {julee-0.1.6 → julee-0.1.8}/src/julee.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: julee
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: Julee - Clean architecture for accountable and transparent digital supply chains
5
5
  Author-email: Pyx Industries <chris@pyx.io>
6
6
  License: GPL-3.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "julee"
7
- version = "0.1.6"
7
+ version = "0.1.8"
8
8
  description = "Julee - Clean architecture for accountable and transparent digital supply chains"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """Julee - Clean architecture for accountable and transparent digital supply chains."""
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.1.8"
@@ -11,6 +11,7 @@ import logging
11
11
  from typing import Any
12
12
 
13
13
  from temporalio import workflow
14
+ from temporalio.workflow import ParentClosePolicy
14
15
 
15
16
  from julee.contrib.polling.domain.models.polling_config import PollingConfig
16
17
  from julee.contrib.polling.infrastructure.temporal.proxies import (
@@ -73,12 +74,13 @@ class NewDataDetectionPipeline:
73
74
  True if successfully triggered, False otherwise
74
75
  """
75
76
  try:
76
- # Start external workflow for downstream processing (fire-and-forget)
77
+ # Start child workflow for downstream processing with abandon policy
77
78
  await workflow.start_child_workflow(
78
79
  downstream_pipeline, # This would be the workflow class name
79
80
  args=[previous_data, new_data],
80
81
  id=f"downstream-{self.endpoint_id}-{workflow.info().workflow_id}",
81
82
  task_queue="downstream-processing-queue",
83
+ parent_close_policy=ParentClosePolicy.ABANDON,
82
84
  )
83
85
 
84
86
  workflow.logger.info(
@@ -433,6 +433,9 @@ class TestNewDataDetectionPipelineErrorHandling:
433
433
  task_queue="test-queue",
434
434
  )
435
435
 
436
+ @pytest.mark.skip(
437
+ reason="Test hangs in current test environment - needs investigation"
438
+ )
436
439
  @pytest.mark.asyncio
437
440
  async def test_downstream_trigger_failure_doesnt_fail_workflow(
438
441
  self, workflow_env, sample_config, mock_polling_results
@@ -41,7 +41,7 @@ class KnowledgeServiceQuery(BaseModel):
41
41
  For Anthropic services::
42
42
 
43
43
  query_metadata = {
44
- "model": "claude-sonnet-4-20250514",
44
+ "model": "claude-sonnet-4-5",
45
45
  "max_tokens": 4000,
46
46
  "temperature": 0.1
47
47
  }
@@ -242,7 +242,7 @@ class TestKnowledgeServiceQueryMetadata:
242
242
  def test_query_metadata_accepts_custom_values(self) -> None:
243
243
  """Test that query_metadata can accept custom service values."""
244
244
  metadata = {
245
- "model": "claude-sonnet-4-20250514",
245
+ "model": "claude-sonnet-4-5",
246
246
  "max_tokens": 4000,
247
247
  "temperature": 0.1,
248
248
  }
@@ -256,7 +256,7 @@ class TestKnowledgeServiceQueryMetadata:
256
256
  )
257
257
 
258
258
  assert query.query_metadata == metadata
259
- assert query.query_metadata["model"] == "claude-sonnet-4-20250514"
259
+ assert query.query_metadata["model"] == "claude-sonnet-4-5"
260
260
  assert query.query_metadata["max_tokens"] == 4000
261
261
  assert query.query_metadata["temperature"] == 0.1
262
262
 
@@ -289,7 +289,7 @@ class TestKnowledgeServiceQueryMetadata:
289
289
  def test_query_metadata_roundtrip_serialization(self) -> None:
290
290
  """Test query_metadata survives JSON roundtrip serialization."""
291
291
  metadata = {
292
- "model": "claude-sonnet-4-20250514",
292
+ "model": "claude-sonnet-4-5",
293
293
  "max_tokens": 2000,
294
294
  "temperature": 0.0,
295
295
  "citations": True,
@@ -14,7 +14,6 @@ from collections.abc import Callable
14
14
  from datetime import datetime, timezone
15
15
  from typing import Any
16
16
 
17
- import jsonpointer # type: ignore
18
17
  import jsonschema
19
18
  import multihash
20
19
 
@@ -37,6 +36,7 @@ from julee.services import KnowledgeService
37
36
  from julee.util.validation import ensure_repository_protocol, validate_parameter_types
38
37
 
39
38
  from .decorators import try_use_case_step
39
+ from .pointable_json_schema import PointableJSONSchema
40
40
 
41
41
  logger = logging.getLogger(__name__)
42
42
 
@@ -389,10 +389,9 @@ class ExtractAssembleDataUseCase:
389
389
  schema_pointer,
390
390
  query_id,
391
391
  ) in assembly_specification.knowledge_service_queries.items():
392
- # Get the relevant schema section
393
- schema_section = self._extract_schema_section(
394
- assembly_specification.jsonschema, schema_pointer
395
- )
392
+ # Use PointableJSONSchema to generate complete schema for pointer target
393
+ pointable_schema = PointableJSONSchema(assembly_specification.jsonschema)
394
+ output_schema = pointable_schema.schema_for_pointer(schema_pointer)
396
395
 
397
396
  # Get the query configuration
398
397
  query = queries[query_id]
@@ -414,19 +413,20 @@ class ExtractAssembleDataUseCase:
414
413
  f"Document not registered with service {query.knowledge_service_id}"
415
414
  )
416
415
 
417
- # Execute the query with schema section embedded in the prompt
418
- query_text = self._build_query_with_schema(query.prompt, schema_section)
419
-
416
+ # Execute query with complete schema
420
417
  query_result = await self.knowledge_service.execute_query(
421
418
  config,
422
- query_text,
419
+ query.prompt,
420
+ output_schema,
423
421
  [service_file_id],
424
422
  query.query_metadata,
425
423
  query.assistant_prompt,
426
424
  )
427
425
 
428
- # Parse and store the result
429
- result_data = self._parse_query_result(query_result.result_data)
426
+ # Knowledge service now returns parsed JSON directly
427
+ result_data = query_result.result_data.get("response")
428
+ if result_data is None:
429
+ raise ValueError("Knowledge service returned no response data")
430
430
  self._store_result_in_assembled_data(
431
431
  assembled_data, schema_pointer, result_data
432
432
  )
@@ -470,49 +470,6 @@ class ExtractAssembleDataUseCase:
470
470
  raise ValueError(f"Document not found: {document_id}")
471
471
  return document
472
472
 
473
- def _extract_schema_section(
474
- self, jsonschema: dict[str, Any], schema_pointer: str
475
- ) -> Any:
476
- """Extract relevant section of JSON schema using JSON Pointer."""
477
- if not schema_pointer:
478
- # Empty pointer refers to the entire schema
479
- return jsonschema
480
-
481
- try:
482
- ptr = jsonpointer.JsonPointer(schema_pointer)
483
- result = ptr.resolve(jsonschema)
484
- return result
485
- except (jsonpointer.JsonPointerException, KeyError, TypeError) as e:
486
- raise ValueError(f"Cannot extract schema section '{schema_pointer}': {e}")
487
-
488
- def _build_query_with_schema(self, base_prompt: str, schema_section: Any) -> str:
489
- """Build the query text with embedded JSON schema section."""
490
- schema_json = json.dumps(schema_section, indent=2)
491
- return f"""{base_prompt}
492
-
493
- Please structure your response according to this JSON schema:
494
- {schema_json}
495
-
496
- Return only valid JSON that conforms to this schema, without any surrounding
497
- text or markdown formatting."""
498
-
499
- def _parse_query_result(self, result_data: dict[str, Any]) -> Any:
500
- """Parse the query result to extract the JSON response."""
501
- response_text = result_data.get("response", "")
502
- if not response_text:
503
- raise ValueError("Empty response from knowledge service")
504
-
505
- # Response must be valid JSON
506
- try:
507
- parsed_result = json.loads(response_text.strip())
508
- return parsed_result
509
- except json.JSONDecodeError as e:
510
- raise ValueError(
511
- f"Knowledge service response must be valid JSON. "
512
- f"Complete response: {response_text} "
513
- f"Parse error: {e}"
514
- )
515
-
516
473
  def _store_result_in_assembled_data(
517
474
  self,
518
475
  assembled_data: dict[str, Any],
@@ -0,0 +1,102 @@
1
+ """
2
+ PointableJSONSchema utility for generating standalone schemas from JSON pointer targets.
3
+
4
+ This module provides the PointableJSONSchema class that handles the complexity of
5
+ extracting targeted schema sections while preserving important root metadata needed
6
+ for proper JSON Schema validation and structured outputs.
7
+ """
8
+
9
+ from typing import Any
10
+
11
+ from jsonpointer import JsonPointer
12
+
13
+
14
+ class PointableJSONSchema:
15
+ """Utility for generating standalone schemas from JSON pointer targets.
16
+
17
+ This class takes a complete root schema and provides methods to generate
18
+ standalone schemas for specific JSON pointer targets, preserving important
19
+ root metadata like $schema, $id, definitions, etc.
20
+ """
21
+
22
+ def __init__(self, root_schema: dict[str, Any]) -> None:
23
+ """Initialize with the complete root schema.
24
+
25
+ Args:
26
+ root_schema: Complete JSON schema with all metadata and definitions
27
+ """
28
+ self.root_schema = root_schema
29
+
30
+ def schema_for_pointer(self, json_pointer: str) -> dict[str, Any]:
31
+ """Generate a standalone schema for the given JSON pointer target.
32
+
33
+ This method extracts the target schema section using the JSON pointer
34
+ and builds a complete, standalone schema that preserves important root
35
+ metadata while making the pointer target the main content structure.
36
+
37
+ Args:
38
+ json_pointer: JSON pointer string (e.g., "/properties/title")
39
+
40
+ Returns:
41
+ Complete standalone schema with preserved metadata, suitable for
42
+ structured outputs or standalone validation
43
+
44
+ Raises:
45
+ ValueError: If JSON pointer is invalid or cannot be resolved
46
+ """
47
+ # Start with a copy of the root schema to preserve all metadata
48
+ standalone_schema = self.root_schema.copy()
49
+
50
+ # Handle empty pointer (refers to entire schema)
51
+ if not json_pointer or json_pointer == "":
52
+ return standalone_schema
53
+
54
+ # Resolve the JSON pointer to get target schema
55
+ try:
56
+ pointer = JsonPointer(json_pointer)
57
+ target_schema = pointer.resolve(self.root_schema)
58
+ except Exception as e:
59
+ raise ValueError(f"Invalid JSON pointer '{json_pointer}': {e}")
60
+
61
+ # Ensure it's an object type and has additionalProperties set
62
+ standalone_schema["type"] = "object"
63
+ standalone_schema["additionalProperties"] = False
64
+
65
+ # Enhance title to show which section this is (if title exists)
66
+ if "title" in standalone_schema:
67
+ standalone_schema["title"] = (
68
+ f"{standalone_schema['title']} - {json_pointer}"
69
+ )
70
+
71
+ # Extract property name from JSON pointer (e.g., "/properties/title" -> "title")
72
+ property_name = self._extract_property_name_from_pointer(json_pointer)
73
+
74
+ # Handle special case for "properties" - use target directly as properties
75
+ if property_name == "properties":
76
+ standalone_schema["properties"] = target_schema
77
+ else:
78
+ # Replace properties with just the target property
79
+ standalone_schema["properties"] = {property_name: target_schema}
80
+ standalone_schema["required"] = [property_name]
81
+
82
+ return standalone_schema
83
+
84
+ def _extract_property_name_from_pointer(self, json_pointer: str) -> str:
85
+ """Extract the final property name from a JSON pointer.
86
+
87
+ Examples:
88
+ "/properties/title" -> "title"
89
+ "/properties/user/properties/name" -> "name"
90
+ "/items" -> "items"
91
+ """
92
+ # Split pointer and get the last segment
93
+ segments = json_pointer.strip("/").split("/")
94
+ if len(segments) >= 2 and segments[-2] == "properties":
95
+ # Standard case: "/properties/something" -> "something"
96
+ return segments[-1]
97
+ elif len(segments) >= 1:
98
+ # Other cases: use the last segment
99
+ return segments[-1]
100
+ else:
101
+ # Fallback for edge cases
102
+ return "result"
@@ -107,7 +107,7 @@ class TestExtractAssembleDataUseCase:
107
107
  QueryResult(
108
108
  query_id="result-1",
109
109
  query_text="Extract the title from this document",
110
- result_data={"response": '"Test Meeting"'},
110
+ result_data={"response": "Test Meeting"},
111
111
  execution_time_ms=100,
112
112
  created_at=datetime.now(timezone.utc),
113
113
  ),
@@ -115,7 +115,7 @@ class TestExtractAssembleDataUseCase:
115
115
  query_id="result-2",
116
116
  query_text="Extract a summary from this document",
117
117
  result_data={
118
- "response": ('"This was a test meeting about important topics"')
118
+ "response": "This was a test meeting about important topics"
119
119
  },
120
120
  execution_time_ms=150,
121
121
  created_at=datetime.now(timezone.utc),
@@ -357,6 +357,147 @@ class TestExtractAssembleDataUseCase:
357
357
  == "This was a test meeting about important topics"
358
358
  )
359
359
 
360
+ async def test_schema_passed_in_metadata(
361
+ self,
362
+ configured_use_case: ExtractAssembleDataUseCase,
363
+ document_repo: MemoryDocumentRepository,
364
+ assembly_repo: MemoryAssemblyRepository,
365
+ assembly_specification_repo: MemoryAssemblySpecificationRepository,
366
+ knowledge_service_query_repo: MemoryKnowledgeServiceQueryRepository,
367
+ knowledge_service_config_repo: MemoryKnowledgeServiceConfigRepository,
368
+ ) -> None:
369
+ """Test that schema sections are passed in query metadata instead of embedded in prompt."""
370
+ # Arrange - Create test document
371
+ content_text = "Sample meeting transcript for testing"
372
+ content_bytes = content_text.encode("utf-8")
373
+ document = Document(
374
+ document_id="doc-123",
375
+ original_filename="test_transcript.txt",
376
+ content_type="text/plain",
377
+ size_bytes=len(content_bytes),
378
+ content_multihash="test-hash-123",
379
+ status=DocumentStatus.CAPTURED,
380
+ content=ContentStream(io.BytesIO(content_bytes)),
381
+ created_at=datetime.now(timezone.utc),
382
+ updated_at=datetime.now(timezone.utc),
383
+ )
384
+ await document_repo.save(document)
385
+
386
+ # Create assembly specification with simple schema
387
+ schema = {
388
+ "type": "object",
389
+ "properties": {
390
+ "title": {"type": "string"},
391
+ },
392
+ "required": ["title"],
393
+ }
394
+
395
+ assembly_spec = AssemblySpecification(
396
+ assembly_specification_id="spec-123",
397
+ name="Test Assembly",
398
+ applicability="Test documents",
399
+ jsonschema=schema,
400
+ status=AssemblySpecificationStatus.ACTIVE,
401
+ knowledge_service_queries={
402
+ "/properties/title": "query-1",
403
+ },
404
+ created_at=datetime.now(timezone.utc),
405
+ updated_at=datetime.now(timezone.utc),
406
+ )
407
+ await assembly_specification_repo.save(assembly_spec)
408
+
409
+ # Create knowledge service config
410
+ ks_config = KnowledgeServiceConfig(
411
+ knowledge_service_id="ks-123",
412
+ name="Test Knowledge Service",
413
+ description="Test service",
414
+ service_api=ServiceApi.ANTHROPIC,
415
+ created_at=datetime.now(timezone.utc),
416
+ updated_at=datetime.now(timezone.utc),
417
+ )
418
+ await knowledge_service_config_repo.save(ks_config)
419
+
420
+ # Create knowledge service query
421
+ query1 = KnowledgeServiceQuery(
422
+ query_id="query-1",
423
+ name="Extract Title",
424
+ knowledge_service_id="ks-123",
425
+ prompt="Extract the title from this document",
426
+ query_metadata={"max_tokens": 100, "temperature": 0.1},
427
+ created_at=datetime.now(timezone.utc),
428
+ updated_at=datetime.now(timezone.utc),
429
+ )
430
+ await knowledge_service_query_repo.save(query1)
431
+
432
+ # Mock knowledge service to capture the actual call parameters
433
+ captured_calls = []
434
+
435
+ async def mock_execute_query(
436
+ config,
437
+ query_text,
438
+ output_schema=None,
439
+ service_file_ids=None,
440
+ query_metadata=None,
441
+ assistant_prompt=None,
442
+ ):
443
+ captured_calls.append(
444
+ {
445
+ "config": config,
446
+ "query_text": query_text,
447
+ "output_schema": output_schema,
448
+ "service_file_ids": service_file_ids,
449
+ "query_metadata": query_metadata,
450
+ "assistant_prompt": assistant_prompt,
451
+ }
452
+ )
453
+ # Return a mock result
454
+ return QueryResult(
455
+ query_id="mock-result",
456
+ query_text=query_text,
457
+ result_data={"response": "Mock Title"},
458
+ execution_time_ms=100,
459
+ created_at=datetime.now(timezone.utc),
460
+ )
461
+
462
+ # Replace the knowledge service execute_query method
463
+ original_execute_query = configured_use_case.knowledge_service.execute_query
464
+ configured_use_case.knowledge_service.execute_query = mock_execute_query
465
+
466
+ try:
467
+ # Act
468
+ await configured_use_case.assemble_data(
469
+ document_id="doc-123",
470
+ assembly_specification_id="spec-123",
471
+ workflow_id="test-workflow-schema",
472
+ )
473
+
474
+ # Assert - Verify the call was made with schema in metadata
475
+ assert len(captured_calls) == 1
476
+ call = captured_calls[0]
477
+
478
+ # Verify query text is clean (no embedded schema)
479
+ assert call["query_text"] == "Extract the title from this document"
480
+ assert "JSON schema" not in call["query_text"]
481
+ assert "Please structure your response" not in call["query_text"]
482
+
483
+ # Verify complete schema is passed as output_schema parameter
484
+ assert call["output_schema"] is not None
485
+ expected_schema = {
486
+ "type": "object",
487
+ "additionalProperties": False,
488
+ "properties": {"title": {"type": "string"}},
489
+ "required": ["title"],
490
+ } # Complete schema generated by PointableJSONSchema
491
+ assert call["output_schema"] == expected_schema
492
+
493
+ # Verify original metadata is preserved (without output_schema)
494
+ assert call["query_metadata"]["max_tokens"] == 100
495
+ assert call["query_metadata"]["temperature"] == 0.1
496
+
497
+ finally:
498
+ # Restore original method
499
+ configured_use_case.knowledge_service.execute_query = original_execute_query
500
+
360
501
  @pytest.mark.asyncio
361
502
  async def test_assembly_fails_when_specification_not_found(
362
503
  self, use_case: ExtractAssembleDataUseCase