Conversation
…with flock Append-only JSONL store for conversation messages. Advisory fcntl.flock on write with warn-and-proceed on lock failure. load_session filters by session_id and returns chronological order. Corrupt lines skipped with warning. 6 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Builds a prompt-injectable context block from ConversationMessage history. Last 10 messages always verbatim; older messages summarized via ManagedClient (patrol lane) when total tokens exceed 60% of the 100k context budget. 14 tests cover all TDD cases including mock-verified LLM call path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t and burn-rate footer - New chat.py: chat_turn() sends questions to ManagedClient with session context, stores user+assistant messages in ConversationStore, includes finding summaries from findings.jsonl in system prompt, enforces max_tokens=2000 per turn, and returns a donut burn-rate footer - cli.py: register 'chat' click subcommand - llm/managed.py: add extra_headers param to __init__, add max_tokens param to chat() - llm_types.py: add max_tokens=None to LLMClient ABC (backward compatible) - 30 new tests covering all 7 TDD steps; full suite: 3689 passed, 0 regressions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lance-zero fallback Implements mallcop.notify.dispatch_notify: checks /v1/balance before summary generation, suppresses non-critical findings at zero balance, sends critical findings with summary=null when balance exhausted. All 6 TDD tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds mallcop/bridge.py with bridge_poll_loop — a daemon thread that polls GET /v1/bridge/poll every 3 seconds, runs local inference for each pending message (with findings context), and posts responses via POST /v1/bridge/respond. Exponential backoff (3→6→12→24→60s, max 60s) on errors; resets on success. Integrates --bridge flag into `mallcop watch`: when Pro config is present (service_token + inference_url), starts the bridge thread as a daemon so it exits automatically when the watch process exits. 25 unit tests covering poll loop, inference, backoff, shutdown, and CLI flag. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e round-trip tests (#4) Implements CampfireConversationAdapter in conversation.py — campfire-backed store with same append/load_session interface as ConversationStore. Maps ConversationMessage fields to campfire tags (session:, platform:, finding_ref:) and instance roles (user/mallcop). ContextWindowManager produces valid context from adapter output identically to ConversationStore output. 6 tests against real campfire (no mocks). Co-authored-by: Claude Sonnet 4.6 <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.
Summary
mallcop chatinteractive REPL that sends user questions to/v1/messageswith conversation contextchat_turn()insrc/mallcop/chat.py— handles session headers, finding summaries, context window trimming, burn-rate footerchatsubcommand intocli.pyviarun_chat_repl()ConversationStore(conversations.jsonl append-only JSONL),ContextWindowManager(token-budget aware history trimming with LLM summarization fallback)Design details
clihardcoded, sent asX-Mallcop-Surfaceheadermax_tokens=2000enforced per turn[1.2 donuts]based onusage.input_tokens + usage.output_tokens(1000 tokens/donut)findings.jsonlTest plan
tests/test_chat.pypassTestChatTurnSendsCorrectPayload— verifies model, system prompt, messagesTestChatTurnStoresMessages— verifies user + assistant persistence in conversations.jsonlTestSystemPromptFindingSummaries— verifies findings.jsonl injected into system promptTestContextWindowManagerInvoked— verifies history trimming and summary injectionTestManagedClientHeaders— verifies X-Mallcop-Session and X-Mallcop-Surface headersTestBurnRateFooter— verifies donut footer format and token calculationTestMaxTokensEnforced— verifies max_tokens=2000 sent on every turnTestChatCommandRegistered— verifieschatis registered in CLI🤖 Generated with Claude Code