Skip to content

feat: add escalation memory cache and ingest#805

Open
mjnovice wants to merge 12 commits into
mainfrom
feat/escalation-memory
Open

feat: add escalation memory cache and ingest#805
mjnovice wants to merge 12 commits into
mainfrom
feat/escalation-memory

Conversation

@mjnovice
Copy link
Copy Markdown
Contributor

@mjnovice mjnovice commented Apr 23, 2026

Depends on #793

Summary

  • Adds memory cache check (_check_escalation_memory_cache) before HITL task creation — cache hit skips human escalation
  • Adds outcome ingest (_ingest_escalation_memory) after human resolution to persist for future recall
  • Gated by isAgentMemoryEnabled + memorySpaceId on the escalation resource config
  • Search settings (threshold, searchMode, fieldSettings) read from resource memory config
  • Span attributes (fromMemory, savedToMemory) for trace observability
  • Extracts completed_by_user email for memory ingest userId

Test plan

  • tests/agent/tools/test_escalation_memory.py — 7 tests for cache check, ingest, and space ID resolution
  • tests/agent/tools/test_escalation_tool.py — all 37 tests pass
  • tests/agent/tools/test_ixp_escalation_tool.py — all 16 tests pass
  • Ruff lint passes

🤖 Generated with Claude Code

@mjnovice
Copy link
Copy Markdown
Contributor Author

Transferring review comments from @andreitava-uip on #793 that apply to escalation memory (now in this PR):

  1. No private repo references in public library — Remove comments referencing .cs files from private repos. Applicable to all comments.

  2. Move memory helpers to a separate file — The memory helpers are completely standalone and should be in their own file rather than in escalation_tool.py.

  3. Hardcoded CONTINUE outcome — Is hardcoding CONTINUE correct? Do we not commit to memory other outcomes?

@mjnovice
Copy link
Copy Markdown
Contributor Author

Another comment from @andreitava-uip on #793:

  1. Lazy load question (escalation_tool.py, around line 438) — "Any reason for the lazy load?"

@mjnovice
Copy link
Copy Markdown
Contributor Author

Another comment from @andreitava-uip on #793:

  1. Hardcoded CONTINUE in tests (test_escalation_memory.py, line 58) — "This mirrors my other comment over whether the action result should get hardcoded to CONTINUE"

@mjnovice mjnovice force-pushed the feat/memory-loop-integration-scaffold branch 4 times, most recently from 8c8b6b1 to 4817a5e Compare April 24, 2026 06:42
Base automatically changed from feat/memory-loop-integration-scaffold to main April 24, 2026 07:12
Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated
Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated
@mjnovice mjnovice force-pushed the feat/escalation-memory branch from 4938bc0 to 7bd14ea Compare April 24, 2026 16:30
Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated
Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated
Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated

def _get_escalation_memory_settings(
resource: AgentEscalationResourceConfig,
) -> dict[str, Any] | None:
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.

this can't return a class?

Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated
"Ingested escalation outcome into memory space '%s'", memory_space_id
)
except Exception:
set_span_attribute("savedToMemory", False)
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.

span needs to be set to error state? error message on span?

Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated
@swathiJayav swathiJayav self-requested a review April 27, 2026 21:33
settings=settings,
)
)
if not fields:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Throw validation error if no fields are set

if response.results and response.results[0].answer:
cached = response.results[0].answer
_escalation_logger.info(
"Escalation memory cache hit for space '%s'", memory_space_id
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Add customMetric for AppInsights, MemoryCacheHit, MemoryCacheMiss (matching Temporal-based execution)

Comment thread src/uipath_langchain/agent/tools/escalation_tool.py Outdated
mjnovice and others added 4 commits May 13, 2026 10:10
Adds memory integration to the escalation tool:
- Before creating HITL task: escalation_search_async() checks for cached answer
- Cache hit returns cached result immediately, skipping human escalation
- After human resolution: escalation_ingest_async() persists outcome
- Gated by isAgentMemoryEnabled + memorySpaceId on the escalation resource
- Search settings (threshold, searchMode, fieldSettings) read from resource config
- Span attributes (fromMemory, savedToMemory) for trace observability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When no fieldSettings are configured in the agent definition,
field_weights should be None (search all fields with default weights)
rather than raising a validation error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mjnovice mjnovice force-pushed the feat/escalation-memory branch from e923f4e to 8fb6534 Compare May 13, 2026 17:26
try:
cached_result = await retriever.aretrieve(serialized_input)
except ValueError:
raise
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.

When will we have this ValueError? Should raise or swallow it?

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants