Commit Graph

23 Commits

Author SHA1 Message Date
wassname b03651855d fix: revert to XML dcp-id tags and add strip-before-inject to prevent echo loop
HTML comment format offered no benefit over XML tags since LLMs see raw
text, not rendered output. Revert to original <dcp-id>m001</dcp-id> and
<dcp-block-id>bN</dcp-block-id> format which is more token-efficient.

Add strip-before-inject in injectMessageIds: each context event strips any
existing dcp-id tags before appending the fresh one. For clean messages
this is idempotent (no cache bust). For model-echoed tags it removes the
duplicate on the next context event, breaking the accumulation loop that
reinforced echoing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 13:59:46 +08:00
wassname b83b3f8c53 fix: use HTML comment format for dcp-id tags to prevent model echo
XML-style <dcp-id>m001</dcp-id> tags get echoed by models because they
look like semantic content. HTML comments <!-- dcp-id: m001 --> are
invisible in rendered markdown and models are trained to skip them.
2026-04-16 15:39:24 +08:00
wassname b18c536b11 fix: add 'do not narrate' instruction to all nudge prompts
Agents were generating visible messages like 'Almost there, will check again on next trigger' when nudged but deciding not to compress. This is because the nudges tell the agent to evaluate and act, but when it decides not to act, it narrates that decision instead of continuing silently.
2026-04-16 15:35:19 +08:00
wassname 3cc0e9b612 docs: clarify 'DCP summary blocks' not message blocks, note message counting reset 2026-04-16 13:29:09 +08:00
wassname ad9c550b41 feat: auto-compaction when DCP blocks exceed threshold
- Add session_compact handler: deactivate all DCP blocks when pi compacts
- Add context handler threshold: trigger ctx.compact() when DCP summary
  blocks occupy >= configurable fraction of context tokens (default 50%)
- Add config.compact.autoCompactThreshold (0 = disabled, 0.5 = default)
- Blocks are deactivated immediately on trigger to prevent re-triggering
- Includes earlier fix: gap calculation scoped to requested range,
  clearer error text for overlap messages
2026-04-16 13:23:28 +08:00
wassname b825dbcf77 fix: gap calculation scoped to requested range, clearer error text 2026-04-16 13:14:49 +08:00
wassname 779e5cc240 fix: prefix overlap error with [compress] for tool identification 2026-04-16 13:10:33 +08:00
wassname 3281b2f9bd fix: match overlap error to actual tool parameter schema 2026-04-16 13:09:53 +08:00
wassname 49f62ac2d0 feat: clearer overlap error with compress() syntax for valid ranges 2026-04-16 13:09:01 +08:00
wassname 32e9d67fa9 feat: report valid compressible gap ranges on overlap error
When a compress call overlaps existing blocks, the error message now
includes the exact mNNN..mNNN ranges that are available for compression
(before, after, and between existing blocks). This lets the model
immediately retry with valid ranges instead of guessing.
2026-04-16 12:57:59 +08:00
Greg Harvell e475cb6bf0 readme update 2026-04-14 14:20:03 -04:00
Greg Harvell 9812beb817 chore(release): 1.0.7
- Fix Infinity anchorTimestamp repair on JSON round-trip (blocks extending
  to end-of-conversation now restored correctly instead of discarded)
- Fix nextBlockId calculation to use max(id)+1 instead of array length
- Rename internal prompt tag <dcp-message-id> to <dcp-id>
- Add regression tests for corrupted-block resilience (PR #3, @wassname)
- Update README with Contributors section
- Update CHANGELOG for 1.0.7
- Bump package.json to 1.0.7

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:04:24 -04:00
Greg Harvell 7cc2b5bbbe Merge pull request #3 from wassname/main
fix: prevent Infinity anchorTimestamp ghost block spiral

Thanks @wassname, I'm going to implement some more fixes before releasing this as well.
2026-04-14 12:44:03 -04:00
wassname 9e2c097782 fix: remove duplicate test 2026-04-10 20:43:42 +00:00
wassname a75f6b7ff7 fix: Infinity anchorTimestamp ghost block, prompt tag name, test cleanup
- resolveAnchorTimestamp returns endTimestamp + 1 instead of Infinity
- Validate timestamps are finite before creating blocks
- Skip corrupted blocks in overlap checks and compression application
- Include block timestamp range in overlap error messages
- Filter out corrupted blocks on session restore
- Fix prompt tag name: dcp-message-id → dcp-id to match injected tags
- Remove duplicate test, keep corrupted-block resilience test
2026-04-10 20:41:47 +00:00
wassname a0d9945830 fix: prevent Infinity anchorTimestamp ghost block spiral
The root cause of the compression spiral (101 failures, 2 hours):
resolveAnchorTimestamp returned Infinity when no message followed the
compression range. Infinity corrupted JSON serialization (became null),
and null timestamps in JS overlap checks coerced to 0, making every
range appear to overlap the ghost block b7.

Fixes:
- resolveAnchorTimestamp returns endTimestamp + 1 instead of Infinity
- Validate all timestamps are finite before creating a block (fail fast)
- Skip blocks with non-finite timestamps in overlap checks and compression
- Include existing block range in overlap error messages (diagnostic)
- Filter out corrupted blocks on session restore
- Guard synthetic message timestamp creation against non-finite values
- Add regression tests for Infinity anchor and null-timestamp blocks
2026-04-10 20:28:22 +00:00
Greg Harvell 8681bd833b fix: prevent orphaned tool_use/tool_result after compression with passthrough roles
Backward and forward expansion now skip PI-internal passthrough roles
(compaction, branch_summary, custom_message) when scanning for paired
assistant↔toolResult messages, ensuring atomic removal. Added a
post-compression repair safety net and deep-cloning to prevent content
mutation across context events.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 20:03:27 -04:00
Greg Harvell 24cf4e5b80 Bugfix for tool crash on compression 2026-03-30 17:30:53 -04:00
Greg Harvell cc4ac20aa7 Adding in pi package details. 2026-03-27 19:51:07 -04:00
Greg Harvell e62d04dfe8 Fixing some errors and issues 2026-03-27 19:38:35 -04:00
Greg Harvell e4b4d13ac7 fix: prevent orphaned tool_use blocks from compression and harden autocomplete
Bug 1 (400 API error): applyCompressionBlocks could remove toolResult
messages while leaving their paired assistant(tool_use) message intact.
This produced invalid API sequences that Claude rejected with:
  messages.N: tool_use ids found without tool_result blocks immediately after

The fix adds two boundary expansions before the splice:
- Expand lo backward: if messages[lo-1] is an assistant whose toolCall
  ids appear as toolResult.toolCallId values inside [lo..hi], pull the
  assistant into the range
- Expand hi forward: for assistants inside [lo..hi], extend hi to include
  any consecutive toolResult messages that immediately follow hi

This ensures tool_use/tool_result pairs are always removed together.

Bug 2 (autocomplete crash): harden getArgumentCompletions to return an
explicitly typed AutocompleteItem[] | null, filter on value (not label,
matching pi-tui's internal contract), and add a typeof guard ensuring no
item with a non-string value can reach getBestAutocompleteMatchIndex.
2026-03-27 18:50:56 -04:00
Greg Harvell ebfde87e57 Updating package.json 2026-03-27 17:50:07 -04:00
Greg Harvell 60b4249501 Initial Commit 2026-03-27 17:47:33 -04:00