-
Notifications
You must be signed in to change notification settings - Fork 120
fix(agent-sessions): treat the GenAI memory operations as known ops #1142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2915845
5672b67
3bcb60a
f5ca7b5
f6836b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| import { | ||
| AI_AGENT_OPERATIONS, | ||
| AI_INFERENCE_OPERATIONS, | ||
| AI_MEMORY_OPERATIONS, | ||
| AI_RETRIEVAL_OPERATIONS, | ||
| AI_TOOL_OPERATIONS, | ||
| } from "@maple/domain/gen-ai" | ||
|
|
@@ -37,8 +38,11 @@ const INFERENCE_OPS: ReadonlySet<string> = new Set(AI_INFERENCE_OPERATIONS) | |
| const RETRIEVAL_OPS: ReadonlySet<string> = new Set(AI_RETRIEVAL_OPERATIONS) | ||
| const TOOL_OPS: ReadonlySet<string> = new Set(AI_TOOL_OPERATIONS) | ||
| const AGENT_OPS: ReadonlySet<string> = new Set(AI_AGENT_OPERATIONS) | ||
| /** A memory-store operation is the agent's own bookkeeping, so it reads as agent | ||
| * work — not a model turn, not a tool call. */ | ||
| const MEMORY_OPS: ReadonlySet<string> = new Set(AI_MEMORY_OPERATIONS) | ||
|
|
||
| /** Every operation name the four sets above recognise. A span name conventionally | ||
| /** Every operation name the five sets above recognise. A span name conventionally | ||
| * leads with one ("execute_tool read_file", "chat gpt-5"), so a view that wants | ||
| * to set the operation apart from its subject needs to know which words are | ||
| * operations — including for the reporters that skip `gen_ai.operation.name`. */ | ||
|
|
@@ -47,6 +51,7 @@ export const GEN_AI_OPERATIONS: ReadonlySet<string> = new Set([ | |
| ...RETRIEVAL_OPS, | ||
| ...TOOL_OPS, | ||
| ...AGENT_OPS, | ||
| ...MEMORY_OPS, | ||
| ]) | ||
|
|
||
| export function spanStartMs(span: AiSessionSpan): number { | ||
|
|
@@ -77,7 +82,7 @@ export function classifyAiSpan(span: AiSessionSpan): AiSpanCategory { | |
| if (operation !== undefined) { | ||
| if (INFERENCE_OPS.has(operation) || RETRIEVAL_OPS.has(operation)) return "inference" | ||
| if (TOOL_OPS.has(operation)) return "tool" | ||
| if (AGENT_OPS.has(operation)) return "agent" | ||
| if (AGENT_OPS.has(operation) || MEMORY_OPS.has(operation)) return "agent" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Memory bookkeeping opens an extra turn When a root memory span precedes an agent invocation, Learn moreAgent-root anchors are AI spans classified as agent work with no AI ancestor. A root memory span now qualifies, although it does not start a user turn. The setup-merging rule only collapses workless anchors that end within five seconds of the next one buildSessionTurns. This makes memory operations produce extra turns when they are separate roots and more than five seconds apart. Example: A Recommended fix: Keep memory operations classified as agent work for display, but exclude Was this helpful? React with 👍 or 👎 to provide feedback.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Valid, fixed in f3f338e.
maple-review-bot[bot] marked this conversation as resolved.
|
||
| } | ||
| // Spans with no AI signal at all are the app's own HTTP/DB work, sharing the | ||
| // agent's traces. They are rendered, muted, and never colored as agent work. | ||
|
|
@@ -436,8 +441,15 @@ function findAnchors(ordered: readonly AiSessionSpan[]): readonly TurnAnchor[] { | |
| } | ||
| return false | ||
| } | ||
| // A memory operation is agent work, but bookkeeping around a turn rather than | ||
| // the start of one: as an anchor, a lookup ahead of the agent run would open a | ||
| // turn of its own. | ||
| const agentRoots = ordered.filter( | ||
| (span) => span.isAiSpan && classifyAiSpan(span) === "agent" && !underAiSpan(span), | ||
| (span) => | ||
| span.isAiSpan && | ||
| classifyAiSpan(span) === "agent" && | ||
| !MEMORY_OPS.has(span.genAi.operationName ?? "") && | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Memory span with no F1 · Warning · correctness The anchor filter reads only the reported attribute, but Prompt for an AI agent
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaving this as is. A memory operation is recognised by its operation everywhere: the ingest gateway ( |
||
| !underAiSpan(span), | ||
| ) | ||
| if (agentRoots.length > 0) { | ||
| return agentRoots.map((span) => ({ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.