Skip to content

feat(assistant): add context build seam#31

Merged
omarluq merged 2 commits into
mainfrom
feat/context-build-seam
May 21, 2026
Merged

feat(assistant): add context build seam#31
omarluq merged 2 commits into
mainfrom
feat/context-build-seam

Conversation

@omarluq
Copy link
Copy Markdown
Owner

@omarluq omarluq commented May 21, 2026

Summary

  • add bounded extension context contributions through the context_build lifecycle seam
  • expose context token breakdown for system, skills, history, and extensions
  • wire model context construction through the new context builder before provider execution

Validation

  • mise exec -- go test ./...
  • mise exec -- task build
  • mise exec -- task ci

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c23239b6-bc83-4165-8fc4-fad652046680

📥 Commits

Reviewing files that changed from the base of the PR and between 784dc88 and 5b3fcd3.

📒 Files selected for processing (2)
  • internal/assistant/context_build.go
  • internal/assistant/lifecycle.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Extensions can provide bounded context contributions via a new context_build lifecycle event; contributions are token-limited and reflected in a detailed usage breakdown.
    • New lifecycle events for provider requests/responses/errors and tool call/result/error were added.
  • Documentation

    • API docs updated with expanded lifecycle event list and clarified bounded payload/usage guidance.
  • Tests

    • Added runtime tests validating contribution limits and breakdown reporting.

Walkthrough

This PR introduces a context build lifecycle pipeline that enables extensions to contribute bounded system context during prompt generation. It adds orchestration and types to assemble base prompts with auto-activated skills, dispatches a context_build lifecycle event, validates/formats extension contributions into the system prompt, computes category token breakdowns, and integrates the flow into the runtime.

Changes

Context Build Lifecycle & Extension Contributions

Layer / File(s) Summary
API Documentation
docs/extension-api.md
Documents the new context_build lifecycle event, handler example, and bounded contributions constraints.
Context Build Core Data Structures & Orchestration
internal/assistant/context_build.go
Adds constants and types plus buildModelContext orchestrator to assemble messages, build base prompt, dispatch extensions, parse/append contributions, and compute usage.
Base System Prompt & Skill Processing
internal/assistant/context_build.go
Implements modelContextBase to build the base prompt, load/format skills, auto-activate skills, and estimate system/skills/history tokens.
Initial Result, Recalculation & Usage Estimation
internal/assistant/context_build.go
Initializes contextBuildResult, recalculates Usage/Breakdown after contributions, and estimates input tokens for budgeting.
Contribution Parsing & Validation
internal/assistant/context_build.go
Parses payload.contributions (list or numeric-key map), validates entry shape/content, enforces per-contribution token limit, normalizes numeric maps, and coerces defaults.
Append & Format Extension Contributions
internal/assistant/context_build.go
Appends validated contributions into the system prompt as an <extension_context> wrapper with per-contribution <block ...> tags and aggregates extension token totals.
Lifecycle Dispatch Refactor & Context Build Payload
internal/assistant/lifecycle.go
Refactors dispatchLifecycle to return (LifecycleDispatchResult, error), adds dispatchObservationalLifecycle, and redesigns context_build payload to include breakdown and cloned fields.
Runtime Integration of Context Build
internal/assistant/runtime.go
Runtime.Prompt uses observational lifecycle dispatch; modelResponse calls buildModelContext for context/messages/usage; baseSystemPrompt replaces previous helper and skill appending is delegated to the context build.
Provider & Tool Event Emission Updates
internal/assistant/runtime_events.go
Provider and tool lifecycle emitters now use dispatchObservationalLifecycle while preserving payload structure.
Token Usage Cleanup
internal/assistant/usage.go
Removes estimateTokenUsage; token estimation is consolidated in the context build implementation.
Context Build Runtime Tests
internal/assistant/context_build_test.go
Adds tests verifying bounded acceptance/rejection of contributions, presence of breakdown and max_contribution_tokens, and published extension token counts on the event bus.

Sequence Diagram

sequenceDiagram
  participant Client
  participant Runtime
  participant ContextBuild as buildModelContext
  participant ContextBase as modelContextBase
  participant Lifecycle
  participant Extensions
  participant Provider

  Client->>Runtime: Prompt()
  Runtime->>ContextBuild: buildModelContext()
  ContextBuild->>ContextBase: build base system prompt & estimate tokens
  ContextBuild->>Lifecycle: dispatchContextBuild(base, result)
  Lifecycle->>Extensions: Emit context_build lifecycle event
  Extensions-->>Lifecycle: Return contributions
  ContextBuild->>ContextBuild: Parse/validate & append contributions
  ContextBuild-->>Runtime: contextBuildResult (prompt, usage, breakdown)
  Runtime->>Provider: make completion request
  Provider-->>Runtime: completion response
  Runtime-->>Client: assistant response
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

  • omarluq/librecode#21: Introduces lifecycle dispatch infrastructure and extension.LifecycleDispatchResult used by this PR.
  • omarluq/librecode#28: Overlaps on context_build payload construction and related lifecycle plumbing.
  • omarluq/librecode#23: Related lifecycle emission/refactor work that intersects with this PR's observational dispatch changes.

Poem

🐰 I hopped through prompts and counted the codes,
Extensions whispered stories in bounded odes,
Tokens tallied, blocks tucked tight,
Context built snug for the model's flight.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(assistant): add context build seam' accurately and concisely describes the main feature addition: introducing a context_build lifecycle seam for the assistant.
Description check ✅ Passed The description directly relates to the changeset, covering all three main objectives: adding bounded extension context contributions, exposing token breakdown, and routing context construction through the new builder.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/context-build-seam

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 21, 2026

Codecov Report

❌ Patch coverage is 84.94208% with 39 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.44%. Comparing base (d9eacf6) to head (5b3fcd3).

Files with missing lines Patch % Lines
internal/assistant/context_build.go 87.75% 14 Missing and 10 partials ⚠️
internal/assistant/lifecycle.go 70.21% 14 Missing ⚠️
internal/assistant/runtime_events.go 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #31      +/-   ##
==========================================
+ Coverage   58.13%   58.44%   +0.30%     
==========================================
  Files         165      166       +1     
  Lines       15973    16160     +187     
==========================================
+ Hits         9286     9444     +158     
- Misses       5719     5742      +23     
- Partials      968      974       +6     
Flag Coverage Δ
unittests 58.44% <84.94%> (+0.30%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/assistant/lifecycle.go (1)

81-89: ⚡ Quick win

Avoid double-logging lifecycle dispatch failures.

dispatchLifecycle already logs the error, so every observational failure gets logged twice once there and once again in dispatchObservationalLifecycle.

🪵 Suggested cleanup
-	if err != nil && runtime.logger != nil {
-		runtime.logger.Debug(
-			"extension lifecycle event failed",
-			slog.String("event", string(name)),
-			slog.Any("error", err),
-		)
-	}
-
 	return result, err

Also applies to: 139-150

🤖 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/assistant/lifecycle.go` around lines 81 - 89,
dispatchObservationalLifecycle is double-logging lifecycle errors because
dispatchLifecycle already logs failures; remove the extra
runtime.logger.Debug/Info/Error call in dispatchObservationalLifecycle (the
block that logs "extension lifecycle event failed" with slog.String("event",
string(name)) and slog.Any("error", err)) and rely on dispatchLifecycle's
logging instead. Apply the same cleanup to the analogous block at the other
location noted (lines where a similar log appears for the other lifecycle
dispatch), referencing the functions dispatchLifecycle and
dispatchObservationalLifecycle and the runtime.logger usage to locate the
duplicated logging.
🤖 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/assistant/context_build.go`:
- Around line 205-233: The two fmt.Fprintf calls in appendContextContributions
(writing attributes and the source/role/tokens block into the strings.Builder)
currently ignore errors by assigning them to blank identifiers; update the
function to properly handle these returns: either switch to using
builder.WriteString/strconv to avoid fmt errors, or change
appendContextContributions to return error and capture the err from each
fmt.Fprintf (remove the underscore assignments), returning the first non-nil
error; also update callers to handle the new error return if you choose the
latter. Ensure you reference appendContextContributions, contextBuildResult,
contextContribution, and result.SystemPrompt when making the change so the
builder writes and error handling are applied to those exact spots.

---

Nitpick comments:
In `@internal/assistant/lifecycle.go`:
- Around line 81-89: dispatchObservationalLifecycle is double-logging lifecycle
errors because dispatchLifecycle already logs failures; remove the extra
runtime.logger.Debug/Info/Error call in dispatchObservationalLifecycle (the
block that logs "extension lifecycle event failed" with slog.String("event",
string(name)) and slog.Any("error", err)) and rely on dispatchLifecycle's
logging instead. Apply the same cleanup to the analogous block at the other
location noted (lines where a similar log appears for the other lifecycle
dispatch), referencing the functions dispatchLifecycle and
dispatchObservationalLifecycle and the runtime.logger usage to locate the
duplicated logging.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b906fc09-01b8-4f7e-88a7-c880063db253

📥 Commits

Reviewing files that changed from the base of the PR and between d9eacf6 and 784dc88.

📒 Files selected for processing (7)
  • docs/extension-api.md
  • internal/assistant/context_build.go
  • internal/assistant/context_build_test.go
  • internal/assistant/lifecycle.go
  • internal/assistant/runtime.go
  • internal/assistant/runtime_events.go
  • internal/assistant/usage.go
💤 Files with no reviewable changes (1)
  • internal/assistant/usage.go

Comment thread internal/assistant/context_build.go
@sonarqubecloud
Copy link
Copy Markdown

@omarluq omarluq merged commit fc90076 into main May 21, 2026
13 checks passed
@omarluq omarluq deleted the feat/context-build-seam branch May 23, 2026 04:40
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