feat: multi-source docs plugin with Odoo integration best practices#162
Open
clemenshelm wants to merge 22 commits into
Open
feat: multi-source docs plugin with Odoo integration best practices#162clemenshelm wants to merge 22 commits into
clemenshelm wants to merge 22 commits into
Conversation
added 22 commits
April 19, 2026 08:58
…ds compat Extends PluginConfig to support a sources[] array (DocSource with id/label/path) alongside the legacy docsPath string. The register() method normalizes legacy format to multi-source at runtime, so existing single-source configs continue to work unchanged. Updates openclaw.plugin.json schema to allow either format, with agents.sources[] for per-agent source scoping (used in Tasks 2-3).
docs_list now returns [{source, label, docs:[...]}] grouped by source,
filtered to only the sources the agent is configured to access.
Renames listMdxFiles → listDocs in preparation for Task 9 (.md support).
Switch from the old flat `docsPath` format to the new `sources` array
format so pinchy-docs can serve docs from multiple named sources. Personal
agents now get `sources: ["pinchy"]` rather than an empty `{}` object.
docs_list now mentions best practices, domain-specific how-tos, and guides users to docs_read. docs_read label drops "Pinchy" prefix to reflect its generic multi-source role.
…le category Creates integration-docs/odoo/accounting/ with VAT booking, invoice types, and fiscal positions guides. Wires pinchy-docs sources to Odoo agents based on which MODEL_CATEGORIES have models in their permissions — agents with account.* models get odoo-accounting, sales.* get odoo-sales, etc. Moves the pinchy-docs block to after Odoo agent configs are built so the wiring logic has access to odooAgentConfigs. Mounts integration-docs into the pinchy container as read-only in docker-compose.yml.
listDocs() now picks up both .md and .mdx files so integration docs created as plain Markdown (e.g. Odoo accounting guides from Task 6) are visible to agents via docs_list and readable via docs_read.
…th docs_list/docs_read references Remove ## Available Data (field lists) and ## Typical Analysis Patterns (query recipes) from all 16 Odoo templates and replace with ODOO_DOCS_INSTRUCTION directing agents to use docs_list/docs_read for domain knowledge and odoo_schema for field discovery. Update existing tests that checked for model names in defaultAgentsMd to check odooConfig.requiredModels instead (equal-strength: requiredModels is the actual access-control source of truth, not the free-text prompt).
…tests - pinchy-docs: invert undefined-sources semantics to fail-closed (undefined = no access) - pinchy-docs: update all existing tests to use explicit sources arrays - pinchy-docs: add test verifying undefined sources returns empty list - openclaw-config: only push pinchy doc source when personal agents exist - openclaw-config: add comment on ODOO_DOC_SOURCES placeholder directories - openclaw-config.test.ts: merge duplicate Odoo doc source tests into one with enabled check
- Move ODOO_DOC_SOURCES constant to module level (was recreated on every config regen) - Fix typo pincySource → pinchySource in openclaw-config.test.ts - Remove leftover '// add this line' comment in pinchy-docs index.test.ts - Update test mocks to use mockInnerJoin() for new .where() query chain from main merge - Add docs section explaining on-demand domain knowledge in connect-odoo.mdx
Extends MODEL_CATEGORIES with 8 new categories (manufacturing, project, expenses, recruitment, pos, marketing, fleet, website) so all Odoo template agents get correct doc sources and sync-UI entries. Extends ODOO_DOC_SOURCES with 11 new entries (crm, purchase, hr + the 8 new categories) at module level for testability. Adds 21 integration-docs files covering all functional areas: accounting (payment reconciliation), sales (lifecycle, subscriptions, pricing), inventory (stock levels, transfers), CRM (pipeline, activities), purchase (lifecycle, supplier pricing), HR (leave, attendance/contracts), manufacturing (production orders, BOM), project (tasks/timesheets), expenses (expense reports), recruitment (applicant pipeline), POS (sessions/reconciliation), marketing (campaigns), fleet (vehicles/services), website (e-commerce orders). Each doc focuses on business concepts, state machines, and cross-model patterns — not field lists (agents use odoo_schema for those). Generic for Odoo 16–19; only subscriptions.md notes v16/v17+ difference. Adds 3 tests for new doc sources (manufacturing, fleet, website).
Wires EMAIL_DOC_SOURCE (/integration-docs/email) automatically for any agent with email provider permissions (google/microsoft/imap), and FILES_DOC_SOURCE (/integration-docs/files) for any agent with pinchy_ls or pinchy_read in their allowedTools. Adds 5 integration-docs files covering the key agent gotchas: - email/gmail-folders-search.md — label names, search syntax - email/composing-and-sending.md — draft vs send, threading, single recipient - email/limitations.md — no CC/BCC/attachments, credential expiry, rate limits - files/navigating-files.md — non-recursive ls, absolute paths, workflow - files/reading-files.md — supported formats, PDF truncation, scanned PDFs Adds 4 tests verifying the doc source wiring for both integrations.
The Odoo schema sync now probes ~76 curated models (up from ~28 after adding manufacturing/project/expenses/recruitment/pos/marketing/fleet/ website categories). The two retry tests use a 500ms backoff per failed model, so with concurrency=5 they each need ~7-8s end-to-end. Vitest's default 5000ms timeout was tripping them. Setting the per-test timeout to 20s gives plenty of headroom and also prevents the cascade where a timed-out retry test leaks pending fields() calls into the next test, breaking the concurrency assertion (10 instead of <=5).
…okup After merging main with the Web Search integration (PR #127), regenerateOpenClawConfig() now calls db.select().from(integrationConnections).where(eq(...)) to find Brave Search credentials. The seven inline mock setups for the new doc-source tests built their own from() mock without .where(), breaking only when the merged code path runs. Adds where: vi.fn().mockResolvedValue([]) to each, matching the shared mockFrom() helper that already supports both .innerJoin().where() and direct .where() chains.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pinchy-docsplugin from a single docs source to a multi-source architecture — each agent sees only the documentation relevant to its integrations (Pinchy docs for Smithers, Odoo accounting docs for Finance Controller, etc.)docs_list(grouped by source, source-scoped per agent) anddocs_read(acceptssourceId/pathformat with per-agent access control) — agents can now look up integration best practices on demand instead of relying on hardcoded knowledgevat-booking.md,invoice-types.md,fiscal-positions.md) and wires them automatically to agents based on their accessible module categories (accounting/sales/inventory)## Available Datafield lists and## Typical Analysis Patternsquery recipes (~386 lines), replaces with adocs_list/docs_read/odoo_schemainstructionArchitecture
{ sources: [{ id, label, path }], agents: { [agentId]: { sources: [] } } }— fully backwards-compatible with legacydocsPathformatopenclaw-config.tsbuilds the config dynamically: personal agents → pinchy source, Odoo agents → Odoo doc sources matched by model category fromMODEL_CATEGORIESundefinedsources = no access (not all access)docs_list(~1k tokens) →docs_read(one doc at a time) — keeps context usage low since tool results stay permanently in OpenClaw session history./integration-docs:/integration-docs:romounted into Pinchy containerTest Plan
packages/plugins/pinchy-docs)packages/web)docs_listreturns sources grouped by source, filtered to agent's allowed sourcesdocs_readacceptssourceId/path.mdformat, enforces cross-source access controlresolveSafe()(existing protection preserved)account.movepermission →odoo-accountingsource in configmail.messagepermission only → no pinchy-docs config emittedundefinedagent sources → no access (fail-closed).mdand.mdxfiles both discovered bydocs_list