docsmind 0.6.0__tar.gz → 0.7.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.6.0 → docsmind-0.7.0}/CHANGELOG.md +21 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/PKG-INFO +1 -1
- {docsmind-0.6.0 → docsmind-0.7.0}/pyproject.toml +1 -1
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/agent.py +5 -4
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/prompts.py +11 -3
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/subagents/specs.py +3 -2
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/__init__.py +5 -2
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/base.py +16 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/delegate.py +5 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/documents.py +14 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/search.py +24 -7
- docsmind-0.7.0/src/docsmind/agent/tools/web.py +273 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/config.py +7 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/keyword.py +3 -1
- docsmind-0.7.0/src/docsmind/server/ui/assets/index-B1Hm9KMP.css +1 -0
- docsmind-0.6.0/src/docsmind/server/ui/assets/index-CqXag2rP.js → docsmind-0.7.0/src/docsmind/server/ui/assets/index-CsNUfZkw.js +112 -112
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/index.html +2 -2
- docsmind-0.6.0/src/docsmind/server/ui/assets/index-QYKdGecG.css +0 -1
- {docsmind-0.6.0 → docsmind-0.7.0}/.gitignore +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/README.md +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/blobs/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/blobs/filesystem.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/embeddings/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/embeddings/openai_embeddings.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/llm/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/llm/anthropic_llm.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/llm/openai_llm.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/memory.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/agent_store.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/engine.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/repository.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/tables.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/tracing/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/vision/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/vision/captioners.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/catalog.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/context.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/memory.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/summarizer.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/tokens.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/loop.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/orchestrator.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/planner.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/sources.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/subagents/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/subagents/change_analysis/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/util.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/app.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/chat.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/db.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/diff.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/doctor.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/enrich.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/ingest.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/inspect.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/serve.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/client.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/agent.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/changes.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/citations.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/documents.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/errors.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/ports.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/tables.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/enrichment/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/enrichment/pricing.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/enrichment/service.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/chunking/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/chunking/page.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/chunking/structural.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/enrichment/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/parsers/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/parsers/pdf.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/pipeline.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/py.typed +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/fusion.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/hybrid.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/app.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/jobs.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/__init__.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/chat.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/documents.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/enrichment.py +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/favicon.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/LICENSE +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/83pv-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-0.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-1.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-3.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-4.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-5.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-6.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-0.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-1.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-3.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-4.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-5.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-0.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-1.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-3.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-4.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-5.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-6.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-0.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-1.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Hankaku.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Hiragana.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Katakana.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/LICENSE +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Roman.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-H.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/V.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/WP-Symbol.bcmap +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/iccs/CGATS001Compat-v2-micro.icc +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/iccs/LICENSE +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_add.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_disclaimer.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_done.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_spinner.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_warning.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-check.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-comment.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-help.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-insert.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-key.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-newparagraph.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-noicon.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-note.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-paperclip.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-paragraph.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-pushpin.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/checkmark.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-actionsButton.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-closeButton.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-editButton.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-popup-editButton.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeHighlight.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeText.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorInk.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorTextHighlight.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-delete.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-edit.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/findbarButton-next.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/findbarButton-previous.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/gv-toolbarButton-download.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/loading-icon.gif +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/loading.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/messageBar_closingButton.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/messageBar_info.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/messageBar_warning.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_closeButton.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_selected.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_viewArrow.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_viewButton.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-documentProperties.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-firstPage.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-handTool.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-lastPage.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCcw.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCw.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollHorizontal.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollPage.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollVertical.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollWrapped.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-selectTool.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadEven.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadNone.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadOdd.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/signature-properties-row-check.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-bookmark.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-currentOutlineItem.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-download.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorFreeText.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorHighlight.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorInk.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorSignature.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorStamp.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrow.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrowNova.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-openFile.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageDown.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageUp.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-presentationMode.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-print.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-search.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-secondaryToolbarToggle.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesError.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesVerified.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewAttachments.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewLayers.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewOutline.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewThumbnail.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewsManagerToggle.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomIn.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomOut.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/treeitem-collapsed.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/treeitem-expanded.svg +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ach/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/af/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/an/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ar/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ast/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/az/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/be/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bg/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bn/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bo/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bqi/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/br/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/brx/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bs/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ca/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/cak/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ckb/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/cs/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/cy/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/da/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/de/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/dsb/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/el/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/en-CA/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/en-GB/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/en-US/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/eo/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-AR/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-CL/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-ES/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-MX/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/et/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/eu/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fa/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ff/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fi/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fr/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fur/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fy-NL/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ga-IE/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gd/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gl/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gn/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gu-IN/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/he/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hi-IN/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hr/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hsb/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hu/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hy-AM/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hye/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ia/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/id/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/is/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/it/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ja/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ka/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/kab/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/kk/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/km/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/kn/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ko/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lij/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lo/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/locale.json +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lt/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ltg/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lv/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/meh/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/mk/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ml/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/mr/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ms/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/my/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/nb-NO/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ne-NP/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/nl/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/nn-NO/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/oc/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pa-IN/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pl/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pt-BR/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pt-PT/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/rm/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ro/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ru/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sat/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sc/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/scn/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sco/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/si/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sk/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/skr/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sl/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/son/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sq/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sr/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sv-SE/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/szl/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ta/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/te/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/tg/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/th/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/tl/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/tr/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/trs/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/uk/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ur/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/uz/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/vi/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/wo/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/xh/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/zh-CN/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/zh-TW/viewer.ftl +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitDingbats.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixed.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBold.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedItalic.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerif.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBold.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifItalic.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSymbol.pfb +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_FOXIT +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_LIBERATION +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Bold.ttf +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Italic.ttf +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Regular.ttf +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/viewer.css +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/viewer.html +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/viewer.mjs +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_JBIG2 +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_OPENJPEG +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_JBIG2 +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_OPENJPEG +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_QCMS +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_QCMS +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/jbig2.wasm +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/jbig2_nowasm_fallback.js +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg.wasm +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/qcms_bg.wasm +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.js +0 -0
- {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.wasm +0 -0
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.7.0] - 2026-11-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Change Analyzer can now look for a published changelog online when the documents themselves
|
|
10
|
+
contain none, using two new subagent-only tools:
|
|
11
|
+
- `web_search`: searches the web via Tavily, optionally limited to given domains. Only offered
|
|
12
|
+
when `DOCSMIND_WEB_SEARCH_API_KEY` is set.
|
|
13
|
+
- `fetch_url`: reads a public web page as text. Hardened for model-supplied URLs (http(s) on
|
|
14
|
+
ports 80/443 only, no credentials, no private/loopback addresses on any redirect hop,
|
|
15
|
+
bounded size and time).
|
|
16
|
+
- Config: `web_search_api_key`, `web_timeout_s`, `web_fetch_max_bytes` (documented in
|
|
17
|
+
`.env.example`).
|
|
18
|
+
- Implementation brief for the Change Analyzer (`docs/`) and unit tests for the web tools.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Change Analyzer prompt and tool list updated to use the web tools as a fallback, preferring
|
|
23
|
+
the publisher's own domain.
|
|
24
|
+
- Rebuilt the bundled frontend UI assets.
|
|
25
|
+
|
|
5
26
|
## [0.6.0] - 2026-11-10
|
|
6
27
|
|
|
7
28
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: docsmind
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.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
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "docsmind"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.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"
|
|
@@ -75,6 +75,7 @@ class DocsmindAgent:
|
|
|
75
75
|
self._memory = memory
|
|
76
76
|
self._query_embedder = None
|
|
77
77
|
self.tools = tools or build_registry()
|
|
78
|
+
self.main_tools = self.tools.for_executor()
|
|
78
79
|
self.builder = ContextBuilder(config)
|
|
79
80
|
self._background: set[asyncio.Task] = set()
|
|
80
81
|
|
|
@@ -187,7 +188,7 @@ class DocsmindAgent:
|
|
|
187
188
|
"with citations that are verified against what it actually read."
|
|
188
189
|
),
|
|
189
190
|
"model": self.config.llm_model,
|
|
190
|
-
"tools": self.
|
|
191
|
+
"tools": self.main_tools.info(),
|
|
191
192
|
},
|
|
192
193
|
"stages": [
|
|
193
194
|
{
|
|
@@ -403,11 +404,11 @@ class DocsmindAgent:
|
|
|
403
404
|
delegate=self._make_delegate(llm, catalog, sources, usage, emit),
|
|
404
405
|
embedder=self.query_embedder,
|
|
405
406
|
)
|
|
406
|
-
bundle = self.builder.executor(state, self.
|
|
407
|
+
bundle = self.builder.executor(state, self.main_tools.specs())
|
|
407
408
|
result = await run_tool_loop(
|
|
408
409
|
llm=llm,
|
|
409
410
|
bundle=bundle,
|
|
410
|
-
registry=self.
|
|
411
|
+
registry=self.main_tools,
|
|
411
412
|
ctx=tool_ctx,
|
|
412
413
|
usage=usage,
|
|
413
414
|
emit=emit,
|
|
@@ -482,7 +483,7 @@ class DocsmindAgent:
|
|
|
482
483
|
delegate=None, # no recursion
|
|
483
484
|
embedder=self.query_embedder,
|
|
484
485
|
)
|
|
485
|
-
registry = self.tools.subset(spec.tools)
|
|
486
|
+
registry = self.tools.subset(spec.tools).configured(self.config)
|
|
486
487
|
bundle = self.builder.subagent(spec, task, sub_catalog, registry.specs())
|
|
487
488
|
|
|
488
489
|
emit(AgentEvent(type="subagent_start", data={"id": sub_id, "name": spec.name, "task": task}))
|
|
@@ -22,12 +22,12 @@ You are the Mind, the assistant inside docsmind. You answer questions about the
|
|
|
22
22
|
|
|
23
23
|
How to work
|
|
24
24
|
- Documents are referred to by handle (D1, D2, ...); the register is listed below.
|
|
25
|
-
- search: ranked
|
|
25
|
+
- search: ranked hybrid search (keywords plus meaning); start here for most questions. Write the query in natural language, e.g. the question or a descriptive phrase.
|
|
26
26
|
- grep: exact phrase or identifier (a clause number, a defined term). Use when search blurs exact wording.
|
|
27
27
|
- read_pages: read the actual text of pages. Read around a promising hit before relying on a snippet.
|
|
28
28
|
- get_outline: the document's table of contents with page numbers.
|
|
29
29
|
- list_documents: only if you need page/word counts again.
|
|
30
|
-
- delegate: hand a self-contained task to a subagent with a fresh context when the work is large or independent (comparing several documents or versions, reading many sections). It returns a short summary that keeps the same [S#] handles. Several delegate calls in one step run in parallel.
|
|
30
|
+
- delegate: hand a self-contained task to a subagent with a fresh context when the work is large or independent (comparing several documents or versions, reading many sections). It returns a short summary that keeps the same [S#] handles; web pages it used appear as markdown links, which you keep as given. Several delegate calls in one step run in parallel.
|
|
31
31
|
- Make independent tool calls in the same step. Prefer a few precise calls over many vague ones. Do not narrate before calling tools.
|
|
32
32
|
- If the question is conversational or not about the documents, answer directly without tools.
|
|
33
33
|
|
|
@@ -73,7 +73,15 @@ Role: researcher. Gather the evidence needed for a focused question. Search, gre
|
|
|
73
73
|
CHANGE_ANALYZER = f"""\
|
|
74
74
|
{SUBAGENT_COMMON}
|
|
75
75
|
|
|
76
|
-
Role: change analyzer. Compare two versions of the same document (or two related documents) and report what was added, removed or reworded, section by section, and why it matters.
|
|
76
|
+
Role: change analyzer. Compare two versions of the same document (or two related documents) and report what was added, removed or reworded, section by section, and why it matters.
|
|
77
|
+
|
|
78
|
+
Step 1, always first: look for a changelog before comparing any text.
|
|
79
|
+
- In the documents: search for "revision history", "summary of changes", "changelog", "what's new", "errata", "change log"; check get_outline for such a section (usually at the front or in an appendix), and read it with read_pages.
|
|
80
|
+
- Online, only if web_search / fetch_url are among your tools and the documents give no usable changelog: search for the publisher's changes page for these exact versions (prefer the publisher's own domain), then fetch_url the best result. Follow a link from that page at most once or twice.
|
|
81
|
+
- Treat a changelog as a map of where to look, not as proof. Confirm every change you report against the document text on both sides.
|
|
82
|
+
- Cite changelog entries that come from a document with [S#]. For a web page, name it as a markdown link [title](url); never give a web page an [S#] handle. If you found no changelog, say so in one line and continue.
|
|
83
|
+
|
|
84
|
+
Step 2: use get_outline on both to align sections, then read_pages on matching sections. Cite both sides of every difference. If the versions are identical in the area asked about, say so."""
|
|
77
85
|
|
|
78
86
|
SUMMARIZER = """\
|
|
79
87
|
You maintain the running summary of a conversation between a user and a document assistant. Merge the new turns into the existing summary.
|
|
@@ -35,10 +35,11 @@ CHANGE_ANALYZER = SubagentSpec(
|
|
|
35
35
|
role="Version comparison",
|
|
36
36
|
description=(
|
|
37
37
|
"Compares two versions of a document (or two related documents) and reports what was "
|
|
38
|
-
"added, removed or reworded, section by section, with citations on both sides."
|
|
38
|
+
"added, removed or reworded, section by section, with citations on both sides. It first "
|
|
39
|
+
"looks for a changelog in the documents and, when web access is configured, online."
|
|
39
40
|
),
|
|
40
41
|
prompt=prompts.CHANGE_ANALYZER,
|
|
41
|
-
tools=("search", "grep", "read_pages", "get_outline"),
|
|
42
|
+
tools=("search", "grep", "read_pages", "get_outline", "web_search", "fetch_url"),
|
|
42
43
|
)
|
|
43
44
|
|
|
44
45
|
SUBAGENTS: dict[str, SubagentSpec] = {s.name: s for s in (RESEARCHER, CHANGE_ANALYZER)}
|
|
@@ -6,13 +6,14 @@ from docsmind.agent.tools.base import Tool, ToolContext, ToolOutput, ToolRegistr
|
|
|
6
6
|
from docsmind.agent.tools.delegate import DelegateTool
|
|
7
7
|
from docsmind.agent.tools.documents import ListDocumentsTool, OutlineTool, ReadPagesTool
|
|
8
8
|
from docsmind.agent.tools.search import GrepTool, SearchTool
|
|
9
|
+
from docsmind.agent.tools.web import FetchUrlTool, WebSearchTool
|
|
9
10
|
|
|
10
11
|
__all__ = ["Tool", "ToolContext", "ToolOutput", "ToolRegistry", "build_registry"]
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def build_registry() -> ToolRegistry:
|
|
14
|
-
"""Every tool
|
|
15
|
-
`agent/subagents/specs.py`) and never `delegate`."""
|
|
15
|
+
"""Every tool. The main executor gets all but the `subagent_only` ones (the web tools);
|
|
16
|
+
subagents get the subset their spec lists (see `agent/subagents/specs.py`) and never `delegate`."""
|
|
16
17
|
return ToolRegistry(
|
|
17
18
|
[
|
|
18
19
|
SearchTool(),
|
|
@@ -21,5 +22,7 @@ def build_registry() -> ToolRegistry:
|
|
|
21
22
|
OutlineTool(),
|
|
22
23
|
ListDocumentsTool(),
|
|
23
24
|
DelegateTool(),
|
|
25
|
+
WebSearchTool(),
|
|
26
|
+
FetchUrlTool(),
|
|
24
27
|
]
|
|
25
28
|
)
|
|
@@ -51,8 +51,15 @@ class Tool:
|
|
|
51
51
|
name: ClassVar[str]
|
|
52
52
|
description: ClassVar[str] # written for the model
|
|
53
53
|
summary: ClassVar[str] = "" # one plain sentence for people (shown in the UI)
|
|
54
|
+
how_it_works: ClassVar[tuple[str, ...]] = () # quick-reference steps for people (UI only, never sent to the model)
|
|
55
|
+
subagent_only: ClassVar[bool] = False # True: never offered to the main executor, only to subagents that list it
|
|
54
56
|
Args: ClassVar[type[BaseModel]]
|
|
55
57
|
|
|
58
|
+
@classmethod
|
|
59
|
+
def available(cls, config: DocsmindConfig) -> bool:
|
|
60
|
+
"""False when the tool needs configuration that is missing (it is then not offered to the model)."""
|
|
61
|
+
return True
|
|
62
|
+
|
|
56
63
|
async def run(self, args: Any, ctx: ToolContext) -> ToolOutput: # pragma: no cover
|
|
57
64
|
raise NotImplementedError
|
|
58
65
|
|
|
@@ -103,6 +110,7 @@ class ToolRegistry:
|
|
|
103
110
|
{
|
|
104
111
|
"name": n,
|
|
105
112
|
"description": tool.summary,
|
|
113
|
+
"how_it_works": list(tool.how_it_works),
|
|
106
114
|
"instructions": spec.description,
|
|
107
115
|
"parameters": spec.parameters,
|
|
108
116
|
}
|
|
@@ -112,6 +120,14 @@ class ToolRegistry:
|
|
|
112
120
|
def subset(self, names: tuple[str, ...] | list[str]) -> ToolRegistry:
|
|
113
121
|
return ToolRegistry([t for n, t in self._tools.items() if n in names])
|
|
114
122
|
|
|
123
|
+
def for_executor(self) -> ToolRegistry:
|
|
124
|
+
"""The tools the main executor may call: everything except subagent-only tools."""
|
|
125
|
+
return ToolRegistry([t for t in self._tools.values() if not t.subagent_only])
|
|
126
|
+
|
|
127
|
+
def configured(self, config: DocsmindConfig) -> ToolRegistry:
|
|
128
|
+
"""Drops tools whose configuration is missing, so the model never sees a tool it cannot use."""
|
|
129
|
+
return ToolRegistry([t for t in self._tools.values() if t.available(config)])
|
|
130
|
+
|
|
115
131
|
def specs(self) -> list[ToolSpec]:
|
|
116
132
|
return [t.spec() for t in self._tools.values()]
|
|
117
133
|
|
|
@@ -37,6 +37,11 @@ class DelegateTool(Tool):
|
|
|
37
37
|
"short report with [S#] citations. Use for large or independent work; several delegate calls in "
|
|
38
38
|
"one step run in parallel.\nSubagents:\n" + _ROSTER
|
|
39
39
|
)
|
|
40
|
+
how_it_works = (
|
|
41
|
+
"The Mind picks a subagent and writes a self-contained task; the subagent never sees the conversation.",
|
|
42
|
+
"The subagent works in a fresh context with its own tools (search, grep, read_pages, get_outline) and cannot delegate further.",
|
|
43
|
+
"Only its short report comes back, with the same [S#] source handles. Several delegations in one step run in parallel.",
|
|
44
|
+
)
|
|
40
45
|
Args = DelegateArgs
|
|
41
46
|
|
|
42
47
|
async def run(self, args: DelegateArgs, ctx: ToolContext) -> ToolOutput:
|
|
@@ -20,6 +20,10 @@ class ListDocumentsTool(Tool):
|
|
|
20
20
|
name = "list_documents"
|
|
21
21
|
summary = "Lists the documents in the register with their collection, version and size."
|
|
22
22
|
description = "List the documents in the register with their handles, collection, version label, page and word counts."
|
|
23
|
+
how_it_works = (
|
|
24
|
+
"Reads the catalog built for this conversation (no database query).",
|
|
25
|
+
"Returns each document's handle (D1, D2, ...), title, collection, version, and page and word counts.",
|
|
26
|
+
)
|
|
23
27
|
Args = ListDocumentsArgs
|
|
24
28
|
|
|
25
29
|
async def run(self, args: ListDocumentsArgs, ctx: ToolContext) -> ToolOutput:
|
|
@@ -37,6 +41,11 @@ class OutlineTool(Tool):
|
|
|
37
41
|
"The document's table of contents (from the PDF's own bookmarks) with page numbers. "
|
|
38
42
|
"Use it to find which pages cover a topic, then read_pages."
|
|
39
43
|
)
|
|
44
|
+
how_it_works = (
|
|
45
|
+
"Loads the document's sections, taken from the PDF's own bookmarks.",
|
|
46
|
+
"Lists them indented by depth, each with its page number (up to 200 entries).",
|
|
47
|
+
"If the PDF has no bookmarks, it says so and the model falls back to search.",
|
|
48
|
+
)
|
|
40
49
|
Args = OutlineArgs
|
|
41
50
|
|
|
42
51
|
async def run(self, args: OutlineArgs, ctx: ToolContext) -> ToolOutput:
|
|
@@ -74,6 +83,11 @@ class ReadPagesTool(Tool):
|
|
|
74
83
|
"Read the full text of one or a few consecutive pages of a document. Each chunk comes with a "
|
|
75
84
|
"source handle to cite."
|
|
76
85
|
)
|
|
86
|
+
how_it_works = (
|
|
87
|
+
"Checks the page range: at most 4 pages per call, and within the document.",
|
|
88
|
+
"Loads every text chunk that overlaps those pages.",
|
|
89
|
+
"Returns the full text, each chunk with a source handle to cite.",
|
|
90
|
+
)
|
|
77
91
|
Args = ReadPagesArgs
|
|
78
92
|
|
|
79
93
|
async def run(self, args: ReadPagesArgs, ctx: ToolContext) -> ToolOutput:
|
|
@@ -24,7 +24,14 @@ def format_passage(doc: CatalogDoc, handle: str, page_start: int | None, page_en
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class SearchArgs(BaseModel):
|
|
27
|
-
query: str = Field(
|
|
27
|
+
query: str = Field(
|
|
28
|
+
min_length=2,
|
|
29
|
+
max_length=1000,
|
|
30
|
+
description=(
|
|
31
|
+
"Natural-language query: a question or a descriptive phrase. "
|
|
32
|
+
"Use grep instead for exact wording, identifiers or clause numbers."
|
|
33
|
+
),
|
|
34
|
+
)
|
|
28
35
|
documents: list[str] | None = Field(default=None, description=_DOCUMENTS_HELP)
|
|
29
36
|
limit: int = Field(default=6, ge=1, le=10, description="Maximum passages to return.")
|
|
30
37
|
|
|
@@ -32,14 +39,19 @@ class SearchArgs(BaseModel):
|
|
|
32
39
|
class SearchTool(Tool):
|
|
33
40
|
name = "search"
|
|
34
41
|
summary = (
|
|
35
|
-
"
|
|
36
|
-
"Returns the best matching passages to cite."
|
|
42
|
+
"Hybrid search over the documents: stemmed keyword matching plus semantic (embedding) similarity, "
|
|
43
|
+
"fused by reciprocal rank fusion. Returns the best matching passages to cite."
|
|
37
44
|
)
|
|
38
45
|
description = (
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
46
|
+
"Find passages by topic or meaning in the documents' text and figure captions. Takes a "
|
|
47
|
+
"natural-language query; matches keywords and paraphrases, ranked best first. Returns passages "
|
|
48
|
+
"with a source handle like [S1] to cite; use read_pages to see the surrounding text. "
|
|
49
|
+
)
|
|
50
|
+
how_it_works = (
|
|
51
|
+
"Keyword search: the query is stemmed and matched with Postgres full-text search.",
|
|
52
|
+
"Semantic search: the query is embedded and the nearest passages are found by cosine similarity (skipped if the documents are not embedded).",
|
|
53
|
+
"Reciprocal rank fusion: each list scores a passage 1 / (60 + rank) and the scores are added, so passages ranked well by both come first.",
|
|
54
|
+
"The top passages come back with source handles to cite.",
|
|
43
55
|
)
|
|
44
56
|
Args = SearchArgs
|
|
45
57
|
|
|
@@ -102,6 +114,11 @@ class GrepTool(Tool):
|
|
|
102
114
|
"Find an exact phrase, clause number or identifier (case-insensitive, literal match, no stemming). "
|
|
103
115
|
"Returns the pages containing it, each with a source handle to cite."
|
|
104
116
|
)
|
|
117
|
+
how_it_works = (
|
|
118
|
+
"Escapes the text and runs a case-insensitive substring match (ILIKE) over every page of the chosen documents.",
|
|
119
|
+
"No stemming and no ranking: only literal matches, in document and page order.",
|
|
120
|
+
"Returns a snippet around the first hit on each page, with the number of occurrences and a source handle.",
|
|
121
|
+
)
|
|
105
122
|
Args = GrepArgs
|
|
106
123
|
|
|
107
124
|
async def run(self, args: GrepArgs, ctx: ToolContext) -> ToolOutput:
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""Web tools, for the Change Analyzer only: find and read a published changelog.
|
|
2
|
+
|
|
3
|
+
Everything a web page says is untrusted DATA, like document text. The fetcher
|
|
4
|
+
is hardened because the URL comes from a model: http(s) on ports 80/443 only,
|
|
5
|
+
no credentials in the URL, no private/loopback/link-local addresses (checked on
|
|
6
|
+
every redirect hop), bounded size and time.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import ipaddress
|
|
13
|
+
import re
|
|
14
|
+
import socket
|
|
15
|
+
from html.parser import HTMLParser
|
|
16
|
+
from urllib.parse import urljoin, urlsplit
|
|
17
|
+
|
|
18
|
+
import httpx
|
|
19
|
+
from pydantic import BaseModel, Field
|
|
20
|
+
|
|
21
|
+
from docsmind.agent.tools.base import Tool, ToolContext, ToolOutput
|
|
22
|
+
from docsmind.config import DocsmindConfig
|
|
23
|
+
from docsmind.domain.errors import ToolInputError
|
|
24
|
+
|
|
25
|
+
TAVILY_URL = "https://api.tavily.com/search"
|
|
26
|
+
PAGE_CHARS = 10_000 # per fetch_url call; below agent_tool_result_max_chars so it is never cut again
|
|
27
|
+
MAX_REDIRECTS = 4
|
|
28
|
+
ALLOWED_PORTS = {None, 80, 443}
|
|
29
|
+
TEXT_TYPES = ("text/html", "application/xhtml", "text/plain", "text/markdown")
|
|
30
|
+
USER_AGENT = "docsmind/1.0 (document assistant; reads public pages)"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# -- web_search ------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class WebSearchArgs(BaseModel):
|
|
37
|
+
query: str = Field(min_length=3, max_length=400, description="What to look for on the web.")
|
|
38
|
+
domains: list[str] | None = Field(
|
|
39
|
+
default=None,
|
|
40
|
+
max_length=5,
|
|
41
|
+
description="Only search these sites, e.g. the publisher's domain. Omit to search the whole web.",
|
|
42
|
+
)
|
|
43
|
+
limit: int = Field(default=5, ge=1, le=8, description="Maximum results to return.")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class WebSearchTool(Tool):
|
|
47
|
+
name = "web_search"
|
|
48
|
+
subagent_only = True
|
|
49
|
+
summary = (
|
|
50
|
+
"Searches the public web, mainly to find a published changelog or release notes for a document. "
|
|
51
|
+
"Needs a Tavily API key (DOCSMIND_WEB_SEARCH_API_KEY)."
|
|
52
|
+
)
|
|
53
|
+
description = (
|
|
54
|
+
"Search the public web. Returns the title, URL and an excerpt of each result. Use it to find "
|
|
55
|
+
"an official changelog, revision history or release notes for a document; prefer the "
|
|
56
|
+
"publisher's own site. Read a result in full with fetch_url."
|
|
57
|
+
)
|
|
58
|
+
how_it_works = (
|
|
59
|
+
"Sends the query (optionally limited to given domains) to the Tavily search API.",
|
|
60
|
+
"Returns each result's title, URL and excerpt. The model reads promising pages with fetch_url.",
|
|
61
|
+
"Only offered when DOCSMIND_WEB_SEARCH_API_KEY is set.",
|
|
62
|
+
)
|
|
63
|
+
Args = WebSearchArgs
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def available(cls, config: DocsmindConfig) -> bool:
|
|
67
|
+
return bool(config.web_search_api_key)
|
|
68
|
+
|
|
69
|
+
async def run(self, args: WebSearchArgs, ctx: ToolContext) -> ToolOutput:
|
|
70
|
+
key = ctx.config.web_search_api_key
|
|
71
|
+
if not key:
|
|
72
|
+
raise ToolInputError("Web search is not configured. Work from the documents only.")
|
|
73
|
+
payload: dict = {
|
|
74
|
+
"query": args.query,
|
|
75
|
+
"max_results": args.limit,
|
|
76
|
+
"search_depth": "basic",
|
|
77
|
+
"include_answer": False,
|
|
78
|
+
}
|
|
79
|
+
if args.domains:
|
|
80
|
+
payload["include_domains"] = args.domains
|
|
81
|
+
try:
|
|
82
|
+
async with httpx.AsyncClient(timeout=ctx.config.web_timeout_s) as client:
|
|
83
|
+
response = await client.post(TAVILY_URL, json=payload, headers={"Authorization": f"Bearer {key}"})
|
|
84
|
+
except httpx.HTTPError as exc:
|
|
85
|
+
raise ToolInputError("Web search is unreachable right now. Work from the documents only.") from exc
|
|
86
|
+
if response.status_code in (401, 403):
|
|
87
|
+
raise ToolInputError("Web search rejected its API key. Work from the documents only.")
|
|
88
|
+
if response.status_code >= 400:
|
|
89
|
+
raise ToolInputError(f"Web search failed (HTTP {response.status_code}). Try different words or skip it.")
|
|
90
|
+
|
|
91
|
+
results = response.json().get("results") or []
|
|
92
|
+
if not results:
|
|
93
|
+
return ToolOutput(
|
|
94
|
+
f"No web results for '{args.query}'. Try other words or a different site.", summary="no results"
|
|
95
|
+
)
|
|
96
|
+
lines = []
|
|
97
|
+
for i, result in enumerate(results[: args.limit], start=1):
|
|
98
|
+
excerpt = re.sub(r"\s+", " ", result.get("content") or "").strip()[:500]
|
|
99
|
+
lines.append(f"{i}. {result.get('title') or '(untitled)'}\n {result.get('url')}\n {excerpt}")
|
|
100
|
+
return ToolOutput("\n\n".join(lines), summary=f"{len(lines)} results")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# -- fetch_url -------------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class FetchUrlArgs(BaseModel):
|
|
107
|
+
url: str = Field(min_length=8, max_length=2000, description="Full http(s) URL of a public web page.")
|
|
108
|
+
offset: int = Field(default=0, ge=0, description="Character to start from, to continue a long page.")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class FetchUrlTool(Tool):
|
|
112
|
+
name = "fetch_url"
|
|
113
|
+
subagent_only = True
|
|
114
|
+
summary = "Reads the text of one public web page, with its links, for example a changelog or release notes."
|
|
115
|
+
description = (
|
|
116
|
+
"Fetch a public web page (HTML or plain text; not PDFs) and return its text, with link targets "
|
|
117
|
+
"shown as 'text (url)'. Long pages come in parts: pass the offset given at the end to continue. "
|
|
118
|
+
"Use it on a changelog, revision history or release-notes page."
|
|
119
|
+
)
|
|
120
|
+
how_it_works = (
|
|
121
|
+
"Accepts only public http(s) URLs: private and local addresses are refused, also after redirects.",
|
|
122
|
+
"Downloads the page (size and time limited) and converts the HTML to plain text, keeping link URLs.",
|
|
123
|
+
"Returns the text in parts of about 10,000 characters; the model asks for the next part with an offset.",
|
|
124
|
+
)
|
|
125
|
+
Args = FetchUrlArgs
|
|
126
|
+
|
|
127
|
+
async def run(self, args: FetchUrlArgs, ctx: ToolContext) -> ToolOutput:
|
|
128
|
+
final_url, content_type, body = await _fetch(args.url, ctx.config)
|
|
129
|
+
if "html" in content_type or "xml" in content_type:
|
|
130
|
+
title, text = _html_to_text(body, final_url)
|
|
131
|
+
else:
|
|
132
|
+
title, text = "", body.strip()
|
|
133
|
+
if not text:
|
|
134
|
+
return ToolOutput(f"{final_url} has no readable text.", summary="no text")
|
|
135
|
+
|
|
136
|
+
total = len(text)
|
|
137
|
+
if args.offset >= total:
|
|
138
|
+
raise ToolInputError(f"offset is past the end of the page ({total} characters).")
|
|
139
|
+
end = min(total, args.offset + PAGE_CHARS)
|
|
140
|
+
header = f"Web page: {final_url}" + (f"\nTitle: {title}" if title else "")
|
|
141
|
+
footer = (
|
|
142
|
+
f"\n[Showing characters {args.offset}-{end} of {total}. Call again with offset={end} for more.]"
|
|
143
|
+
if end < total
|
|
144
|
+
else ""
|
|
145
|
+
)
|
|
146
|
+
host = urlsplit(final_url).hostname or final_url
|
|
147
|
+
return ToolOutput(f"{header}\n\n{text[args.offset:end]}{footer}", summary=f"{host} ({total} chars)")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
async def _assert_public(host: str) -> None:
|
|
151
|
+
try:
|
|
152
|
+
infos = await asyncio.get_running_loop().getaddrinfo(host, None, type=socket.SOCK_STREAM)
|
|
153
|
+
except socket.gaierror as exc:
|
|
154
|
+
raise ToolInputError(f"Cannot resolve {host}.") from exc
|
|
155
|
+
for info in infos:
|
|
156
|
+
ip = ipaddress.ip_address(info[4][0].split("%")[0])
|
|
157
|
+
if ip.version == 6 and ip.ipv4_mapped is not None:
|
|
158
|
+
ip = ip.ipv4_mapped
|
|
159
|
+
if not ip.is_global:
|
|
160
|
+
raise ToolInputError("That address is on a private or local network and cannot be fetched.")
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _check_url(url: str) -> str:
|
|
164
|
+
parts = urlsplit(url.strip())
|
|
165
|
+
if parts.scheme not in ("http", "https") or not parts.hostname:
|
|
166
|
+
raise ToolInputError("Only full http(s) URLs can be fetched.")
|
|
167
|
+
if parts.username or parts.password:
|
|
168
|
+
raise ToolInputError("URLs with credentials are not allowed.")
|
|
169
|
+
try:
|
|
170
|
+
port = parts.port
|
|
171
|
+
except ValueError as exc:
|
|
172
|
+
raise ToolInputError("The URL has an invalid port.") from exc
|
|
173
|
+
if port not in ALLOWED_PORTS:
|
|
174
|
+
raise ToolInputError("Only the standard web ports (80, 443) are allowed.")
|
|
175
|
+
return parts.geturl()
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
async def _fetch(url: str, config: DocsmindConfig) -> tuple[str, str, str]:
|
|
179
|
+
"""-> (final url, content type, decoded body). Redirects are followed by hand so every hop is checked."""
|
|
180
|
+
url = _check_url(url)
|
|
181
|
+
headers = {"User-Agent": USER_AGENT, "Accept": "text/html,text/plain;q=0.9,*/*;q=0.1"}
|
|
182
|
+
async with httpx.AsyncClient(timeout=config.web_timeout_s, follow_redirects=False, headers=headers) as client:
|
|
183
|
+
for _ in range(MAX_REDIRECTS + 1):
|
|
184
|
+
await _assert_public(urlsplit(url).hostname or "")
|
|
185
|
+
try:
|
|
186
|
+
async with client.stream("GET", url) as response:
|
|
187
|
+
if response.is_redirect:
|
|
188
|
+
location = response.headers.get("location")
|
|
189
|
+
if not location:
|
|
190
|
+
raise ToolInputError("The server redirected without saying where.")
|
|
191
|
+
url = _check_url(urljoin(url, location))
|
|
192
|
+
continue
|
|
193
|
+
if response.status_code >= 400:
|
|
194
|
+
raise ToolInputError(f"The server answered HTTP {response.status_code} for {url}.")
|
|
195
|
+
content_type = response.headers.get("content-type", "").split(";")[0].strip().lower()
|
|
196
|
+
if content_type and not content_type.startswith(TEXT_TYPES):
|
|
197
|
+
raise ToolInputError(
|
|
198
|
+
f"{url} is {content_type}, which cannot be read here. Only HTML or plain text pages work."
|
|
199
|
+
)
|
|
200
|
+
data = bytearray()
|
|
201
|
+
async for chunk in response.aiter_bytes():
|
|
202
|
+
data += chunk
|
|
203
|
+
if len(data) > config.web_fetch_max_bytes:
|
|
204
|
+
break
|
|
205
|
+
encoding = response.encoding or "utf-8"
|
|
206
|
+
try:
|
|
207
|
+
return url, content_type or "text/html", bytes(data).decode(encoding, errors="replace")
|
|
208
|
+
except LookupError:
|
|
209
|
+
return url, content_type or "text/html", bytes(data).decode("utf-8", errors="replace")
|
|
210
|
+
except httpx.HTTPError as exc:
|
|
211
|
+
raise ToolInputError(f"Could not fetch {url}: {type(exc).__name__}.") from exc
|
|
212
|
+
raise ToolInputError("Too many redirects.")
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
_BLOCK_TAGS = {
|
|
216
|
+
"p", "div", "br", "li", "tr", "section", "article", "header", "footer", "blockquote", "pre",
|
|
217
|
+
"ul", "ol", "table", "h1", "h2", "h3", "h4", "h5", "h6", "dt", "dd", "hr",
|
|
218
|
+
} # fmt: skip
|
|
219
|
+
_SKIP_TAGS = {"script", "style", "noscript", "svg", "template"}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class _TextExtractor(HTMLParser):
|
|
223
|
+
"""Visible text, one block per line, with links written as 'text (url)'."""
|
|
224
|
+
|
|
225
|
+
def __init__(self, base_url: str) -> None:
|
|
226
|
+
super().__init__(convert_charrefs=True)
|
|
227
|
+
self.base_url = base_url
|
|
228
|
+
self.title = ""
|
|
229
|
+
self.parts: list[str] = []
|
|
230
|
+
self._skip = 0
|
|
231
|
+
self._in_title = False
|
|
232
|
+
self._links: list[str | None] = []
|
|
233
|
+
|
|
234
|
+
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
|
|
235
|
+
if tag in _SKIP_TAGS:
|
|
236
|
+
self._skip += 1
|
|
237
|
+
elif tag == "title":
|
|
238
|
+
self._in_title = True
|
|
239
|
+
elif tag == "a":
|
|
240
|
+
href = dict(attrs).get("href") or ""
|
|
241
|
+
target = urljoin(self.base_url, href) if href and not href.startswith(("#", "javascript:", "mailto:")) else None
|
|
242
|
+
self._links.append(target if target and target.startswith(("http://", "https://")) else None)
|
|
243
|
+
if tag in _BLOCK_TAGS:
|
|
244
|
+
self.parts.append("\n")
|
|
245
|
+
|
|
246
|
+
def handle_endtag(self, tag: str) -> None:
|
|
247
|
+
if tag in _SKIP_TAGS and self._skip:
|
|
248
|
+
self._skip -= 1
|
|
249
|
+
elif tag == "title":
|
|
250
|
+
self._in_title = False
|
|
251
|
+
elif tag == "a" and self._links:
|
|
252
|
+
target = self._links.pop()
|
|
253
|
+
if target:
|
|
254
|
+
self.parts.append(f" ({target})")
|
|
255
|
+
if tag in _BLOCK_TAGS:
|
|
256
|
+
self.parts.append("\n")
|
|
257
|
+
|
|
258
|
+
def handle_data(self, data: str) -> None:
|
|
259
|
+
if self._in_title:
|
|
260
|
+
self.title += data
|
|
261
|
+
elif not self._skip:
|
|
262
|
+
self.parts.append(data)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def _html_to_text(html: str, base_url: str) -> tuple[str, str]:
|
|
266
|
+
parser = _TextExtractor(base_url)
|
|
267
|
+
parser.feed(html)
|
|
268
|
+
parser.close()
|
|
269
|
+
text = "".join(parser.parts)
|
|
270
|
+
text = re.sub(r"[ \t\r\f\v]+", " ", text)
|
|
271
|
+
text = re.sub(r" ?\n ?", "\n", text)
|
|
272
|
+
text = re.sub(r"\n{2,}", "\n", text).strip()
|
|
273
|
+
return re.sub(r"\s+", " ", parser.title).strip(), text
|
|
@@ -62,6 +62,13 @@ class DocsmindConfig(BaseSettings):
|
|
|
62
62
|
agent_recent_turns: int = 4 # user/assistant pairs always kept verbatim
|
|
63
63
|
agent_memory_enabled: bool = True
|
|
64
64
|
|
|
65
|
+
# --- web access (Change Analyzer only) ---
|
|
66
|
+
# Tavily API key (https://tavily.com). Unset = the `web_search` tool is not offered; `fetch_url`
|
|
67
|
+
# (read one public web page) needs no key and stays available.
|
|
68
|
+
web_search_api_key: str | None = None
|
|
69
|
+
web_timeout_s: float = 15.0 # per web request
|
|
70
|
+
web_fetch_max_bytes: int = 2_000_000 # page bytes read before giving up
|
|
71
|
+
|
|
65
72
|
# --- ingestion ---
|
|
66
73
|
chunk_size_tokens: int = 700
|
|
67
74
|
chunk_overlap_tokens: int = 100
|
|
@@ -5,7 +5,9 @@ from __future__ import annotations
|
|
|
5
5
|
import re
|
|
6
6
|
|
|
7
7
|
_TOKEN_RE = re.compile(r"[^\W_]+", re.UNICODE)
|
|
8
|
-
|
|
8
|
+
# Safety bound only (keeps the tsquery a sane size for pathological input);
|
|
9
|
+
# normal questions never get near it, and the vector side embeds the full text.
|
|
10
|
+
MAX_QUERY_TERMS = 64
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
def query_terms(text: str) -> list[str]:
|