docsmind 0.3.0__tar.gz → 0.4.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 (490) hide show
  1. {docsmind-0.3.0 → docsmind-0.4.0}/CHANGELOG.md +19 -0
  2. {docsmind-0.3.0 → docsmind-0.4.0}/PKG-INFO +58 -15
  3. {docsmind-0.3.0 → docsmind-0.4.0}/README.md +57 -14
  4. {docsmind-0.3.0 → docsmind-0.4.0}/pyproject.toml +1 -1
  5. docsmind-0.4.0/src/docsmind/adapters/llm/__init__.py +31 -0
  6. docsmind-0.4.0/src/docsmind/adapters/llm/anthropic_llm.py +152 -0
  7. docsmind-0.4.0/src/docsmind/adapters/llm/openai_llm.py +182 -0
  8. docsmind-0.4.0/src/docsmind/adapters/storage/memory.py +83 -0
  9. docsmind-0.4.0/src/docsmind/adapters/storage/postgres/agent_store.py +190 -0
  10. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/storage/postgres/repository.py +118 -1
  11. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/storage/postgres/tables.py +37 -0
  12. docsmind-0.4.0/src/docsmind/agent/agent.py +432 -0
  13. docsmind-0.4.0/src/docsmind/agent/catalog.py +85 -0
  14. docsmind-0.4.0/src/docsmind/agent/harness/__init__.py +2 -0
  15. docsmind-0.4.0/src/docsmind/agent/harness/context.py +154 -0
  16. docsmind-0.4.0/src/docsmind/agent/harness/memory.py +119 -0
  17. docsmind-0.4.0/src/docsmind/agent/harness/summarizer.py +67 -0
  18. docsmind-0.4.0/src/docsmind/agent/harness/tokens.py +36 -0
  19. docsmind-0.4.0/src/docsmind/agent/loop.py +131 -0
  20. docsmind-0.4.0/src/docsmind/agent/orchestrator.py +41 -0
  21. docsmind-0.4.0/src/docsmind/agent/planner.py +38 -0
  22. docsmind-0.4.0/src/docsmind/agent/prompts.py +93 -0
  23. docsmind-0.4.0/src/docsmind/agent/sources.py +95 -0
  24. docsmind-0.4.0/src/docsmind/agent/subagents/specs.py +44 -0
  25. docsmind-0.4.0/src/docsmind/agent/tools/__init__.py +25 -0
  26. docsmind-0.4.0/src/docsmind/agent/tools/base.py +130 -0
  27. docsmind-0.4.0/src/docsmind/agent/tools/delegate.py +48 -0
  28. docsmind-0.4.0/src/docsmind/agent/tools/documents.py +109 -0
  29. docsmind-0.4.0/src/docsmind/agent/tools/search.py +126 -0
  30. docsmind-0.4.0/src/docsmind/agent/util.py +53 -0
  31. docsmind-0.4.0/src/docsmind/cli/chat.py +44 -0
  32. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/client.py +44 -5
  33. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/config.py +20 -0
  34. docsmind-0.4.0/src/docsmind/domain/agent.py +147 -0
  35. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/citations.py +5 -0
  36. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/errors.py +18 -0
  37. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/ports.py +63 -6
  38. docsmind-0.4.0/src/docsmind/retrieval/keyword.py +48 -0
  39. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/server/app.py +2 -1
  40. docsmind-0.4.0/src/docsmind/server/routes/chat.py +161 -0
  41. docsmind-0.4.0/src/docsmind/server/ui/assets/index-DvL2_fGF.js +5423 -0
  42. docsmind-0.4.0/src/docsmind/server/ui/assets/index-ae6vf384.css +1 -0
  43. docsmind-0.4.0/src/docsmind/server/ui/favicon.svg +1 -0
  44. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/server/ui/index.html +3 -3
  45. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/LICENSE +177 -0
  46. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-H.bcmap +0 -0
  47. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-V.bcmap +0 -0
  48. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-H.bcmap +0 -0
  49. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-H.bcmap +0 -0
  50. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-V.bcmap +0 -0
  51. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-V.bcmap +0 -0
  52. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-H.bcmap +0 -0
  53. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-V.bcmap +0 -0
  54. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/83pv-RKSJ-H.bcmap +0 -0
  55. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-H.bcmap +0 -0
  56. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-V.bcmap +0 -0
  57. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-H.bcmap +0 -0
  58. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-V.bcmap +0 -0
  59. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-H.bcmap +0 -0
  60. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-V.bcmap +0 -0
  61. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-H.bcmap +0 -0
  62. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-H.bcmap +0 -0
  63. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-V.bcmap +0 -0
  64. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-V.bcmap +0 -0
  65. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-0.bcmap +0 -0
  66. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-1.bcmap +0 -0
  67. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-2.bcmap +0 -0
  68. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-3.bcmap +0 -0
  69. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-4.bcmap +0 -0
  70. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-5.bcmap +0 -0
  71. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-6.bcmap +0 -0
  72. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  73. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-0.bcmap +0 -0
  74. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-1.bcmap +0 -0
  75. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-2.bcmap +0 -0
  76. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-3.bcmap +0 -0
  77. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-4.bcmap +0 -0
  78. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-5.bcmap +0 -0
  79. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  80. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-0.bcmap +0 -0
  81. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-1.bcmap +0 -0
  82. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-2.bcmap +0 -0
  83. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-3.bcmap +0 -0
  84. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-4.bcmap +0 -0
  85. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-5.bcmap +0 -0
  86. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-6.bcmap +0 -0
  87. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  88. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-0.bcmap +0 -0
  89. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-1.bcmap +0 -0
  90. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-2.bcmap +0 -0
  91. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  92. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5-H.bcmap +0 -0
  93. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5-V.bcmap +0 -0
  94. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-H.bcmap +0 -0
  95. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-V.bcmap +0 -0
  96. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-H.bcmap +0 -0
  97. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-V.bcmap +0 -0
  98. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-H.bcmap +0 -0
  99. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-V.bcmap +0 -0
  100. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-H.bcmap +0 -0
  101. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-V.bcmap +3 -0
  102. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-H.bcmap +0 -0
  103. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-V.bcmap +0 -0
  104. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-H.bcmap +0 -0
  105. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-V.bcmap +0 -0
  106. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-H.bcmap +3 -0
  107. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-V.bcmap +0 -0
  108. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-H.bcmap +0 -0
  109. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-V.bcmap +0 -0
  110. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-H.bcmap +0 -0
  111. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-H.bcmap +0 -0
  112. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-V.bcmap +0 -0
  113. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-V.bcmap +0 -0
  114. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-H.bcmap +0 -0
  115. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-V.bcmap +0 -0
  116. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-H.bcmap +4 -0
  117. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-V.bcmap +0 -0
  118. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-H.bcmap +0 -0
  119. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-V.bcmap +0 -0
  120. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-H.bcmap +0 -0
  121. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-V.bcmap +0 -0
  122. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-H.bcmap +0 -0
  123. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-V.bcmap +0 -0
  124. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-H.bcmap +0 -0
  125. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-V.bcmap +0 -0
  126. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-H.bcmap +0 -0
  127. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-V.bcmap +0 -0
  128. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-H.bcmap +0 -0
  129. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-V.bcmap +0 -0
  130. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-H.bcmap +0 -0
  131. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-V.bcmap +0 -0
  132. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/H.bcmap +0 -0
  133. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-H.bcmap +0 -0
  134. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-V.bcmap +0 -0
  135. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-H.bcmap +0 -0
  136. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-V.bcmap +0 -0
  137. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-H.bcmap +0 -0
  138. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-V.bcmap +0 -0
  139. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-H.bcmap +0 -0
  140. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-V.bcmap +0 -0
  141. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-H.bcmap +0 -0
  142. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-V.bcmap +0 -0
  143. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-H.bcmap +0 -0
  144. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-V.bcmap +0 -0
  145. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Hankaku.bcmap +0 -0
  146. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Hiragana.bcmap +0 -0
  147. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-H.bcmap +0 -0
  148. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-V.bcmap +0 -0
  149. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-H.bcmap +0 -0
  150. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-H.bcmap +0 -0
  151. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-V.bcmap +0 -0
  152. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-V.bcmap +0 -0
  153. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-H.bcmap +0 -0
  154. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  155. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  156. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-V.bcmap +0 -0
  157. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-H.bcmap +0 -0
  158. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-V.bcmap +0 -0
  159. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Katakana.bcmap +0 -0
  160. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/LICENSE +36 -0
  161. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-H.bcmap +0 -0
  162. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-V.bcmap +0 -0
  163. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-H.bcmap +0 -0
  164. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-V.bcmap +0 -0
  165. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Roman.bcmap +0 -0
  166. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  167. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  168. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  169. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  170. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  171. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  172. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  173. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  174. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-H.bcmap +0 -0
  175. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-V.bcmap +0 -0
  176. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-H.bcmap +0 -0
  177. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-V.bcmap +0 -0
  178. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-H.bcmap +0 -0
  179. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-V.bcmap +0 -0
  180. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-H.bcmap +0 -0
  181. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-V.bcmap +0 -0
  182. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  183. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  184. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  185. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  186. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  187. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  188. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  189. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  190. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  191. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  192. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  193. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  194. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  195. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  196. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  197. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  198. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  199. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  200. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  201. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  202. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  203. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  204. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  205. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-H.bcmap +0 -0
  206. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-V.bcmap +0 -0
  207. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-H.bcmap +0 -0
  208. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-V.bcmap +0 -0
  209. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-H.bcmap +0 -0
  210. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-V.bcmap +0 -0
  211. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-H.bcmap +0 -0
  212. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-V.bcmap +0 -0
  213. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/V.bcmap +0 -0
  214. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/WP-Symbol.bcmap +0 -0
  215. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/iccs/CGATS001Compat-v2-micro.icc +0 -0
  216. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/iccs/LICENSE +116 -0
  217. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_add.svg +3 -0
  218. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_disclaimer.svg +3 -0
  219. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_done.svg +3 -0
  220. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_spinner.svg +30 -0
  221. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_warning.svg +3 -0
  222. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-check.svg +11 -0
  223. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-comment.svg +16 -0
  224. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-help.svg +26 -0
  225. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-insert.svg +10 -0
  226. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-key.svg +11 -0
  227. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-newparagraph.svg +11 -0
  228. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-noicon.svg +7 -0
  229. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-note.svg +42 -0
  230. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-paperclip.svg +6 -0
  231. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-paragraph.svg +16 -0
  232. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-pushpin.svg +7 -0
  233. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/checkmark.svg +5 -0
  234. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-actionsButton.svg +3 -0
  235. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-closeButton.svg +3 -0
  236. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-editButton.svg +8 -0
  237. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-popup-editButton.svg +5 -0
  238. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeHighlight.svg +6 -0
  239. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeText.svg +3 -0
  240. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorInk.svg +4 -0
  241. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorTextHighlight.svg +8 -0
  242. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-delete.svg +5 -0
  243. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-edit.svg +3 -0
  244. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/findbarButton-next.svg +3 -0
  245. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/findbarButton-previous.svg +3 -0
  246. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/gv-toolbarButton-download.svg +3 -0
  247. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/loading-icon.gif +0 -0
  248. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/loading.svg +1 -0
  249. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/messageBar_closingButton.svg +3 -0
  250. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/messageBar_info.svg +3 -0
  251. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/messageBar_warning.svg +3 -0
  252. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_closeButton.svg +3 -0
  253. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_selected.svg +7 -0
  254. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_viewArrow.svg +3 -0
  255. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_viewButton.svg +3 -0
  256. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-documentProperties.svg +3 -0
  257. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-firstPage.svg +3 -0
  258. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-handTool.svg +3 -0
  259. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-lastPage.svg +3 -0
  260. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCcw.svg +3 -0
  261. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCw.svg +3 -0
  262. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollHorizontal.svg +3 -0
  263. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollPage.svg +3 -0
  264. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollVertical.svg +3 -0
  265. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollWrapped.svg +3 -0
  266. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-selectTool.svg +3 -0
  267. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadEven.svg +3 -0
  268. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadNone.svg +3 -0
  269. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadOdd.svg +3 -0
  270. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/signature-properties-row-check.svg +4 -0
  271. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-bookmark.svg +3 -0
  272. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-currentOutlineItem.svg +3 -0
  273. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-download.svg +4 -0
  274. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorFreeText.svg +5 -0
  275. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorHighlight.svg +6 -0
  276. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorInk.svg +4 -0
  277. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorSignature.svg +6 -0
  278. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorStamp.svg +8 -0
  279. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrow.svg +3 -0
  280. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrowNova.svg +3 -0
  281. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-openFile.svg +3 -0
  282. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageDown.svg +3 -0
  283. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageUp.svg +3 -0
  284. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-presentationMode.svg +3 -0
  285. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-print.svg +3 -0
  286. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-search.svg +3 -0
  287. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-secondaryToolbarToggle.svg +3 -0
  288. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesError.svg +7 -0
  289. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesVerified.svg +7 -0
  290. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewAttachments.svg +3 -0
  291. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewLayers.svg +3 -0
  292. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewOutline.svg +3 -0
  293. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewThumbnail.svg +3 -0
  294. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewsManagerToggle.svg +3 -0
  295. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomIn.svg +3 -0
  296. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomOut.svg +3 -0
  297. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/treeitem-collapsed.svg +1 -0
  298. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/treeitem-expanded.svg +1 -0
  299. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ach/viewer.ftl +184 -0
  300. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/af/viewer.ftl +163 -0
  301. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/an/viewer.ftl +207 -0
  302. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ar/viewer.ftl +807 -0
  303. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ast/viewer.ftl +156 -0
  304. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/az/viewer.ftl +207 -0
  305. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/be/viewer.ftl +822 -0
  306. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bg/viewer.ftl +392 -0
  307. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bn/viewer.ftl +202 -0
  308. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bo/viewer.ftl +206 -0
  309. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bqi/viewer.ftl +307 -0
  310. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/br/viewer.ftl +299 -0
  311. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/brx/viewer.ftl +175 -0
  312. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bs/viewer.ftl +560 -0
  313. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ca/viewer.ftl +563 -0
  314. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/cak/viewer.ftl +243 -0
  315. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ckb/viewer.ftl +198 -0
  316. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/cs/viewer.ftl +836 -0
  317. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/cy/viewer.ftl +864 -0
  318. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/da/viewer.ftl +711 -0
  319. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/de/viewer.ftl +808 -0
  320. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/dsb/viewer.ftl +836 -0
  321. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/el/viewer.ftl +808 -0
  322. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/en-CA/viewer.ftl +808 -0
  323. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/en-GB/viewer.ftl +808 -0
  324. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/en-US/viewer.ftl +873 -0
  325. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/eo/viewer.ftl +808 -0
  326. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-AR/viewer.ftl +808 -0
  327. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-CL/viewer.ftl +808 -0
  328. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-ES/viewer.ftl +783 -0
  329. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-MX/viewer.ftl +720 -0
  330. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/et/viewer.ftl +221 -0
  331. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/eu/viewer.ftl +812 -0
  332. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fa/viewer.ftl +808 -0
  333. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ff/viewer.ftl +206 -0
  334. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fi/viewer.ftl +808 -0
  335. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fr/viewer.ftl +804 -0
  336. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fur/viewer.ftl +620 -0
  337. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fy-NL/viewer.ftl +808 -0
  338. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ga-IE/viewer.ftl +164 -0
  339. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gd/viewer.ftl +245 -0
  340. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gl/viewer.ftl +563 -0
  341. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gn/viewer.ftl +788 -0
  342. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gu-IN/viewer.ftl +206 -0
  343. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/he/viewer.ftl +808 -0
  344. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hi-IN/viewer.ftl +205 -0
  345. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hr/viewer.ftl +695 -0
  346. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hsb/viewer.ftl +836 -0
  347. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hu/viewer.ftl +808 -0
  348. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hy-AM/viewer.ftl +618 -0
  349. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hye/viewer.ftl +221 -0
  350. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ia/viewer.ftl +808 -0
  351. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/id/viewer.ftl +561 -0
  352. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/is/viewer.ftl +544 -0
  353. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/it/viewer.ftl +808 -0
  354. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ja/viewer.ftl +752 -0
  355. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ka/viewer.ftl +808 -0
  356. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/kab/viewer.ftl +599 -0
  357. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/kk/viewer.ftl +808 -0
  358. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/km/viewer.ftl +222 -0
  359. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/kn/viewer.ftl +166 -0
  360. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ko/viewer.ftl +752 -0
  361. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lij/viewer.ftl +206 -0
  362. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lo/viewer.ftl +245 -0
  363. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/locale.json +1 -0
  364. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lt/viewer.ftl +221 -0
  365. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ltg/viewer.ftl +205 -0
  366. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lv/viewer.ftl +269 -0
  367. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/meh/viewer.ftl +48 -0
  368. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/mk/viewer.ftl +719 -0
  369. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ml/viewer.ftl +489 -0
  370. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/mr/viewer.ftl +194 -0
  371. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ms/viewer.ftl +206 -0
  372. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/my/viewer.ftl +157 -0
  373. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/nb-NO/viewer.ftl +808 -0
  374. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ne-NP/viewer.ftl +185 -0
  375. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/nl/viewer.ftl +808 -0
  376. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/nn-NO/viewer.ftl +808 -0
  377. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/oc/viewer.ftl +372 -0
  378. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pa-IN/viewer.ftl +808 -0
  379. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pl/viewer.ftl +821 -0
  380. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pt-BR/viewer.ftl +808 -0
  381. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pt-PT/viewer.ftl +808 -0
  382. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/rm/viewer.ftl +611 -0
  383. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ro/viewer.ftl +822 -0
  384. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ru/viewer.ftl +822 -0
  385. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sat/viewer.ftl +257 -0
  386. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sc/viewer.ftl +442 -0
  387. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/scn/viewer.ftl +32 -0
  388. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sco/viewer.ftl +217 -0
  389. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/si/viewer.ftl +214 -0
  390. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sk/viewer.ftl +836 -0
  391. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/skr/viewer.ftl +437 -0
  392. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sl/viewer.ftl +836 -0
  393. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/son/viewer.ftl +157 -0
  394. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sq/viewer.ftl +707 -0
  395. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sr/viewer.ftl +822 -0
  396. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sv-SE/viewer.ftl +808 -0
  397. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/szl/viewer.ftl +207 -0
  398. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ta/viewer.ftl +182 -0
  399. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/te/viewer.ftl +196 -0
  400. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/tg/viewer.ftl +713 -0
  401. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/th/viewer.ftl +687 -0
  402. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/tl/viewer.ftl +207 -0
  403. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/tr/viewer.ftl +808 -0
  404. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/trs/viewer.ftl +160 -0
  405. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/uk/viewer.ftl +699 -0
  406. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ur/viewer.ftl +206 -0
  407. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/uz/viewer.ftl +140 -0
  408. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/vi/viewer.ftl +752 -0
  409. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/wo/viewer.ftl +93 -0
  410. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/xh/viewer.ftl +163 -0
  411. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/zh-CN/viewer.ftl +733 -0
  412. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/zh-TW/viewer.ftl +752 -0
  413. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitDingbats.pfb +0 -0
  414. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixed.pfb +0 -0
  415. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBold.pfb +0 -0
  416. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  417. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedItalic.pfb +0 -0
  418. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerif.pfb +0 -0
  419. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBold.pfb +0 -0
  420. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  421. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifItalic.pfb +0 -0
  422. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSymbol.pfb +0 -0
  423. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_FOXIT +27 -0
  424. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_LIBERATION +363 -0
  425. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Bold.ttf +0 -0
  426. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  427. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Italic.ttf +0 -0
  428. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Regular.ttf +0 -0
  429. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/viewer.css +8265 -0
  430. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/viewer.html +1236 -0
  431. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/viewer.mjs +26437 -0
  432. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_JBIG2 +196 -0
  433. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_OPENJPEG +39 -0
  434. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_JBIG2 +13 -0
  435. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_OPENJPEG +22 -0
  436. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_QCMS +19 -0
  437. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_QCMS +21 -0
  438. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/jbig2.wasm +0 -0
  439. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/jbig2_nowasm_fallback.js +15 -0
  440. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg.wasm +0 -0
  441. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +17 -0
  442. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/qcms_bg.wasm +0 -0
  443. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.js +16 -0
  444. docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.wasm +0 -0
  445. docsmind-0.3.0/src/docsmind/cli/chat.py +0 -26
  446. docsmind-0.3.0/src/docsmind/server/__init__.py +0 -0
  447. docsmind-0.3.0/src/docsmind/server/routes/__init__.py +0 -0
  448. docsmind-0.3.0/src/docsmind/server/ui/assets/index-DSQOFo_H.css +0 -1
  449. docsmind-0.3.0/src/docsmind/server/ui/assets/index-QBP12Bcv.js +0 -5385
  450. docsmind-0.3.0/src/docsmind/server/ui/favicon.svg +0 -1
  451. docsmind-0.3.0/src/docsmind/server/ui/icons.svg +0 -24
  452. {docsmind-0.3.0 → docsmind-0.4.0}/.gitignore +0 -0
  453. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/__init__.py +0 -0
  454. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/__init__.py +0 -0
  455. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/blobs/__init__.py +0 -0
  456. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/blobs/filesystem.py +0 -0
  457. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/embeddings/__init__.py +0 -0
  458. {docsmind-0.3.0/src/docsmind/adapters/llm → docsmind-0.4.0/src/docsmind/adapters/storage}/__init__.py +0 -0
  459. {docsmind-0.3.0/src/docsmind/adapters/storage → docsmind-0.4.0/src/docsmind/adapters/storage/postgres}/__init__.py +0 -0
  460. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/storage/postgres/engine.py +0 -0
  461. {docsmind-0.3.0/src/docsmind/adapters/storage/postgres → docsmind-0.4.0/src/docsmind/adapters/tracing}/__init__.py +0 -0
  462. {docsmind-0.3.0/src/docsmind/adapters/tracing → docsmind-0.4.0/src/docsmind/adapters/vision}/__init__.py +0 -0
  463. {docsmind-0.3.0/src/docsmind/adapters/vision → docsmind-0.4.0/src/docsmind/agent}/__init__.py +0 -0
  464. {docsmind-0.3.0/src/docsmind/agent → docsmind-0.4.0/src/docsmind/agent/subagents}/__init__.py +0 -0
  465. {docsmind-0.3.0/src/docsmind/agent/subagents → docsmind-0.4.0/src/docsmind/agent/subagents/change_analysis}/__init__.py +0 -0
  466. {docsmind-0.3.0/src/docsmind/agent/subagents/change_analysis → docsmind-0.4.0/src/docsmind/cli}/__init__.py +0 -0
  467. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/app.py +0 -0
  468. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/db.py +0 -0
  469. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/diff.py +0 -0
  470. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/doctor.py +0 -0
  471. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/ingest.py +0 -0
  472. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/inspect.py +0 -0
  473. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/serve.py +0 -0
  474. {docsmind-0.3.0/src/docsmind/agent/tools → docsmind-0.4.0/src/docsmind/domain}/__init__.py +0 -0
  475. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/changes.py +0 -0
  476. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/documents.py +0 -0
  477. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/tables.py +0 -0
  478. {docsmind-0.3.0/src/docsmind/cli → docsmind-0.4.0/src/docsmind/ingestion}/__init__.py +0 -0
  479. {docsmind-0.3.0/src/docsmind/domain → docsmind-0.4.0/src/docsmind/ingestion/chunking}/__init__.py +0 -0
  480. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/chunking/page.py +0 -0
  481. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/chunking/structural.py +0 -0
  482. {docsmind-0.3.0/src/docsmind/ingestion → docsmind-0.4.0/src/docsmind/ingestion/enrichment}/__init__.py +0 -0
  483. {docsmind-0.3.0/src/docsmind/ingestion/chunking → docsmind-0.4.0/src/docsmind/ingestion/parsers}/__init__.py +0 -0
  484. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/parsers/pdf.py +0 -0
  485. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/pipeline.py +0 -0
  486. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/py.typed +0 -0
  487. {docsmind-0.3.0/src/docsmind/ingestion/enrichment → docsmind-0.4.0/src/docsmind/retrieval}/__init__.py +0 -0
  488. {docsmind-0.3.0/src/docsmind/ingestion/parsers → docsmind-0.4.0/src/docsmind/server}/__init__.py +0 -0
  489. {docsmind-0.3.0/src/docsmind/retrieval → docsmind-0.4.0/src/docsmind/server/routes}/__init__.py +0 -0
  490. {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/server/routes/documents.py +0 -0
@@ -2,6 +2,25 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.4.0] - 2026-10-31
6
+
7
+ ### Added
8
+
9
+ - The Mind: a chat agent (orchestrator, planner, tool-using executor, parallel subagents)
10
+ with a deterministic harness (context builder with prompt-cache breakpoint, summarizer,
11
+ memory writer). Answers carry verified `[S#]` citations.
12
+ - Provider-neutral LLM layer with OpenAI and Anthropic streaming adapters.
13
+ - Tools: `search`, `grep`, `read_pages`, `get_outline`, `list_documents`, `delegate`;
14
+ subagents: `researcher`, `change_analyzer`.
15
+ - Migration `0004`: `conversations`, `messages`, `agent_memory` tables (run `docsmind db upgrade`).
16
+ - HTTP: `POST /api/chat` (SSE), `GET/DELETE /api/conversations`, `GET /api/agent`.
17
+ - UI: streaming chat in Workspace with live agent activity, markdown answers, citation chips
18
+ and source cards that open the PDF at the cited page; Activity lists saved conversations;
19
+ Agents reads the real registry. New frontend deps: `react-markdown`, `remark-gfm`.
20
+ - `Docsmind.chat_result()`; `chat`/`achat` accept `conversation_id`; `docsmind chat` REPL keeps
21
+ the conversation.
22
+ - Config: `agent_*` settings, `openai_base_url`, `openai_reasoning_effort`.
23
+
5
24
  ## [0.3.0] - 2026-10-03
6
25
 
7
26
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: docsmind
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Chat with your documents. Version-aware retrieval, change analysis, and an editable table workspace, backed by Postgres/pgvector.
5
5
  Project-URL: Homepage, https://github.com/yauheniya-ai/docsmind
6
6
  Project-URL: Repository, https://github.com/yauheniya-ai/docsmind
@@ -68,9 +68,8 @@ Description-Content-Type: text/markdown
68
68
  Chat with your documents. Track what changed between versions, and why it matters.
69
69
 
70
70
  `docsmind` ingests PDFs (and soon DOCX/text) into a version-aware Postgres/pgvector
71
- store, and gives you an agent, **the Mind**, to chat with them. A built-in subagent,
72
- **diffra**, will do change analysis between document versions: what changed, where, and
73
- its compliance implications, with citations back to exact pages.
71
+ store, and gives you an agent, **the Mind**, to analyze them. Built-in subagents
72
+ will perform specialized tasks.
74
73
 
75
74
  > **Alpha.** Ingestion and inspection work today. Embeddings, chat and change analysis
76
75
  > are designed and scaffolded but not implemented yet; see [What works today](#what-works-today).
@@ -85,7 +84,7 @@ its compliance implications, with citations back to exact pages.
85
84
  | ✅ `docsmind doctor` | Checks database, blob storage and API keys, and tells you what to fix |
86
85
  | ✅ Table extraction | Extract and store tables skipping repeating ones (e.g. headers or footers) |
87
86
  | ✅ server + UI | FastAPI backend (`docsmind serve`) + React UI (`frontend/`): add documents, browse indexed content, image and table galleries |
88
- | 🚧 Chat agent (the Mind) | `docsmind chat` exists as a command, without an agent behind it yet |
87
+ | ✅ Chat agent (the Mind) | Routes each question, plans complex ones, searches/reads your documents with tools, delegates to subagents, and answers with verified `[S#]` citations. Streams to the UI over SSE; conversations are saved |
89
88
  | 🚧 Image captioning | Images are extracted and stored; vision captioning is next |
90
89
  | 🚧 Embeddings + hybrid search | Chunks are stored without embeddings for now |
91
90
  | 🚧 Change analysis (diffra) | `docsmind diff` exists as a command, without an implementation yet |
@@ -130,8 +129,9 @@ docsmind doctor
130
129
  ```
131
130
 
132
131
  Configuration is environment-driven (`DOCSMIND_*`, or a `.env` file). Copy
133
- `.env.example` to `.env` to see every option. Model API keys aren't needed yet;
134
- they'll be required once embeddings and chat land.
132
+ `.env.example` to `.env` to see every option. Chat needs an LLM key
133
+ (`DOCSMIND_LLM_PROVIDER` plus `DOCSMIND_ANTHROPIC_API_KEY` or `DOCSMIND_OPENAI_API_KEY`);
134
+ ingestion and browsing don't.
135
135
 
136
136
  ### 2. Ingest a PDF
137
137
 
@@ -187,13 +187,55 @@ cd ../docsmind
187
187
  python scripts/bundle_frontend.py
188
188
  ```
189
189
 
190
- ### 5. Coming next
190
+ ### 5. Ask the Mind
191
+
192
+ In the UI, open **Workspace** and ask a question (needs `docsmind[openai]` or `docsmind[anthropic]`
193
+ plus an API key). From the terminal or Python:
194
+
195
+ ```bash
196
+ docsmind chat "What are our data retention obligations?" # one-shot
197
+ docsmind chat # REPL, keeps the conversation
198
+ ```
191
199
 
192
200
  ```python
193
- print(dm.chat("What are our data retention obligations?")) # planned
194
- change_set = dm.compare(v1.id, v2.id) # planned (diffra)
201
+ result = dm.chat_result("What are our data retention obligations?")
202
+ print(result.answer, result.citations)
203
+ change_set = dm.compare(v1.id, v2.id) # planned (diffra)
195
204
  ```
196
205
 
206
+ ## How the Mind works
207
+
208
+ ```
209
+ Question -> Orchestrator --simple--> Executor <-> Tools / Subagents -> Answer
210
+ | ^
211
+ +--complex--> Planner --+ Harness feeds every role:
212
+ context builder, prompt cache,
213
+ summarizer, memory
214
+ ```
215
+
216
+ - **Orchestrator**: one cheap call that routes the question (`simple` or `complex`) and rewrites
217
+ it as a standalone question using the conversation so far.
218
+ - **Planner** (complex only): a short list of steps the executor follows.
219
+ - **Executor**: a bounded tool loop (`search`, `grep`, `read_pages`, `get_outline`,
220
+ `list_documents`, `delegate`). The last step forces an answer; tool errors go back to the
221
+ model, not the user; old tool results are elided when the context grows.
222
+ - **Subagents** (`researcher`, `change_analyzer`): fresh context, a subset of the tools, run in
223
+ parallel, cannot delegate further.
224
+ - **Harness**: deterministic code, not another agent. It orders the prompt stable-first so the
225
+ prefix caches, summarizes long histories, and saves durable notes to memory after each answer.
226
+ - **Citations**: tools register passages as `S1, S2, ...`; the model cites `[S#]`; invented
227
+ handles are dropped and the rest renumbered by first appearance. Document text is treated as
228
+ untrusted data, never as instructions.
229
+ - **Search** is Postgres full-text (ranked) plus exact-text grep until embeddings land.
230
+
231
+ Tuning (all `DOCSMIND_*`): `AGENT_FAST_MODEL` (router/summarizer/memory model, defaults to
232
+ `LLM_MODEL`), `AGENT_MAX_STEPS`, `AGENT_SUBAGENT_MAX_STEPS`, `AGENT_MEMORY_ENABLED`,
233
+ `OPENAI_REASONING_EFFORT`, `OPENAI_BASE_URL`. See `.env.example`.
234
+
235
+ HTTP: `POST /api/chat` streams Server-Sent Events (`route`, `plan`, `tool_start`, `tool_end`,
236
+ `subagent_start`, `subagent_end`, `token`, `note`, `answer`, `error`, `done`);
237
+ `GET /api/conversations[/{id}]`, `DELETE /api/conversations/{id}`, `GET /api/agent`.
238
+
197
239
  ## How ingestion works
198
240
 
199
241
  Ingestion is deliberately simple and predictable. There's no layout guessing, because
@@ -226,7 +268,8 @@ heuristics that work on one PDF break on the next.
226
268
  | `docsmind db up` / `upgrade` / `psql` | Start local Postgres, apply migrations, open psql |
227
269
  | `docsmind doctor` | Check your setup |
228
270
  | `docsmind serve [--host] [--port] [--reload]` | Run the FastAPI backend for the `frontend/` UI |
229
- | `docsmind chat`, `docsmind diff` | Planned |
271
+ | `docsmind chat [question] [-c <collection>]` | Ask the Mind once, or start a REPL that keeps the conversation |
272
+ | `docsmind diff` | Planned |
230
273
 
231
274
  ## Architecture
232
275
 
@@ -238,7 +281,7 @@ src/docsmind/
238
281
  │
239
282
  ├── domain/ # pure data + interfaces, no I/O
240
283
  │ ├── documents.py # Document, DocumentVersion, Section, Chunk, Image, ParsedDocument
241
- │ ├── changes.py # Change, ChangeSet, ImpactAssessment (diffra)
284
+ │ ├── changes.py # Change, ChangeSet, ImpactAssessment
242
285
  │ ├── citations.py # Citation
243
286
  │ ├── tables.py # AgentTable, TableRevision
244
287
  │ └── ports.py # LLM, Embedder, VisionCaptioner, VectorStore, BlobStore, Parser
@@ -255,9 +298,9 @@ src/docsmind/
255
298
  │ ├── llm/ embeddings/ vision/ tracing/ # planned
256
299
  │
257
300
  ├── cli/ # Typer app: ingest, versions, fulltext, outline, chunks, db, doctor
258
- ├── retrieval/ # hybrid vector + keyword search (planned)
259
- ├── agent/ # the Mind + diffra subagent (planned)
260
- └── server/ # FastAPI app + routes backing frontend/ (documents: ingest, read back content/images/tables)
301
+ ├── retrieval/ # keyword (full-text) search helpers; vector search planned
302
+ ├── agent/ # the Mind: orchestrator, planner, tool loop, tools, subagents, harness
303
+ └── server/ # FastAPI app + routes backing frontend/ (documents, chat SSE, conversations)
261
304
 
262
305
  alembic/ tests/ examples/ docs/
263
306
  ```
@@ -11,9 +11,8 @@
11
11
  Chat with your documents. Track what changed between versions, and why it matters.
12
12
 
13
13
  `docsmind` ingests PDFs (and soon DOCX/text) into a version-aware Postgres/pgvector
14
- store, and gives you an agent, **the Mind**, to chat with them. A built-in subagent,
15
- **diffra**, will do change analysis between document versions: what changed, where, and
16
- its compliance implications, with citations back to exact pages.
14
+ store, and gives you an agent, **the Mind**, to analyze them. Built-in subagents
15
+ will perform specialized tasks.
17
16
 
18
17
  > **Alpha.** Ingestion and inspection work today. Embeddings, chat and change analysis
19
18
  > are designed and scaffolded but not implemented yet; see [What works today](#what-works-today).
@@ -28,7 +27,7 @@ its compliance implications, with citations back to exact pages.
28
27
  | ✅ `docsmind doctor` | Checks database, blob storage and API keys, and tells you what to fix |
29
28
  | ✅ Table extraction | Extract and store tables skipping repeating ones (e.g. headers or footers) |
30
29
  | ✅ server + UI | FastAPI backend (`docsmind serve`) + React UI (`frontend/`): add documents, browse indexed content, image and table galleries |
31
- | 🚧 Chat agent (the Mind) | `docsmind chat` exists as a command, without an agent behind it yet |
30
+ | ✅ Chat agent (the Mind) | Routes each question, plans complex ones, searches/reads your documents with tools, delegates to subagents, and answers with verified `[S#]` citations. Streams to the UI over SSE; conversations are saved |
32
31
  | 🚧 Image captioning | Images are extracted and stored; vision captioning is next |
33
32
  | 🚧 Embeddings + hybrid search | Chunks are stored without embeddings for now |
34
33
  | 🚧 Change analysis (diffra) | `docsmind diff` exists as a command, without an implementation yet |
@@ -73,8 +72,9 @@ docsmind doctor
73
72
  ```
74
73
 
75
74
  Configuration is environment-driven (`DOCSMIND_*`, or a `.env` file). Copy
76
- `.env.example` to `.env` to see every option. Model API keys aren't needed yet;
77
- they'll be required once embeddings and chat land.
75
+ `.env.example` to `.env` to see every option. Chat needs an LLM key
76
+ (`DOCSMIND_LLM_PROVIDER` plus `DOCSMIND_ANTHROPIC_API_KEY` or `DOCSMIND_OPENAI_API_KEY`);
77
+ ingestion and browsing don't.
78
78
 
79
79
  ### 2. Ingest a PDF
80
80
 
@@ -130,13 +130,55 @@ cd ../docsmind
130
130
  python scripts/bundle_frontend.py
131
131
  ```
132
132
 
133
- ### 5. Coming next
133
+ ### 5. Ask the Mind
134
+
135
+ In the UI, open **Workspace** and ask a question (needs `docsmind[openai]` or `docsmind[anthropic]`
136
+ plus an API key). From the terminal or Python:
137
+
138
+ ```bash
139
+ docsmind chat "What are our data retention obligations?" # one-shot
140
+ docsmind chat # REPL, keeps the conversation
141
+ ```
134
142
 
135
143
  ```python
136
- print(dm.chat("What are our data retention obligations?")) # planned
137
- change_set = dm.compare(v1.id, v2.id) # planned (diffra)
144
+ result = dm.chat_result("What are our data retention obligations?")
145
+ print(result.answer, result.citations)
146
+ change_set = dm.compare(v1.id, v2.id) # planned (diffra)
138
147
  ```
139
148
 
149
+ ## How the Mind works
150
+
151
+ ```
152
+ Question -> Orchestrator --simple--> Executor <-> Tools / Subagents -> Answer
153
+ | ^
154
+ +--complex--> Planner --+ Harness feeds every role:
155
+ context builder, prompt cache,
156
+ summarizer, memory
157
+ ```
158
+
159
+ - **Orchestrator**: one cheap call that routes the question (`simple` or `complex`) and rewrites
160
+ it as a standalone question using the conversation so far.
161
+ - **Planner** (complex only): a short list of steps the executor follows.
162
+ - **Executor**: a bounded tool loop (`search`, `grep`, `read_pages`, `get_outline`,
163
+ `list_documents`, `delegate`). The last step forces an answer; tool errors go back to the
164
+ model, not the user; old tool results are elided when the context grows.
165
+ - **Subagents** (`researcher`, `change_analyzer`): fresh context, a subset of the tools, run in
166
+ parallel, cannot delegate further.
167
+ - **Harness**: deterministic code, not another agent. It orders the prompt stable-first so the
168
+ prefix caches, summarizes long histories, and saves durable notes to memory after each answer.
169
+ - **Citations**: tools register passages as `S1, S2, ...`; the model cites `[S#]`; invented
170
+ handles are dropped and the rest renumbered by first appearance. Document text is treated as
171
+ untrusted data, never as instructions.
172
+ - **Search** is Postgres full-text (ranked) plus exact-text grep until embeddings land.
173
+
174
+ Tuning (all `DOCSMIND_*`): `AGENT_FAST_MODEL` (router/summarizer/memory model, defaults to
175
+ `LLM_MODEL`), `AGENT_MAX_STEPS`, `AGENT_SUBAGENT_MAX_STEPS`, `AGENT_MEMORY_ENABLED`,
176
+ `OPENAI_REASONING_EFFORT`, `OPENAI_BASE_URL`. See `.env.example`.
177
+
178
+ HTTP: `POST /api/chat` streams Server-Sent Events (`route`, `plan`, `tool_start`, `tool_end`,
179
+ `subagent_start`, `subagent_end`, `token`, `note`, `answer`, `error`, `done`);
180
+ `GET /api/conversations[/{id}]`, `DELETE /api/conversations/{id}`, `GET /api/agent`.
181
+
140
182
  ## How ingestion works
141
183
 
142
184
  Ingestion is deliberately simple and predictable. There's no layout guessing, because
@@ -169,7 +211,8 @@ heuristics that work on one PDF break on the next.
169
211
  | `docsmind db up` / `upgrade` / `psql` | Start local Postgres, apply migrations, open psql |
170
212
  | `docsmind doctor` | Check your setup |
171
213
  | `docsmind serve [--host] [--port] [--reload]` | Run the FastAPI backend for the `frontend/` UI |
172
- | `docsmind chat`, `docsmind diff` | Planned |
214
+ | `docsmind chat [question] [-c <collection>]` | Ask the Mind once, or start a REPL that keeps the conversation |
215
+ | `docsmind diff` | Planned |
173
216
 
174
217
  ## Architecture
175
218
 
@@ -181,7 +224,7 @@ src/docsmind/
181
224
  │
182
225
  ├── domain/ # pure data + interfaces, no I/O
183
226
  │ ├── documents.py # Document, DocumentVersion, Section, Chunk, Image, ParsedDocument
184
- │ ├── changes.py # Change, ChangeSet, ImpactAssessment (diffra)
227
+ │ ├── changes.py # Change, ChangeSet, ImpactAssessment
185
228
  │ ├── citations.py # Citation
186
229
  │ ├── tables.py # AgentTable, TableRevision
187
230
  │ └── ports.py # LLM, Embedder, VisionCaptioner, VectorStore, BlobStore, Parser
@@ -198,9 +241,9 @@ src/docsmind/
198
241
  │ ├── llm/ embeddings/ vision/ tracing/ # planned
199
242
  │
200
243
  ├── cli/ # Typer app: ingest, versions, fulltext, outline, chunks, db, doctor
201
- ├── retrieval/ # hybrid vector + keyword search (planned)
202
- ├── agent/ # the Mind + diffra subagent (planned)
203
- └── server/ # FastAPI app + routes backing frontend/ (documents: ingest, read back content/images/tables)
244
+ ├── retrieval/ # keyword (full-text) search helpers; vector search planned
245
+ ├── agent/ # the Mind: orchestrator, planner, tool loop, tools, subagents, harness
246
+ └── server/ # FastAPI app + routes backing frontend/ (documents, chat SSE, conversations)
204
247
 
205
248
  alembic/ tests/ examples/ docs/
206
249
  ```
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "docsmind"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "Chat with your documents. Version-aware retrieval, change analysis, and an editable table workspace, backed by Postgres/pgvector."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,31 @@
1
+ """LLM adapter registry. SDKs are imported lazily inside each adapter, so a
2
+ bare `pip install docsmind` never needs openai/anthropic installed."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from docsmind.config import DocsmindConfig
7
+ from docsmind.domain.errors import LLMConfigurationError
8
+ from docsmind.domain.ports import LLM
9
+
10
+
11
+ def create_llm(config: DocsmindConfig, *, model: str | None = None) -> LLM:
12
+ """Build the configured LLM. `model` overrides `config.llm_model` (used
13
+ for the fast model that routes, summarizes and writes memory)."""
14
+ provider = config.llm_provider.lower()
15
+ model = model or config.llm_model
16
+ if provider == "openai":
17
+ from docsmind.adapters.llm.openai_llm import OpenAILLM
18
+
19
+ return OpenAILLM(
20
+ api_key=config.openai_api_key,
21
+ model=model,
22
+ base_url=config.openai_base_url,
23
+ reasoning_effort=config.openai_reasoning_effort,
24
+ )
25
+ if provider == "anthropic":
26
+ from docsmind.adapters.llm.anthropic_llm import AnthropicLLM
27
+
28
+ return AnthropicLLM(api_key=config.anthropic_api_key, model=model)
29
+ raise LLMConfigurationError(
30
+ f"Unknown DOCSMIND_LLM_PROVIDER '{config.llm_provider}'. Use 'anthropic' or 'openai'."
31
+ )
@@ -0,0 +1,152 @@
1
+ """Anthropic messages adapter.
2
+
3
+ Prompt caching is explicit on Anthropic: the harness orders system blocks
4
+ stable-first and flags where the stable prefix ends (`SystemBlock.cache`);
5
+ those become `cache_control` breakpoints here. Tools are rendered before the
6
+ system prompt in Anthropic's cache order, so they're covered by the same
7
+ breakpoint.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from collections.abc import Awaitable, Callable
13
+ from typing import Any
14
+
15
+ from docsmind.domain.agent import (
16
+ LLMResponse,
17
+ Message,
18
+ StopReason,
19
+ SystemBlock,
20
+ ToolCall,
21
+ ToolChoice,
22
+ ToolSpec,
23
+ Usage,
24
+ )
25
+ from docsmind.domain.errors import LLMConfigurationError
26
+
27
+ _STOP: dict[str, StopReason] = {
28
+ "end_turn": "end",
29
+ "stop_sequence": "end",
30
+ "tool_use": "tool_use",
31
+ "max_tokens": "max_tokens",
32
+ }
33
+
34
+
35
+ class AnthropicLLM:
36
+ def __init__(self, *, api_key: str | None, model: str, timeout: float = 120.0) -> None:
37
+ if not api_key:
38
+ raise LLMConfigurationError(
39
+ "Anthropic API key is not set. Add DOCSMIND_ANTHROPIC_API_KEY to your .env "
40
+ "(or set DOCSMIND_LLM_PROVIDER=openai)."
41
+ )
42
+ try:
43
+ from anthropic import AsyncAnthropic
44
+ except ImportError as exc: # pragma: no cover - import guard
45
+ raise LLMConfigurationError(
46
+ 'The anthropic package is not installed. Run `pip install "docsmind[anthropic]"`.'
47
+ ) from exc
48
+ self.model = model
49
+ self._client = AsyncAnthropic(api_key=api_key, max_retries=3, timeout=timeout)
50
+
51
+ @staticmethod
52
+ def _system(blocks: list[SystemBlock]) -> list[dict[str, Any]]:
53
+ out: list[dict[str, Any]] = []
54
+ for b in blocks:
55
+ if not b.text.strip():
56
+ continue
57
+ item: dict[str, Any] = {"type": "text", "text": b.text}
58
+ if b.cache:
59
+ item["cache_control"] = {"type": "ephemeral"}
60
+ out.append(item)
61
+ return out
62
+
63
+ @staticmethod
64
+ def _convert(messages: list[Message]) -> list[dict[str, Any]]:
65
+ out: list[dict[str, Any]] = []
66
+ pending_results: list[dict[str, Any]] = []
67
+
68
+ def flush() -> None:
69
+ if pending_results:
70
+ out.append({"role": "user", "content": list(pending_results)})
71
+ pending_results.clear()
72
+
73
+ for m in messages:
74
+ if m.role == "tool":
75
+ # All results for one assistant turn go in a single user message.
76
+ pending_results.append(
77
+ {
78
+ "type": "tool_result",
79
+ "tool_use_id": m.tool_call_id,
80
+ "content": m.content or "(empty)",
81
+ "is_error": m.is_error,
82
+ }
83
+ )
84
+ continue
85
+ flush()
86
+ if m.role == "user":
87
+ out.append({"role": "user", "content": m.content})
88
+ else:
89
+ blocks: list[dict[str, Any]] = []
90
+ if m.content.strip():
91
+ blocks.append({"type": "text", "text": m.content})
92
+ blocks.extend(
93
+ {"type": "tool_use", "id": c.id, "name": c.name, "input": c.arguments}
94
+ for c in m.tool_calls
95
+ )
96
+ if blocks:
97
+ out.append({"role": "assistant", "content": blocks})
98
+ flush()
99
+ return out
100
+
101
+ async def complete(
102
+ self,
103
+ messages: list[Message],
104
+ *,
105
+ system: list[SystemBlock],
106
+ tools: list[ToolSpec] | None = None,
107
+ tool_choice: ToolChoice = "auto",
108
+ max_tokens: int = 1024,
109
+ on_text: Callable[[str], Awaitable[None]] | None = None,
110
+ ) -> LLMResponse:
111
+ kwargs: dict[str, Any] = {
112
+ "model": self.model,
113
+ "max_tokens": max_tokens,
114
+ "system": self._system(system),
115
+ "messages": self._convert(messages),
116
+ }
117
+ if tools:
118
+ kwargs["tools"] = [
119
+ {"name": t.name, "description": t.description, "input_schema": t.parameters}
120
+ for t in tools
121
+ ]
122
+ kwargs["tool_choice"] = {"type": tool_choice}
123
+
124
+ async with self._client.messages.stream(**kwargs) as stream:
125
+ async for text in stream.text_stream:
126
+ if on_text and text:
127
+ await on_text(text)
128
+ final = await stream.get_final_message()
129
+
130
+ text_parts: list[str] = []
131
+ calls: list[ToolCall] = []
132
+ for block in final.content:
133
+ if block.type == "text":
134
+ text_parts.append(block.text)
135
+ elif block.type == "tool_use":
136
+ calls.append(
137
+ ToolCall(
138
+ id=block.id,
139
+ name=block.name,
140
+ arguments=dict(block.input) if isinstance(block.input, dict) else {},
141
+ )
142
+ )
143
+ u = final.usage
144
+ usage = Usage(
145
+ input_tokens=(u.input_tokens or 0)
146
+ + (getattr(u, "cache_read_input_tokens", 0) or 0)
147
+ + (getattr(u, "cache_creation_input_tokens", 0) or 0),
148
+ output_tokens=u.output_tokens or 0,
149
+ cached_input_tokens=getattr(u, "cache_read_input_tokens", 0) or 0,
150
+ )
151
+ stop: StopReason = "tool_use" if calls else _STOP.get(final.stop_reason or "", "other")
152
+ return LLMResponse(text="".join(text_parts), tool_calls=calls, stop_reason=stop, usage=usage)
@@ -0,0 +1,182 @@
1
+ """OpenAI (and OpenAI-compatible) chat-completions adapter.
2
+
3
+ Prompt caching on OpenAI is automatic for a stable prompt prefix, so this
4
+ adapter just keeps the system blocks in the order the harness gave them
5
+ (stable first) and doesn't need explicit cache markers.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import logging
12
+ from collections.abc import Awaitable, Callable
13
+ from typing import Any
14
+
15
+ from docsmind.domain.agent import (
16
+ LLMResponse,
17
+ Message,
18
+ StopReason,
19
+ SystemBlock,
20
+ ToolCall,
21
+ ToolChoice,
22
+ ToolSpec,
23
+ Usage,
24
+ )
25
+ from docsmind.domain.errors import LLMConfigurationError
26
+
27
+ _FINISH: dict[str, StopReason] = {"stop": "end", "tool_calls": "tool_use", "length": "max_tokens"}
28
+ log = logging.getLogger(__name__)
29
+
30
+
31
+ def parse_tool_arguments(raw: str) -> tuple[dict[str, Any], str | None]:
32
+ """Models occasionally emit malformed JSON for tool arguments. Don't crash
33
+ the turn: report it so the tool layer can tell the model to retry."""
34
+ if not raw.strip():
35
+ return {}, None
36
+ try:
37
+ value = json.loads(raw)
38
+ except json.JSONDecodeError as exc:
39
+ return {}, f"arguments were not valid JSON ({exc.msg})"
40
+ if not isinstance(value, dict):
41
+ return {}, "arguments must be a JSON object"
42
+ return value, None
43
+
44
+
45
+ class OpenAILLM:
46
+ def __init__(
47
+ self,
48
+ *,
49
+ api_key: str | None,
50
+ model: str,
51
+ base_url: str | None = None,
52
+ reasoning_effort: str | None = None,
53
+ timeout: float = 120.0,
54
+ ) -> None:
55
+ if not api_key:
56
+ raise LLMConfigurationError(
57
+ "OpenAI API key is not set. Add DOCSMIND_OPENAI_API_KEY to your .env "
58
+ "(or set DOCSMIND_LLM_PROVIDER=anthropic)."
59
+ )
60
+ try:
61
+ from openai import AsyncOpenAI, BadRequestError
62
+ except ImportError as exc: # pragma: no cover - import guard
63
+ raise LLMConfigurationError(
64
+ 'The openai package is not installed. Run `pip install "docsmind[openai]"`.'
65
+ ) from exc
66
+ self.model = model
67
+ self._bad_request = BadRequestError
68
+ self._reasoning_effort = reasoning_effort
69
+ self._client = AsyncOpenAI(api_key=api_key, base_url=base_url, max_retries=3, timeout=timeout)
70
+
71
+ @staticmethod
72
+ def _convert(messages: list[Message], system: list[SystemBlock]) -> list[dict[str, Any]]:
73
+ out: list[dict[str, Any]] = []
74
+ system_text = "\n\n".join(b.text for b in system if b.text.strip())
75
+ if system_text:
76
+ out.append({"role": "system", "content": system_text})
77
+ for m in messages:
78
+ if m.role == "user":
79
+ out.append({"role": "user", "content": m.content})
80
+ elif m.role == "assistant":
81
+ item: dict[str, Any] = {"role": "assistant", "content": m.content or None}
82
+ if m.tool_calls:
83
+ item["tool_calls"] = [
84
+ {
85
+ "id": c.id,
86
+ "type": "function",
87
+ "function": {"name": c.name, "arguments": json.dumps(c.arguments)},
88
+ }
89
+ for c in m.tool_calls
90
+ ]
91
+ out.append(item)
92
+ else:
93
+ out.append({"role": "tool", "tool_call_id": m.tool_call_id, "content": m.content})
94
+ return out
95
+
96
+ async def complete(
97
+ self,
98
+ messages: list[Message],
99
+ *,
100
+ system: list[SystemBlock],
101
+ tools: list[ToolSpec] | None = None,
102
+ tool_choice: ToolChoice = "auto",
103
+ max_tokens: int = 1024,
104
+ on_text: Callable[[str], Awaitable[None]] | None = None,
105
+ ) -> LLMResponse:
106
+ kwargs: dict[str, Any] = {
107
+ "model": self.model,
108
+ "messages": self._convert(messages, system),
109
+ "max_completion_tokens": max_tokens,
110
+ "stream": True,
111
+ "stream_options": {"include_usage": True},
112
+ }
113
+ if self._reasoning_effort:
114
+ kwargs["reasoning_effort"] = self._reasoning_effort
115
+ if tools:
116
+ kwargs["tools"] = [
117
+ {
118
+ "type": "function",
119
+ "function": {"name": t.name, "description": t.description, "parameters": t.parameters},
120
+ }
121
+ for t in tools
122
+ ]
123
+ kwargs["tool_choice"] = tool_choice
124
+
125
+ text_parts: list[str] = []
126
+ partial: dict[int, dict[str, str]] = {}
127
+ finish: str | None = None
128
+ usage = Usage()
129
+
130
+ try:
131
+ stream = await self._client.chat.completions.create(**kwargs)
132
+ except self._bad_request as exc:
133
+ # Some reasoning models refuse function tools on chat-completions
134
+ # unless reasoning is off. Remember that and retry once.
135
+ if not (tools and "reasoning_effort" in str(exc) and self._reasoning_effort != "none"):
136
+ raise
137
+ log.warning("%s rejects tools with reasoning; retrying with reasoning_effort='none'", self.model)
138
+ self._reasoning_effort = "none"
139
+ kwargs["reasoning_effort"] = "none"
140
+ stream = await self._client.chat.completions.create(**kwargs)
141
+ async for chunk in stream:
142
+ if chunk.usage:
143
+ details = getattr(chunk.usage, "prompt_tokens_details", None)
144
+ usage = Usage(
145
+ input_tokens=chunk.usage.prompt_tokens or 0,
146
+ output_tokens=chunk.usage.completion_tokens or 0,
147
+ cached_input_tokens=(getattr(details, "cached_tokens", 0) or 0) if details else 0,
148
+ )
149
+ if not chunk.choices:
150
+ continue
151
+ choice = chunk.choices[0]
152
+ delta = choice.delta
153
+ if delta and delta.content:
154
+ text_parts.append(delta.content)
155
+ if on_text:
156
+ await on_text(delta.content)
157
+ for tc in (delta.tool_calls or []) if delta else []:
158
+ slot = partial.setdefault(tc.index, {"id": "", "name": "", "args": ""})
159
+ if tc.id:
160
+ slot["id"] = tc.id
161
+ if tc.function:
162
+ if tc.function.name:
163
+ slot["name"] += tc.function.name
164
+ if tc.function.arguments:
165
+ slot["args"] += tc.function.arguments
166
+ if choice.finish_reason:
167
+ finish = choice.finish_reason
168
+
169
+ calls: list[ToolCall] = []
170
+ for index in sorted(partial):
171
+ slot = partial[index]
172
+ args, error = parse_tool_arguments(slot["args"])
173
+ calls.append(
174
+ ToolCall(
175
+ id=slot["id"] or f"call_{index}",
176
+ name=slot["name"],
177
+ arguments=args,
178
+ parse_error=error,
179
+ )
180
+ )
181
+ stop: StopReason = "tool_use" if calls else _FINISH.get(finish or "", "other")
182
+ return LLMResponse(text="".join(text_parts), tool_calls=calls, stop_reason=stop, usage=usage)