b4pt0r-the-framework 0.1.0__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 (213) hide show
  1. b4pt0r_the_framework-0.1.0/.gitignore +13 -0
  2. b4pt0r_the_framework-0.1.0/AGENTS.md +59 -0
  3. b4pt0r_the_framework-0.1.0/CHANGELOG.md +16 -0
  4. b4pt0r_the_framework-0.1.0/LICENSE +21 -0
  5. b4pt0r_the_framework-0.1.0/PKG-INFO +245 -0
  6. b4pt0r_the_framework-0.1.0/README.md +206 -0
  7. b4pt0r_the_framework-0.1.0/docs/framework-api-simplification-audit.md +37 -0
  8. b4pt0r_the_framework-0.1.0/docs/framework-clarification-audit.md +51 -0
  9. b4pt0r_the_framework-0.1.0/docs/framework-model-style-audit.md +143 -0
  10. b4pt0r_the_framework-0.1.0/docs/framework.md +520 -0
  11. b4pt0r_the_framework-0.1.0/docs/starter-plan.md +87 -0
  12. b4pt0r_the_framework-0.1.0/examples/minimal_agent_app.py +87 -0
  13. b4pt0r_the_framework-0.1.0/pyproject.toml +60 -0
  14. b4pt0r_the_framework-0.1.0/starter/README.md +161 -0
  15. b4pt0r_the_framework-0.1.0/starter/__init__.py +1 -0
  16. b4pt0r_the_framework-0.1.0/starter/__main__.py +6 -0
  17. b4pt0r_the_framework-0.1.0/starter/application.py +70 -0
  18. b4pt0r_the_framework-0.1.0/starter/desktop.py +156 -0
  19. b4pt0r_the_framework-0.1.0/starter/instructions.md +47 -0
  20. b4pt0r_the_framework-0.1.0/starter/memory.md +25 -0
  21. b4pt0r_the_framework-0.1.0/starter/security.py +41 -0
  22. b4pt0r_the_framework-0.1.0/starter/server.py +179 -0
  23. b4pt0r_the_framework-0.1.0/starter/ui/.gitignore +2 -0
  24. b4pt0r_the_framework-0.1.0/starter/ui/index.html +12 -0
  25. b4pt0r_the_framework-0.1.0/starter/ui/package-lock.json +1153 -0
  26. b4pt0r_the_framework-0.1.0/starter/ui/package.json +18 -0
  27. b4pt0r_the_framework-0.1.0/starter/ui/src/api.js +25 -0
  28. b4pt0r_the_framework-0.1.0/starter/ui/src/main.jsx +380 -0
  29. b4pt0r_the_framework-0.1.0/starter/ui/src/realtime-audio.js +113 -0
  30. b4pt0r_the_framework-0.1.0/starter/ui/src/realtime-transcript.js +51 -0
  31. b4pt0r_the_framework-0.1.0/starter/ui/src/realtime-transcript.test.js +24 -0
  32. b4pt0r_the_framework-0.1.0/starter/ui/src/session.js +83 -0
  33. b4pt0r_the_framework-0.1.0/starter/ui/src/session.test.js +118 -0
  34. b4pt0r_the_framework-0.1.0/starter/ui/src/settings.jsx +117 -0
  35. b4pt0r_the_framework-0.1.0/starter/ui/src/style.css +297 -0
  36. b4pt0r_the_framework-0.1.0/starter/ui/src/voice.js +84 -0
  37. b4pt0r_the_framework-0.1.0/starter/ui/src/voice.test.js +106 -0
  38. b4pt0r_the_framework-0.1.0/starter/ui/vite.config.js +3 -0
  39. b4pt0r_the_framework-0.1.0/starter/voice.py +65 -0
  40. b4pt0r_the_framework-0.1.0/tests/agentic/test_agent_spec.py +365 -0
  41. b4pt0r_the_framework-0.1.0/tests/agentic/test_agentic_loop_control.py +206 -0
  42. b4pt0r_the_framework-0.1.0/tests/agentic/test_architecture.py +73 -0
  43. b4pt0r_the_framework-0.1.0/tests/agentic/test_atomic_persistence.py +78 -0
  44. b4pt0r_the_framework-0.1.0/tests/agentic/test_bash_plugin.py +230 -0
  45. b4pt0r_the_framework-0.1.0/tests/agentic/test_command_loop.py +60 -0
  46. b4pt0r_the_framework-0.1.0/tests/agentic/test_context_compaction.py +389 -0
  47. b4pt0r_the_framework-0.1.0/tests/agentic/test_declaration_schema.py +51 -0
  48. b4pt0r_the_framework-0.1.0/tests/agentic/test_dependencies.py +21 -0
  49. b4pt0r_the_framework-0.1.0/tests/agentic/test_embeddings.py +40 -0
  50. b4pt0r_the_framework-0.1.0/tests/agentic/test_event_loop.py +30 -0
  51. b4pt0r_the_framework-0.1.0/tests/agentic/test_fleet.py +663 -0
  52. b4pt0r_the_framework-0.1.0/tests/agentic/test_function_specs.py +52 -0
  53. b4pt0r_the_framework-0.1.0/tests/agentic/test_lifecycle.py +53 -0
  54. b4pt0r_the_framework-0.1.0/tests/agentic/test_native_model_coercion.py +196 -0
  55. b4pt0r_the_framework-0.1.0/tests/agentic/test_plugin_endpoint.py +59 -0
  56. b4pt0r_the_framework-0.1.0/tests/agentic/test_plugin_status.py +19 -0
  57. b4pt0r_the_framework-0.1.0/tests/agentic/test_plugin_tools.py +988 -0
  58. b4pt0r_the_framework-0.1.0/tests/agentic/test_recovery.py +105 -0
  59. b4pt0r_the_framework-0.1.0/tests/agentic/test_registry_plugin.py +148 -0
  60. b4pt0r_the_framework-0.1.0/tests/agentic/test_runtime_models.py +108 -0
  61. b4pt0r_the_framework-0.1.0/tests/agentic/test_scheduler_plugin.py +45 -0
  62. b4pt0r_the_framework-0.1.0/tests/agentic/test_server_runtime.py +73 -0
  63. b4pt0r_the_framework-0.1.0/tests/agentic/test_session.py +457 -0
  64. b4pt0r_the_framework-0.1.0/tests/agentic/test_starter_voice.py +90 -0
  65. b4pt0r_the_framework-0.1.0/tests/agentic/test_supervisor.py +115 -0
  66. b4pt0r_the_framework-0.1.0/tests/agentic/test_system_plugin.py +162 -0
  67. b4pt0r_the_framework-0.1.0/tests/agentic/test_tailscale.py +108 -0
  68. b4pt0r_the_framework-0.1.0/tests/agentic/test_tokenization.py +50 -0
  69. b4pt0r_the_framework-0.1.0/tests/agentic/test_usage.py +47 -0
  70. b4pt0r_the_framework-0.1.0/tests/agentic/test_web_search_plugin.py +44 -0
  71. b4pt0r_the_framework-0.1.0/tests/agentic/test_worker.py +867 -0
  72. b4pt0r_the_framework-0.1.0/tests/agentic/test_worker_process.py +77 -0
  73. b4pt0r_the_framework-0.1.0/tests/application/README.md +4 -0
  74. b4pt0r_the_framework-0.1.0/tests/application/fixtures/starter_restart_server.py +43 -0
  75. b4pt0r_the_framework-0.1.0/tests/application/fixtures/unauthenticated_worker.py +14 -0
  76. b4pt0r_the_framework-0.1.0/tests/application/test_application_bridge.py +138 -0
  77. b4pt0r_the_framework-0.1.0/tests/application/test_browser_rpc_lifecycle.py +140 -0
  78. b4pt0r_the_framework-0.1.0/tests/application/test_endpoint_models.py +124 -0
  79. b4pt0r_the_framework-0.1.0/tests/application/test_endpoint_registry.py +261 -0
  80. b4pt0r_the_framework-0.1.0/tests/application/test_framework.py +405 -0
  81. b4pt0r_the_framework-0.1.0/tests/application/test_framework_bootstrap.py +45 -0
  82. b4pt0r_the_framework-0.1.0/tests/application/test_framework_independence.py +76 -0
  83. b4pt0r_the_framework-0.1.0/tests/application/test_framework_wheel.py +89 -0
  84. b4pt0r_the_framework-0.1.0/tests/application/test_framework_worker_integration.py +111 -0
  85. b4pt0r_the_framework-0.1.0/tests/application/test_mapping_store.py +57 -0
  86. b4pt0r_the_framework-0.1.0/tests/application/test_media_response.py +5 -0
  87. b4pt0r_the_framework-0.1.0/tests/application/test_minimal_example.py +29 -0
  88. b4pt0r_the_framework-0.1.0/tests/application/test_plugin_host.py +289 -0
  89. b4pt0r_the_framework-0.1.0/tests/application/test_runtime_lifecycle.py +97 -0
  90. b4pt0r_the_framework-0.1.0/tests/application/test_scheduler.py +264 -0
  91. b4pt0r_the_framework-0.1.0/tests/application/test_services.py +124 -0
  92. b4pt0r_the_framework-0.1.0/tests/application/test_starter.py +211 -0
  93. b4pt0r_the_framework-0.1.0/tests/application/test_starter_browser_recovery.py +138 -0
  94. b4pt0r_the_framework-0.1.0/tests/application/test_starter_desktop.py +73 -0
  95. b4pt0r_the_framework-0.1.0/tests/application/test_starter_live.py +78 -0
  96. b4pt0r_the_framework-0.1.0/tests/application/test_starter_security.py +34 -0
  97. b4pt0r_the_framework-0.1.0/tests/application/test_starter_voice_live.py +87 -0
  98. b4pt0r_the_framework-0.1.0/tests/application/test_supervisor_shutdown.py +50 -0
  99. b4pt0r_the_framework-0.1.0/tests/application/test_surfaces.py +276 -0
  100. b4pt0r_the_framework-0.1.0/tests/application/test_system_control.py +238 -0
  101. b4pt0r_the_framework-0.1.0/tests/application/test_websockets.py +70 -0
  102. b4pt0r_the_framework-0.1.0/tests/fixtures/fake_worker.py +242 -0
  103. b4pt0r_the_framework-0.1.0/the_framework/__init__.py +30 -0
  104. b4pt0r_the_framework-0.1.0/the_framework/__main__.py +6 -0
  105. b4pt0r_the_framework-0.1.0/the_framework/agent/__init__.py +265 -0
  106. b4pt0r_the_framework-0.1.0/the_framework/agent/context/__init__.py +1 -0
  107. b4pt0r_the_framework-0.1.0/the_framework/agent/context/builder.py +137 -0
  108. b4pt0r_the_framework-0.1.0/the_framework/agent/context/caching.py +8 -0
  109. b4pt0r_the_framework-0.1.0/the_framework/agent/context/compaction.py +95 -0
  110. b4pt0r_the_framework-0.1.0/the_framework/agent/context/projections.py +37 -0
  111. b4pt0r_the_framework-0.1.0/the_framework/agent/context/session.py +504 -0
  112. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/__init__.py +1 -0
  113. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/commands.py +114 -0
  114. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/endpoints.py +132 -0
  115. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/hooks.py +45 -0
  116. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/instructions.py +53 -0
  117. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/plugin.py +196 -0
  118. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/providers.py +138 -0
  119. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/schema.py +155 -0
  120. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/specialists.py +180 -0
  121. b4pt0r_the_framework-0.1.0/the_framework/agent/extensions/tools.py +259 -0
  122. b4pt0r_the_framework-0.1.0/the_framework/agent/models/__init__.py +1 -0
  123. b4pt0r_the_framework-0.1.0/the_framework/agent/models/base.py +63 -0
  124. b4pt0r_the_framework-0.1.0/the_framework/agent/models/config.py +115 -0
  125. b4pt0r_the_framework-0.1.0/the_framework/agent/models/content.py +28 -0
  126. b4pt0r_the_framework-0.1.0/the_framework/agent/models/events.py +363 -0
  127. b4pt0r_the_framework-0.1.0/the_framework/agent/models/lifecycle.py +100 -0
  128. b4pt0r_the_framework-0.1.0/the_framework/agent/models/responses.py +454 -0
  129. b4pt0r_the_framework-0.1.0/the_framework/agent/models/state.py +28 -0
  130. b4pt0r_the_framework-0.1.0/the_framework/agent/models/usage.py +66 -0
  131. b4pt0r_the_framework-0.1.0/the_framework/agent/models/worker.py +60 -0
  132. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/__init__.py +1 -0
  133. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/agent.py +318 -0
  134. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/agentic_loop.py +623 -0
  135. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/application.py +25 -0
  136. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/chat.py +17 -0
  137. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/command_loop.py +82 -0
  138. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/event_loop.py +92 -0
  139. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/prompts/README.md +3 -0
  140. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/prompts/tool_outputs.md +23 -0
  141. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/protocol.py +274 -0
  142. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/worker.py +549 -0
  143. b4pt0r_the_framework-0.1.0/the_framework/agent/runtime/worker_process.py +100 -0
  144. b4pt0r_the_framework-0.1.0/the_framework/agent/spec.py +264 -0
  145. b4pt0r_the_framework-0.1.0/the_framework/cli.py +67 -0
  146. b4pt0r_the_framework-0.1.0/the_framework/plugins/__init__.py +1 -0
  147. b4pt0r_the_framework-0.1.0/the_framework/plugins/bash/__init__.py +3 -0
  148. b4pt0r_the_framework-0.1.0/the_framework/plugins/bash/instructions.md +18 -0
  149. b4pt0r_the_framework-0.1.0/the_framework/plugins/bash/plugin.py +531 -0
  150. b4pt0r_the_framework-0.1.0/the_framework/plugins/browser/__init__.py +3 -0
  151. b4pt0r_the_framework-0.1.0/the_framework/plugins/browser/instructions.md +9 -0
  152. b4pt0r_the_framework-0.1.0/the_framework/plugins/browser/plugin.py +259 -0
  153. b4pt0r_the_framework-0.1.0/the_framework/plugins/embeddings.py +50 -0
  154. b4pt0r_the_framework-0.1.0/the_framework/plugins/memory/__init__.py +1 -0
  155. b4pt0r_the_framework-0.1.0/the_framework/plugins/memory/curator.py +590 -0
  156. b4pt0r_the_framework-0.1.0/the_framework/plugins/memory/instructions.md +6 -0
  157. b4pt0r_the_framework-0.1.0/the_framework/plugins/memory/live.py +178 -0
  158. b4pt0r_the_framework-0.1.0/the_framework/plugins/memory/plugin.py +456 -0
  159. b4pt0r_the_framework-0.1.0/the_framework/plugins/memory/store.py +704 -0
  160. b4pt0r_the_framework-0.1.0/the_framework/plugins/realtime/__init__.py +3 -0
  161. b4pt0r_the_framework-0.1.0/the_framework/plugins/realtime/plugin.py +251 -0
  162. b4pt0r_the_framework-0.1.0/the_framework/plugins/registry/__init__.py +3 -0
  163. b4pt0r_the_framework-0.1.0/the_framework/plugins/registry/instructions.md +19 -0
  164. b4pt0r_the_framework-0.1.0/the_framework/plugins/registry/live.py +78 -0
  165. b4pt0r_the_framework-0.1.0/the_framework/plugins/registry/plugin.py +462 -0
  166. b4pt0r_the_framework-0.1.0/the_framework/plugins/scheduler/__init__.py +3 -0
  167. b4pt0r_the_framework-0.1.0/the_framework/plugins/scheduler/instructions.md +18 -0
  168. b4pt0r_the_framework-0.1.0/the_framework/plugins/scheduler/plugin.py +112 -0
  169. b4pt0r_the_framework-0.1.0/the_framework/plugins/scheduler/service.py +463 -0
  170. b4pt0r_the_framework-0.1.0/the_framework/plugins/system/__init__.py +3 -0
  171. b4pt0r_the_framework-0.1.0/the_framework/plugins/system/instructions.md +31 -0
  172. b4pt0r_the_framework-0.1.0/the_framework/plugins/system/plugin.py +146 -0
  173. b4pt0r_the_framework-0.1.0/the_framework/plugins/system/service.py +279 -0
  174. b4pt0r_the_framework-0.1.0/the_framework/plugins/web_search/__init__.py +3 -0
  175. b4pt0r_the_framework-0.1.0/the_framework/plugins/web_search/instructions.md +5 -0
  176. b4pt0r_the_framework-0.1.0/the_framework/plugins/web_search/plugin.py +34 -0
  177. b4pt0r_the_framework-0.1.0/the_framework/py.typed +1 -0
  178. b4pt0r_the_framework-0.1.0/the_framework/server/__init__.py +46 -0
  179. b4pt0r_the_framework-0.1.0/the_framework/server/api/__init__.py +1 -0
  180. b4pt0r_the_framework-0.1.0/the_framework/server/api/agent.py +168 -0
  181. b4pt0r_the_framework-0.1.0/the_framework/server/api/endpoints.py +513 -0
  182. b4pt0r_the_framework-0.1.0/the_framework/server/api/health.py +38 -0
  183. b4pt0r_the_framework-0.1.0/the_framework/server/api/media.py +15 -0
  184. b4pt0r_the_framework-0.1.0/the_framework/server/api/model_schema.py +59 -0
  185. b4pt0r_the_framework-0.1.0/the_framework/server/api/plugins.py +84 -0
  186. b4pt0r_the_framework-0.1.0/the_framework/server/api/surfaces.py +120 -0
  187. b4pt0r_the_framework-0.1.0/the_framework/server/api/transport.py +80 -0
  188. b4pt0r_the_framework-0.1.0/the_framework/server/api/uploads.py +139 -0
  189. b4pt0r_the_framework-0.1.0/the_framework/server/api/websockets.py +127 -0
  190. b4pt0r_the_framework-0.1.0/the_framework/server/clients/__init__.py +1 -0
  191. b4pt0r_the_framework-0.1.0/the_framework/server/clients/browser.py +497 -0
  192. b4pt0r_the_framework-0.1.0/the_framework/server/clients/browser_rpc.py +247 -0
  193. b4pt0r_the_framework-0.1.0/the_framework/server/clients/remote.py +1071 -0
  194. b4pt0r_the_framework-0.1.0/the_framework/server/clients/surfaces.py +418 -0
  195. b4pt0r_the_framework-0.1.0/the_framework/server/clients/tailscale.py +154 -0
  196. b4pt0r_the_framework-0.1.0/the_framework/server/composition/__init__.py +1 -0
  197. b4pt0r_the_framework-0.1.0/the_framework/server/composition/application.py +612 -0
  198. b4pt0r_the_framework-0.1.0/the_framework/server/composition/controls.py +46 -0
  199. b4pt0r_the_framework-0.1.0/the_framework/server/composition/dependencies.py +26 -0
  200. b4pt0r_the_framework-0.1.0/the_framework/server/composition/plugins.py +385 -0
  201. b4pt0r_the_framework-0.1.0/the_framework/server/composition/services.py +195 -0
  202. b4pt0r_the_framework-0.1.0/the_framework/server/runtime/__init__.py +1 -0
  203. b4pt0r_the_framework-0.1.0/the_framework/server/runtime/application.py +446 -0
  204. b4pt0r_the_framework-0.1.0/the_framework/server/runtime/bridge.py +309 -0
  205. b4pt0r_the_framework-0.1.0/the_framework/server/runtime/discovery.py +165 -0
  206. b4pt0r_the_framework-0.1.0/the_framework/server/runtime/fleet.py +658 -0
  207. b4pt0r_the_framework-0.1.0/the_framework/server/runtime/realtime.py +858 -0
  208. b4pt0r_the_framework-0.1.0/the_framework/server/runtime/supervisor.py +160 -0
  209. b4pt0r_the_framework-0.1.0/the_framework/utils/__init__.py +1 -0
  210. b4pt0r_the_framework-0.1.0/the_framework/utils/ids.py +7 -0
  211. b4pt0r_the_framework-0.1.0/the_framework/utils/persistence.py +76 -0
  212. b4pt0r_the_framework-0.1.0/the_framework/utils/tokens.py +97 -0
  213. b4pt0r_the_framework-0.1.0/uv.lock +1260 -0
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ .coverage
5
+ .venv/
6
+ .playwright-browsers/
7
+ node_modules/
8
+ starter/ui/dist/
9
+ .env
10
+ .env.*
11
+ !.env.example
12
+ *.log
13
+ .DS_Store
@@ -0,0 +1,59 @@
1
+ # Working on The Framework
2
+
3
+ The public Python package is `the_framework/`; `starter/` is an editable
4
+ example that uses it. Read [README.md](README.md) for the first-run path and
5
+ [docs/framework.md](docs/framework.md) for the composition API. This
6
+ file records the constraints to preserve when changing the framework.
7
+
8
+ ## Ownership and contracts
9
+
10
+ - Keep application identity, instructions, policies and domain-specific
11
+ features outside `the_framework`. Dependencies point from applications to the
12
+ framework, never the reverse. The starter must depend on `the_framework`, not
13
+ on any particular application.
14
+ - An `AgentApplication` has one durable primary conversation. The worker is its
15
+ only history writer. Plugins may declare private specialist agents, but a
16
+ specialist must not write into primary history; results return through the
17
+ owning plugin or an ordered primary-agent input.
18
+ - The server owns authentication, routes, client connections and worker
19
+ supervision. Workers own inference, tools and their sessions. Clients own
20
+ their local interface and media/device execution. Do not move a
21
+ responsibility across these process boundaries merely to simplify a call.
22
+ - Treat saved sessions, task delivery, HTTP/WebSocket payloads and client
23
+ security as contracts. Preserve them when refactoring, or provide an explicit
24
+ tested migration. A client reconnection or worker restart must not create a
25
+ second main conversation or bypass safety controls.
26
+ - Plugins contribute through the framework's declarations and lifecycle, not
27
+ by mutating FastAPI internals or global registries. Loading a plugin is
28
+ separate from exposing its tools to an agent; server routes may remain
29
+ available when an agent binding is disabled.
30
+
31
+ ## Making changes
32
+
33
+ - Keep the public API small and typed. Prefer improving an existing primitive
34
+ to adding a forwarding layer. Migrate internal callers when an internal API
35
+ changes rather than retaining obsolete aliases.
36
+ - Use `modict` for structured models where its mapping and validation features
37
+ fit. Inspect its API before adding a parallel model or conversion layer.
38
+ Backend-specific Responses behavior belongs at the `codex-backend-sdk`
39
+ boundary, not in ad hoc transport code elsewhere.
40
+ - Changes to shared dependencies such as `modict` or `codex-backend-sdk` must
41
+ remain generally useful and backward-compatible; test them in their own
42
+ repositories before relying on the change here.
43
+ - Keep the starter runnable from an installed wheel outside this checkout.
44
+ Its source and interface must remain editable application code, not hidden
45
+ framework policy.
46
+
47
+ ## Verification
48
+
49
+ Add focused tests for the behavior being changed. Then run the framework suite:
50
+
51
+ ```sh
52
+ uv sync --extra dev
53
+ uv run pytest -q tests/application tests/agentic
54
+ ```
55
+
56
+ `tests/application/` covers observable contracts and includes wheel-only
57
+ checks. `tests/agentic/` covers internals that may evolve. For changes to the
58
+ starter UI, also run its npm tests and build as described in
59
+ [starter/README.md](starter/README.md).
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ Notable changes to the Python distribution are recorded here. Versions follow
4
+ the distribution `b4pt0r-the-framework`; the import remains `the_framework`.
5
+ Until a stable release, minor versions may revise the public composition API.
6
+
7
+ ## Unreleased
8
+
9
+ - No changes recorded yet.
10
+
11
+ ## 0.1.0 - 2026-09-22
12
+
13
+ - Provide the `AgentApplication` composition API for one persistent primary
14
+ agent, server extensions, plugins, private specialists and client surfaces.
15
+ - Include the editable starter application and `the-framework bootstrap` CLI.
16
+ - Package typed Python modules and runtime resources with MIT licensing.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 B4PT0R
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,245 @@
1
+ Metadata-Version: 2.5
2
+ Name: b4pt0r-the-framework
3
+ Version: 0.1.0
4
+ Summary: Build persistent, extensible local agent applications with supervised workers and authenticated clients
5
+ Project-URL: Homepage, https://github.com/B4PT0R/the_framework
6
+ Project-URL: Documentation, https://github.com/B4PT0R/the_framework/blob/main/README.md
7
+ Project-URL: Repository, https://github.com/B4PT0R/the_framework
8
+ Project-URL: Changelog, https://github.com/B4PT0R/the_framework/blob/main/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/B4PT0R/the_framework/issues
10
+ Author: B4PT0R
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: agentic-applications,agents,fastapi,framework,plugins
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Framework :: FastAPI
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: codex-backend-sdk>=0.5.3
24
+ Requires-Dist: fastapi
25
+ Requires-Dist: httpx
26
+ Requires-Dist: jsonschema>=4.26.0
27
+ Requires-Dist: modict>=0.4.19
28
+ Requires-Dist: pillow
29
+ Requires-Dist: playwright
30
+ Requires-Dist: python-multipart
31
+ Requires-Dist: pyyaml
32
+ Requires-Dist: tiktoken
33
+ Requires-Dist: uvicorn
34
+ Requires-Dist: websockets
35
+ Provides-Extra: dev
36
+ Requires-Dist: httpx2>=2.0.0; extra == 'dev'
37
+ Requires-Dist: pytest; extra == 'dev'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # The Framework
41
+
42
+ The Framework is a Python library for building applications around a persistent
43
+ AI agent. It supplies the parts that are easy to get wrong repeatedly: one
44
+ durable conversation, a supervised agent worker, plugin and specialist-agent
45
+ lifecycle, authenticated HTTP/WebSocket connections, and versioned web
46
+ interfaces. You supply the agent's identity, instructions, application
47
+ services, security policy and user experience.
48
+
49
+ You can use it for a local desktop companion, a private agent with tools and
50
+ memory, or another agent application whose browser and backend need to survive
51
+ worker restarts without losing the conversation. It is a library, not a hosted
52
+ agent service. The included [starter](https://github.com/B4PT0R/the_framework/blob/main/starter/README.md) is an editable
53
+ application that shows the pieces working together; you are free to build a
54
+ different frontend or none at all.
55
+
56
+ The PyPI distribution is named `b4pt0r-the-framework`. Python code imports
57
+ `the_framework`, and the template command is `the-framework`. Python 3.12 or
58
+ newer is required.
59
+
60
+ To install the published package in a virtual environment:
61
+
62
+ ```sh
63
+ python3 -m venv .venv
64
+ . .venv/bin/activate
65
+ python -m pip install b4pt0r-the-framework
66
+ ```
67
+
68
+ The Python wheel includes the framework and the editable starter template, but
69
+ not a prebuilt browser UI or Playwright's Chromium binary. Those are prepared
70
+ separately when you run the starter.
71
+
72
+ ## What an application is made of
73
+
74
+ | Part | What it does | What your application decides |
75
+ | --- | --- | --- |
76
+ | `AgentApplication` | Validates and assembles one application | Name, version, plugins, server services, security and client surfaces |
77
+ | `AgentSpec` | Describes an agent and its session policy | Instructions, model configuration, tools and resources |
78
+ | `Plugin` / `PluginSpec` | Adds agent tools, context, hooks and optional server runtime | Which capabilities exist and when they are exposed |
79
+ | `Extension` / `@endpoint` | Starts services and exposes validated API routes | Application state, route schemas and authorization |
80
+ | `ClientSurface` | Builds, previews, publishes and rolls back an editable web UI | Source, build command, routes and release policy |
81
+
82
+ There is exactly **one primary, durable conversation**. Private specialist
83
+ agents can perform bounded background work, but their sessions are not new
84
+ user-facing conversations and they cannot edit the primary history directly.
85
+ The server supervises workers and owns authentication and client transport;
86
+ workers own inference and their own sessions; a browser client owns its local
87
+ interface and device/media execution. This separation lets a client reconnect
88
+ or refresh while the main conversation remains intact.
89
+
90
+ Plugins may provide agent-facing tools without a server runtime, or both. A
91
+ plugin's runtime state and its binding to an agent are separate: turning off its
92
+ tools for the agent need not remove routes that a settings screen still uses.
93
+ Specialists, durable task delivery and versioned public capabilities are
94
+ available when a simple plugin is not enough. More detail is in the
95
+ [framework guide](https://github.com/B4PT0R/the_framework/blob/main/docs/framework.md).
96
+
97
+ ## Try a working application
98
+
99
+ Install [`uv`](https://docs.astral.sh/uv/) and Node.js/npm, then from this
100
+ checkout run:
101
+
102
+ ```sh
103
+ uv sync
104
+ npm --prefix starter/ui ci
105
+ npm --prefix starter/ui run build
106
+ uv run playwright install chromium
107
+ uv run python -m starter
108
+ ```
109
+
110
+ Playwright Chromium also needs its system libraries; on Linux,
111
+ `uv run playwright install --with-deps chromium` can install them if you have
112
+ the required system permissions. The starter opens a local Chromium window with
113
+ chat, settings, file attachments and an editable React interface. Its server
114
+ listens on loopback and authenticates the browser. You can inspect the UI and
115
+ settings without model credentials; generating replies, using hosted search or
116
+ embeddings, and voice features require a usable account/capabilities through
117
+ `codex-backend-sdk`. The [starter guide](https://github.com/B4PT0R/the_framework/blob/main/starter/README.md) covers sign-in,
118
+ data storage and feature-by-feature behavior.
119
+
120
+ To make an independent, editable copy, run `the-framework bootstrap` in the
121
+ environment where you installed the package. From this checkout, prefix it
122
+ with `uv run`:
123
+
124
+ ```sh
125
+ uv run the-framework bootstrap --code-dir /path/to/my-agent-code --data-dir /path/to/my-agent-data
126
+ ```
127
+
128
+ Both directories must be empty or absent, distinct and non-overlapping. The
129
+ command copies the starter source and records the private data location; it
130
+ does not install npm dependencies, build the UI or launch the app. From the new
131
+ code directory, run `npm --prefix starter/ui ci`,
132
+ `npm --prefix starter/ui run build`, then `python -m starter` in an environment
133
+ with `b4pt0r-the-framework` installed. Change `starter/application.py` and
134
+ `starter/instructions.md` first; `starter/ui/` contains the editable interface.
135
+ Keep the data directory private: it holds conversation history, configuration,
136
+ uploads, memory and browser profiles.
137
+
138
+ ## Build a small application yourself
139
+
140
+ Save the following as `example.py`. It is a complete HTTP application; the
141
+ repository also includes an [expanded version](https://github.com/B4PT0R/the_framework/blob/main/examples/minimal_agent_app.py)
142
+ with `modict` request/response models and a health endpoint.
143
+
144
+ ```python
145
+ from the_framework import AgentApplication, AgentSpec, Extension, SessionPolicy, endpoint
146
+ from the_framework.server.api.endpoints import Principal
147
+
148
+
149
+ class BearerSecurity:
150
+ async def authenticate(self, request):
151
+ if request.headers.get("authorization") != "Bearer example-secret":
152
+ return None
153
+ return Principal(id="example-client", scopes=frozenset({"counter:write"}))
154
+
155
+ async def authorize(self, principal, requirement, request):
156
+ return requirement is None or requirement.get("scope") in principal.scopes
157
+
158
+
159
+ class Counter:
160
+ def __init__(self):
161
+ self.value = 0
162
+ self.running = False
163
+
164
+ async def start(self):
165
+ self.running = True
166
+
167
+ async def stop(self):
168
+ self.running = False
169
+
170
+ @endpoint(
171
+ "post", "/api/v1/counter/increment",
172
+ request={"type": "object", "properties": {"amount": {"type": "integer"}},
173
+ "required": ["amount"], "additionalProperties": False},
174
+ response={"type": "object", "properties": {"value": {"type": "integer"}},
175
+ "required": ["value"]},
176
+ authorization={"scope": "counter:write"},
177
+ )
178
+ def increment(self, amount: int):
179
+ """Increment the application counter."""
180
+ self.value += amount
181
+ return {"value": self.value}
182
+
183
+
184
+ counter = Counter()
185
+ application = AgentApplication(
186
+ name="Counter Agent",
187
+ version="0.1",
188
+ primary_agent=AgentSpec(
189
+ name="assistant",
190
+ description="The application's primary agent",
191
+ session=SessionPolicy.durable(),
192
+ ),
193
+ security=BearerSecurity(),
194
+ extensions=(Extension(name="counter", service=counter,
195
+ endpoints=(counter.increment,)),),
196
+ )
197
+ app = application.build()
198
+ ```
199
+
200
+ Start it with:
201
+
202
+ ```sh
203
+ uv run uvicorn example:app --host 127.0.0.1 --port 8000
204
+ ```
205
+
206
+ Then, in another terminal:
207
+
208
+ ```sh
209
+ curl -sS -X POST http://127.0.0.1:8000/api/v1/counter/increment \
210
+ -H 'Authorization: Bearer example-secret' \
211
+ -H 'Content-Type: application/json' \
212
+ -d '{"amount": 2}'
213
+ ```
214
+
215
+ The result is `{"value":2}`. The literal bearer secret is **only** for this
216
+ loopback demonstration; use a real authentication policy for an application.
217
+ The primary agent declaration alone does not create a chat API or start
218
+ inference: the starter shows how to add its supervised worker and client
219
+ transport. `@endpoint` validates request and response data and contributes an
220
+ OpenAPI schema. `Extension` manages dependencies and service startup/shutdown;
221
+ `AgentApplication.compile()` checks the full graph before runtime startup.
222
+
223
+ For the next step, read [composition and runtime](https://github.com/B4PT0R/the_framework/blob/main/docs/framework.md) for
224
+ plugins, private specialists, persistent resources, security, voice and client
225
+ surfaces. The [starter source](https://github.com/B4PT0R/the_framework/tree/main/starter) shows these features in one application
226
+ without requiring you to adopt its UI design.
227
+
228
+ ## Develop and package
229
+
230
+ ```sh
231
+ uv sync --extra dev
232
+ uv run pytest -q tests/application tests/agentic
233
+ uv build
234
+ ```
235
+
236
+ The build produces a wheel and source archive in `dist/`. The wheel contains
237
+ the typed `the_framework` package, runtime prompts and the editable starter
238
+ template; it does **not** bundle Node modules or a prebuilt browser UI. The
239
+ test suite includes a wheel-only import/bootstrap check outside the checkout.
240
+ For UI changes, also run `npm --prefix starter/ui test` and
241
+ `npm --prefix starter/ui run build`.
242
+
243
+ This repository is [MIT licensed](https://github.com/B4PT0R/the_framework/blob/main/LICENSE). See the [changelog](https://github.com/B4PT0R/the_framework/blob/main/CHANGELOG.md)
244
+ for version notes. Publishing to PyPI is a separate release action; building
245
+ locally does not publish anything.
@@ -0,0 +1,206 @@
1
+ # The Framework
2
+
3
+ The Framework is a Python library for building applications around a persistent
4
+ AI agent. It supplies the parts that are easy to get wrong repeatedly: one
5
+ durable conversation, a supervised agent worker, plugin and specialist-agent
6
+ lifecycle, authenticated HTTP/WebSocket connections, and versioned web
7
+ interfaces. You supply the agent's identity, instructions, application
8
+ services, security policy and user experience.
9
+
10
+ You can use it for a local desktop companion, a private agent with tools and
11
+ memory, or another agent application whose browser and backend need to survive
12
+ worker restarts without losing the conversation. It is a library, not a hosted
13
+ agent service. The included [starter](https://github.com/B4PT0R/the_framework/blob/main/starter/README.md) is an editable
14
+ application that shows the pieces working together; you are free to build a
15
+ different frontend or none at all.
16
+
17
+ The PyPI distribution is named `b4pt0r-the-framework`. Python code imports
18
+ `the_framework`, and the template command is `the-framework`. Python 3.12 or
19
+ newer is required.
20
+
21
+ To install the published package in a virtual environment:
22
+
23
+ ```sh
24
+ python3 -m venv .venv
25
+ . .venv/bin/activate
26
+ python -m pip install b4pt0r-the-framework
27
+ ```
28
+
29
+ The Python wheel includes the framework and the editable starter template, but
30
+ not a prebuilt browser UI or Playwright's Chromium binary. Those are prepared
31
+ separately when you run the starter.
32
+
33
+ ## What an application is made of
34
+
35
+ | Part | What it does | What your application decides |
36
+ | --- | --- | --- |
37
+ | `AgentApplication` | Validates and assembles one application | Name, version, plugins, server services, security and client surfaces |
38
+ | `AgentSpec` | Describes an agent and its session policy | Instructions, model configuration, tools and resources |
39
+ | `Plugin` / `PluginSpec` | Adds agent tools, context, hooks and optional server runtime | Which capabilities exist and when they are exposed |
40
+ | `Extension` / `@endpoint` | Starts services and exposes validated API routes | Application state, route schemas and authorization |
41
+ | `ClientSurface` | Builds, previews, publishes and rolls back an editable web UI | Source, build command, routes and release policy |
42
+
43
+ There is exactly **one primary, durable conversation**. Private specialist
44
+ agents can perform bounded background work, but their sessions are not new
45
+ user-facing conversations and they cannot edit the primary history directly.
46
+ The server supervises workers and owns authentication and client transport;
47
+ workers own inference and their own sessions; a browser client owns its local
48
+ interface and device/media execution. This separation lets a client reconnect
49
+ or refresh while the main conversation remains intact.
50
+
51
+ Plugins may provide agent-facing tools without a server runtime, or both. A
52
+ plugin's runtime state and its binding to an agent are separate: turning off its
53
+ tools for the agent need not remove routes that a settings screen still uses.
54
+ Specialists, durable task delivery and versioned public capabilities are
55
+ available when a simple plugin is not enough. More detail is in the
56
+ [framework guide](https://github.com/B4PT0R/the_framework/blob/main/docs/framework.md).
57
+
58
+ ## Try a working application
59
+
60
+ Install [`uv`](https://docs.astral.sh/uv/) and Node.js/npm, then from this
61
+ checkout run:
62
+
63
+ ```sh
64
+ uv sync
65
+ npm --prefix starter/ui ci
66
+ npm --prefix starter/ui run build
67
+ uv run playwright install chromium
68
+ uv run python -m starter
69
+ ```
70
+
71
+ Playwright Chromium also needs its system libraries; on Linux,
72
+ `uv run playwright install --with-deps chromium` can install them if you have
73
+ the required system permissions. The starter opens a local Chromium window with
74
+ chat, settings, file attachments and an editable React interface. Its server
75
+ listens on loopback and authenticates the browser. You can inspect the UI and
76
+ settings without model credentials; generating replies, using hosted search or
77
+ embeddings, and voice features require a usable account/capabilities through
78
+ `codex-backend-sdk`. The [starter guide](https://github.com/B4PT0R/the_framework/blob/main/starter/README.md) covers sign-in,
79
+ data storage and feature-by-feature behavior.
80
+
81
+ To make an independent, editable copy, run `the-framework bootstrap` in the
82
+ environment where you installed the package. From this checkout, prefix it
83
+ with `uv run`:
84
+
85
+ ```sh
86
+ uv run the-framework bootstrap --code-dir /path/to/my-agent-code --data-dir /path/to/my-agent-data
87
+ ```
88
+
89
+ Both directories must be empty or absent, distinct and non-overlapping. The
90
+ command copies the starter source and records the private data location; it
91
+ does not install npm dependencies, build the UI or launch the app. From the new
92
+ code directory, run `npm --prefix starter/ui ci`,
93
+ `npm --prefix starter/ui run build`, then `python -m starter` in an environment
94
+ with `b4pt0r-the-framework` installed. Change `starter/application.py` and
95
+ `starter/instructions.md` first; `starter/ui/` contains the editable interface.
96
+ Keep the data directory private: it holds conversation history, configuration,
97
+ uploads, memory and browser profiles.
98
+
99
+ ## Build a small application yourself
100
+
101
+ Save the following as `example.py`. It is a complete HTTP application; the
102
+ repository also includes an [expanded version](https://github.com/B4PT0R/the_framework/blob/main/examples/minimal_agent_app.py)
103
+ with `modict` request/response models and a health endpoint.
104
+
105
+ ```python
106
+ from the_framework import AgentApplication, AgentSpec, Extension, SessionPolicy, endpoint
107
+ from the_framework.server.api.endpoints import Principal
108
+
109
+
110
+ class BearerSecurity:
111
+ async def authenticate(self, request):
112
+ if request.headers.get("authorization") != "Bearer example-secret":
113
+ return None
114
+ return Principal(id="example-client", scopes=frozenset({"counter:write"}))
115
+
116
+ async def authorize(self, principal, requirement, request):
117
+ return requirement is None or requirement.get("scope") in principal.scopes
118
+
119
+
120
+ class Counter:
121
+ def __init__(self):
122
+ self.value = 0
123
+ self.running = False
124
+
125
+ async def start(self):
126
+ self.running = True
127
+
128
+ async def stop(self):
129
+ self.running = False
130
+
131
+ @endpoint(
132
+ "post", "/api/v1/counter/increment",
133
+ request={"type": "object", "properties": {"amount": {"type": "integer"}},
134
+ "required": ["amount"], "additionalProperties": False},
135
+ response={"type": "object", "properties": {"value": {"type": "integer"}},
136
+ "required": ["value"]},
137
+ authorization={"scope": "counter:write"},
138
+ )
139
+ def increment(self, amount: int):
140
+ """Increment the application counter."""
141
+ self.value += amount
142
+ return {"value": self.value}
143
+
144
+
145
+ counter = Counter()
146
+ application = AgentApplication(
147
+ name="Counter Agent",
148
+ version="0.1",
149
+ primary_agent=AgentSpec(
150
+ name="assistant",
151
+ description="The application's primary agent",
152
+ session=SessionPolicy.durable(),
153
+ ),
154
+ security=BearerSecurity(),
155
+ extensions=(Extension(name="counter", service=counter,
156
+ endpoints=(counter.increment,)),),
157
+ )
158
+ app = application.build()
159
+ ```
160
+
161
+ Start it with:
162
+
163
+ ```sh
164
+ uv run uvicorn example:app --host 127.0.0.1 --port 8000
165
+ ```
166
+
167
+ Then, in another terminal:
168
+
169
+ ```sh
170
+ curl -sS -X POST http://127.0.0.1:8000/api/v1/counter/increment \
171
+ -H 'Authorization: Bearer example-secret' \
172
+ -H 'Content-Type: application/json' \
173
+ -d '{"amount": 2}'
174
+ ```
175
+
176
+ The result is `{"value":2}`. The literal bearer secret is **only** for this
177
+ loopback demonstration; use a real authentication policy for an application.
178
+ The primary agent declaration alone does not create a chat API or start
179
+ inference: the starter shows how to add its supervised worker and client
180
+ transport. `@endpoint` validates request and response data and contributes an
181
+ OpenAPI schema. `Extension` manages dependencies and service startup/shutdown;
182
+ `AgentApplication.compile()` checks the full graph before runtime startup.
183
+
184
+ For the next step, read [composition and runtime](https://github.com/B4PT0R/the_framework/blob/main/docs/framework.md) for
185
+ plugins, private specialists, persistent resources, security, voice and client
186
+ surfaces. The [starter source](https://github.com/B4PT0R/the_framework/tree/main/starter) shows these features in one application
187
+ without requiring you to adopt its UI design.
188
+
189
+ ## Develop and package
190
+
191
+ ```sh
192
+ uv sync --extra dev
193
+ uv run pytest -q tests/application tests/agentic
194
+ uv build
195
+ ```
196
+
197
+ The build produces a wheel and source archive in `dist/`. The wheel contains
198
+ the typed `the_framework` package, runtime prompts and the editable starter
199
+ template; it does **not** bundle Node modules or a prebuilt browser UI. The
200
+ test suite includes a wheel-only import/bootstrap check outside the checkout.
201
+ For UI changes, also run `npm --prefix starter/ui test` and
202
+ `npm --prefix starter/ui run build`.
203
+
204
+ This repository is [MIT licensed](https://github.com/B4PT0R/the_framework/blob/main/LICENSE). See the [changelog](https://github.com/B4PT0R/the_framework/blob/main/CHANGELOG.md)
205
+ for version notes. Publishing to PyPI is a separate release action; building
206
+ locally does not publish anything.
@@ -0,0 +1,37 @@
1
+ # Framework API simplification
2
+
3
+ ## Decisions and evidence
4
+
5
+ | Objective | Result | Regression coverage |
6
+ | --- | --- | --- |
7
+ | One agent declaration | `AgentSpec` owns configuration, instructions, plugins, session/queue policy and completion settings. `agent_trigger(spec, ...)` owns selection and result handling only. | `test_agent_spec.py`, `test_framework.py`, worker/fleet tests |
8
+ | Internal wire representation | `WorkerProfile` remains a JSON execution payload, not a public facade export or a second source retained in AgentSpec. Older profile configuration fields are read at the worker boundary. | profile round trips, native coercion, real worker process tests |
9
+ | Explicit construction | `AgentResources` replaces implicit option dictionaries and parallel build keywords. Explicit resources bypass the factory completely. | factory identity, defaults, invalid contracts, configuration persistence tests |
10
+ | Concise plugin installation | Plugin classes with an explicit name normalize to PluginSpec; full declarations retain policies, dependencies and services. | shorthand/full-form discovery, duplicate identities, no construction during compilation |
11
+ | Lifecycle simplicity | Existing Extension start/stop adapters suffice. Permanent restart callback composition happens at construction; absent restart remains absent. No new manager or lifecycle abstraction. | `test_runtime_composition.py`, service rollback and runtime shutdown tests |
12
+ | Model endpoint contracts | Request/response modict classes work alongside explicit JSON Schema. Native validators/defaults are applied at the existing HTTP boundary; field metadata supplies OpenAPI. | `test_endpoint_models.py`, endpoint registry, minimal application tests |
13
+
14
+ The actual product migrated its primary construction, simple plugin declarations,
15
+ memory curator and visual specialists. The minimal standalone application uses
16
+ model-based endpoint contracts. No application-specific policy was added to the
17
+ core, and no Pydantic DTO or alternate dispatch path was introduced.
18
+
19
+ ## Deliberate limits
20
+
21
+ Final verification: `pytest -q --tb=short tests/application tests/agentic` reports
22
+ **900 passed**. This includes the isolated wheel and real worker subprocess
23
+ tests. The product compiles 14 plugins and 10 agents. Ruff's F401/F811/F821/F822/
24
+ F823/E9 checks and `git diff --check` pass for the changed core and endpoint tests.
25
+
26
+ - OpenAPI projection describes JSON field types, required fields and extra-field
27
+ policy. It does not reverse-engineer Python validators or execute factories.
28
+ Unsupported/recursive hints require an explicit JSON Schema. Runtime model
29
+ validation remains authoritative for custom constraints.
30
+ - A wire profile cannot serialize Python closures or application services.
31
+ Application-backed workers continue resolving the original namespaced spec.
32
+ - This work verifies source, transports and packaging with automated tests.
33
+ It does not claim a production restart, real inference, voice or device run.
34
+ - No server restart, publish or push was performed for this goal.
35
+
36
+ The follow-ups already recorded in TODO.md remain separate from this API work:
37
+ YAML declaration errors, grouping usage records, and older architecture wording.
@@ -0,0 +1,51 @@
1
+ # Framework clarification follow-up
2
+
3
+ ## Changes and verification boundaries
4
+
5
+ - Usage payloads (`ResponseUsage`, `TokenDetails`) live in `agent/models/usage.py`.
6
+ The session store imports that owner, not the context builder. Public agent
7
+ exports remain; internal callers were migrated without compatibility aliases.
8
+ Recovery, coercion, session and context tests cover the unchanged behavior.
9
+ - Invalid YAML raises a contextual `ValueError` naming the declaring callable
10
+ and YAML location, with the parser exception chained. Invalid metadata shapes
11
+ no longer disappear through falsey fallback. Plain descriptions and empty
12
+ docstrings remain supported. Both tool and endpoint construction are tested.
13
+ - AGENTS.md now describes distributed capability ownership and authenticated
14
+ remote clients, rather than a local-desktop-only runtime. Evidence:
15
+ `server/clients/remote.py`, `the_harness/remote_composition.py`,
16
+ `docs/remote-client-protocol.md`, and `test_client_remote.py` (exclusive leases,
17
+ revocation, stale generations and remote ownership without local Chromium).
18
+ - Memory instructions now distinguish temporary working capacity from completion
19
+ constraints, omit the obsolete entry-count cap and describe deferred embedding.
20
+ Evidence: `plugins/memory/store.py::_validate_capacity`,
21
+ `plugins/memory/curator.py::completion_constraint_error` and `complete_curation`,
22
+ plus memory tests for soft capacity, reduction beyond hard capacity, deferred
23
+ embeddings and completion repair. No runtime policy or personal data changed.
24
+
25
+ ## Schema comparison: deliberate non-extraction
26
+
27
+ Tools and signature-derived endpoints already share `signature_parameters` and
28
+ `annotation_schema`. The separate HTTP model projection reads modict field
29
+ metadata, defaults and required/extra policy; it never executes default factories.
30
+ The modict README field and configuration contracts were checked locally.
31
+
32
+ The remaining visitors overlap on scalar/list/union syntax, but differ in real
33
+ contracts: callable annotation inference is best-effort and accepts tuple/set
34
+ shapes, whereas explicit HTTP model contracts reject unsupported hints, non-string
35
+ mapping keys and recursive models rather than silently understating validation.
36
+ Combining them now would add policy switches or callbacks to a small visitor.
37
+ No new generic abstraction is introduced solely to deduplicate those branches.
38
+
39
+ Comparison did uncover a nullable-enum defect in callable projection: adding null
40
+ to `type` while preserving a non-null `enum` still excludes null. Union projection
41
+ now uses `anyOf` for constrained branches. A JSON Schema behavior test verifies
42
+ null and declared enum members are accepted, but arbitrary values are rejected.
43
+
44
+ No SDK/modict patch, publication, server restart or deployment was needed.
45
+
46
+ ## Final verification
47
+
48
+ `pytest -q --tb=short tests/application tests/agentic`: **914 passed**,
49
+ including isolated-wheel imports and worker-process tests. Focused Ruff checks
50
+ (F401/F811/F821/F822/F823/E9) and `git diff --check` pass. The nullable contracts
51
+ are tested by accepted/rejected values rather than a prescribed JSON layout.