feat(coding-agent): delivered job and LSP notifications via aside channel

- Routed background-job completions and late LSP diagnostics through the new non-interrupting aside channel so the model sees them mid-run between requests.
- Removed inline custom rendering from the LSP tool now that diagnostics surface through the shared transcript renderer.
This commit is contained in:
can1357
2026-06-08 06:16:37 +02:00
parent dbd09cf4ee
commit d9d061348c
5 changed files with 6 additions and 7 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Added
- Added a non-interrupting "aside" message channel to the agent loop (`AgentLoopConfig.getAsideMessages` / `Agent.setAsideMessageProvider`). Asides are drained at each step boundary (after a tool batch, before the next model call) and at the yield check, so passive notifications (e.g. background-job completions, late LSP diagnostics) reach the model *between requests* without waiting for the agent to stop and without aborting in-flight tools the way steering does.
### Changed
- Changed core custom and hook messages to convert to `developer` messages for provider context.
+1
View File
@@ -8,6 +8,7 @@
### Changed
- Changed background-job completion and late LSP diagnostic delivery to inject at the next agent step boundary (mid-run), via the new non-interrupting "aside" channel, instead of only when the agent reaches a yield/follow-up point. The model now sees these notifications between its own requests without the turn having to end first, and in-flight tools are never interrupted; `job`-poll acknowledgement still suppresses results the agent already saw.
- Changed late LSP diagnostics after edit or write to surface in the chat transcript as `Late diagnostics` entries rendered through the same grouped tree renderer the `edit`/`write` tools use (per-file nodes, severity icons, `:line:col` locations), and to honor the global tool-output expand toggle (collapsed entries cap at 5 diagnostics with a `… N more` hint)
- Changed delayed diagnostics delivery to batch late results in one message per flush instead of a raw hidden custom payload
- Changed hidden custom messages and file-mention context to reach providers as `developer` messages instead of user-authored turns, so system reminders no longer pollute compacted user history.
@@ -4,7 +4,6 @@ import type { GalleryFixture } from "./types";
export const codeintelFixtures: Record<string, GalleryFixture> = {
lsp: {
label: "LSP",
customRendered: true,
streamingArgs: {
action: "references",
file: "src/server/auth.ts",
@@ -25,7 +25,7 @@ export interface GalleryFixture {
renderState?: (state: GalleryFixtureState, width: number, expanded: boolean) => string[] | Promise<string[]>;
/**
* Set for tools whose real `AgentTool` attaches `renderCall`/`renderResult`
* directly on the instance (e.g. `lsp`, `task`). The harness then attaches
* directly on the instance (e.g. `task`). The harness then attaches
* the registry renderer onto the fake tool so the component routes through
* the custom-tool branch — the same path production takes — instead of the
* built-in registry branch. The two branches can diverge, so exercising the
-5
View File
@@ -40,7 +40,6 @@ import {
rangesOverlap,
} from "./edits";
import { detectLspmux } from "./lspmux";
import { renderCall, renderResult } from "./render";
import {
type CodeAction,
type CodeActionContext,
@@ -1310,10 +1309,6 @@ export class LspTool implements AgentTool<typeof lspSchema, LspToolDetails, Them
readonly summary = "Query LSP (language server) for diagnostics, hover info, and references";
readonly description: string;
readonly parameters = lspSchema;
readonly renderCall = renderCall;
readonly renderResult = renderResult;
readonly mergeCallAndResult = true;
readonly inline = true;
readonly strict = true;
constructor(private readonly session: ToolSession) {