feat: add ContextClaw AutoGen adapter#5
Conversation
📝 WalkthroughWalkthroughA new "ContextClaw AutoGen Adapter" package is introduced under Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (1)
adapters/autogen/__tests__/autogen-adapter.test.js (1)
28-33: Tighten invalid-input assertion to expected error message/type.Line 30–Line 32 currently passes on any throw. Assert the expected message to make this test meaningful.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@adapters/autogen/__tests__/autogen-adapter.test.js` around lines 28 - 33, Tighten the test by asserting the specific error type/message thrown by ContextClawAutoGenAdapter.pruneMessages for non-array input: replace the broad assert.throws with an assertion that the thrown error is the expected TypeError (or the concrete error class your implementation uses) and that its message matches the expected text (use assert.throws with a regex or the { name/message } options to match the exact message returned by pruneMessages, e.g., matching "messages must be an array" or whatever the implementation returns).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@adapters/autogen/__tests__/autogen-adapter.test.js`:
- Around line 54-59: Update the test so it verifies policy behavior, not just
presence: instantiate ContextClawAutoGenAdapter with policies: { FILE_READ: {
keep: 2 } }, then create and save at least three mock FILE_READ items into the
adapter's storage (use adapter.storage.save or the adapter API that persists
context items), call the adapter method that enforces policies (e.g.,
adapter.prune / adapter.enforcePolicies / adapter.applyPolicies — use the actual
enforcement method on ContextClawAutoGenAdapter), and assert that
adapter.storage.list (or the adapter's retrieval API) returns only 2 FILE_READ
items after enforcement; keep the test name "ContextClawAutoGenAdapter - custom
policies work" and assert on the stored items length/content to prove pruning
occurred.
In `@adapters/autogen/index.js`:
- Around line 2-5: The constructor saves config.policies to this.policies but
the pruning logic still uses a hardcoded truncation path, so policy settings are
ignored; update the pruning/truncation code (the method handling prune/autogen
truncation around lines referenced in the diff) to read and apply this.policies
(e.g., policy-based maxTokens, keepStrategy, or path selection) instead of the
fixed truncation behavior, falling back to current defaults when a policy key is
missing; ensure you reference the constructor's this.policies and replace the
hardcoded truncation branch with conditional logic that selects the truncation
strategy based on this.policies entries.
- Around line 62-67: The _truncateContent function currently returns 200
characters plus a three-character ellipsis, exceeding the intended 200-char cap;
update _truncateContent so the returned string is at most 200 characters by
truncating the original content to 197 characters and appending '...' when
content.length > 200 (i.e., change the ternary to use substring(0,197) + '...')
so the final output from _truncateContent never exceeds 200 chars.
In `@adapters/autogen/package.json`:
- Line 8: The package.json currently defines a generic "test" script with the
command "node --test __tests__/*.test.js" which isolates this adapter from
repo-level test orchestration; rename the script key to a unique name (e.g.
"test:autogen-adapter") preserving the existing command string, and then update
the repository root test orchestration (e.g. the root "test" or "test:all"
scripts) to invoke this new script via workspace-aware invocation (npm/yarn/pnpm
run in workspaces) so the adapter tests are executed in CI.
In `@adapters/autogen/README.md`:
- Around line 14-19: The README claims advanced features (headings "Intelligent
Message Truncation", "Content-Type Classification", "Custom Retention Policies",
"Debug Mode") but the adapter only performs fixed string truncation; either
update the README to truthfully state current behavior (describe that
truncateMessages performs simple string truncation, no type-aware classification
or retention enforcement) or implement the documented features by adding a
classifyMessageType function and updating truncateMessages/applyRetentionPolicy
to perform type-aware trimming and per-type retention rules and a debug mode
that logs why each message was pruned; reference the symbols truncateMessages,
classifyMessageType, applyRetentionPolicy and the README headings when making
the change.
- Around line 27-125: The README has an unclosed fenced code block starting at
the triple-backtick on the "npm install contextclaw-autogen-adapter" snippet
which causes all subsequent content (sections like "🚀 Quick Start", "🔧
Advanced Configuration", examples labeled JavaScript/Bash, and the API
Reference) to render as code; fix this by closing each opened fence (e.g., add
matching ``` after each code example such as the npm install, the JavaScript
examples, and the bash/npm test snippet) and ensure prose (headings,
explanations, and lists) is placed outside of fenced blocks so sections like
pruneMessages, prepareContextForLLM, analyzeContext, and the examples render as
normal Markdown.
In `@package.json`:
- Line 51: Add Node engine constraints to package.json by adding or updating the
"engines" field to require Node versions compatible with vitest 4.1.4 (e.g.,
"node": "^20.0.0 || ^22.0.0 || >=24.0.0"). Locate package.json (the file
containing the "vitest": "^4.1.4" dependency) and add the engines entry so CI
and installs will fail fast on unsupported Node versions rather than allowing
Node 18/19 to run.
---
Nitpick comments:
In `@adapters/autogen/__tests__/autogen-adapter.test.js`:
- Around line 28-33: Tighten the test by asserting the specific error
type/message thrown by ContextClawAutoGenAdapter.pruneMessages for non-array
input: replace the broad assert.throws with an assertion that the thrown error
is the expected TypeError (or the concrete error class your implementation uses)
and that its message matches the expected text (use assert.throws with a regex
or the { name/message } options to match the exact message returned by
pruneMessages, e.g., matching "messages must be an array" or whatever the
implementation returns).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c6208e61-ec0e-4263-b31a-5ae84f5a6260
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (5)
adapters/autogen/README.mdadapters/autogen/__tests__/autogen-adapter.test.jsadapters/autogen/index.jsadapters/autogen/package.jsonpackage.json
| test('ContextClawAutoGenAdapter - custom policies work', () => { | ||
| const adapter = new ContextClawAutoGenAdapter({ | ||
| policies: { FILE_READ: { keep: 2 } }, | ||
| }); | ||
| assert.ok(adapter.policies.FILE_READ); | ||
| }); |
There was a problem hiding this comment.
Policy test validates storage, not behavior.
Line 54–Line 59 only checks that adapter.policies.FILE_READ exists. It does not verify that policies change pruning output, so regressions can slip through.
Suggested stronger test
test('ContextClawAutoGenAdapter - custom policies work', () => {
const adapter = new ContextClawAutoGenAdapter({
- policies: { FILE_READ: { keep: 2 } },
+ policies: { user: { maxCharsAfter: 10 } },
});
- assert.ok(adapter.policies.FILE_READ);
+ const { messages } = adapter.pruneMessages([{ role: 'user', content: '123456789012345' }]);
+ assert.equal(messages[0].content.length, 10);
});🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@adapters/autogen/__tests__/autogen-adapter.test.js` around lines 54 - 59,
Update the test so it verifies policy behavior, not just presence: instantiate
ContextClawAutoGenAdapter with policies: { FILE_READ: { keep: 2 } }, then create
and save at least three mock FILE_READ items into the adapter's storage (use
adapter.storage.save or the adapter API that persists context items), call the
adapter method that enforces policies (e.g., adapter.prune /
adapter.enforcePolicies / adapter.applyPolicies — use the actual enforcement
method on ContextClawAutoGenAdapter), and assert that adapter.storage.list (or
the adapter's retrieval API) returns only 2 FILE_READ items after enforcement;
keep the test name "ContextClawAutoGenAdapter - custom policies work" and assert
on the stored items length/content to prove pruning occurred.
| constructor(config = {}) { | ||
| this.stats = config.stats || false; | ||
| this.debug = config.debug || false; | ||
| this.policies = config.policies || {}; |
There was a problem hiding this comment.
policies is accepted but not applied during pruning.
Line 5 stores config.policies, but Line 16 always applies a hardcoded truncation path. This makes policy configuration effectively inert in core behavior.
Proposed direction
class ContextClawAutoGenAdapter {
constructor(config = {}) {
this.stats = config.stats || false;
this.debug = config.debug || false;
this.policies = config.policies || {};
}
+ _resolveMaxChars(msg) {
+ const rolePolicy = this.policies?.[msg?.role];
+ return rolePolicy?.maxCharsAfter ?? 200;
+ }
+
pruneMessages(messages) {
@@
const prunedMessages = messages.map((msg) => ({
...msg,
- content: this._truncateContent(msg.content),
+ content: this._truncateContent(msg.content, this._resolveMaxChars(msg)),
}));Also applies to: 14-17
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@adapters/autogen/index.js` around lines 2 - 5, The constructor saves
config.policies to this.policies but the pruning logic still uses a hardcoded
truncation path, so policy settings are ignored; update the pruning/truncation
code (the method handling prune/autogen truncation around lines referenced in
the diff) to read and apply this.policies (e.g., policy-based maxTokens,
keepStrategy, or path selection) instead of the fixed truncation behavior,
falling back to current defaults when a policy key is missing; ensure you
reference the constructor's this.policies and replace the hardcoded truncation
branch with conditional logic that selects the truncation strategy based on
this.policies entries.
| _truncateContent(content) { | ||
| if (!content || typeof content !== 'string') { | ||
| return content; | ||
| } | ||
| return content.length > 200 ? content.substring(0, 200) + '...' : content; | ||
| } |
There was a problem hiding this comment.
Truncation exceeds the nominal 200-char cap.
Line 66 returns 200 chars plus ... (203 total). If 200 is intended as max output length, this is a boundary bug.
Patch
- _truncateContent(content) {
+ _truncateContent(content, maxChars = 200) {
if (!content || typeof content !== 'string') {
return content;
}
- return content.length > 200 ? content.substring(0, 200) + '...' : content;
+ if (content.length <= maxChars) return content;
+ if (maxChars <= 3) return '.'.repeat(maxChars);
+ return content.slice(0, maxChars - 3) + '...';
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@adapters/autogen/index.js` around lines 62 - 67, The _truncateContent
function currently returns 200 characters plus a three-character ellipsis,
exceeding the intended 200-char cap; update _truncateContent so the returned
string is at most 200 characters by truncating the original content to 197
characters and appending '...' when content.length > 200 (i.e., change the
ternary to use substring(0,197) + '...') so the final output from
_truncateContent never exceeds 200 chars.
| "main": "index.js", | ||
| "type": "module", | ||
| "scripts": { | ||
| "test": "node --test __tests__/*.test.js" |
There was a problem hiding this comment.
Adapter tests are isolated from repo-level test flow.
Line 8 defines local tests, but root scripts (test / test:all) do not run this adapter package test command. This can silently skip coverage in CI.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@adapters/autogen/package.json` at line 8, The package.json currently defines
a generic "test" script with the command "node --test __tests__/*.test.js" which
isolates this adapter from repo-level test orchestration; rename the script key
to a unique name (e.g. "test:autogen-adapter") preserving the existing command
string, and then update the repository root test orchestration (e.g. the root
"test" or "test:all" scripts) to invoke this new script via workspace-aware
invocation (npm/yarn/pnpm run in workspaces) so the adapter tests are executed
in CI.
| - **✂️ Intelligent Message Truncation:** Automatically identifies and truncates overly verbose tool outputs or system logs. | ||
| - **🏷️ Content-Type Classification:** Understands the difference between user prompts, system instructions, and tool outputs. | ||
| - **📉 Token Usage Optimization:** Drastically reduces LLM costs and prevents context-window overflow. | ||
| - **⚙️ Custom Retention Policies:** Define exactly how many messages of a certain type to keep, and how long they should be. | ||
| - **🐛 Debug Mode:** Built-in troubleshooting tools to see exactly what is being pruned and why. | ||
| - **🔌 Framework Agnostic:** Designed for AutoGen, but works seamlessly with any standard LLM message array framework. |
There was a problem hiding this comment.
README overstates current adapter capabilities.
Lines 14–19 and Line 53 onward describe content-type classification and retention-policy behavior, but current implementation applies fixed string truncation and does not perform type-aware policy execution. Please align docs with actual behavior (or implement the documented behavior).
Also applies to: 53-59, 82-103
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@adapters/autogen/README.md` around lines 14 - 19, The README claims advanced
features (headings "Intelligent Message Truncation", "Content-Type
Classification", "Custom Retention Policies", "Debug Mode") but the adapter only
performs fixed string truncation; either update the README to truthfully state
current behavior (describe that truncateMessages performs simple string
truncation, no type-aware classification or retention enforcement) or implement
the documented features by adding a classifyMessageType function and updating
truncateMessages/applyRetentionPolicy to perform type-aware trimming and
per-type retention rules and a debug mode that logs why each message was pruned;
reference the symbols truncateMessages, classifyMessageType,
applyRetentionPolicy and the README headings when making the change.
| ```bash | ||
| npm install contextclaw-autogen-adapter | ||
| 🚀 Quick Start | ||
| Get up and running in seconds. Here is the most basic implementation: | ||
|
|
||
| JavaScript | ||
| import { ContextClawAutoGenAdapter } from 'contextclaw-autogen-adapter'; | ||
|
|
||
| // 1. Initialize the adapter | ||
| const adapter = new ContextClawAutoGenAdapter(); | ||
|
|
||
| // 2. Your standard message array | ||
| const messages = [ | ||
| { role: 'user', content: 'Can you analyze this 50MB log file?' }, | ||
| { role: 'tool', content: '{ ... massive JSON output ... }' }, | ||
| { role: 'assistant', content: 'I have analyzed the file.' }, | ||
| ]; | ||
|
|
||
| // 3. Prune the context before sending to the LLM | ||
| const { messages: leanMessages } = adapter.pruneMessages(messages); | ||
|
|
||
| console.log(leanMessages); | ||
| 🔧 Advanced Configuration | ||
| You can customize the adapter's behavior by passing an options object during instantiation. Tailor the retention policies to fit your specific agent's needs. | ||
|
|
||
| JavaScript | ||
| const adapter = new ContextClawAutoGenAdapter({ | ||
| stats: true, // Enable statistics tracking | ||
| debug: true, // Enable detailed debug logging | ||
| policies: { // Define custom retention rules | ||
| FILE_READ: { keep: 2, truncate: 200 }, | ||
| CMD_OUTPUT: { keep: 1, truncate: 150 } | ||
| } | ||
| }); | ||
| 📖 Usage Examples | ||
| Example 1: Extracting Optimization Statistics | ||
| Curious how many tokens/characters you are saving? Enable stats and check the output. | ||
|
|
||
| JavaScript | ||
| const adapter = new ContextClawAutoGenAdapter({ stats: true }); | ||
|
|
||
| const { messages, stats } = adapter.pruneMessages(conversation); | ||
|
|
||
| console.log(`Optimization Complete!`); | ||
| console.log(`Messages reduced: ${stats.inputCount} → ${stats.outputCount}`); | ||
| console.log(`Total characters saved: ${stats.totalSaved}`); | ||
| Example 2: Preparing Context directly for the LLM | ||
| If you don't need the stats object and just want the lean array returned directly: | ||
|
|
||
| JavaScript | ||
| const adapter = new ContextClawAutoGenAdapter(); | ||
|
|
||
| // Returns just the pruned array, ready to be passed to your LLM API | ||
| const leanContext = adapter.prepareContextForLLM(conversation); | ||
| 📚 API Reference | ||
| pruneMessages(messages) | ||
| Core function that applies ContextClaw policies to an array of messages. | ||
|
|
||
| Parameters: | ||
| messages (Array) - Array of standard message objects (must contain role and content). | ||
| Returns: | ||
| Object - Contains { messages: Array, stats?: Object }. | ||
| prepareContextForLLM(messages) | ||
| A convenience wrapper around pruneMessages that returns strictly the pruned message array. | ||
|
|
||
| Parameters: | ||
| messages (Array) - Array of message objects. | ||
| Returns: | ||
| Array - The optimized array of messages. | ||
| analyzeContext(messages) | ||
| Analyzes the current context window without modifying it, returning useful size and composition statistics. | ||
|
|
||
| Parameters: | ||
| messages (Array) - Array of message objects. | ||
| Returns: | ||
| Object - { totalMessages: Number, totalChars: Number, typeCounts: Object }. | ||
| 🧪 Testing | ||
| This project maintains high test coverage. To run the test suite locally: | ||
|
|
||
| bash | ||
| npm test | ||
| Expected Output: | ||
|
|
||
| Text | ||
| ✔ ContextClawAutoGenAdapter - basic instantiation | ||
| ✔ ContextClawAutoGenAdapter - pruneMessages returns messages array | ||
| ✔ ContextClawAutoGenAdapter - handles empty messages | ||
| ✔ ContextClawAutoGenAdapter - throws on invalid input | ||
| ✔ ContextClawAutoGenAdapter - preprocessMessages works | ||
| ✔ ContextClawAutoGenAdapter - analyzeContext returns stats | ||
| ✔ ContextClawAutoGenAdapter - custom policies work | ||
| ✔ ContextClawAutoGenAdapter - debug mode works | ||
|
|
||
| pass 8 | ||
| fail 0 | ||
| 📄 License | ||
| This project is licensed under the MIT License. See the LICENSE file for details. | ||
|
|
||
| Maintained by @dodge1218 No newline at end of file |
There was a problem hiding this comment.
Markdown structure is broken (unclosed code fence).
Line 27 opens a fenced block, and subsequent headings/examples are rendered as code instead of documentation. Please close fences around each snippet and keep prose outside blocks.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@adapters/autogen/README.md` around lines 27 - 125, The README has an unclosed
fenced code block starting at the triple-backtick on the "npm install
contextclaw-autogen-adapter" snippet which causes all subsequent content
(sections like "🚀 Quick Start", "🔧 Advanced Configuration", examples labeled
JavaScript/Bash, and the API Reference) to render as code; fix this by closing
each opened fence (e.g., add matching ``` after each code example such as the
npm install, the JavaScript examples, and the bash/npm test snippet) and ensure
prose (headings, explanations, and lists) is placed outside of fenced blocks so
sections like pruneMessages, prepareContextForLLM, analyzeContext, and the
examples render as normal Markdown.
| "@types/ws": "^8.5.0" | ||
| "@types/ws": "^8.5.0", | ||
| "typescript": "^5.5.0", | ||
| "vitest": "^4.1.4" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Root package engines =="
jq '.engines // {}' package.json
echo "== Node version pins in repo =="
fd -HI -t f '^(\.nvmrc|\.node-version)$' -x sh -c 'echo "--- {} ---"; cat "{}"; echo'
echo "== Vitest 4.1.4 engines from npm =="
npm view vitest@4.1.4 engines --jsonRepository: dodge1218/contextclaw
Length of output: 209
Add Node version constraints to ensure Vitest 4.1.4 compatibility.
Vitest 4.1.4 requires Node ^20.0.0 || ^22.0.0 || >=24.0.0. The repository has no engine constraints defined in package.json. Add explicit Node engine constraints to package.json before merging to prevent CI failures with unsupported Node versions (18.x, 19.x).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@package.json` at line 51, Add Node engine constraints to package.json by
adding or updating the "engines" field to require Node versions compatible with
vitest 4.1.4 (e.g., "node": "^20.0.0 || ^22.0.0 || >=24.0.0"). Locate
package.json (the file containing the "vitest": "^4.1.4" dependency) and add the
engines entry so CI and installs will fail fast on unsupported Node versions
rather than allowing Node 18/19 to run.
Adds the ContextClaw AutoGen adapter, tests, and documentation.
Summary by CodeRabbit
New Features
Chores