Skip to content

feat(subagent): link child sessions to parent and support resume (#87)#92

Merged
ezynda3 merged 3 commits into
masterfrom
feat/87-subagent-session-linking
Jul 8, 2026
Merged

feat(subagent): link child sessions to parent and support resume (#87)#92
ezynda3 merged 3 commits into
masterfrom
feat/87-subagent-session-linking

Conversation

@ezynda3

@ezynda3 ezynda3 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Description

Subagent runs currently create disconnected child sessions, and every invocation is one-shot — follow-up questions re-establish context from scratch. This PR implements both halves of #87:

1. Parent-child session linking. When a subagent is spawned from a session-backed parent, the child session's header now records parent_session_id (parent UUID), parent_session (parent file path), and subagent_task (the original prompt). Combined with the existing subagent_session_id tool-response metadata, links are now bidirectional, enabling session-tree navigation of delegated work. A new SubagentConfig.ParentSessionID allows an explicit override, and the previously-unused extension ParentSessionID field is now propagated through extbridge.

2. Resumable subagents. SubagentConfig gains a SessionID field (exposed to the LLM as an optional session_id parameter on the subagent tool). When set, the child Kit opens the existing session instead of starting fresh, so follow-up tasks reuse the subagent's accumulated context:

first, _ := host.Subagent(ctx, kit.SubagentConfig{Prompt: "Research how session persistence works"})

followUp, _ := host.Subagent(ctx, kit.SubagentConfig{
    Prompt:    "Now check how it handles errors",
    SessionID: first.SessionID, // resume the same child session
})

The tool description documents the resume workflow so the model knows to pass subagent_session_id back.

Fixes #87

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the documentation accordingly
  • New and existing unit tests pass locally with my changes (go test -race; only pre-existing environment-dependent activate_skill failures remain, reproduced identically on clean master)
  • golangci-lint run reports 0 issues on all touched packages

Additional Information

New primitives

  • internal/session/tree_manager.goTreeManager.SetParentLink(): stamps the parent reference into the header via in-place JSONL rewrite (header is line 1); in-memory sessions update in place
  • internal/session/store.goFindSessionPathByID(): header-only (first-line) session lookup by UUID, cwd session dir first with fallback scan of ~/.kit/sessions

Plumbing

  • pkg/kit/kit.goSubagentConfig.SessionID / ParentSessionID; Kit.Subagent() resolves resume paths up front (fast-fail on unknown IDs), stamps the parent link on newly created child sessions
  • internal/core/subagent.gosession_id tool parameter, threaded through SubagentSpawnRequest; updated tool description
  • internal/extensions/subagent.go + internal/extbridge/extbridge.go — extension SubagentConfig.SessionID added; SessionID/ParentSessionID propagated into the SDK path

Testsinternal/session/parent_link_test.go (5), pkg/kit/subagent_session_test.go (2), plus 2 in internal/core/subagent_test.go

Docspkg/kit/README.md, skills/kit-extensions/SKILL.md, and docs site (www/pages/advanced/subagents.md — new "Session linking and resuming" section — plus sdk/overview.md, extensions/capabilities.md, sessions.md); tome build passes

Backward compatibility

  • All new fields/parameters are optional; default behaviour is unchanged except that new subagent sessions now record the parent link when the parent is persisted (additive omitempty header fields)
  • SessionID + NoSession is rejected as mutually exclusive; unknown session IDs fail fast with an actionable error
  • Auto-linking only applies when the parent session is persisted — no dangling links to ephemeral in-memory parents; resumed sessions keep their original parent link

Related: #84 (named agents), #86 (background subagent handle) share these code paths.

Summary by CodeRabbit

  • New Features
    • Added subagent session resumption via session_id, returning a subagent_session_id for follow-up runs.
    • New child subagent sessions record parent-session linkage for improved traceability.
  • Bug Fixes
    • Improved session file discovery and clearer failures when resuming with unknown/invalid IDs.
    • Better handling of scan errors when reading session files.
  • Documentation
    • Expanded subagent/session docs with session linking and resumption guidance and updated examples.
  • Tests
    • Added coverage for session resumption, tool schema/description, and parent-link/session-path behavior.

- Stamp parent_session_id, parent_session, and subagent_task into new
  subagent session headers when the parent is session-backed, enabling
  bidirectional session-tree navigation of delegated work
- Add SubagentConfig.SessionID to resume an existing subagent session
  so follow-up tasks reuse the child's accumulated context; expose it
  as an optional session_id parameter on the subagent tool
- Add SubagentConfig.ParentSessionID override and propagate the
  previously-unused extension ParentSessionID through extbridge
- Add TreeManager.SetParentLink (in-place header rewrite) and
  FindSessionPathByID (header-only session lookup by UUID)
- Document the resume workflow in the tool description, SDK README,
  extension skill, and docs site

Fixes #87
@mark-iii-labs-huly

Copy link
Copy Markdown

Connected to Huly®: KIT-93

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ezynda3, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 39 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eee66583-b6d8-4740-9d7e-f9080bfd8870

📥 Commits

Reviewing files that changed from the base of the PR and between 98e5df0 and b4e847f.

📒 Files selected for processing (1)
  • internal/session/tree_manager.go
📝 Walkthrough

Walkthrough

This PR adds resumable subagent sessions and parent-child session linking. It extends subagent configuration and tool inputs, adds session lookup and session-header rewrite support, wires Kit.Subagent to resume or link sessions, propagates the new fields through extbridge, and updates tests and docs.

Changes

Resumable subagent sessions

Layer / File(s) Summary
SubagentConfig session fields
internal/extensions/subagent.go, pkg/kit/kit.go
Adds SessionID and ParentSessionID fields with documentation describing resume semantics and mutual exclusivity with NoSession.
Session lookup and parent-link persistence
internal/session/store.go, internal/session/tree_manager.go, internal/session/parent_link_test.go
Adds FindSessionPathByID with header-scanning helpers, a scanner error check in extractSessionInfo, and TreeManager.SetParentLink to rewrite headers and entries, with tests covering reopen, rewrite, in-memory, lookup, and malformed-file scenarios.
Kit.Subagent resume and parent-link wiring
pkg/kit/kit.go, pkg/kit/subagent_session_test.go
Subagent() validates SessionID/NoSession conflicts, resolves the resume path, sets SessionPath for the child, calls SetParentLink for newly created sessions, and forwards SessionID through the internal generate path; tests verify conflict and unknown-session-id failure paths.
Subagent tool session_id parameter
internal/core/subagent.go, internal/core/subagent_test.go
Adds SessionID to SubagentSpawnRequest and subagentArgs, updates tool description and parameters, and wires args.SessionID into the spawn request; tests verify forwarding and description content.
Extbridge session field propagation
internal/extbridge/extbridge.go
Forwards SessionID and ParentSessionID from extension config into kit.SubagentConfig.
Documentation updates for session linking and resume
pkg/kit/README.md, skills/kit-extensions/SKILL.md, www/pages/advanced/subagents.md, www/pages/extensions/capabilities.md, www/pages/sdk/overview.md, www/pages/sessions.md
Documents parent-child session linkage, session_id resume usage, and header fields across SDK and extension docs.

Estimated code review effort: 4 (Complex) | ~60 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements both requested capabilities: bidirectional session linking and session_id-based subagent resumption, with matching docs and tests.
Out of Scope Changes check ✅ Passed The changes are focused on session linking and resume support, with only supporting lookup, header, test, and documentation updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the two main changes: parent-child session linking and resumable subagent sessions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/87-subagent-session-linking

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@internal/session/store.go`:
- Around line 385-386: Wrap the scanner error returned from readSessionHeader so
it follows the same error-handling pattern as extractSessionInfo. Update the
scanner.Err() branch in readSessionHeader to return a contextual fmt.Errorf with
the session-file scanning message and %w wrapping, instead of returning err
directly.

In `@internal/session/tree_manager.go`:
- Around line 315-363: SetParentLink in TreeManager rewrites the session file
non-atomically, so a failed write can truncate the original data and corrupt the
on-disk session. Update the rewrite path to write the new header and entries to
a temporary file first, flush and close it successfully, then atomically replace
the original file with rename/replace semantics. Keep the existing header
rewrite flow in SetParentLink, but ensure tm.file, tm.writer, and tm.filePath
are only switched to the new file after the temp file has been fully written.

In `@pkg/kit/kit.go`:
- Around line 2352-2359: The session resume path lookup in the `cfg.SessionID`
block ignores the error from `os.Getwd()`, so `session.FindSessionPathByID` may
run with an invalid base directory. Update this flow in `kit.go` to check the
`os.Getwd()` result before calling `session.FindSessionPathByID`, and return a
wrapped `fmt.Errorf("context: %w", err)`-style error if it fails so `resumePath`
is only used when `cwd` is valid.

In `@www/pages/advanced/subagents.md`:
- Line 50: The description in subagents.md overstates capabilities by saying
child Kit instances have “full tool access”; update the wording in the subagents
section to reflect that they inherit the parent’s active tools minus subagent,
and that named-agent presets and allowlists may further restrict access. Use the
existing subagents explanation as the anchor and rewrite only that sentence to
be accurate and precise.

In `@www/pages/sessions.md`:
- Around line 22-23: The session documentation wording in the subagents section
overstates the behavior of parent headers; update the sentence so it only claims
parent_session_id, parent_session, and subagent_task are recorded when the
parent is session-backed. Keep the change localized to the affected prose in the
sessions guide and align the phrasing with the actual behavior described by the
subagents feature.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 18387294-3fd0-4c7d-abe4-6642fca6ae9e

📥 Commits

Reviewing files that changed from the base of the PR and between eaec327 and a81d2cf.

📒 Files selected for processing (15)
  • internal/core/subagent.go
  • internal/core/subagent_test.go
  • internal/extbridge/extbridge.go
  • internal/extensions/subagent.go
  • internal/session/parent_link_test.go
  • internal/session/store.go
  • internal/session/tree_manager.go
  • pkg/kit/README.md
  • pkg/kit/kit.go
  • pkg/kit/subagent_session_test.go
  • skills/kit-extensions/SKILL.md
  • www/pages/advanced/subagents.md
  • www/pages/extensions/capabilities.md
  • www/pages/sdk/overview.md
  • www/pages/sessions.md

Comment thread internal/session/store.go Outdated
Comment thread internal/session/tree_manager.go
Comment thread pkg/kit/kit.go
Comment thread www/pages/advanced/subagents.md Outdated
Comment thread www/pages/sessions.md Outdated
)

- Make SetParentLink's header rewrite atomic: write to a temp file and
  rename over the original so a partial write can never truncate or
  corrupt the session (Major); extend test to assert no temp file leaks
- Check and wrap the os.Getwd error in Kit.Subagent's resume path
  instead of discarding it (Minor)
- Wrap scanner.Err in readSessionHeader per error-handling guidelines
  (Minor)
- Docs: qualify tool-access wording on the subagents page and the
  parent-header claim in sessions.md to match actual behavior (Minor)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/session/tree_manager.go (1)

371-376: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Optional: Sync() the temp file before rename for crash durability.

w.Flush() pushes the buffer to the OS but does not force it to stable storage. If the process/host crashes between rename and the OS flushing the temp file's data blocks, the renamed file can contain the new metadata entry but zero-length data on some filesystems. Adding tmpFile.Sync() before Close() (and optionally an fsync of the parent dir) closes this window. The atomicity guarantee against partial-write corruption already holds via rename; this only strengthens durability.

🤖 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 `@internal/session/tree_manager.go` around lines 371 - 376, The temp-file
rewrite flow in tree_manager.go should strengthen crash durability by syncing
the file before rename. In the rewrite path around the existing w.Flush() and
tmpFile.Close() handling, call tmpFile.Sync() after flushing buffered writes and
before closing, so the temp file’s contents are forced to stable storage before
the atomic rename. Keep the current rewriteErr handling in the same rewrite
helper logic, and if you choose to harden further, also sync the parent
directory after the rename.
🤖 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.

Nitpick comments:
In `@internal/session/tree_manager.go`:
- Around line 371-376: The temp-file rewrite flow in tree_manager.go should
strengthen crash durability by syncing the file before rename. In the rewrite
path around the existing w.Flush() and tmpFile.Close() handling, call
tmpFile.Sync() after flushing buffered writes and before closing, so the temp
file’s contents are forced to stable storage before the atomic rename. Keep the
current rewriteErr handling in the same rewrite helper logic, and if you choose
to harden further, also sync the parent directory after the rename.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9abbabfe-79ca-4802-9462-d34be197eac3

📥 Commits

Reviewing files that changed from the base of the PR and between a81d2cf and 98e5df0.

📒 Files selected for processing (6)
  • internal/session/parent_link_test.go
  • internal/session/store.go
  • internal/session/tree_manager.go
  • pkg/kit/kit.go
  • www/pages/advanced/subagents.md
  • www/pages/sessions.md
✅ Files skipped from review due to trivial changes (2)
  • www/pages/sessions.md
  • www/pages/advanced/subagents.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/session/parent_link_test.go
  • internal/session/store.go
  • pkg/kit/kit.go

- Address CodeRabbit nitpick: w.Flush() reaches the OS cache only; a
  crash between rename and writeback could leave a renamed-but-empty
  session file on some filesystems. Sync before close closes the window.
@ezynda3 ezynda3 merged commit 10e9e27 into master Jul 8, 2026
3 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.

feat: parent-child session linking and resumable subagents

1 participant