Repository navigation
Conversation
limin1975
force-pushed
the
main
branch
3 times, most recently
from
November 8, 2026 08:06
b69a64e to
afbd65a
Compare
The agent could only reach its own long-term memory (search_answer / search_guide / search_code / search_in_memory). Documents the user explicitly uploaded into the shared knowledge base were unreachable. Add a dedicated knowledge_search tool that queries the KnowledgeStore where Manual=true, and keep the two surfaces disjoint: - knowledge_search.go: new tool over KnowledgeStore.SearchDocuments, scoped to Manual=true via the existing KnowledgeFilter. - search.go: excludeManualKnowledgeDocs drops Manual=true documents from the agent's own memory search, so user-curated documents are reachable only through knowledge_search. - registry.go: tool name, type mapping, definition, and message type. The search_* definitions now state that they cover only agent-authored content and point at knowledge_search for user-uploaded documents. - tools.go: assemble the tool for both the agent-orchestrated and the direct (useAgents=false) assistant paths. - assistant.tmpl / templates.go / assistant.go: render the tool name and state the mandatory routing rule (FIRST retrieval action for a task that depends on user-provided documents). The knowledge package no longer imports graph/subscriptions: the publisher surface it needs is declared locally as knowledge.KnowledgePublisher, which breaks the tools -> knowledge -> subscriptions -> converter -> tester -> tools import cycle. router.go adapts the subscriptions publisher to it. Verified end to end: the agent calls knowledge_search and returns the document content from the knowledge base.
The agent picks its own tool on the first assistant iteration, so the
retrieval path a task takes depends on the model's judgement. To make
that routing reproducible — for verification, and for any task that must
start from a specific tool — allow an extra llms.CallOption to reach the
provider.
- performer.go: callWithRetries takes extraOpts and forwards them via
CallWithExtraOptions instead of CallWithTools. On the assistant path,
when PENTAGI_ASSISTANT_FORCE_KBSEARCH=1, the first iteration requests
tool_choice = {"type":"function","function":{"name":"knowledge_search"}}.
The object form is required: OpenAI-compatible endpoints reject a bare
tool name.
- docker-compose.yml: pass the flag through. It is empty by default, so
the production behaviour is unchanged unless it is explicitly set.
- performer_test.go: cover both states — the flag forces the named
tool_choice, and without it no tool_choice is set.
Used to verify the knowledge_search path deterministically; the flag is
off by default.
Run the embedding model locally instead of reaching a cloud endpoint. - Dockerfile.ollama: build Ollama from alpine 3.23 with the community apk mirror, since the official ollama/ollama image layer kept getting reset mid-pull. - docker-compose.yml: add the ollama-server service on the pentagi network, reached by the service name, with models kept in the pentagi-ollama volume.
The custom binary and its image build context are ~100MB each and are rebuilt locally, so they must not be staged. Also ignore the local provider config, the installer-generated example link stubs, and the local verification scripts and their logs.
Routing every assistant call through CallWithExtraOptions broke providers whose two entry points behave differently: the mock provider resolves its canned responses in CallWithTools, so the tool-free-agent and optional refiner tests failed and the package panicked. Only take the CallWithExtraOptions path when there are options to pass. With the flag off the assistant call is byte-for-byte the old CallWithTools call again.
Author
|
Hi maintainers, thanks for taking a look at this PR! Since it's opened from a fork, the CI workflows are currently awaiting approval (2 workflows). Could you please approve the workflows so they can run, and review the changes when you get a chance? Quick recap: this adds a knowledge_search tool over the shared/manual knowledge base, plus an env-gated forced tool_choice path that is disabled by default (production behavior unchanged). All 6 commits are signed and show as Verified. Happy to address any feedback — thanks! |
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
Adds a
knowledge_searchtool that lets the assistant query the shared/manualknowledge base (documents flagged
Manual=true) via natural language. Thiscomplements the per-agent RAG retriever (which now excludes
Manualdocs), sooperators can publish curated knowledge that is only reachable through an
explicit tool call instead of being silently mixed into every agent turn.
Changes
pkg/tools/knowledge_search.go: new tool callingKnowledgeStore.SearchDocuments, scoped toManual=true.pkg/tools/search.go: excludeManual=truedocs from the generic retriever.pkg/tools/registry.go+tools.go: register the tool (only wheneveryService=true).pkg/templates/...+providers/assistant.go: forced-retrieval rule + tool-name rendering.pkg/providers/performer.go:callWithRetriesacceptsextraOpts ...llms.CallOption; keepsCallWithToolson the default path and switches toCallWithExtraOptionsonly when extra options (e.g. a forced namedtool_choice) are present.pkg/database/knowledge/knowledge.go: defineKnowledgePublisherlocally to break thetools → knowledge → subscriptions → toolsimport cycle.PENTAGI_ASSISTANT_FORCE_KBSEARCH(default off) forces the first assistant call to a namedtool_choicefor deterministic retrieval; verified disabled in production.docker-compose.yml+Dockerfile.ollama+.gitignore: optional local Ollama service for RAG embeddings.push_to_fork.sh: one-shot helper to push to the fork over SSH port 443.Why
Shared knowledge (deployment briefs, access keys, runbooks) should be explicitly
retrievable and auditable, not injected into every agent context.
Testing
knowledge_searchand returned the correct curated document (relevance 0.8655).pkg/tools/...andpkg/providers/...tests pass (two pre-existing upstream README/Graphiti baseline failures are unrelated).CGO_ENABLED=0; API login returns 200.Notes
The forced-
tool_choicepath is env-gated and disabled by default; production behavior is unchanged unless explicitly enabled.