feat(openclaw): answer without inference, opt-in - #24
Merged
Conversation
Adds compound inference: when a question matches one already answered, the stored reasoning is served and no model call is made. OpenClaw's before_agent_run can end a turn before any model input — the interception point folklore's own research concluded was missing in Claude Code, where the same behaviour needs a wire-compatible /v1/messages SSE proxy. New `folklore reuse lookup|record` (CLI + read-only IPC handler). It exists separately from `ask` because ask deliberately expands a resolved-query match into its answer DOCS and drops the node, which is right for retrieval and useless here: reuse needs the node, its distilled trace, and the query-to-query distance. recordResolvedQuery already accepted a trace and nothing ever passed one, which is why all 91 resolved-query nodes on a real graph were question-only pointers with nothing to serve. OFF by default, and the reason is the finding rather than caution. Measured against one stored trace: paraphrases of the same question land at 0.940 and 1.012, while 'what port is the relay on' — a different question about the same subject — lands at 1.074. The ranges overlap, so no threshold on this evidence separates them. The default (0.25) admits little more than a restatement: low recall, but it cannot answer the wrong question. Calibrating looser needs a labelled set, not a guess. Served answers disclose their provenance, age and sources. A user who cannot tell an answer was cached has no way to distrust it when it is wrong. Not wired: automatic capture from llm_output. Traces are recordable via the CLI today; writing model output to the graph automatically interacts with the privacy classifier and deserves its own pass.
Deploying folklore with
|
| Latest commit: |
99d457e
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://321b9fee.folklore-3pb.pages.dev |
| Branch Preview URL: | https://feat-openclaw-compound-infer.folklore-3pb.pages.dev |
Pre-existing work from the author's working tree, committed here because the OpenClaw compound-inference feature in this branch depends on it and could not build without it. Adds an optional distilled trace to a resolved-query node: recordResolvedQuery takes trace/resolvedAt, makeResolvedQueryNode carries the summary, and the public/private rule follows the trace — a trace-bearing node is shareable while a raw question-only pointer stays local. The embedded vector remains question-only so query-to-query retrieval stays the reuse signal. 7 tests, green.
Collaborator
Author
|
Added the trace plumbing this depends on as a separate commit (99d457e). CI failed because |
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.
Completes the third piece of the OpenClaw integration: when a question matches one already answered, the stored reasoning is served and no model call is made.
OpenClaw's
before_agent_runcan end a turn before any model input, with user-facing text. That is exactly the interception pointdocs/research/PEER-INFERENCE-STREAMING.mdconcluded was missing in Claude Code, where the same behaviour needs a wire-compatible/v1/messagesSSE proxy. Here it's a hook.What's new
folklore reuse lookup|record— CLI plus a read-only IPC handler. Separate fromaskon purpose:askexpands a resolved-query match into its answer docs and drops the node, which is right for retrieval and useless here. Reuse needs the node, its distilled trace, and the query-to-query distance that says how safely it can stand in for a fresh answer.recordResolvedQueryalready accepted atraceand nothing ever passed one — which is why all 91 resolved-query nodes on a real graph are question-only pointers with nothing to serve. The record path closes that.Why it ships off by default
This is a finding, not caution. Measured against one stored trace ("what transport does the folklore relay use"):
Paraphrases and adjacent-but-distinct questions overlap, so no threshold on this evidence separates them. The default (
0.25) therefore admits little more than a restatement: low recall, but it cannot answer the wrong question. Calibrating looser needs a labelled set, not a guess.FOLKLORE_REUSE_INFERENCE=1opts in;FOLKLORE_REUSE_MAX_DISTANCE/FOLKLORE_REUSE_MAX_AGE_DAYStune it.Age is stricter here than in retrieval (30d default): a stale document a human reads is evidence, a stale answer served as the answer is a wrong answer.
Served answers disclose provenance, age and sources. A user who cannot tell an answer was cached has no way to distrust it when it is wrong.
Verification
Plugin suite 34 tests (9 new, weighted towards the refusals: distant question, stale answer, empty trace, disabled). Core suites green including help coverage.
End-to-end against the live daemon and real graph:
Not in this branch
Automatic capture from
llm_output. Traces are recordable via the CLI today; writing model output into the graph automatically interacts with the privacy classifier and deserves its own pass rather than being tacked on here.