Skip to content

Feat/node xtrace memory#1065

Merged
dsapandora merged 14 commits into
developfrom
feat/node-xtrace-memory
Jun 2, 2026
Merged

Feat/node xtrace memory#1065
dsapandora merged 14 commits into
developfrom
feat/node-xtrace-memory

Conversation

@dsapandora

@dsapandora dsapandora commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator
Captura de pantalla 2026-06-02 a las 16 13 59 Captura de pantalla 2026-06-02 a las 16 14 18

Summary

  • A tool node giving agents long-term, shared memory via the xTrace Memory RESTAPI: xtrace.remember (store turns) and xtrace.recall (ready-to-inject context).
  • Minimal config: API Key + Org id required; everything else behind an "Advanced settings" toggle. Field help links to app.xtrace.ai (Developer Portal), not mem.xtrace.ai.
  • Verified end-to-end: a real fact ("User works in DevOps.") was stored under demo-user in the org

Type

feat

Testing

  • Tests added or updated
  • Tested locally
  • ./builder test passes

Checklist

  • Commit messages follow conventional commits
  • No secrets or credentials included
  • Wiki updated (if applicable)
  • Breaking changes documented (if applicable)

Linked Issue

Fixes #
Fixes #1038

Summary by CodeRabbit

  • New Features

    • Added xTrace Memory tool for agents providing persistent remember/recall tools and an example workflow showing wiring to an agent.
  • Documentation

    • Added README documenting integration, configuration options, and usage notes.
  • Tests

    • Added unit tests for input normalization and remember/recall request/response behavior.
  • Chores

    • Added runtime dependencies required by the new memory tool.

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.
@github-actions github-actions Bot added docs Documentation module:nodes Python pipeline nodes labels Jun 2, 2026
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

xTrace Memory Node

Layer / File(s) Summary
Global configuration and credential management
nodes/src/nodes/tool_xtrace_memory/IGlobal.py, nodes/src/nodes/tool_xtrace_memory/__init__.py, nodes/src/nodes/tool_xtrace_memory/requirements.txt, nodes/src/nodes/tool_xtrace_memory/services.json, nodes/src/nodes/tool_xtrace_memory/README.md, examples/xtrace-memory-agent.pipe
_split_group_ids normalizes group scoping; IGlobal.beginGlobal() loads credentials from node config or env, validates required api_key/org_id, normalizes base_url, flags, timeouts and limits; validateConfig() warns non-fatally; endGlobal() clears creds. Package exports added, requests/tenacity declared; service metadata/schema, preconfig, and Pipe shape are defined; README and example pipe added.
Runtime helpers and tool implementations
nodes/src/nodes/tool_xtrace_memory/IInstance.py
IInstance exposes remember (ingest) and recall (search) tools. Includes _coerce_messages, _headers, _request_with_retry (tenacity-backed, idempotency-aware), and _await_terminal polling. remember POSTs /v1/memories and optionally waits for job completion; recall POSTs /v1/memories/search and shapes results.
Unit tests and test harness
nodes/test/tool_xtrace_memory/test_tools.py, nodes/test/conftest.py
Pytest suite with stubbed deps validates _split_group_ids, _coerce_messages, remember payload/terminal outcomes, recall payload/result shaping, and negative validation cases that avoid network calls. conftest.py updated to skip tool_xtrace_memory in dynamic tests by default.

Sequence Diagram

sequenceDiagram
  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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • jmaionchi
  • stepmikhaylov
  • Rod-Christensen

Poem

🐰 I nibbled through code and stitched a tree,
Memories stored for agents like me,
Recall when you ask, remember what’s true,
Long-term facts planted, now ready for you. ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Title 'Feat/node xtrace memory' is vague and uses a generic format with non-descriptive prefix; it doesn't convey meaningful information about adding xTrace shared memory integration. Revise title to be more descriptive and specific about the main feature, e.g., 'Add xTrace Memory tool node for agent long-term semantic recall' or similar.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The code changes fully implement the requirements from issue #1038: integrating xTrace shared memory as a nodes module with remember/recall tools for agent persistence and retrieval.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the linked issue #1038 objectives; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/node-xtrace-memory

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Replace the embedded-PNG placeholder with the official XTraceAI SVG
(vector mark + wordmark, animated gradient).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between c3f8d95 and bfc0360.

⛔ Files ignored due to path filters (1)
  • nodes/src/nodes/tool_xtrace_memory/xtrace.svg is excluded by !**/*.svg
📒 Files selected for processing (9)
  • examples/xtrace-memory-agent.pipe
  • nodes/src/nodes/tool_xtrace_memory/IGlobal.py
  • nodes/src/nodes/tool_xtrace_memory/IInstance.py
  • nodes/src/nodes/tool_xtrace_memory/README.md
  • nodes/src/nodes/tool_xtrace_memory/__init__.py
  • nodes/src/nodes/tool_xtrace_memory/requirements.txt
  • nodes/src/nodes/tool_xtrace_memory/services.json
  • nodes/test/tool_xtrace_memory/__init__.py
  • nodes/test/tool_xtrace_memory/test_tools.py

Comment thread nodes/src/nodes/tool_xtrace_memory/IInstance.py Outdated
Comment thread nodes/src/nodes/tool_xtrace_memory/services.json
Comment thread nodes/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.
@rocketride-org rocketride-org deleted a comment from github-actions Bot Jun 2, 2026
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@asclearuc asclearuc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsapandora

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?

Comment thread nodes/src/nodes/tool_xtrace_memory/IGlobal.py Outdated
Comment thread nodes/src/nodes/tool_xtrace_memory/IInstance.py
Comment thread nodes/src/nodes/tool_xtrace_memory/IInstance.py Outdated
…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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Unreachable code at line 391.

The raise RuntimeError('xtrace_memory: max retries exceeded') statement is unreachable. The Retrying(...)(_attempt) call either:

  1. Returns successfully (function exits)
  2. Raises an exception caught by except requests.RequestException which raises RuntimeError
  3. Raises a non-RequestException which propagates out (with reraise=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

📥 Commits

Reviewing files that changed from the base of the PR and between 71fcfd1 and 5a25847.

📒 Files selected for processing (5)
  • nodes/src/nodes/tool_xtrace_memory/IGlobal.py
  • nodes/src/nodes/tool_xtrace_memory/IInstance.py
  • nodes/src/nodes/tool_xtrace_memory/requirements.txt
  • nodes/test/conftest.py
  • nodes/test/tool_xtrace_memory/test_tools.py

@dsapandora
dsapandora merged commit 30af066 into develop Jun 2, 2026
26 checks passed
@dsapandora
dsapandora deleted the feat/node-xtrace-memory branch June 2, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation module:nodes Python pipeline nodes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(node): add xTrace node

2 participants