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.
- {docsmind-0.3.0 → docsmind-0.4.0}/CHANGELOG.md +19 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/PKG-INFO +58 -15
- {docsmind-0.3.0 → docsmind-0.4.0}/README.md +57 -14
- {docsmind-0.3.0 → docsmind-0.4.0}/pyproject.toml +1 -1
- docsmind-0.4.0/src/docsmind/adapters/llm/__init__.py +31 -0
- docsmind-0.4.0/src/docsmind/adapters/llm/anthropic_llm.py +152 -0
- docsmind-0.4.0/src/docsmind/adapters/llm/openai_llm.py +182 -0
- docsmind-0.4.0/src/docsmind/adapters/storage/memory.py +83 -0
- docsmind-0.4.0/src/docsmind/adapters/storage/postgres/agent_store.py +190 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/storage/postgres/repository.py +118 -1
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/storage/postgres/tables.py +37 -0
- docsmind-0.4.0/src/docsmind/agent/agent.py +432 -0
- docsmind-0.4.0/src/docsmind/agent/catalog.py +85 -0
- docsmind-0.4.0/src/docsmind/agent/harness/__init__.py +2 -0
- docsmind-0.4.0/src/docsmind/agent/harness/context.py +154 -0
- docsmind-0.4.0/src/docsmind/agent/harness/memory.py +119 -0
- docsmind-0.4.0/src/docsmind/agent/harness/summarizer.py +67 -0
- docsmind-0.4.0/src/docsmind/agent/harness/tokens.py +36 -0
- docsmind-0.4.0/src/docsmind/agent/loop.py +131 -0
- docsmind-0.4.0/src/docsmind/agent/orchestrator.py +41 -0
- docsmind-0.4.0/src/docsmind/agent/planner.py +38 -0
- docsmind-0.4.0/src/docsmind/agent/prompts.py +93 -0
- docsmind-0.4.0/src/docsmind/agent/sources.py +95 -0
- docsmind-0.4.0/src/docsmind/agent/subagents/specs.py +44 -0
- docsmind-0.4.0/src/docsmind/agent/tools/__init__.py +25 -0
- docsmind-0.4.0/src/docsmind/agent/tools/base.py +130 -0
- docsmind-0.4.0/src/docsmind/agent/tools/delegate.py +48 -0
- docsmind-0.4.0/src/docsmind/agent/tools/documents.py +109 -0
- docsmind-0.4.0/src/docsmind/agent/tools/search.py +126 -0
- docsmind-0.4.0/src/docsmind/agent/util.py +53 -0
- docsmind-0.4.0/src/docsmind/cli/chat.py +44 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/client.py +44 -5
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/config.py +20 -0
- docsmind-0.4.0/src/docsmind/domain/agent.py +147 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/citations.py +5 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/errors.py +18 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/ports.py +63 -6
- docsmind-0.4.0/src/docsmind/retrieval/keyword.py +48 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/server/app.py +2 -1
- docsmind-0.4.0/src/docsmind/server/routes/chat.py +161 -0
- docsmind-0.4.0/src/docsmind/server/ui/assets/index-DvL2_fGF.js +5423 -0
- docsmind-0.4.0/src/docsmind/server/ui/assets/index-ae6vf384.css +1 -0
- docsmind-0.4.0/src/docsmind/server/ui/favicon.svg +1 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/server/ui/index.html +3 -3
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/LICENSE +177 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/83pv-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Add-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-0.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-1.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-3.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-4.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-5.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-6.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-0.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-1.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-3.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-4.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-5.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-0.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-1.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-3.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-4.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-5.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-6.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-0.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-1.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-V.bcmap +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-H.bcmap +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-H.bcmap +4 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GB-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Hankaku.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Hiragana.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Katakana.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/LICENSE +36 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/Roman.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-H.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/V.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/cmaps/WP-Symbol.bcmap +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/iccs/CGATS001Compat-v2-micro.icc +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/iccs/LICENSE +116 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_add.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_disclaimer.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_done.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_spinner.svg +30 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/altText_warning.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-check.svg +11 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-comment.svg +16 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-help.svg +26 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-insert.svg +10 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-key.svg +11 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-newparagraph.svg +11 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-noicon.svg +7 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-note.svg +42 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-paperclip.svg +6 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-paragraph.svg +16 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/annotation-pushpin.svg +7 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/checkmark.svg +5 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-actionsButton.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-closeButton.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-editButton.svg +8 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/comment-popup-editButton.svg +5 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeHighlight.svg +6 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeText.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorInk.svg +4 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/cursor-editorTextHighlight.svg +8 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-delete.svg +5 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-edit.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/findbarButton-next.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/findbarButton-previous.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/gv-toolbarButton-download.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/loading-icon.gif +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/loading.svg +1 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/messageBar_closingButton.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/messageBar_info.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/messageBar_warning.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_closeButton.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_selected.svg +7 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_viewArrow.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/pages_viewButton.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-documentProperties.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-firstPage.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-handTool.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-lastPage.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCcw.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCw.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollHorizontal.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollPage.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollVertical.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollWrapped.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-selectTool.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadEven.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadNone.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadOdd.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/signature-properties-row-check.svg +4 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-bookmark.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-currentOutlineItem.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-download.svg +4 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorFreeText.svg +5 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorHighlight.svg +6 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorInk.svg +4 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorSignature.svg +6 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorStamp.svg +8 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrow.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrowNova.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-openFile.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageDown.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageUp.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-presentationMode.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-print.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-search.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-secondaryToolbarToggle.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesError.svg +7 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesVerified.svg +7 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewAttachments.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewLayers.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewOutline.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewThumbnail.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewsManagerToggle.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomIn.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomOut.svg +3 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/treeitem-collapsed.svg +1 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/images/treeitem-expanded.svg +1 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ach/viewer.ftl +184 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/af/viewer.ftl +163 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/an/viewer.ftl +207 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ar/viewer.ftl +807 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ast/viewer.ftl +156 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/az/viewer.ftl +207 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/be/viewer.ftl +822 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bg/viewer.ftl +392 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bn/viewer.ftl +202 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bo/viewer.ftl +206 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bqi/viewer.ftl +307 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/br/viewer.ftl +299 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/brx/viewer.ftl +175 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/bs/viewer.ftl +560 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ca/viewer.ftl +563 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/cak/viewer.ftl +243 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ckb/viewer.ftl +198 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/cs/viewer.ftl +836 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/cy/viewer.ftl +864 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/da/viewer.ftl +711 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/de/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/dsb/viewer.ftl +836 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/el/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/en-CA/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/en-GB/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/en-US/viewer.ftl +873 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/eo/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-AR/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-CL/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-ES/viewer.ftl +783 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/es-MX/viewer.ftl +720 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/et/viewer.ftl +221 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/eu/viewer.ftl +812 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fa/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ff/viewer.ftl +206 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fi/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fr/viewer.ftl +804 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fur/viewer.ftl +620 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/fy-NL/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ga-IE/viewer.ftl +164 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gd/viewer.ftl +245 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gl/viewer.ftl +563 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gn/viewer.ftl +788 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/gu-IN/viewer.ftl +206 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/he/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hi-IN/viewer.ftl +205 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hr/viewer.ftl +695 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hsb/viewer.ftl +836 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hu/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hy-AM/viewer.ftl +618 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/hye/viewer.ftl +221 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ia/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/id/viewer.ftl +561 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/is/viewer.ftl +544 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/it/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ja/viewer.ftl +752 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ka/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/kab/viewer.ftl +599 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/kk/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/km/viewer.ftl +222 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/kn/viewer.ftl +166 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ko/viewer.ftl +752 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lij/viewer.ftl +206 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lo/viewer.ftl +245 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/locale.json +1 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lt/viewer.ftl +221 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ltg/viewer.ftl +205 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/lv/viewer.ftl +269 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/meh/viewer.ftl +48 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/mk/viewer.ftl +719 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ml/viewer.ftl +489 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/mr/viewer.ftl +194 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ms/viewer.ftl +206 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/my/viewer.ftl +157 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/nb-NO/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ne-NP/viewer.ftl +185 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/nl/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/nn-NO/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/oc/viewer.ftl +372 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pa-IN/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pl/viewer.ftl +821 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pt-BR/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/pt-PT/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/rm/viewer.ftl +611 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ro/viewer.ftl +822 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ru/viewer.ftl +822 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sat/viewer.ftl +257 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sc/viewer.ftl +442 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/scn/viewer.ftl +32 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sco/viewer.ftl +217 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/si/viewer.ftl +214 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sk/viewer.ftl +836 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/skr/viewer.ftl +437 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sl/viewer.ftl +836 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/son/viewer.ftl +157 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sq/viewer.ftl +707 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sr/viewer.ftl +822 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/sv-SE/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/szl/viewer.ftl +207 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ta/viewer.ftl +182 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/te/viewer.ftl +196 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/tg/viewer.ftl +713 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/th/viewer.ftl +687 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/tl/viewer.ftl +207 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/tr/viewer.ftl +808 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/trs/viewer.ftl +160 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/uk/viewer.ftl +699 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/ur/viewer.ftl +206 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/uz/viewer.ftl +140 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/vi/viewer.ftl +752 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/wo/viewer.ftl +93 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/xh/viewer.ftl +163 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/zh-CN/viewer.ftl +733 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/locale/zh-TW/viewer.ftl +752 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitDingbats.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixed.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBold.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedItalic.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerif.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBold.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifItalic.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSymbol.pfb +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_FOXIT +27 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_LIBERATION +363 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Bold.ttf +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Italic.ttf +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Regular.ttf +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/viewer.css +8265 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/viewer.html +1236 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/viewer.mjs +26437 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_JBIG2 +196 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_OPENJPEG +39 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_JBIG2 +13 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_OPENJPEG +22 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_QCMS +19 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_QCMS +21 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/jbig2.wasm +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/jbig2_nowasm_fallback.js +15 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg.wasm +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +17 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/qcms_bg.wasm +0 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.js +16 -0
- docsmind-0.4.0/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.wasm +0 -0
- docsmind-0.3.0/src/docsmind/cli/chat.py +0 -26
- docsmind-0.3.0/src/docsmind/server/__init__.py +0 -0
- docsmind-0.3.0/src/docsmind/server/routes/__init__.py +0 -0
- docsmind-0.3.0/src/docsmind/server/ui/assets/index-DSQOFo_H.css +0 -1
- docsmind-0.3.0/src/docsmind/server/ui/assets/index-QBP12Bcv.js +0 -5385
- docsmind-0.3.0/src/docsmind/server/ui/favicon.svg +0 -1
- docsmind-0.3.0/src/docsmind/server/ui/icons.svg +0 -24
- {docsmind-0.3.0 → docsmind-0.4.0}/.gitignore +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/blobs/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/blobs/filesystem.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/embeddings/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/adapters/llm → docsmind-0.4.0/src/docsmind/adapters/storage}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/adapters/storage → docsmind-0.4.0/src/docsmind/adapters/storage/postgres}/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/adapters/storage/postgres/engine.py +0 -0
- {docsmind-0.3.0/src/docsmind/adapters/storage/postgres → docsmind-0.4.0/src/docsmind/adapters/tracing}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/adapters/tracing → docsmind-0.4.0/src/docsmind/adapters/vision}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/adapters/vision → docsmind-0.4.0/src/docsmind/agent}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/agent → docsmind-0.4.0/src/docsmind/agent/subagents}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/agent/subagents → docsmind-0.4.0/src/docsmind/agent/subagents/change_analysis}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/agent/subagents/change_analysis → docsmind-0.4.0/src/docsmind/cli}/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/app.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/db.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/diff.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/doctor.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/ingest.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/inspect.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/cli/serve.py +0 -0
- {docsmind-0.3.0/src/docsmind/agent/tools → docsmind-0.4.0/src/docsmind/domain}/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/changes.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/documents.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/domain/tables.py +0 -0
- {docsmind-0.3.0/src/docsmind/cli → docsmind-0.4.0/src/docsmind/ingestion}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/domain → docsmind-0.4.0/src/docsmind/ingestion/chunking}/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/chunking/page.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/chunking/structural.py +0 -0
- {docsmind-0.3.0/src/docsmind/ingestion → docsmind-0.4.0/src/docsmind/ingestion/enrichment}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/ingestion/chunking → docsmind-0.4.0/src/docsmind/ingestion/parsers}/__init__.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/parsers/pdf.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/ingestion/pipeline.py +0 -0
- {docsmind-0.3.0 → docsmind-0.4.0}/src/docsmind/py.typed +0 -0
- {docsmind-0.3.0/src/docsmind/ingestion/enrichment → docsmind-0.4.0/src/docsmind/retrieval}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/ingestion/parsers → docsmind-0.4.0/src/docsmind/server}/__init__.py +0 -0
- {docsmind-0.3.0/src/docsmind/retrieval → docsmind-0.4.0/src/docsmind/server/routes}/__init__.py +0 -0
- {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
|
+
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
|
|
72
|
-
|
|
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
|
-
|
|
|
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.
|
|
134
|
-
|
|
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.
|
|
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
|
-
|
|
194
|
-
|
|
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
|
|
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
|
|
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/ #
|
|
259
|
-
├── agent/ # the Mind
|
|
260
|
-
└── server/ # FastAPI app + routes backing frontend/ (documents
|
|
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
|
|
15
|
-
|
|
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
|
-
|
|
|
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.
|
|
77
|
-
|
|
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.
|
|
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
|
-
|
|
137
|
-
|
|
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
|
|
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
|
|
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/ #
|
|
202
|
-
├── agent/ # the Mind
|
|
203
|
-
└── server/ # FastAPI app + routes backing frontend/ (documents
|
|
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.
|
|
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)
|