Skip to content

fix(omp): render custom context and openviking messages as distinct timeline blocks - #4187

Closed
DennysOliveira wants to merge 2 commits into
getpaseo:mainfrom
DennysOliveira:fix/omp-custom-message-timeline-rendering
Closed

DennysOliveira wants to merge 2 commits into
getpaseo:mainfrom
DennysOliveira:fix/omp-custom-message-timeline-rendering

Conversation

@DennysOliveira

Copy link
Copy Markdown

Problem

When using omp (Oh My Pi) as the backend provider in Paseo, prompt injection hooks and memory layers like OpenViking inject context before the model turns via before_agent_start. In OMP, these are emitted and recorded as custom_message entries with role: "custom" and customType: "custom-message".

Previously, Paseo's OMP provider only recognized advisor messages and system-notice envelopes, falling back to mapping any other custom message as an assistant_message:

item: item ?? { type: "assistant_message", text }

This caused injected contexts (such as <openviking-context> blocks containing profile and memory indexes) to be rendered directly inside the assistant's speech bubble, visually blending the injected system prompt context with the actual model response.

Solution

  1. Added dedicated detection and mapping for OpenViking context blocks (<openviking-context>, <user-profile>, <available-memories>, <relevant-memories>) into synthetic completed tool_call timeline items (name: "openviking_context", icon: "brain", labeled accordingly like OpenViking · Profile & Memories or OpenViking · Recalled Context).
  2. Added synthetic tool-call mapping for generic custom messages / context injections (customType: "custom-message", <system-reminder>, etc.) so they render as distinct collapsible contextual blocks rather than assistant messages.
  3. Kept legacy plain-text fallbacks intact for unrecognized non-context custom text.
  4. Added full test coverage in history-mapper.test.ts and agent.test.ts for both replayed and streamed custom context messages.

Verification

  • npm run build:server passed
  • npm run typecheck:server passed (all packages: relay, protocol, client, server, cli)
  • npm run lint passed (0 errors, 0 warnings across 3950 files)
  • npm run format:check passed
  • npx vitest run packages/server/src/server/agent/providers/omp/ passed (20 test suites, 126 tests)

@greptile-apps

greptile-apps Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR maps streamed and replayed OMP custom context into distinct completed tool-call timeline blocks instead of assistant speech.

  • Adds specialized OpenViking context detection, labels, metadata, and stable synthetic call IDs.
  • Adds a generic custom-context mapping while preserving the assistant-message fallback for unrecognized text.
  • Routes live events and history replay through the shared custom-message mapper and adds coverage for both paths.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
packages/server/src/server/agent/providers/omp/custom-message.ts Adds centralized classification and timeline mapping for OpenViking and generic OMP custom messages.
packages/server/src/server/agent/providers/omp/agent.ts Routes streamed custom messages through the shared timeline mapper.
packages/server/src/server/agent/providers/omp/history-hooks.ts Uses the same custom-message mapping behavior during history replay.
packages/server/src/server/agent/providers/omp/agent.test.ts Covers streamed OpenViking context as a distinct synthetic tool-call block.
packages/server/src/server/agent/providers/omp/history-mapper.test.ts Covers replayed OpenViking and generic custom-context timeline blocks.

Reviews (2): Last reviewed commit: "Merge branch 'main' into fix/omp-custom-..." | Re-trigger Greptile

Comment on lines +2 to 6
import type { AgentTimelineItem, ToolCallTimelineItem } from "../../agent-sdk-types.js";
import type { OmpAgentMessage } from "./rpc-types.js";
import { mapOmpAdvisorMessageToToolCall } from "./advisor-message.js";
import { mapOmpSystemNoticeToToolCall } from "./system-notice.js";

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.

P2 Server conventions diverge

This module imports internal server code through relative paths rather than the required @server/* alias, and buildCustomMessageCallId takes three positional parameters including an optional argument instead of one object parameter. These departures make server imports and call sites less consistent and increase refactoring friction.

Context Used: packages/server/CLAUDE.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@boudra

boudra commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

This presentation can live in a timeline plugin. The API is on main for the upcoming 0.8 release: timeline plugins. I prefer that implementation over adding it to core.

@boudra boudra closed this Sep 7, 2026
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.

2 participants