Feat/node xtrace memory#1065
Conversation
Long-term, shared agent memory exposed as tools, backed by xTrace Memory Manager's HTTP API. 'remember' ingests conversation turns (POST /v1/memories, sync wait + poll) and 'recall' searches the pool (POST /v1/memories/search, compose mode returns ready-to-inject context). classType tool, so it complements the agent's required short-term memory subsystem. Includes example pipe and unit tests (helpers, payloads, scope/validation).
… fields optional Only api_key and org_id are required now; base_url, user_id, agent_id, app_id, group_ids, wait, ingest_timeout, extract_artifacts, search_mode and search_limit are marked optional (they have sensible defaults), so the config panel no longer shows them as required. Removes the 'experimental' capability so the node card no longer shows the EXPERIMENTAL badge.
Trim the config panel to the essentials: API Key and Org id (required), plus optional User id and Group ids (shared memory). Hide the advanced knobs (base_url, agent_id, app_id, synchronous ingest, ingest timeout, extract_artifacts, recall mode/limit) — they keep sensible defaults in IGlobal, so behavior is unchanged but the UI is much simpler.
… settings' toggle Keep the panel minimal by default (API Key, Org id, User id, Group ids) and reveal the advanced knobs (base_url, agent_id, app_id, synchronous ingest, ingest timeout, extract_artifacts, recall mode/limit) only when the user flips the 'Advanced settings' toggle — same conditional pattern llamaparse and tool_mcp_client use. Defaults unchanged.
RocketRide only substitutes ${ROCKETRIDE_*} placeholders in pipelines, so
${XTRACE_API_KEY}/${XTRACE_ORG_ID} were never resolved. Use
${ROCKETRIDE_XTRACE_API_KEY} and ${ROCKETRIDE_XTRACE_ORG_ID}.
…ai (not mem.xtrace.ai) Surface where to get credentials right in the form: the API Key and Org id field help now link to the Developer Portal (app.xtrace.ai → Settings → API Keys) and warn that mem.xtrace.ai (memhub/MCP, OAuth) has no API key. README gets a matching 'Where to get your credentials' section.
Keep the API Key/Org id guidance focused: get them from app.xtrace.ai → Settings → API Keys (not mem.xtrace.ai). The MCP server / OAuth path isn't relevant to this node, so it's removed from the field help and README.
📝 WalkthroughWalkthroughAdds a new tool_xtrace_memory node that provides xtrace.remember and xtrace.recall agent tools, global config/validation, HTTP helpers and idempotency-aware retries, service metadata and UI shape, unit tests, README, and an example agent pipe. ChangesxTrace Memory Node
Sequence DiagramsequenceDiagram
participant Agent
participant IInstance
participant xTraceAPI
participant JobAPI as JobStatus
Agent->>IInstance: xtrace.remember(messages, user_id, conv_id?)
IInstance->>xTraceAPI: POST /v1/memories (ingest payload + auth)
xTraceAPI-->>IInstance: job_id / immediate response
IInstance->>JobAPI: (if wait) GET /v1/memories/jobs/{job_id} (poll)
JobAPI-->>IInstance: terminal state (succeeded/failed)
IInstance-->>Agent: remember result (job metadata / error)
Agent->>IInstance: xtrace.recall(query, mode, limit, scope)
IInstance->>xTraceAPI: POST /v1/memories/search (query payload)
xTraceAPI-->>IInstance: search rows + context
IInstance-->>Agent: results, count, context
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Replace the embedded-PNG placeholder with the official XTraceAI SVG (vector mark + wordmark, animated gradient).
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@nodes/src/nodes/tool_xtrace_memory/IInstance.py`:
- Around line 340-363: The retry loop in _request_with_retry currently retries
all methods (using max_retries) which can double-ingest on non-idempotent calls
like POST /v1/memories; change _request_with_retry to only perform automatic
retries for idempotent HTTP methods (e.g., GET, HEAD, PUT, DELETE, OPTIONS) or
when an explicit idempotency key is provided, and for the remember/ingest path
('POST' to '/v1/memories' or the remember() caller) disable automatic retries
(set attempts=0) or require a stable client-generated idempotency token before
retrying; update the logic that checks method/endpoint before applying the
429/5xx and Timeout retry branches and ensure max_retries is honored only for
allowed methods.
In `@nodes/src/nodes/tool_xtrace_memory/services.json`:
- Line 11: Update the "documentation" JSON field to match the PR's user-facing
guidance: inspect the README/field-help text to confirm whether docs should
point to app.xtrace.ai instead of docs.mem.xtrace.ai, then replace the existing
"documentation" value in services.json (the "documentation" key in the
tool_xtrace_memory service entry) with the confirmed URL (e.g.,
https://app.xtrace.ai/…); ensure the string exactly matches the README guidance
and run a quick build/validation to confirm no JSON formatting errors.
In `@nodes/test/tool_xtrace_memory/test_tools.py`:
- Around line 36-104: Add short PEP 257 docstrings to the helper functions
_tool_function, _ensure_rocketlib, _passthrough, and _ensure_pkg: for each,
include a one-line summary, describe parameters (e.g., _meta for _tool_function,
args/tool_name for _passthrough) and return value (or None) and note any
side-effects (e.g., mutating sys.modules in _ensure_rocketlib/_ensure_pkg). Keep
existing docstrings for _ensure_ai_common and _ensure_requests as-is; place the
new docstrings immediately under each function signature and keep them concise
(one-line summary + one short sentences for args/returns/side-effects).
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ca712aa5-3592-4c09-b523-b8eef5dfa151
⛔ Files ignored due to path filters (1)
nodes/src/nodes/tool_xtrace_memory/xtrace.svgis excluded by!**/*.svg
📒 Files selected for processing (9)
examples/xtrace-memory-agent.pipenodes/src/nodes/tool_xtrace_memory/IGlobal.pynodes/src/nodes/tool_xtrace_memory/IInstance.pynodes/src/nodes/tool_xtrace_memory/README.mdnodes/src/nodes/tool_xtrace_memory/__init__.pynodes/src/nodes/tool_xtrace_memory/requirements.txtnodes/src/nodes/tool_xtrace_memory/services.jsonnodes/test/tool_xtrace_memory/__init__.pynodes/test/tool_xtrace_memory/test_tools.py
The node header already shows the name, so the icon now uses just the xTrace symbol (viewBox 0 0 140 140) instead of the full XTraceAI wordmark, which was illegible squished into the small square icon slot.
…imeout _request_with_retry gains an 'idempotent' flag (default True). The ingest POST passes idempotent=False so it only retries on 429 (not processed), avoiding duplicate memories on ambiguous 5xx/timeout. Reads (search, poll) keep full retries. Addresses CodeRabbit review on PR #1065.
|
No description provided. |
… (match llm_anthropic style)
asclearuc
left a comment
There was a problem hiding this comment.
It looks good — nice, clean node. Several comments below.
Frankly, none of them is a blocker, but let's make the code shine :)
Could you please address them?
…docstring, skip dynamic test) - Retries via tenacity (Retrying + retry_if_exception) instead of a hand-rolled loop, keeping the idempotent gating (429 always; 5xx/timeout only for reads). - Extract magic constants: _DEFAULT_BASE_URL, _DEFAULT_INGEST_TIMEOUT, _MAX_INGEST_TIMEOUT, _REQUEST_TIMEOUT. - Full Args/Returns/Raises docstring on _request_with_retry. - Add tool_xtrace_memory to conftest skip_nodes: its dynamic test needs live xTrace credentials (no live calls in default CI; opt-in via ROCKETRIDE_INCLUDE_SKIP). Mocked unit tests still cover the logic.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
nodes/src/nodes/tool_xtrace_memory/IInstance.py (1)
379-392:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUnreachable code at line 391.
The
raise RuntimeError('xtrace_memory: max retries exceeded')statement is unreachable. TheRetrying(...)(_attempt)call either:
- Returns successfully (function exits)
- Raises an exception caught by
except requests.RequestExceptionwhich raisesRuntimeError- Raises a non-
RequestExceptionwhich propagates out (withreraise=True)The line after the try/except block can never be reached.
🧹 Remove unreachable statement
except requests.RequestException as exc: status = getattr(getattr(exc, 'response', None), 'status_code', None) detail = f' (HTTP {status})' if status else '' raise RuntimeError(f'xtrace_memory: request failed{detail}: {type(exc).__name__}') from None - - raise RuntimeError('xtrace_memory: max retries exceeded')🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@nodes/src/nodes/tool_xtrace_memory/IInstance.py` around lines 379 - 392, The final raise RuntimeError('xtrace_memory: max retries exceeded') is unreachable because Retrying(...)(_attempt) either returns or raises (caught RequestException re-raised as RuntimeError or other exceptions propagate due to reraise=True); remove that unreachable statement and any dead imports/comments referencing it in the scope where Retrying, _attempt and _is_retryable are used, keeping the existing try/except that converts requests.RequestException into the RuntimeError with HTTP status detail.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@nodes/src/nodes/tool_xtrace_memory/IInstance.py`:
- Around line 379-392: The final raise RuntimeError('xtrace_memory: max retries
exceeded') is unreachable because Retrying(...)(_attempt) either returns or
raises (caught RequestException re-raised as RuntimeError or other exceptions
propagate due to reraise=True); remove that unreachable statement and any dead
imports/comments referencing it in the scope where Retrying, _attempt and
_is_retryable are used, keeping the existing try/except that converts
requests.RequestException into the RuntimeError with HTTP status detail.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9518fccd-9176-450d-92b3-f9cf5b3b518f
📒 Files selected for processing (5)
nodes/src/nodes/tool_xtrace_memory/IGlobal.pynodes/src/nodes/tool_xtrace_memory/IInstance.pynodes/src/nodes/tool_xtrace_memory/requirements.txtnodes/test/conftest.pynodes/test/tool_xtrace_memory/test_tools.py
Summary
Type
feat
Testing
./builder testpassesChecklist
Linked Issue
Fixes #
Fixes #1038
Summary by CodeRabbit
New Features
Documentation
Tests
Chores