feat: OCG-backed agent long-term memory#126
Open
NicholasDCole wants to merge 1 commit into
Open
Conversation
Port the agentspan "OCG-backed agent memory" feature to the Java SDK. - Agent gains semanticMemory / memorySummaryModel / feedbackSink params - AgentConfigSerializer emits longTermMemory + feedbackSink on the wire (camelCase, omitted when unset) so the server-side compiler activates retrieval + distill/save/feedback on the deployed path - OCGMemoryStore: synchronous MemoryStore HTTP adapter over the OCG BFF (search / add / delete / listAll + feedback-links mint), built on the JDK HttpClient with a pluggable Transport seam for tests - MemorySummary + FeedbackEvent + buildMemorySummarizer for parity - Unit tests (OcgMemoryStoreTest, SerializerTest additions) + Example118 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Ports the SDK side of the agentspan "OCG-backed agent memory" feature (agentspan-ai/agentspan#298) to the Java SDK. The server-side compiler that consumes the wire fields emitted here lives in conductor-oss/conductor (
agentspan-server:LongTermMemoryConfig.java,AgentConfig.longTermMemory/feedbackSink).What was ported
Agent params (
conductor-ai/.../Agent.java)semanticMemory(SemanticMemory)— the memory store handlememorySummaryModel(String)— optional model override for the distillerfeedbackSink(Consumer<FeedbackEvent>)— receives the good/bad capability links out-of-bandSerializer emission (
conductor-ai/.../internal/AgentConfigSerializer.java) — the most important piece; the server only activates the feature when this is emitted:longTermMemory:{ocgUrl, credential, agent, user, scope, maxResults, summaryModel}, camelCase, null-valued keys omitted.credentialis a server-resolvable secret NAME (defaultOCG_PUBLIC_KEY), never the raw client token.summaryModelfalls back to the agent's model. Emitted only when the store is anOCGMemoryStore.feedbackSink:{taskName: "<agent>_feedback_sink"}, emitted only when afeedbackSinkis set alongside OCG memory.OCGMemoryStore (
conductor-ai/.../model/OCGMemoryStore.java) — synchronousMemoryStoreHTTP adapter over the OCG BFF:search→POST /api/v1/memories/search;add→POST /api/v1/memories;delete→DELETE;listAll→GET;feedbackLinks(key)→POST /api/v1/memories/{key}/feedback-links. Auth viaAuthorization: Bearer <token>. Search folds the human good/bad signal (and bad-verdict reasons) into result content. Built on the JDKHttpClient(the convention already used byServerlessCodeExecutor/GPTAssistantAgent), with a pluggableTransportseam so tests can capture requests and serve canned responses — the Java equivalent of the Python tests'httpx.MockTransport.Supporting types (
conductor-ai/.../model/) —MemorySummary(structured summarizer output),FeedbackEvent(distilled summary + signed URLs), andOCGMemoryStore.buildMemorySummarizer(...)(recursion-safe internal summarizer sub-agent, built withoutsemanticMemory).Example —
Example118OcgMemory.java, mirroring Python's118_ocg_memory.py.Java-specific adaptations
_baseattribute; the Java serializer usesstore instanceof OCGMemoryStore, which is cleaner and typed.feedback_sink(a Python callable) maps toConsumer<FeedbackEvent>.MemorySummary(pydantic model) maps to a plain POJO used as the summarizer'soutputType.HttpClient+ Jackson (JsonMapper), nothttpx.SemanticMemorygained agetStore()accessor so the serializer can inspect the backing store.What was skipped, and why
Runtime pre/post-run wiring is not ported. The Java
AgentRuntime.run()has no client-side agent turn loop equivalent to Python'sruntime.py— it serializes the agent and delegates the entire run to the server (startAgent+ wait for result). There is no client-side point at which to inject retrieved memories into a copy of the instructions or to run a post-run summarizer/save. On the deployed path this is exactly what the emittedlongTermMemoryconfig drives server-side. Consequently the Pythonruntime.pysave/retrieval hook unit tests are not translated; the store, summary, and serializer tests are. Registering a<agent>_feedback_sinkworker for the compiled path is a natural follow-up (it belongs to that same runtime-wiring surface).Tests
./gradlew :conductor-ai:test— 286 tests, 0 failures, 0 errors, 10 skipped. New:OcgMemoryStoreTest(8) and 4 additions toSerializerTest(58 total).spotlessCheckpasses.🤖 Generated with Claude Code