refactor(coding-agent): add runtime host for session switching closes #2024
This commit is contained in:
@@ -33,10 +33,6 @@ export default function (pi: ExtensionAPI) {
|
||||
applyLabel(ctx);
|
||||
});
|
||||
|
||||
pi.on("session_switch", async (_event, ctx) => {
|
||||
applyLabel(ctx);
|
||||
});
|
||||
|
||||
pi.registerCommand("thinking-label", {
|
||||
description: "Set the hidden thinking label. Use without args to reset.",
|
||||
handler: async (args, ctx) => {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* - notify() - after each dialog completes
|
||||
* - setStatus() - on turn_start/turn_end
|
||||
* - setWidget() - on session_start
|
||||
* - setTitle() - on session_start and session_switch
|
||||
* - setTitle() - on session_start
|
||||
* - setEditorText() - via /rpc-prefill command
|
||||
*/
|
||||
|
||||
@@ -24,18 +24,12 @@ export default function (pi: ExtensionAPI) {
|
||||
|
||||
// -- setTitle, setWidget, setStatus on session lifecycle --
|
||||
|
||||
pi.on("session_start", async (_event, ctx) => {
|
||||
ctx.ui.setTitle("pi RPC Demo");
|
||||
pi.on("session_start", async (event, ctx) => {
|
||||
ctx.ui.setTitle(event.reason === "new" ? "pi RPC Demo (new session)" : "pi RPC Demo");
|
||||
ctx.ui.setWidget("rpc-demo", ["--- RPC Extension UI Demo ---", "Loaded and ready."]);
|
||||
ctx.ui.setStatus("rpc-demo", `Turns: ${turnCount}`);
|
||||
});
|
||||
|
||||
pi.on("session_switch", async (_event, ctx) => {
|
||||
turnCount = 0;
|
||||
ctx.ui.setTitle("pi RPC Demo (new session)");
|
||||
ctx.ui.setStatus("rpc-demo", `Turns: ${turnCount}`);
|
||||
});
|
||||
|
||||
// -- setStatus on turn lifecycle --
|
||||
|
||||
pi.on("turn_start", async (_event, ctx) => {
|
||||
|
||||
@@ -29,12 +29,4 @@ export default function (pi: ExtensionAPI) {
|
||||
const text = theme.fg("dim", ` Turn ${turnCount} complete`);
|
||||
ctx.ui.setStatus("status-demo", check + text);
|
||||
});
|
||||
|
||||
pi.on("session_switch", async (event, ctx) => {
|
||||
if (event.reason === "new") {
|
||||
turnCount = 0;
|
||||
const theme = ctx.ui.theme;
|
||||
ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,8 +130,6 @@ export default function (pi: ExtensionAPI) {
|
||||
|
||||
// Reconstruct state on session events
|
||||
pi.on("session_start", async (_event, ctx) => reconstructState(ctx));
|
||||
pi.on("session_switch", async (_event, ctx) => reconstructState(ctx));
|
||||
pi.on("session_fork", async (_event, ctx) => reconstructState(ctx));
|
||||
pi.on("session_tree", async (_event, ctx) => reconstructState(ctx));
|
||||
|
||||
// Register the todo tool for the LLM
|
||||
|
||||
@@ -138,9 +138,4 @@ export default function toolsExtension(pi: ExtensionAPI) {
|
||||
pi.on("session_tree", async (_event, ctx) => {
|
||||
restoreFromBranch(ctx);
|
||||
});
|
||||
|
||||
// Restore state after forking
|
||||
pi.on("session_fork", async (_event, ctx) => {
|
||||
restoreFromBranch(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
const applyWidgets = (ctx: ExtensionContext) => {
|
||||
if (!ctx.hasUI) return;
|
||||
ctx.ui.setWidget("widget-above", ["Above editor widget"]);
|
||||
ctx.ui.setWidget("widget-below", ["Below editor widget"], { placement: "belowEditor" });
|
||||
};
|
||||
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
export default function widgetPlacementExtension(pi: ExtensionAPI) {
|
||||
pi.on("session_start", (_event, ctx) => {
|
||||
applyWidgets(ctx);
|
||||
});
|
||||
|
||||
pi.on("session_switch", (_event, ctx) => {
|
||||
applyWidgets(ctx);
|
||||
if (!ctx.hasUI) return;
|
||||
ctx.ui.setWidget("widget-above", ["Above editor widget"]);
|
||||
ctx.ui.setWidget("widget-below", ["Below editor widget"], { placement: "belowEditor" });
|
||||
});
|
||||
}
|
||||
|
||||
49
packages/coding-agent/examples/sdk/13-session-runtime.ts
Normal file
49
packages/coding-agent/examples/sdk/13-session-runtime.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Session Runtime Host
|
||||
*
|
||||
* Use the runtime host when you need to replace the active AgentSession,
|
||||
* for example for new-session, resume, fork, or import flows.
|
||||
*
|
||||
* The important pattern is: after the host replaces the runtime, rebind any
|
||||
* session-local subscriptions and extension bindings to `runtimeHost.session`.
|
||||
*/
|
||||
|
||||
import { AgentSessionRuntimeHost, createAgentSessionRuntime, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
const bootstrap = {};
|
||||
const runtime = await createAgentSessionRuntime(bootstrap, {
|
||||
cwd: process.cwd(),
|
||||
sessionManager: SessionManager.create(process.cwd()),
|
||||
});
|
||||
const runtimeHost = new AgentSessionRuntimeHost(bootstrap, runtime);
|
||||
|
||||
let unsubscribe: (() => void) | undefined;
|
||||
|
||||
async function bindSession() {
|
||||
unsubscribe?.();
|
||||
const session = runtimeHost.session;
|
||||
await session.bindExtensions({});
|
||||
unsubscribe = session.subscribe((event) => {
|
||||
if (event.type === "queue_update") {
|
||||
console.log("Queued:", event.steering.length + event.followUp.length);
|
||||
}
|
||||
});
|
||||
return session;
|
||||
}
|
||||
|
||||
let session = await bindSession();
|
||||
const originalSessionFile = session.sessionFile;
|
||||
console.log("Initial session:", originalSessionFile);
|
||||
|
||||
await runtimeHost.newSession();
|
||||
session = await bindSession();
|
||||
console.log("After newSession():", session.sessionFile);
|
||||
|
||||
if (originalSessionFile) {
|
||||
await runtimeHost.switchSession(originalSessionFile);
|
||||
session = await bindSession();
|
||||
console.log("After switchSession():", session.sessionFile);
|
||||
}
|
||||
|
||||
unsubscribe?.();
|
||||
await runtimeHost.dispose();
|
||||
@@ -1,6 +1,6 @@
|
||||
# SDK Examples
|
||||
|
||||
Programmatic usage of pi-coding-agent via `createAgentSession()`.
|
||||
Programmatic usage of pi-coding-agent via `createAgentSession()` and `createAgentSessionRuntime()`.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -18,6 +18,7 @@ Programmatic usage of pi-coding-agent via `createAgentSession()`.
|
||||
| `10-settings.ts` | Override compaction, retry, terminal settings |
|
||||
| `11-sessions.ts` | In-memory, persistent, continue, list sessions |
|
||||
| `12-full-control.ts` | Replace everything, no discovery |
|
||||
| `13-session-runtime.ts` | Manage runtime-backed session replacement |
|
||||
|
||||
## Running
|
||||
|
||||
|
||||
Reference in New Issue
Block a user