Skip to content

feat: wire conversation compaction into the live chat loop#2822

Merged
chubes4 merged 4 commits into
mainfrom
wire-chat-compaction
Jun 30, 2026
Merged

feat: wire conversation compaction into the live chat loop#2822
chubes4 merged 4 commits into
mainfrom
wire-chat-compaction

Conversation

@chubes4

@chubes4 chubes4 commented Jun 30, 2026

Copy link
Copy Markdown
Member

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 the compaction_policy or summarizer options the loop's maybe_compact() requires, so compaction was a permanent no-op for live chat — the primitive was only reachable from DailyMemoryTask. Live chat transcripts therefore grew unbounded.

Closes #2821

What this wires

  • Policy resolution from agent_config. New inc/Engine/AI/Compaction/ConversationCompactionPolicyResolver.php follows the exact pattern of the existing sibling resolvers (ToolPolicyResolver, MemoryPolicyResolver, ActionPolicyResolver, DirectivePolicyResolver): reads agent_config.conversation_compaction_policy and the supports_conversation_compaction capability flag, normalizes through the substrate contract (WP_Agent_Conversation_Compaction::normalize_policy()), and exposes a datamachine_resolved_conversation_compaction_policy filter. Opt-in is satisfied by an explicit policy enabled=true or by the capability flag; an explicit enabled=false always wins.
  • DM-owned summarizer. New ConversationCompactionSummarizer supplies the (array $messages, array $context): string callable the contract-only substrate asks for. It drives a single, tool-free model turn through DM's own datamachine_run_conversation() entry point (mirroring how DailyMemoryTask drives 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.
  • Summarizer model selection. Resolves the acting agent's system-mode model — the same cheap maintenance model class DM already uses for memory compaction — honoring an explicit policy summary_provider/summary_model pin and a datamachine_conversation_compaction_summary_model filter.
  • Wiring. compaction_policy + summarizer are attached to the existing run() options array only when the agent opted in. preserve_tool_boundaries stays on (substrate default).
  • Observability. Substrate compaction_started / compaction_completed / compaction_failed / compaction_overflow_archived lifecycle events are forwarded through the existing on_event sink (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 substrate maybe_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 to enabled=false).

Design notes / forks taken

  • Summarizer drives the full DM conversation primitive (single tool-free turn) rather than a bespoke one-shot dispatch. This reuses DM's established model-call mechanism (auth, request assembly, model resolution) instead of duplicating RequestBuilder wiring, and matches the DailyMemoryTask precedent of using DM's own primitives to feed the substrate. Recursion is impossible because the summarization call passes no compaction policy.
  • No new abstraction beyond the policy resolver + summarizer factory, per scope. The resolver is a direct sibling of the four existing *PolicyResolver classes.

Layer purity

No agents-api changes. The substrate primitive is complete and correct; DM consumes it from the consumer layer only.

Tests

  • New 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.phpPASS (no regressions).
  • Bundled vendor/wordpress/agents-api/tests/conversation-compaction-smoke.php — 50 assertions PASS (substrate sanity).
  • php -l clean on all changed files; phpcs exit 0 on all changed/added files.

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
@homeboy-ci

homeboy-ci Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Homeboy Results — data-machine

Lint

lint — passed

ℹ️ Full options: homeboy docs commands/lint
Deep dive: homeboy lint data-machine --changed-since e5becf8

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-lint-quality-Linux-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-lint-quality-Linux-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine/actions/runs/28448258017

Test

test — passed

ℹ️ Auto-fix lint issues: homeboy refactor data-machine --from lint --write
ℹ️ Collect coverage: homeboy test data-machine --coverage
ℹ️ Pass args to test runner: homeboy test -- [args]
ℹ️ Full options: homeboy docs commands/test
Deep dive: homeboy test data-machine --changed-since e5becf8

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-test-quality-Linux-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-test-quality-Linux-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine/actions/runs/28448258017

Audit

audit — passed

  • audit — 13 finding(s)
  • Total: 13 finding(s)

Deep dive: homeboy audit data-machine --changed-since e5becf8

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-audit-quality-Linux-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-audit-quality-Linux-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine/actions/runs/28447982977
Tooling versions
  • Homeboy CLI: homeboy 0.271.0+2380b123a86e+892a02fb
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: 9a4b5f39
  • Action: unknown@unknown

homeboy-ci Bot added 3 commits June 30, 2026 13:23
…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.
@chubes4 chubes4 merged commit c40dbd1 into main Jun 30, 2026
4 of 5 checks passed
@chubes4 chubes4 deleted the wire-chat-compaction branch June 30, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chat conversation loop never consumes the agents-api compaction primitive (unbounded context growth)

1 participant