agent-chat-fastapi-langgraph-assistant-ui 0.2.0__tar.gz → 0.3.3__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 (122) hide show
  1. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/.gitignore +5 -0
  2. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/PKG-INFO +30 -4
  3. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/README.md +29 -3
  4. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/pyproject.toml +11 -4
  5. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/scripts/build_wheel.sh +33 -0
  6. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/__init__.py +51 -0
  7. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/config.py +3 -0
  8. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/demo_agent/agent_factory.py +14 -3
  9. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/demo_agent/calculator.py +4 -1
  10. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/demo_agent/get_graph.py +2 -1
  11. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/docs/agents.md +74 -0
  12. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/docs/configuration.md +60 -0
  13. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/docs/index.md +29 -0
  14. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/docs/providers.md +42 -0
  15. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/docs/quickstart.md +45 -0
  16. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/docs/threads.md +72 -0
  17. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/docs.py +35 -0
  18. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/registry.py +8 -4
  19. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/server.py +639 -0
  20. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/threads.py +111 -0
  21. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/404/index.html +1 -1
  22. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/404.html +1 -1
  23. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/__next.__PAGE__.txt +1 -1
  24. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/__next._full.txt +1 -1
  25. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/__next._head.txt +1 -1
  26. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/__next._index.txt +1 -1
  27. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/__next._tree.txt +1 -1
  28. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/__next._full.txt +1 -1
  29. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/__next._head.txt +1 -1
  30. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/__next._index.txt +1 -1
  31. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/__next._not-found.__PAGE__.txt +1 -1
  32. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/__next._not-found.txt +1 -1
  33. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/__next._tree.txt +1 -1
  34. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/index.html +1 -1
  35. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_not-found/index.txt +1 -1
  36. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/index.html +1 -1
  37. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/index.txt +1 -1
  38. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/404/index.html +1 -0
  39. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/404.html +1 -0
  40. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/__next.__PAGE__.txt +7 -0
  41. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/__next._full.txt +18 -0
  42. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/__next._head.txt +8 -0
  43. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/__next._index.txt +5 -0
  44. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/__next._tree.txt +5 -0
  45. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/1f69191700b503ef.js +28 -0
  46. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/3ace7f114fa1f091.js +2 -0
  47. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/4d2c63e33cdf7066.js +1 -0
  48. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/7c80bf5e80113a8b.css +3 -0
  49. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/8c25bd17dcc24038.css +1 -0
  50. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/a53a0fc1920ff4e8.js +1 -0
  51. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  52. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/a9779bfdd3066160.js +1 -0
  53. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/c4faa8443adcf05d.js +1 -0
  54. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/c7d807cf58f04d9d.js +1 -0
  55. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/d3d30b9a6eebcdc0.js +1 -0
  56. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/f258a48c9462f5ff.js +4 -0
  57. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/chunks/turbopack-ff4ab21e688d1749.js +3 -0
  58. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/4fa387ec64143e14-s.3b336396.woff2 +0 -0
  59. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/53b9e256198e5412-s.853d50a3.woff2 +0 -0
  60. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/5ce348bf30bf5439-s.56c1f21e.woff2 +0 -0
  61. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/6306c77e7c8268e4-s.e3369375.woff2 +0 -0
  62. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/7178b3e590c64307-s.55554cd0.woff2 +0 -0
  63. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/797e433ab948586e-s.p.29207c2f.woff2 +0 -0
  64. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/7d817b4c03b0c5f1-s.a40b9a8b.woff2 +0 -0
  65. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/8a480f0b521d4e75-s.ea323500.woff2 +0 -0
  66. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/bbc41e54d2fcbd21-s.fe42ddf4.woff2 +0 -0
  67. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/caa3a2e1cccd8315-s.p.3b6cae6d.woff2 +0 -0
  68. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/favicon.0b3bf435.ico +0 -0
  69. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/media/fef07dbb0973bf53-s.518e079e.woff2 +0 -0
  70. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/vDJ9TpIrx4WCEQOfdoH8L/_buildManifest.js +11 -0
  71. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/vDJ9TpIrx4WCEQOfdoH8L/_clientMiddlewareManifest.json +1 -0
  72. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_next/static/vDJ9TpIrx4WCEQOfdoH8L/_ssgManifest.js +1 -0
  73. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/__next._full.txt +14 -0
  74. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/__next._head.txt +8 -0
  75. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/__next._index.txt +5 -0
  76. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/__next._not-found.__PAGE__.txt +5 -0
  77. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/__next._not-found.txt +4 -0
  78. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/__next._tree.txt +2 -0
  79. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/index.html +1 -0
  80. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/_not-found/index.txt +14 -0
  81. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/__next._full.txt +20 -0
  82. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/__next._head.txt +8 -0
  83. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/__next._index.txt +5 -0
  84. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/__next._tree.txt +4 -0
  85. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/__next.admin.__PAGE__.txt +9 -0
  86. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/__next.admin.txt +4 -0
  87. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/index.html +1 -0
  88. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/admin/index.txt +20 -0
  89. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/favicon.ico +0 -0
  90. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/index.html +1 -0
  91. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web_full/index.txt +18 -0
  92. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/tests/test_docs.py +25 -0
  93. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/tests/test_full_ui.py +45 -0
  94. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/tests/test_provider_agnostic.py +1 -1
  95. agent_chat_fastapi_langgraph_assistant_ui-0.3.3/tests/test_threads.py +143 -0
  96. agent_chat_fastapi_langgraph_assistant_ui-0.2.0/.gitignore +0 -3
  97. agent_chat_fastapi_langgraph_assistant_ui-0.2.0/scripts/build_wheel.sh +0 -24
  98. agent_chat_fastapi_langgraph_assistant_ui-0.2.0/src/agent_chat_minimal/__init__.py +0 -24
  99. agent_chat_fastapi_langgraph_assistant_ui-0.2.0/src/agent_chat_minimal/server.py +0 -336
  100. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/Dockerfile +0 -0
  101. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/scripts/smoke_test_wheel.sh +0 -0
  102. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/demo_agent/__init__.py +0 -0
  103. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/demo_agent/tools/__init__.py +0 -0
  104. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/demo_agent/tools/graph_tool.py +0 -0
  105. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0/src/agent_chat_minimal/web/_next/static/HvflKuXozGvVNVw4d_lvG → agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web/_next/static/F2G0VtxugBGp8iZRIDw24}/_buildManifest.js +0 -0
  106. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0/src/agent_chat_minimal/web/_next/static/HvflKuXozGvVNVw4d_lvG → agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web/_next/static/F2G0VtxugBGp8iZRIDw24}/_clientMiddlewareManifest.json +0 -0
  107. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0/src/agent_chat_minimal/web/_next/static/HvflKuXozGvVNVw4d_lvG → agent_chat_fastapi_langgraph_assistant_ui-0.3.3/src/agent_chat_minimal/web/_next/static/F2G0VtxugBGp8iZRIDw24}/_ssgManifest.js +0 -0
  108. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/01753452ac5baafa.js +0 -0
  109. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/30d8e87dcbdddc4d.js +0 -0
  110. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/339892169798c284.js +0 -0
  111. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/4a95dc46ade64fde.js +0 -0
  112. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/8c25bd17dcc24038.css +0 -0
  113. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/a09b0e81b13178b3.css +0 -0
  114. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  115. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/a6dad97d9634a72d.js.map +0 -0
  116. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/c1f433e6da65e45d.js +0 -0
  117. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/e54de45640ef90a8.js +0 -0
  118. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/src/agent_chat_minimal/web/_next/static/chunks/turbopack-6a8c15a03bc4b465.js +0 -0
  119. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/tests/test_config_state.py +0 -0
  120. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/tests/test_injectable_graph.py +0 -0
  121. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/tests/test_registry.py +0 -0
  122. {agent_chat_fastapi_langgraph_assistant_ui-0.2.0 → agent_chat_fastapi_langgraph_assistant_ui-0.3.3}/tests/test_serving.py +0 -0
@@ -0,0 +1,5 @@
1
+ /dist/
2
+ /src/agent_chat_minimal/web/*
3
+ !/src/agent_chat_minimal/web/.gitkeep
4
+ /src/agent_chat_minimal/web_full/*
5
+ !/src/agent_chat_minimal/web_full/.gitkeep
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agent-chat-fastapi-langgraph-assistant-ui
3
- Version: 0.2.0
3
+ Version: 0.3.3
4
4
  Summary: Portable FastAPI and LangGraph chat with a bundled static UI
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: assistant-stream-ce>=0.0.2
@@ -45,9 +45,11 @@ python -m pip install packages/agent-chat-minimal/dist/*.whl
45
45
  minimal-chat-serve --port 8011
46
46
  ```
47
47
 
48
- Open <http://localhost:8011/>. Set `OPENAI_API_KEY` to enable `/assistant`;
49
- without it, the UI and `/health` still work and `/assistant` returns 503.
50
- `MINIMAL_WEB_DIR` may override the bundled web directory.
48
+ Open <http://localhost:8011/> (single-prompt chat) or
49
+ <http://localhost:8011/full/> (thread sidebar with previous chats).
50
+ Set `OPENAI_API_KEY` to enable `/assistant`; without it, the UIs and
51
+ `/health` still work and `/assistant` returns 503.
52
+ `MINIMAL_WEB_DIR` / `FULL_WEB_DIR` may override the bundled web directories.
51
53
 
52
54
  ## Arbitrary agents & providers
53
55
 
@@ -70,6 +72,30 @@ app = create_app(graph=make_my_agent("anthropic:claude-sonnet-4-5"))
70
72
  `state.thread_id` / `runConfig.thread_id` is forwarded as LangGraph
71
73
  `configurable.thread_id` for checkpointer-backed graphs.
72
74
 
75
+ ## Documentation (in the wheel)
76
+
77
+ Six guides ship inside the package and are readable at runtime:
78
+
79
+ ```python
80
+ from agent_chat_minimal import docs
81
+ docs.list() # ['index', 'quickstart', 'agents', ...]
82
+ docs.show("threads")
83
+ ```
84
+
85
+ | Guide | Covers |
86
+ | ----- | ------ |
87
+ | `quickstart` | install → first chat in 2 minutes |
88
+ | `agents` | write + serve + share your own agent |
89
+ | `providers` | OpenAI / Anthropic / Ollama specs & creds |
90
+ | `configuration` | env vars, CLI flags, hooks, 503 semantics |
91
+ | `threads` | multi-thread chats, frontend-full compat |
92
+
93
+ ## Threads (frontend-full compatible)
94
+
95
+ The server also speaks the full-stack thread protocol (`/threads`,
96
+ `/threads/{id}/messages`, scoped `POST /assistant` with `thread_id`/`user_id`),
97
+ so `frontend-full` works against either backend. See the `threads` guide.
98
+
73
99
  ## Configuration
74
100
 
75
101
  ```text
@@ -28,9 +28,11 @@ python -m pip install packages/agent-chat-minimal/dist/*.whl
28
28
  minimal-chat-serve --port 8011
29
29
  ```
30
30
 
31
- Open <http://localhost:8011/>. Set `OPENAI_API_KEY` to enable `/assistant`;
32
- without it, the UI and `/health` still work and `/assistant` returns 503.
33
- `MINIMAL_WEB_DIR` may override the bundled web directory.
31
+ Open <http://localhost:8011/> (single-prompt chat) or
32
+ <http://localhost:8011/full/> (thread sidebar with previous chats).
33
+ Set `OPENAI_API_KEY` to enable `/assistant`; without it, the UIs and
34
+ `/health` still work and `/assistant` returns 503.
35
+ `MINIMAL_WEB_DIR` / `FULL_WEB_DIR` may override the bundled web directories.
34
36
 
35
37
  ## Arbitrary agents & providers
36
38
 
@@ -53,6 +55,30 @@ app = create_app(graph=make_my_agent("anthropic:claude-sonnet-4-5"))
53
55
  `state.thread_id` / `runConfig.thread_id` is forwarded as LangGraph
54
56
  `configurable.thread_id` for checkpointer-backed graphs.
55
57
 
58
+ ## Documentation (in the wheel)
59
+
60
+ Six guides ship inside the package and are readable at runtime:
61
+
62
+ ```python
63
+ from agent_chat_minimal import docs
64
+ docs.list() # ['index', 'quickstart', 'agents', ...]
65
+ docs.show("threads")
66
+ ```
67
+
68
+ | Guide | Covers |
69
+ | ----- | ------ |
70
+ | `quickstart` | install → first chat in 2 minutes |
71
+ | `agents` | write + serve + share your own agent |
72
+ | `providers` | OpenAI / Anthropic / Ollama specs & creds |
73
+ | `configuration` | env vars, CLI flags, hooks, 503 semantics |
74
+ | `threads` | multi-thread chats, frontend-full compat |
75
+
76
+ ## Threads (frontend-full compatible)
77
+
78
+ The server also speaks the full-stack thread protocol (`/threads`,
79
+ `/threads/{id}/messages`, scoped `POST /assistant` with `thread_id`/`user_id`),
80
+ so `frontend-full` works against either backend. See the `threads` guide.
81
+
56
82
  ## Configuration
57
83
 
58
84
  ```text
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agent-chat-fastapi-langgraph-assistant-ui"
7
- version = "0.2.0"
7
+ version = "0.3.3"
8
8
  description = "Portable FastAPI and LangGraph chat with a bundled static UI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -33,13 +33,20 @@ minimal-chat-serve = "agent_chat_minimal.server:main"
33
33
 
34
34
  [tool.hatch.build.targets.wheel]
35
35
  packages = ["src/agent_chat_minimal"]
36
+ # The tracked .gitkeep placeholders would otherwise be collected twice (once
37
+ # via `packages`, once via `force-include`) and fail the build with "A second
38
+ # file is being added to the wheel archive at the same path".
39
+ exclude = ["**/.gitkeep"]
36
40
 
37
41
  [tool.hatch.build.targets.wheel.force-include]
38
42
  "src/agent_chat_minimal/web" = "agent_chat_minimal/web"
43
+ "src/agent_chat_minimal/web_full" = "agent_chat_minimal/web_full"
39
44
 
40
- # The sdist must also bundle the prebuilt static UI (which is gitignored and
41
- # staged from application/frontend/frontend-minimal/out before building).
45
+ # The sdist file list comes from git, where the staged prebuilt UIs are
46
+ # ignored - so they must be force-included here (staged from
47
+ # application/frontend/{frontend-minimal,frontend-full}/out before building).
42
48
  # python -m build builds the wheel from the sdist, so without this the PyPI
43
- # wheel would ship without the UI.
49
+ # wheel would ship without the UIs.
44
50
  [tool.hatch.build.targets.sdist.force-include]
45
51
  "src/agent_chat_minimal/web" = "src/agent_chat_minimal/web"
52
+ "src/agent_chat_minimal/web_full" = "src/agent_chat_minimal/web_full"
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
5
+ frontend_minimal="$repo_root/application/frontend/frontend-minimal"
6
+ frontend_full="$repo_root/application/frontend/frontend-full"
7
+ package="$repo_root/packages/agent-chat-minimal"
8
+ web="$package/src/agent_chat_minimal/web"
9
+ web_full="$package/src/agent_chat_minimal/web_full"
10
+
11
+ cleanup() {
12
+ rm -rf "$web" "$web_full"
13
+ mkdir -p "$web" "$web_full"
14
+ : > "$web/.gitkeep"
15
+ : > "$web_full/.gitkeep"
16
+ }
17
+ trap cleanup EXIT
18
+
19
+ pnpm --dir "$frontend_minimal" install --frozen-lockfile
20
+ pnpm --dir "$frontend_minimal" build
21
+ rm -rf "$web"
22
+ cp -R "$frontend_minimal/out" "$web"
23
+
24
+ # Full UI (thread sidebar) is namespaced under /full and talks same-origin.
25
+ pnpm --dir "$frontend_full" install --frozen-lockfile
26
+ NEXT_PUBLIC_API_BASE="" FULL_UI_BASE_PATH=/full pnpm --dir "$frontend_full" build
27
+ rm -rf "$web_full"
28
+ cp -R "$frontend_full/out" "$web_full"
29
+
30
+ (
31
+ cd "$package"
32
+ uv build --wheel
33
+ )
@@ -0,0 +1,51 @@
1
+ """Portable FastAPI + LangGraph chat with a bundled Assistant UI.
2
+
3
+ Quick links (also shipped as markdown in ``agent_chat_minimal/docs/``):
4
+
5
+ - ``docs.list()`` / ``docs.get(name)`` — guides: quickstart, agents,
6
+ providers, configuration, threads.
7
+ - ``create_app(...)`` — serve one graph, a factory, or an agent registry.
8
+ - ``Settings.from_env()`` — all env vars in one place.
9
+ - ``GET /docs`` on a running server — interactive Swagger UI.
10
+
11
+ Example:
12
+ >>> from agent_chat_minimal import create_app
13
+ >>> app = create_app(agents={"weather": ...}) # doctest: +SKIP
14
+ """
15
+
16
+ from . import docs
17
+ from .config import ENV_DOC, Settings
18
+ from .registry import AGENT_REGISTRY, discover_agents
19
+ from .server import (
20
+ DEFAULT_WEB_DIR,
21
+ DEFAULT_WEB_FULL_DIR,
22
+ ChatGraph,
23
+ ScopedChatRequest,
24
+ create_app,
25
+ default_prepare_state,
26
+ main,
27
+ resolve_thread_id,
28
+ )
29
+ from .threads import ThreadManager, ThreadMessageStore, ThreadMetadata
30
+
31
+ __version__ = "0.3.3"
32
+
33
+ __all__ = [
34
+ "__version__",
35
+ "AGENT_REGISTRY",
36
+ "ENV_DOC",
37
+ "ChatGraph",
38
+ "DEFAULT_WEB_DIR",
39
+ "DEFAULT_WEB_FULL_DIR",
40
+ "ScopedChatRequest",
41
+ "Settings",
42
+ "ThreadManager",
43
+ "ThreadMessageStore",
44
+ "ThreadMetadata",
45
+ "create_app",
46
+ "default_prepare_state",
47
+ "discover_agents",
48
+ "docs",
49
+ "main",
50
+ "resolve_thread_id",
51
+ ]
@@ -16,6 +16,7 @@ class Settings:
16
16
  model: str = "openai:gpt-4o-mini"
17
17
  default_agent: str = "weather"
18
18
  web_dir: str | None = None
19
+ web_full_dir: str | None = None
19
20
 
20
21
  @classmethod
21
22
  def from_env(cls) -> "Settings":
@@ -30,6 +31,7 @@ class Settings:
30
31
  model=os.getenv("MODEL", "openai:gpt-4o-mini"),
31
32
  default_agent=os.getenv("DEFAULT_AGENT", "weather"),
32
33
  web_dir=os.getenv("MINIMAL_WEB_DIR"),
34
+ web_full_dir=os.getenv("FULL_WEB_DIR"),
33
35
  )
34
36
 
35
37
  def web_dir_path(self, fallback: Path) -> Path | None:
@@ -44,6 +46,7 @@ PORT=8011 # uvicorn bind port
44
46
  MODEL=openai:gpt-4o-mini # provider:model spec (anthropic:.., ollama:..)
45
47
  DEFAULT_AGENT=weather # registry id aliased by POST /assistant
46
48
  MINIMAL_WEB_DIR= # override bundled web/ (empty = bundled)
49
+ FULL_WEB_DIR= # override bundled web_full/ (empty = bundled)
47
50
  OPENAI_API_KEY= # credential for the default openai model
48
51
  ANTHROPIC_API_KEY= # credential when MODEL uses anthropic:
49
52
  """
@@ -1,6 +1,6 @@
1
1
  """Shared helpers for building provider-agnostic tool agents (#12)."""
2
2
 
3
- from typing import Annotated, TypedDict
3
+ from typing import Annotated, Any, TypedDict
4
4
 
5
5
  from langchain_core.language_models.chat_models import BaseChatModel
6
6
  from langchain_core.messages import BaseMessage
@@ -32,8 +32,19 @@ def make_tool_agent(
32
32
  model: str | BaseChatModel,
33
33
  tools: list,
34
34
  system_prompt: str | None = None,
35
+ checkpointer: Any | None = None,
35
36
  ) -> StateGraph:
36
- """Build a compiled ``agent <-> tools`` graph for any tool list."""
37
+ """Build a compiled ``agent <-> tools`` graph for any tool list.
38
+
39
+ Args:
40
+ model: ``provider:name`` spec (see :mod:`docs/providers`) or a chat
41
+ model instance.
42
+ tools: LangChain tools bound to the model and served by a ``ToolNode``.
43
+ system_prompt: Optional system message prepended at invoke time.
44
+ checkpointer: Optional LangGraph checkpointer (e.g. ``MemorySaver()``).
45
+ Compiling with one enables per-``thread_id`` persistence: pass
46
+ ``config={"configurable": {"thread_id": ...}}`` at invoke time.
47
+ """
37
48
  llm = resolve_llm(model).bind_tools(tools)
38
49
  tool_node = ToolNode(tools)
39
50
 
@@ -53,4 +64,4 @@ def make_tool_agent(
53
64
  workflow.set_entry_point("agent")
54
65
  workflow.add_conditional_edges("agent", tools_condition)
55
66
  workflow.add_edge("tools", "agent")
56
- return workflow.compile()
67
+ return workflow.compile(checkpointer=checkpointer)
@@ -44,6 +44,9 @@ CALCULATOR_SYSTEM_PROMPT = (
44
44
 
45
45
  def make_calculator_agent(
46
46
  model: str | BaseChatModel = "openai:gpt-4o-mini",
47
+ checkpointer=None,
47
48
  ) -> StateGraph:
48
49
  """Build the calculator agent for any provider model spec/instance."""
49
- return make_tool_agent(model, list(CALCULATOR_TOOLS), CALCULATOR_SYSTEM_PROMPT)
50
+ return make_tool_agent(
51
+ model, list(CALCULATOR_TOOLS), CALCULATOR_SYSTEM_PROMPT, checkpointer
52
+ )
@@ -19,6 +19,7 @@ def get_weather(city: str):
19
19
 
20
20
  def make_agent_with_weather_tool(
21
21
  model: str | BaseChatModel = "openai:gpt-4o-mini",
22
+ checkpointer=None,
22
23
  ) -> StateGraph:
23
24
  """Build the weather demo agent for any provider model spec/instance.
24
25
 
@@ -31,4 +32,4 @@ def make_agent_with_weather_tool(
31
32
  if model == "gpt-4o-mini": # backward compat: bare legacy default
32
33
  model = "openai:gpt-4o-mini"
33
34
  tools = [get_weather, render_graph]
34
- return make_tool_agent(model, tools)
35
+ return make_tool_agent(model, tools, checkpointer=checkpointer)
@@ -0,0 +1,74 @@
1
+ # Implementing an agent
2
+
3
+ Any compiled LangGraph graph over `{"messages": [...]}` is servable. The only
4
+ contract (see `ChatGraph` in `server.py`) is:
5
+
6
+ ```python
7
+ graph.astream(input, config=..., stream_mode=[...], subgraphs=True)
8
+ # yields (namespace, event_type, chunk) triples
9
+ ```
10
+
11
+ ## Minimal custom agent (5 minutes)
12
+
13
+ ```python
14
+ # my_agent.py
15
+ from langchain_core.tools import tool
16
+ from agent_chat_minimal.demo_agent.agent_factory import make_tool_agent
17
+
18
+ @tool
19
+ def shout(text: str) -> str:
20
+ """Uppercase the input."""
21
+ return text.upper()
22
+
23
+ def make_shout_agent(model="openai:gpt-4o-mini", checkpointer=None):
24
+ return make_tool_agent(model, [shout], "Reply ONLY with the tool result.")
25
+ ```
26
+
27
+ Serve it — no server fork needed:
28
+
29
+ ```python
30
+ # serve.py
31
+ from agent_chat_minimal import create_app
32
+ from my_agent import make_shout_agent
33
+
34
+ app = create_app(graph_factory=make_shout_agent)
35
+ # python -m uvicorn serve:app --port 8011
36
+ ```
37
+
38
+ Prefer an instance? `create_app(graph=make_shout_agent(...))` works too;
39
+ the factory form defers credential errors to startup instead of import.
40
+
41
+ ## Multi-agent serving
42
+
43
+ ```python
44
+ app = create_app(agents={"shout": make_shout_agent})
45
+ # POST /assistant/shout, GET /agents -> ["calculator","shout","weather"]
46
+ ```
47
+
48
+ `POST /assistant` aliases the `default_agent` (`"weather"` unless overridden).
49
+
50
+ ## Reference: calculator agent
51
+
52
+ `demo_agent/calculator.py` (`add`/`subtract`/`multiply`/`divide` +
53
+ `make_calculator_agent`) is the canonical example: tools, system prompt,
54
+ provider-agnostic model arg, optional `checkpointer` passthrough.
55
+
56
+ ## Sharing via pip (no fork)
57
+
58
+ Register the `agent_chat.agents` entry-points group:
59
+
60
+ ```toml
61
+ [project.entry-points."agent_chat.agents"]
62
+ shout = "my_package.my_agent:make_shout_agent"
63
+ ```
64
+
65
+ `discover_agents()` picks it up automatically alongside the built-ins.
66
+
67
+ ## Checklist
68
+
69
+ - [ ] Factory signature `(model=..., checkpointer=None)` so the server can
70
+ inject the shared checkpointer.
71
+ - [ ] Tools have clear docstrings — the model only sees those.
72
+ - [ ] Offline test with a fake model (see `tests/test_provider_agnostic.py`).
73
+ - [ ] `minimal-chat-serve --agent shout --check` builds without network creds
74
+ only if the model is fake/local; otherwise expect a credential error.
@@ -0,0 +1,60 @@
1
+ # Configuration
2
+
3
+ Single source of truth: `Settings` in `config.py` (stdlib only, no extra
4
+ dependency). CLI flags override env vars.
5
+
6
+ ## Environment
7
+
8
+ ```text
9
+ HOST=0.0.0.0 # uvicorn bind host
10
+ PORT=8011 # uvicorn bind port
11
+ MODEL=openai:gpt-4o-mini # provider:model spec (see providers.md)
12
+ DEFAULT_AGENT=weather # registry id aliased by POST /assistant
13
+ MINIMAL_WEB_DIR= # override bundled web/ (empty = bundled)
14
+ OPENAI_API_KEY= # credential for the default openai model
15
+ ANTHROPIC_API_KEY= # credential when MODEL uses anthropic:
16
+ ```
17
+
18
+ ```python
19
+ from agent_chat_minimal import Settings
20
+ Settings.from_env() # Settings(host='0.0.0.0', port=8011, ...)
21
+ ```
22
+
23
+ ## CLI
24
+
25
+ ```bash
26
+ minimal-chat-serve --host 127.0.0.1 --port 8011 \
27
+ --model ollama:llama3.1 --agent calculator
28
+ minimal-chat-serve --agent weather --check # build graph, exit, no server
29
+ ```
30
+
31
+ `--check` is the fast CI smoke test: non-zero exit with the real factory
32
+ error when credentials are missing.
33
+
34
+ ## Hooks (`create_app(...)`)
35
+
36
+ | Parameter | Purpose |
37
+ | ---------------- | -------------------------------------------------- |
38
+ | `graph=` | Serve one prebuilt graph (`/agents == ["default"]`)|
39
+ | `graph_factory=` | Deferred single-graph build (errors at startup) |
40
+ | `agents=` | Name → factory map (multi-agent mode) |
41
+ | `default_agent=` | Id aliased by `POST /assistant` |
42
+ | `web_dir=` | Override the bundled UI directory |
43
+ | `prepare_state=` | `(state, request) -> message dicts` reducer |
44
+ | `checkpointer=` | Shared checkpointer (`"memory"` default, see below)|
45
+ | `thread_manager=`/`message_store=` | Swap thread storage (tests) |
46
+
47
+ ## Checkpointer
48
+
49
+ `"memory"` (default) builds one shared `MemorySaver` and passes it to every
50
+ factory whose signature accepts `checkpointer`. Per-`thread_id` graph state
51
+ then persists across requests (see [threads.md](threads.md)). Pass an explicit
52
+ saver instance for custom backends, or `None` to disable injection.
53
+
54
+ ## `/assistant` 503 semantics
55
+
56
+ - Default registry + no `OPENAI_API_KEY` → legacy
57
+ `{"error": "OPENAI_API_KEY not configured", ...}` (backward compatible).
58
+ - Custom graph/factory failure →
59
+ `{"error": "agent_not_ready", "message": ..., "hint": ...}` with the real
60
+ factory exception in `hint`.
@@ -0,0 +1,29 @@
1
+ # agent-chat-minimal — documentation index
2
+
3
+ Portable FastAPI + LangGraph chat server with a bundled Assistant UI.
4
+ Install from PyPI (Python 3.11+, no Node needed) and serve one command:
5
+
6
+ ```bash
7
+ pip install agent-chat-fastapi-langgraph-assistant-ui
8
+ minimal-chat-serve --port 8011
9
+ ```
10
+
11
+ Guides (shipped inside the wheel under `agent_chat_minimal/docs/`):
12
+
13
+ - [quickstart.md](quickstart.md) — install, serve, first chat (2 minutes).
14
+ - [agents.md](agents.md) — implement and serve your own agent.
15
+ - [providers.md](providers.md) — model specs for OpenAI, Anthropic, Ollama, ….
16
+ - [configuration.md](configuration.md) — env vars, CLI flags, hooks.
17
+ - [threads.md](threads.md) — multi-thread chats, frontend-full compatibility.
18
+ - [index.md](index.md) — this file: architecture overview.
19
+
20
+ Discoverability: every guide is readable at runtime without unpacking the wheel:
21
+
22
+ ```python
23
+ from agent_chat_minimal import docs
24
+ docs.list() # ['agents', 'configuration', ...]
25
+ print(docs.get("agents"))
26
+ docs.show("threads") # prints to stdout
27
+ ```
28
+
29
+ FastAPI also serves interactive Swagger UI at `GET /docs` when the server runs.
@@ -0,0 +1,42 @@
1
+ # Model providers
2
+
3
+ Factories take either a `provider:name` spec (resolved via LangChain's
4
+ `init_chat_model`) or an already-built chat model instance.
5
+
6
+ ## Specs
7
+
8
+ | Spec prefix | Example | Credential env | Install extra |
9
+ | ----------- | --------------------------- | ------------------- | -------------------- |
10
+ | `openai:` | `openai:gpt-4o-mini` | `OPENAI_API_KEY` | `langchain-openai` ✓ |
11
+ | `anthropic:`| `anthropic:claude-sonnet-4-5` | `ANTHROPIC_API_KEY` | `langchain-anthropic`|
12
+ | `ollama:` | `ollama:llama3.1` | none (local daemon) | `langchain-ollama` |
13
+ | `google_genai:` | `google_genai:gemini-2.5-flash` | `GOOGLE_API_KEY`| `langchain-google-genai` |
14
+
15
+ ✓ = bundled with this wheel. Others need their LangChain partner package;
16
+ the import happens lazily, only when that provider is selected.
17
+
18
+ Bare `gpt-4o-mini` still works (provider inferred as OpenAI) for backward
19
+ compatibility; prefer the explicit `openai:` prefix.
20
+
21
+ ## Selecting the model
22
+
23
+ ```bash
24
+ MODEL=anthropic:claude-sonnet-4-5 minimal-chat-serve
25
+ minimal-chat-serve --model ollama:llama3.1 --agent calculator
26
+ ```
27
+
28
+ ## Instances and offline tests
29
+
30
+ Pass any `BaseChatModel` (streaming or fake) straight in:
31
+
32
+ ```python
33
+ from langchain_core.language_models.fake_chat_models import GenericFakeChatModel
34
+
35
+ class Bindable(GenericFakeChatModel):
36
+ def bind_tools(self, *a, **k):
37
+ return self # base class raises NotImplementedError
38
+
39
+ graph = make_calculator_agent(Bindable(messages=iter([...])))
40
+ ```
41
+
42
+ This is how the bundled tests run the full agent loop with no network.
@@ -0,0 +1,45 @@
1
+ # Quickstart
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ pip install agent-chat-fastapi-langgraph-assistant-ui
7
+ ```
8
+
9
+ Or from this repo (builds the UI + wheel; Node/pnpm needed only here):
10
+
11
+ ```bash
12
+ packages/agent-chat-minimal/scripts/build_wheel.sh
13
+ python -m pip install packages/agent-chat-minimal/dist/*.whl
14
+ ```
15
+
16
+ ## Serve
17
+
18
+ ```bash
19
+ export OPENAI_API_KEY=sk-...
20
+ minimal-chat-serve --port 8011
21
+ # open http://localhost:8011/
22
+ ```
23
+
24
+ Without `OPENAI_API_KEY`, the UI and `GET /health` still work; `POST /assistant`
25
+ returns 503 with setup instructions.
26
+
27
+ ## First chat
28
+
29
+ ```bash
30
+ curl -s localhost:8011/health
31
+ # {"status":"ok"}
32
+
33
+ curl -s localhost:8011/agents
34
+ # {"agents":["calculator","weather"],"default":"weather"}
35
+ ```
36
+
37
+ In the UI, try *"What is 12 × 8?"* (calculator) or *"Weather in London?"*.
38
+ For the sidebar with previous chats, open <http://localhost:8011/full/>.
39
+
40
+ ## Next steps
41
+
42
+ - Custom agent? → [agents.md](agents.md).
43
+ - Another model provider? → [providers.md](providers.md).
44
+ - Env vars and flags? → [configuration.md](configuration.md).
45
+ - Threaded chats / frontend-full? → [threads.md](threads.md).
@@ -0,0 +1,72 @@
1
+ # Threads (multi-conversation chats)
2
+
3
+ The portable server speaks the same thread protocol as the full backend, so
4
+ `frontend-full` (thread list, history, multiple chats) works against either
5
+ server. Single-prompt clients can ignore this page entirely.
6
+
7
+ ## Concepts
8
+
9
+ - **Thread**: a conversation id. Metadata (title, owner, archived) is kept by
10
+ `ThreadManager`; content lives in two places:
11
+ - assistant-ui message objects, stored verbatim per thread (tool UI parts
12
+ rehydrate on reload);
13
+ - LangGraph checkpointer state keyed by `thread_id` (graph-side memory).
14
+ - **Scoped request**: `POST /assistant` accepts `thread_id`/`user_id`
15
+ top-level fields (plus the classic `commands`/`state`). Missing ids are
16
+ auto-generated and their metadata auto-created — the same behavior as the
17
+ full backend.
18
+
19
+ ## Endpoints
20
+
21
+ ```text
22
+ GET /threads[?user_id=&include_archived=]
23
+ POST /threads {localId, user_id?, title?}
24
+ GET /threads/{id} PATCH /threads/{id} {title}
25
+ POST /threads/{id}/archive|unarchive
26
+ DELETE /threads/{id} (also drops stored messages)
27
+ GET /threads/{id}/messages (persisted UI messages, else checkpointer fallback)
28
+ POST /threads/{id}/messages {message} (history.append hook)
29
+ POST /assistant POST /assistant/{agent_id} (scoped shape supported)
30
+ ```
31
+
32
+ ## Example flow
33
+
34
+ ```bash
35
+ curl -X POST localhost:8011/threads -H 'Content-Type: application/json' \
36
+ -d '{"localId":"trip","title":"Trip planning"}'
37
+
38
+ curl -X POST localhost:8011/assistant -H 'Content-Type: application/json' \
39
+ -d '{"thread_id":"trip","state":{"thread_id":"trip"},"commands":[]}'
40
+
41
+ curl localhost:8011/threads/trip/messages
42
+ ```
43
+
44
+ ## Frontend-full compatibility
45
+
46
+ ## Bundled full UI
47
+
48
+ The wheel ships the full frontend (thread sidebar) at `/full/` — no separate
49
+ Next.js server needed. It is built with `NEXT_PUBLIC_API_BASE=""` so it talks
50
+ to the same origin (`/assistant`, `/threads`). The minimal single-prompt chat
51
+ stays at `/`. To serve a custom full build instead:
52
+
53
+ ```bash
54
+ FULL_WEB_DIR=/path/to/frontend-full/out minimal-chat-serve
55
+ ```
56
+
57
+ Pointing an external full frontend at the portable server also works
58
+ (`NEXT_PUBLIC_API_URL` without the trailing `/assistant`); thread list,
59
+ switching, rename, archive, and history rehydration all use the endpoints
60
+ above. Responses stream over the Assistant Stream protocol with
61
+ `messages`/`updates`/`custom` events, including `tool_updates` progress
62
+ entries like the full backend.
63
+
64
+ ## Persistence notes
65
+
66
+ - Default storage is in-memory (`MemorySaver` + dicts): restarts lose it —
67
+ identical to the full backend's default. Restart-safe backends plug in via
68
+ `create_app(checkpointer=<saver>)`.
69
+ - History larger than the 500-message store cap (or 200 tool updates) is
70
+ trimmed oldest-first.
71
+ - AI messages with `tool_calls` but no matching `ToolMessage` are dropped
72
+ before invoke (invalid-history guard, same as full backend).