You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(events): context injection for opencode and JSON-envelope agent hooks (#3934)
* feat(events): context injection for opencode and JSON-envelope agent hooks
Adds first-class context injection to agent runtime events:
1. opencode: maps session_start to experimental.chat.system.transform (injects into system prompt) and user_prompt_submit to chat.message (injects synthetic TextPart). TS plugin captures runEvent stdout (stdio pipe, encoding utf-8) and pushes into output objects. Part IDs derive from output.parts[last].id to preserve OpenCode's prt_ brand and prevent session schema crashes.
2. JSON-envelope hook wrapping: adds events_context_envelope to IntegrationBase so agents that require JSON on stdout receive their target envelope via the dispatcher's 5th argument:
- gemini, tabnine, qwen, devin: hookSpecificOutput.additionalContext on session_start/user_prompt_submit; suppress on non-injectable events (prevents systemMessage user-facing noise)
- copilot: top-level additionalContext on session_start
- cursor: top-level additional_context on session_start; suppress elsewhere
- claude, codex: plain stdout passthrough (already injected)
3. Dispatcher template and resolve_and_run_event_command parse the 5th envelope arg and wrap stdout accordingly.
Tests added for opencode TextPart schema, part ID derivation, envelope command generation, and dispatcher output wrapping. All 162 events/integration tests pass.
* fix(events): address code review on #3934
- Qwen/Gemini/Tabnine/Devin: include native hookEventName inside
hookSpecificOutput envelope (required by Qwen's hooks spec). Thread
the native event name from the integration's CANONICAL_TO_NATIVE
through _dispatcher_command as a 6th dispatcher argument, through
the dispatcher template's main()/_run_inline()/_emit(), and through
resolve_and_run_event_command()/_emit_event_stdout().
- Copilot: map user_prompt_submit to additionalContext (previously
unmapped, breaking per-prompt context injection despite Copilot CLI
supporting it via userPromptSubmitted).
- OpenCode: guard experimental.chat.system.transform so canonical
session_start handlers only run when input.sessionID is present —
OpenCode fires this hook for non-session operations (e.g. agent
generation) with no sessionID.
Assisted-by: opencode (model: glm-5.2, supervised)
* fix(events): address second Copilot review round on #3934
- Positional arg alignment: always emit default timeout (60s) as the
4th dispatcher argument even when timeout_seconds is omitted, so the
envelope (5th) and native_event (6th) land in the correct argv slots.
Previously, omitting timeout_seconds caused the envelope to be parsed
as an invalid timeout, silently falling back to plain stdout.
- OpenCode session_start caching: cache handler output per sessionID in
the generated TS plugin so non-idempotent handlers (setup, telemetry,
file-mutating scripts) run once per session instead of on every LLM
request. Cache is evicted on session.deleted.
- Updated PR description to reflect Copilot user_prompt_submit now maps
to additionalContext (was documented as plain/unprocessed).
Assisted-by: opencode (model: glm-5.2, supervised)
0 commit comments