feat: wire conversation compaction into the live chat loop#2822
Merged
Conversation
The DM chat/system conversation loop calls WP_Agent_Conversation_Loop::run() but never passed compaction_policy or a summarizer, so the substrate's maybe_compact() always no-opped and the agents-api compaction primitive was only reachable from DailyMemoryTask. This left live chat transcripts to grow unbounded. Add a per-agent ConversationCompactionPolicyResolver (mirroring the existing Tool/Memory/Action/Directive policy resolvers — reads agent_config.conversation_compaction_policy and the supports_conversation_compaction capability flag) and a DM-owned ConversationCompactionSummarizer that drives a single tool-free model turn through datamachine_run_conversation() on the agent's system-mode maintenance model. Both options are attached to run() only when the agent opts in, and substrate compaction lifecycle events are forwarded through the existing on_event sink for observability. Compaction is disabled by default: agents that have not opted in resolve to enabled=false, keeping the loop a strict no-op and fully backward-compatible. Closes #2821
Contributor
Homeboy Results —
|
…ns under the Playground SAPI The STDOUT/STDERR constants are only defined under the CLI SAPI. The host smoke harness runs tests in WP Codebox Playground (web SAPI), where the trailing fwrite(STDOUT, ...) success message threw 'Undefined constant STDOUT' AFTER all 14 assertions passed — green on CLI, red in CI. Opening the php://stdout/php://stderr streams works under both SAPIs.
…ption detail Resolves 5 WordPress-ruleset phpcs findings the CI lint surfaced in ConversationCompactionSummarizer.php: four Squiz.Strings.DoubleQuoteUsage on prompt strings with no interpolation, and one EscapeOutput on the error detail concatenated into the RuntimeException message.
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
Wires the agents-api conversation-compaction primitive into Data Machine's live chat/system conversation loop. DM already called
WP_Agent_Conversation_Loop::run()but never passed thecompaction_policyorsummarizeroptions the loop'smaybe_compact()requires, so compaction was a permanent no-op for live chat — the primitive was only reachable fromDailyMemoryTask. Live chat transcripts therefore grew unbounded.Closes #2821
What this wires
agent_config. Newinc/Engine/AI/Compaction/ConversationCompactionPolicyResolver.phpfollows the exact pattern of the existing sibling resolvers (ToolPolicyResolver,MemoryPolicyResolver,ActionPolicyResolver,DirectivePolicyResolver): readsagent_config.conversation_compaction_policyand thesupports_conversation_compactioncapability flag, normalizes through the substrate contract (WP_Agent_Conversation_Compaction::normalize_policy()), and exposes adatamachine_resolved_conversation_compaction_policyfilter. Opt-in is satisfied by an explicit policyenabled=trueor by the capability flag; an explicitenabled=falsealways wins.ConversationCompactionSummarizersupplies the(array $messages, array $context): stringcallable the contract-only substrate asks for. It drives a single, tool-free model turn through DM's owndatamachine_run_conversation()entry point (mirroring howDailyMemoryTaskdrives a summarization model call through DM's conversation primitive instead of rolling a new dispatch path). The summarization call passes no compaction policy of its own, so it cannot recurse.system-mode model — the same cheap maintenance model class DM already uses for memory compaction — honoring an explicit policysummary_provider/summary_modelpin and adatamachine_conversation_compaction_summary_modelfilter.compaction_policy+summarizerare attached to the existingrun()options array only when the agent opted in.preserve_tool_boundariesstays on (substrate default).compaction_started/compaction_completed/compaction_failed/compaction_overflow_archivedlifecycle events are forwarded through the existingon_eventsink (datamachine_emit_loop_event) in the result-events loop.Backward compatibility
Disabled by default. Agents that have not configured compaction resolve to
enabled=false; the loop then omits both options entirely, and the substratemaybe_compact()requires both an array policy and a callable summarizer to do anything — so the non-compacting path is byte-identical to before for every existing agent. Verified by smoke test (no agent / no config / explicit-disable all resolve toenabled=false).Design notes / forks taken
RequestBuilderwiring, and matches theDailyMemoryTaskprecedent of using DM's own primitives to feed the substrate. Recursion is impossible because the summarization call passes no compaction policy.*PolicyResolverclasses.Layer purity
No agents-api changes. The substrate primitive is complete and correct; DM consumes it from the consumer layer only.
Tests
tests/conversation-compaction-policy-resolver-smoke.php— 14 assertions covering: default-disabled no-op (no agent / no config), explicit-policy opt-in, capability-flag opt-in, explicit-disable override, summarizer model pin/filter/fallback, and the factory returning a callable. PASS.tests/ai-loop-event-sink-smoke.php,tests/agent-conversation-result-smoke.php,tests/directive-policy-resolver-smoke.php— PASS (no regressions).vendor/wordpress/agents-api/tests/conversation-compaction-smoke.php— 50 assertions PASS (substrate sanity).php -lclean on all changed files;phpcsexit 0 on all changed/added files.