Skip to content

feat(recall): link an OMP subagent's session to its parent for adoption - #935

Merged
jeff-r2026 merged 3 commits into
Tencent:mainfrom
SaulMoro:feat/omp-recall-parent-link
Oct 1, 2026
Merged

jeff-r2026 merged 3 commits into
Tencent:mainfrom
SaulMoro:feat/omp-recall-parent-link

Conversation

@SaulMoro

@SaulMoro SaulMoro commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

On OMP, a doc the main agent opens after the teamai-recall subagent recalled it is now upvoted. OMP gives every subagent a session of its own, and nothing linked that session to its parent. So on OMP the subagent path, the one we recommend, gave 0. This is the "OMP's parent link" follow-up from #925.

OMP has no API that returns a subagent's parent session, but its session files record it:

~/.omp/agent/sessions/<cwd slug>/
├── <ts>_<main id>.jsonl        line 1: {"type":"title",…,"pad":"   "}   OMP's title slot, rewritten in place
│                               line 2: {"type":"session","id":"<main id>",…}
└── <ts>_<main id>/             the parent's artifacts dir
    └── <agent id>.jsonl        the subagent's session (getSessionFile())
 tool_result (generated OMP extension)
   payload = { tool_name, tool_input, tool_response, tool_status }
+  until this session is linked:
+    parent = id of the session header of <dirname(getSessionFile())>.jsonl (the line after the title slot)
+    if parent: payload.session_link = { child: session_id, parent }; mark linked
   hook-dispatch post-tool-use --tool omp
 Stop (main session)
   reducer: runs and reads of every session linked up to the root   (unchanged, as for OpenCode)

The recall log, the reducer and the stats are unchanged. OMP now sends the same session_link the OpenCode plugin sends for a task call. The usage guides (EN and zh-CN) and skill-data/core/references/troubleshooting.md now list OMP's subagent path as supported, verified against OMP 18.4.8.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature causing existing behavior to change)
  • Documentation only
  • Refactor / internal cleanup

Test Plan

  • npx tsc --noEmit passes
  • npm run lint passes
  • npx vitest run passes: 358 files, 6658 passed, 1 skipped (with CLAUDE_CONFIG_DIR unset: self-mode-agents reads it from the environment)
  • npm run test:e2e passes: 64 files, 394 passed, 26 skipped
  • Added/updated tests for the change

Before / after (live OMP session). OMP 18.4.8 (openai-codex/gpt-6.1-sol), in a temp HOME with a local git team holding one learning (redis-timeout) and recall enabled. teamai pull from this branch's build deployed ~/.omp/agent/agents/teamai-recall.md and ~/.omp/agent/extensions/teamai-hooks.ts; teamai on PATH ran the same build. One prompt:

omp -p "Use the task tool to delegate to the teamai-recall subagent: ask it to find team knowledge
        about 'redis timeout'. When it returns, open the team doc file it names yourself with your
        read tool, then reply with the code word in that doc and the absolute path you read."

The model delegated, the subagent ran teamai recall --caller teamai-recall, and the main agent read ~/.teamai/learnings/redis-timeout.md. "Before" is the same session with the deployed extension's lookup reverted to this PR's previous revision (header read from line 1); nothing else changed.

Before (def8e28) After
link lines in the recall log 0 1 (child = subagent session, parent = main session)
teamai stats adopted 0 1
  session   agent  runs  recalled  adopted
  01a0f6ac  omp       1         1        0      before: credited to the subagent's session
  01a0f6aa  omp       1         1        1      after:  credited to the main session

New rows in src/__tests__/recall-attribution.test.ts. The harness writes OMP's session files as OMP 18.2.1 and 18.4.8 write them (title slot line, then the session header) and hands getSessionFile to the extension:

row                                                                      before              after
recall subagent recalls and reads, then the main agent reads             {} (failed)         { redis-timeout: 1 }
parent file not on disk at the subagent's first call, written later      {} (failed)         { redis-timeout: 1 }
linked recall subagent reads the doc, the main agent does not            {}                  {}
main session has no session file (--no-session), main agent reads        {}                  {}

Both failing rows failed against def8e28 once the harness wrote the title slot.

Related Issues

Follow-up to #925 (#884).

Notes for Reviewers

Merge Danger

Door: two-way. The change touches only the generated extension. Reverting it and running teamai pull regenerates the old extension. Link lines already in the recall log stay valid, and upvotes already cast stay as ordinary counts.

Blast Radius: OMP hooks. Until a session is linked, each of its tool_result events tries to open its parent's session file and read up to 64 KiB of it. For a subagent that happens once, as soon as the parent's file is on disk. A main session has no parent file, so each of its calls costs one failed open (ENOENT). Every failure is swallowed, so the result is at worst no link, which is how OMP behaved before. Other agents are untouched.

Where to look: parentSessionOf in src/omp-hooks.ts. It relies on OMP's on-disk layout, not on a public API: the artifacts dir beside the parent's file (task/executor.ts), and the title slot before the session header (session/session-manager.ts, #fileBody). If OMP changes either, the link disappears silently and adoption falls back to 0. A parentSession field in OMP's session header would replace this, so an upstream request is worth making.

Review follow-ups.

  • @jeff-r2026 asked to verify the OMP row. The previous revision did not work in a real session: it parsed only line 1 of the parent's file, but OMP always writes a title slot line first, so no link ever formed. The test harness and the earlier Bun-driven run both used a file headed by the session line, a layout OMP never writes. Across 59 real subagent session files on this machine (OMP 18.2.1), the old lookup linked 0. The lookup now skips the title slot, the harness writes it, and the live session above checks the result. The docs say "verified against OMP 18.4.8" in place of "unverified".
  • skill-data/core/references/troubleshooting.md still listed OMP as main-agent-only. Updated.
  • A session was marked as looked up before its parent was found, so a parent file not yet on disk lost the link for the whole session. A session is now marked only once it is linked.
  • No row showed that a linked subagent's own read still scores 0. Added.
  • The docs named the no-link case "a subagent kept in memory". It is the main session having no file (--no-session). Reworded in both guides.
  • Smaller items: the 64 KiB limit is named (HEADER_READ_BYTES), and the bridge no longer repeats the recorder's child !== parent check.

OMP gives a subagent a session of its own, so a recall the teamai-recall
subagent ran never credited the main agent's later reads. OMP writes a
subagent's session to <parent>/<agent id>.jsonl beside the parent's
<parent>.jsonl, whose header names the parent session. The generated
extension now reads that header on a session's first tool_result and
sends the session_link the OpenCode plugin already sends, so the reducer
credits the root session. A session kept only in memory has no file and
still gets no link.
…ked (PR review)

A session was marked as looked up before its parent was found, so a parent session file not yet on disk lost the link for the whole session. Also: skill-data troubleshooting lists OMP's subagent path, the docs name the no-link case (--no-session), a row shows a linked subagent's own read still scores 0, and the header read limit is named.
@jeff-r2026 jeff-r2026 self-assigned this Oct 1, 2026
@SaulMoro

SaulMoro commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator Author

@jeff-r2026 The Codex PR Review check failed on infrastructure (DeploymentNotFound from the model endpoint), so no review ran. Could you re-assign the PR to trigger it again?

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

No findings.

  • The PR description includes sufficient testing, including a representative real-CLI/Bun end-to-end verification.
  • The delayed parent-file lookup issue and documentation/test gaps described in the PR are resolved in the current diff.
  • Per instruction, I only inspected the diff and did not run or build PR code.

Comment thread docs/usage-guide.md Outdated
| Cursor | Yes | No: as for Copilot CLI |
| OpenCode | Yes | Yes: the `task` call links the subagent's session to its parent |
| OMP | Yes, settled only by the claim of its `bash` call | No: the subagent's session is not linked to its parent |
| OMP | Yes, settled only by the claim of its `bash` call | Yes (unverified): the subagent's session file sits under its parent's, whose header links the two sessions |

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.

Could you please verified this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, you were right to ask: it did not work in a real session. OMP writes a padded title slot line before the session header, so the lookup read {"type":"title",…} and never linked a subagent. The harness wrote a file headed by the session line, a layout OMP never writes, so the tests passed anyway. Against the 59 real subagent session files on my machine (OMP 18.2.1), the old lookup linked 0.

Fixed in 3ed4c24: the lookup skips the title slot, and the harness now writes it, which makes both positive rows fail against def8e28. Verified in a live OMP 18.4.8 session: the teamai-recall subagent recalled, the main agent read the doc, and the recall log got a link line. teamai stats shows adopted 1; with the old lookup the same session gave 0. The row now reads "verified against OMP 18.4.8". Details are in the PR description.

… (PR review)

OMP writes a padded title slot line before the session header, so the
parent lookup parsed the title line and never linked a subagent. The test
harness now writes OMP's real layout; verified in a live OMP 18.4.8
session.
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

No findings.

  • The PR description documents sufficient testing, including a representative real-CLI OMP 18.4.8 end-to-end verification.
  • The delayed parent-file lookup, title-slot parsing, no-session behavior, and subagent-read exclusion are addressed in the current diff.
  • Per instruction, I only inspected the diff and did not run or build PR code.

@jeff-r2026
jeff-r2026 merged commit 85ff72c into Tencent:main Oct 1, 2026
13 checks passed
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