diff --git a/packages/app/src/components/dialog-custom-provider.tsx b/packages/app/src/components/dialog-custom-provider.tsx
index 647e5002a2..dfc1bb8c22 100644
--- a/packages/app/src/components/dialog-custom-provider.tsx
+++ b/packages/app/src/components/dialog-custom-provider.tsx
@@ -177,7 +177,7 @@ export function DialogCustomProvider(props: Props) {
>
-
+
{language.t("provider.custom.title")}
diff --git a/packages/app/src/components/settings-providers.tsx b/packages/app/src/components/settings-providers.tsx
index 24e7a60104..ca6413e4ba 100644
--- a/packages/app/src/components/settings-providers.tsx
+++ b/packages/app/src/components/settings-providers.tsx
@@ -226,7 +226,7 @@ const SettingsProvidersContent: Component = () => {
>
-
+
{language.t("provider.custom.title")}
{language.t("settings.providers.tag.custom")}
diff --git a/packages/app/src/components/settings-v2/providers.tsx b/packages/app/src/components/settings-v2/providers.tsx
index cd24bbd455..e244581b97 100644
--- a/packages/app/src/components/settings-v2/providers.tsx
+++ b/packages/app/src/components/settings-v2/providers.tsx
@@ -223,7 +223,7 @@ export const SettingsProvidersV2: Component = () => {
event.type)).toEqual(["server.connected", "model.selected"])
+ expect(Array.from(events).map((event) => event.type)).toEqual(["server.connected", "session.model.selected"])
const durable = events[1]
- if (durable?.type !== "model.selected") throw new Error("Expected model event")
+ if (durable?.type !== "session.model.selected") throw new Error("Expected model event")
expect(DateTime.toEpochMillis(durable.created)).toBe(1_717_171_717_000)
expect(durable.durable).toEqual({ aggregateID: "ses_test", seq: 1, version: 1 })
})
@@ -159,8 +159,8 @@ test("session methods retain decoded Effect inputs and outputs", async () => {
expect(result.context).toEqual([])
expect(logQueries[0]).toEqual({ after: "0" })
const logged = Array.from(result.log)
- expect(logged.map((item) => item.type)).toEqual(["model.selected", "log.synced"])
- expect(logged[0]?.type === "model.selected" && DateTime.toEpochMillis(logged[0].created)).toBe(
+ expect(logged.map((item) => item.type)).toEqual(["session.model.selected", "log.synced"])
+ expect(logged[0]?.type === "session.model.selected" && DateTime.toEpochMillis(logged[0].created)).toBe(
1_717_171_717_000,
)
expect(logged.at(-1)).toEqual(synced)
@@ -228,7 +228,7 @@ const modelSwitchedMessage = {
const modelSwitchedEvent = {
id: "evt_model",
created: 1_717_171_717_000,
- type: "model.selected",
+ type: "session.model.selected",
durable: { aggregateID: "ses_test", seq: 1, version: 1 },
data: {
sessionID: "ses_test",
diff --git a/packages/client/test/promise.test.ts b/packages/client/test/promise.test.ts
index 9e8ea7acfe..d445a69c08 100644
--- a/packages/client/test/promise.test.ts
+++ b/packages/client/test/promise.test.ts
@@ -160,7 +160,7 @@ test("event.subscribe exposes the Promise event stream wire projection", async (
for await (const event of client.event.subscribe()) events.push(event)
expect(events).toEqual([{ id: "evt_connected", created: 0, type: "server.connected", data: {} }, modelSwitchedEvent])
- expect(events[1]?.type === "model.selected" && events[1].created).toBe(1_717_171_717_000)
+ expect(events[1]?.type === "session.model.selected" && events[1].created).toBe(1_717_171_717_000)
})
test("event.subscribe terminates on malformed Promise SSE data", async () => {
@@ -329,7 +329,7 @@ const synced = { type: "log.synced", aggregateID: "ses_test", seq: 1 }
const modelSwitchedEvent = {
id: "evt_model",
created: 1_717_171_717_000,
- type: "model.selected",
+ type: "session.model.selected",
durable: { aggregateID: "ses_test", seq: 1, version: 1 },
data: {
sessionID: "ses_test",
diff --git a/packages/core/src/database/migration.gen.ts b/packages/core/src/database/migration.gen.ts
index 7956b64f4d..e6a236f527 100644
--- a/packages/core/src/database/migration.gen.ts
+++ b/packages/core/src/database/migration.gen.ts
@@ -43,5 +43,6 @@ export const migrations = (
import("./migration/20260702134641_add_session_context_entry"),
import("./migration/20260703090000_reset_v2_event_rename_sweep"),
import("./migration/20260703181610_event_created_column"),
+ import("./migration/20260703190000_reset_v2_shell_event_payloads"),
])
).map((module) => module.default) satisfies DatabaseMigration.Migration[]
diff --git a/packages/core/src/database/migration/20260703190000_reset_v2_shell_event_payloads.ts b/packages/core/src/database/migration/20260703190000_reset_v2_shell_event_payloads.ts
new file mode 100644
index 0000000000..ffbe40652c
--- /dev/null
+++ b/packages/core/src/database/migration/20260703190000_reset_v2_shell_event_payloads.ts
@@ -0,0 +1,14 @@
+import { Effect } from "effect"
+import type { DatabaseMigration } from "../migration"
+
+export default {
+ id: "20260703190000_reset_v2_shell_event_payloads",
+ up(tx) {
+ return Effect.gen(function* () {
+ yield* tx.run(`DELETE FROM \`session_input\`;`)
+ yield* tx.run(`DELETE FROM \`session_message\`;`)
+ yield* tx.run(`DELETE FROM \`event\`;`)
+ yield* tx.run(`DELETE FROM \`event_sequence\`;`)
+ })
+ },
+} satisfies DatabaseMigration.Migration
diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts
index 108d36707a..e8928a7520 100644
--- a/packages/core/src/session.ts
+++ b/packages/core/src/session.ts
@@ -41,8 +41,8 @@ import type { EventLog } from "@opencode-ai/schema/event-log"
import { SkillV2 } from "./skill"
import { Job } from "./job"
import { CommandV2 } from "./command"
-import { Identifier } from "./util/identifier"
import { Shell } from "./shell"
+import { Shell as ShellSchema } from "@opencode-ai/schema/shell"
import { KeyedMutex } from "./effect/keyed-mutex"
export const RevertState = Revert.State
@@ -272,19 +272,6 @@ const layer = Layer.effect(
),
)
- // Session shell is user-initiated and synchronous at the API boundary, while
- // the Location shell service owns process lifecycle and file-backed output.
- const runShellCommand = (command: string, cwd: string) =>
- Effect.gen(function* () {
- const shell = yield* Shell.Service
- const info = yield* shell.create({ command, cwd })
- yield* shell.wait(info.id)
- const output = yield* shell.output(info.id, { limit: SHELL_MAX_CAPTURE_BYTES })
- return output.output || "(no output)"
- }).pipe(
- Effect.catchTag("Shell.NotFoundError", () => Effect.succeed("Shell command output is no longer available.")),
- )
-
const result = Service.of({
create: Effect.fn("V2Session.create")(function* (input) {
const sessionID = input.id ?? SessionSchema.ID.create()
@@ -550,23 +537,38 @@ const layer = Layer.effect(
Effect.gen(function* () {
activeShells.add(input.sessionID)
if ((yield* execution.active).has(input.sessionID)) yield* execution.awaitIdle(input.sessionID)
- const callID = Identifier.ascending()
+ const started = yield* Effect.gen(function* () {
+ const shell = yield* Shell.Service
+ return yield* shell.create({ command: input.command, cwd: session.location.directory })
+ }).pipe(Effect.provide(locations.get(session.location)))
yield* events.publish(
SessionEvent.Shell.Started,
{
sessionID: input.sessionID,
- callID,
- command: input.command,
+ shell: started,
},
{ id: input.id },
)
- const output = yield* runShellCommand(input.command, session.location.directory).pipe(
- Effect.provide(locations.get(session.location)),
- )
+ const completed = yield* Effect.gen(function* () {
+ const shell = yield* Shell.Service
+ const terminal = yield* shell.wait(started.id).pipe(
+ Effect.map((info) => ({ info, retained: true as const })),
+ Effect.catchTag("Shell.NotFoundError", () =>
+ Effect.succeed({ info: synthesizeTerminalShellInfo(started), retained: false as const }),
+ ),
+ )
+ const output = terminal.retained
+ ? yield* shell
+ .output(started.id, { limit: SHELL_MAX_CAPTURE_BYTES })
+ .pipe(Effect.catchTag("Shell.NotFoundError", () => Effect.succeed(missingShellOutput())))
+ : missingShellOutput()
+ return { shell: terminal.info, output }
+ })
+ .pipe(Effect.provide(locations.get(session.location)))
yield* events.publish(SessionEvent.Shell.Ended, {
sessionID: input.sessionID,
- callID,
- output,
+ shell: completed.shell,
+ output: completed.output,
})
}).pipe(
Effect.ensuring(
@@ -706,6 +708,26 @@ const layer = Layer.effect(
}),
)
+function missingShellOutput() {
+ const output = "Shell command output is no longer available."
+ return {
+ output,
+ cursor: Buffer.byteLength(output),
+ size: Buffer.byteLength(output),
+ truncated: false,
+ }
+}
+
+function synthesizeTerminalShellInfo(started: ShellSchema.Info): ShellSchema.Info {
+ return {
+ ...started,
+ // The Shell record was removed before waiters could observe it; publish a terminal
+ // boundary instead of leaving the Session shell message permanently running.
+ status: "killed",
+ time: { ...started.time, completed: Date.now() },
+ }
+}
+
const resolvePrompt = (input: PromptInput.Prompt) =>
Prompt.make({
text: input.text,
diff --git a/packages/core/src/session/compaction.ts b/packages/core/src/session/compaction.ts
index 1174b65f40..9ad9ddc81a 100644
--- a/packages/core/src/session/compaction.ts
+++ b/packages/core/src/session/compaction.ts
@@ -129,7 +129,7 @@ const serialize = (message: SessionMessage.Message) => {
if (message.type === "system") return `[System update]: ${message.text}`
if (message.type === "synthetic") return `[Synthetic context]: ${message.text}`
if (message.type === "skill") return `[Skill activated: ${message.name}]\n${message.text}`
- if (message.type === "shell") return `[Shell]: ${message.command}\n${truncate(message.output)}`
+ if (message.type === "shell") return `[Shell]: ${message.shell.command}\n${truncate(message.output?.output ?? "")}`
return ""
}
diff --git a/packages/core/src/session/message-updater.ts b/packages/core/src/session/message-updater.ts
index a23ecb224c..3658e67c0f 100644
--- a/packages/core/src/session/message-updater.ts
+++ b/packages/core/src/session/message-updater.ts
@@ -8,21 +8,25 @@ export type MemoryState = {
}
export interface Adapter {
- readonly getCurrentAssistant: () => Effect.Effect
- readonly getAssistant: (messageID: SessionMessage.ID) => Effect.Effect
- readonly getCurrentShell: (callID: string) => Effect.Effect
- readonly updateAssistant: (assistant: SessionMessage.Assistant) => Effect.Effect
- readonly updateShell: (shell: SessionMessage.Shell) => Effect.Effect
- readonly appendMessage: (message: SessionMessage.Message) => Effect.Effect
+ readonly getCurrentAssistant: () => Effect.Effect
+ readonly getAssistant: (
+ messageID: SessionMessage.ID,
+ ) => Effect.Effect
+ readonly getShell: (
+ shellID: SessionMessage.Shell["shell"]["id"],
+ ) => Effect.Effect
+ readonly updateAssistant: (assistant: SessionMessage.Assistant) => Effect.Effect
+ readonly updateShell: (shell: SessionMessage.Shell) => Effect.Effect
+ readonly appendMessage: (message: SessionMessage.Message) => Effect.Effect
}
export function memory(state: MemoryState): Adapter {
const assistantIndex = (messageID: SessionMessage.ID) =>
state.messages.findLastIndex((message) => message.id === messageID)
+ const shellIndex = (messageID: SessionMessage.ID) =>
+ state.messages.findLastIndex((message) => message.id === messageID)
// A newer step supersedes stale incomplete rows; never resume an older assistant projection.
const latestAssistantIndex = () => state.messages.findLastIndex((message) => message.type === "assistant")
- const activeShellIndex = (callID: string) =>
- state.messages.findLastIndex((message) => message.type === "shell" && message.callID === callID)
return {
getCurrentAssistant() {
@@ -41,12 +45,11 @@ export function memory(state: MemoryState): Adapter {
return assistant?.type === "assistant" ? assistant : undefined
})
},
- getCurrentShell(callID) {
+ getShell(shellID) {
return Effect.sync(() => {
- const index = activeShellIndex(callID)
- if (index < 0) return
- const shell = state.messages[index]
- return shell?.type === "shell" ? shell : undefined
+ return state.messages.find((message): message is SessionMessage.Shell => {
+ return message.type === "shell" && message.shell.id === shellID
+ })
})
},
updateAssistant(assistant) {
@@ -60,7 +63,7 @@ export function memory(state: MemoryState): Adapter {
},
updateShell(shell) {
return Effect.sync(() => {
- const index = activeShellIndex(shell.callID)
+ const index = shellIndex(shell.id)
if (index < 0) return
const current = state.messages[index]
if (current?.type !== "shell") return
@@ -100,7 +103,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
return Effect.gen(function* () {
yield* SessionEvent.All.match(event, {
- "agent.selected": (event) => {
+ "session.agent.selected": (event) => {
return adapter.appendMessage(
SessionMessage.AgentSelected.make({
id: SessionMessage.ID.fromEvent(event.id),
@@ -111,7 +114,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}),
)
},
- "model.selected": (event) => {
+ "session.model.selected": (event) => {
return adapter.appendMessage(
SessionMessage.ModelSelected.make({
id: SessionMessage.ID.fromEvent(event.id),
@@ -123,11 +126,11 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
)
},
"session.moved": () => Effect.void,
- renamed: () => Effect.void,
- forked: () => Effect.void,
- "prompt.promoted": () => Effect.void,
- "prompt.admitted": () => Effect.void,
- "execution.settled": () => Effect.void,
+ "session.renamed": () => Effect.void,
+ "session.forked": () => Effect.void,
+ "session.prompt.promoted": () => Effect.void,
+ "session.prompt.admitted": () => Effect.void,
+ "session.execution.settled": () => Effect.void,
"session.context.updated": (event) =>
adapter.appendMessage(
SessionMessage.System.make({
@@ -137,7 +140,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
time: { created: event.created },
}),
),
- synthetic: (event) => {
+ "session.synthetic": (event) => {
return adapter.appendMessage(
SessionMessage.Synthetic.make({
sessionID: event.data.sessionID,
@@ -150,7 +153,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}),
)
},
- "skill.activated": (event) => {
+ "session.skill.activated": (event) => {
return adapter.appendMessage(
SessionMessage.Skill.make({
id: SessionMessage.ID.fromEvent(event.id),
@@ -161,25 +164,24 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}),
)
},
- "shell.started": (event) => {
+ "session.shell.started": (event) => {
return adapter.appendMessage(
SessionMessage.Shell.make({
id: SessionMessage.ID.fromEvent(event.id),
type: "shell",
metadata: event.metadata,
- callID: event.data.callID,
- command: event.data.command,
- output: "",
+ shell: event.data.shell,
time: { created: event.created },
}),
)
},
- "shell.ended": (event) => {
+ "session.shell.ended": (event) => {
return Effect.gen(function* () {
- const currentShell = yield* adapter.getCurrentShell(event.data.callID)
+ const currentShell = yield* adapter.getShell(event.data.shell.id)
if (currentShell) {
yield* adapter.updateShell(
produce(currentShell, (draft) => {
+ draft.shell = castDraft(event.data.shell)
draft.output = event.data.output
draft.time.completed = event.created
}),
@@ -187,7 +189,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}
})
},
- "step.started": (event) => {
+ "session.step.started": (event) => {
return Effect.gen(function* () {
const currentAssistant = yield* adapter.getCurrentAssistant()
if (currentAssistant) {
@@ -210,7 +212,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
)
})
},
- "step.ended": (event) => {
+ "session.step.ended": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
draft.time.completed = event.created
draft.finish = event.data.finish
@@ -224,33 +226,33 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}
})
},
- "step.failed": (event) => {
+ "session.step.failed": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
draft.time.completed = event.created
draft.finish = "error"
draft.error = event.data.error
})
},
- "text.started": (event) => {
+ "session.text.started": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
draft.content.push(
castDraft(SessionMessage.AssistantText.make({ type: "text", id: event.data.textID, text: "" })),
)
})
},
- "text.delta": (event) => {
+ "session.text.delta": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestText(draft, event.data.textID)
if (match) match.text += event.data.delta
})
},
- "text.ended": (event) => {
+ "session.text.ended": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestText(draft, event.data.textID)
if (match) match.text = event.data.text
})
},
- "tool.input.started": (event) => {
+ "session.tool.input.started": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
draft.content.push(
castDraft(
@@ -265,14 +267,14 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
)
})
},
- "tool.input.delta": () => Effect.void,
- "tool.input.ended": (event) => {
+ "session.tool.input.delta": () => Effect.void,
+ "session.tool.input.ended": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestTool(draft, event.data.callID)
if (match && match.state.status === "pending") match.state.input = event.data.text
})
},
- "tool.called": (event) => {
+ "session.tool.called": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestTool(draft, event.data.callID)
if (match) {
@@ -289,7 +291,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}
})
},
- "tool.progress": (event) => {
+ "session.tool.progress": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestTool(draft, event.data.callID)
if (match && match.state.status === "running") {
@@ -298,7 +300,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}
})
},
- "tool.success": (event) => {
+ "session.tool.success": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestTool(draft, event.data.callID)
if (match && match.state.status === "running") {
@@ -321,7 +323,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}
})
},
- "tool.failed": (event) => {
+ "session.tool.failed": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestTool(draft, event.data.callID)
if (match && (match.state.status === "pending" || match.state.status === "running")) {
@@ -344,7 +346,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}
})
},
- "reasoning.started": (event) => {
+ "session.reasoning.started": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
draft.content.push(
castDraft(
@@ -359,13 +361,13 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
)
})
},
- "reasoning.delta": (event) => {
+ "session.reasoning.delta": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestReasoning(draft, event.data.reasoningID)
if (match) match.text += event.data.delta
})
},
- "reasoning.ended": (event) => {
+ "session.reasoning.ended": (event) => {
return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
const match = latestReasoning(draft, event.data.reasoningID)
if (match) {
@@ -375,10 +377,10 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}
})
},
- retried: () => Effect.void,
- "compaction.started": () => Effect.void,
- "compaction.delta": () => Effect.void,
- "compaction.ended": (event) => {
+ "session.retried": () => Effect.void,
+ "session.compaction.started": () => Effect.void,
+ "session.compaction.delta": () => Effect.void,
+ "session.compaction.ended": (event) => {
return adapter.appendMessage(
SessionMessage.Compaction.make({
id: SessionMessage.ID.fromEvent(event.id),
@@ -391,9 +393,9 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
}),
)
},
- "revert.staged": () => Effect.void,
- "revert.cleared": () => Effect.void,
- "revert.committed": () => Effect.void,
+ "session.revert.staged": () => Effect.void,
+ "session.revert.cleared": () => Effect.void,
+ "session.revert.committed": () => Effect.void,
})
})
}
diff --git a/packages/core/src/session/projector.ts b/packages/core/src/session/projector.ts
index c5b552e8b4..746e448a3b 100644
--- a/packages/core/src/session/projector.ts
+++ b/packages/core/src/session/projector.ts
@@ -393,18 +393,25 @@ function run(db: DatabaseService, event: MessageEvent) {
return message.type === "assistant" ? message : undefined
})
},
- getCurrentShell(callID) {
+ getShell(shellID) {
return Effect.gen(function* () {
- const rows = yield* db
+ const row = yield* db
.select()
.from(SessionMessageTable)
- .where(and(eq(SessionMessageTable.session_id, event.data.sessionID), eq(SessionMessageTable.type, "shell")))
+ .where(
+ and(
+ eq(SessionMessageTable.session_id, event.data.sessionID),
+ eq(SessionMessageTable.type, "shell"),
+ sql`json_extract(${SessionMessageTable.data}, '$.shell.id') = ${shellID}`,
+ ),
+ )
.orderBy(desc(SessionMessageTable.seq))
- .all()
+ .limit(1)
+ .get()
.pipe(Effect.orDie)
- return rows
- .map(decodeRow)
- .find((message): message is SessionMessage.Shell => message.type === "shell" && message.callID === callID)
+ if (!row) return
+ const message = decodeRow(row)
+ return message.type === "shell" ? message : undefined
})
},
updateAssistant: updateMessage,
diff --git a/packages/core/src/session/runner/to-llm-message.ts b/packages/core/src/session/runner/to-llm-message.ts
index 0d9055e480..e6a91a9ef1 100644
--- a/packages/core/src/session/runner/to-llm-message.ts
+++ b/packages/core/src/session/runner/to-llm-message.ts
@@ -139,7 +139,7 @@ function toLLMMessage(message: SessionMessage.Message, model: Model): Message[]
Message.make({
id: message.id,
role: "user",
- content: `Shell command: ${message.command}\n\n${message.output}`,
+ content: `Shell command: ${message.shell.command}\n\n${message.output?.output ?? ""}`,
metadata: message.metadata,
}),
]
diff --git a/packages/core/test/session-create.test.ts b/packages/core/test/session-create.test.ts
index 0100ca4ae9..d18c2c8e81 100644
--- a/packages/core/test/session-create.test.ts
+++ b/packages/core/test/session-create.test.ts
@@ -213,7 +213,7 @@ describe("SessionV2.create", () => {
expect(forkContext.map((message) => message.id)).not.toEqual(parentContext.map((message) => message.id))
expect(history).toHaveLength(1)
expect(history[0]).toMatchObject({
- type: "forked",
+ type: "session.forked",
durable: { seq: 0 },
data: { sessionID: forked.id, parentID: parent.id },
})
@@ -378,8 +378,8 @@ describe("SessionV2.create", () => {
expect(
Array.from(yield* logEvents(session, created.id, true).pipe(Stream.take(2), Stream.runCollect)),
).toMatchObject([
- { durable: { seq: 1 }, type: "prompt.admitted", data: { prompt: { text: "Hello" } } },
- { durable: { seq: 2 }, type: "prompt.promoted" },
+ { durable: { seq: 1 }, type: "session.prompt.admitted", data: { prompt: { text: "Hello" } } },
+ { durable: { seq: 2 }, type: "session.prompt.promoted" },
])
}),
)
@@ -494,8 +494,9 @@ describe("SessionV2.create", () => {
const messages = yield* session.messages({ sessionID: created.id, order: "asc" })
const shell = messages.find((message): message is SessionMessage.Shell => message.type === "shell")
- expect(shell).toMatchObject({ type: "shell", command: "echo hello" })
- expect(shell?.output).toContain("hello")
+ expect(shell).toMatchObject({ type: "shell", shell: { command: "echo hello", status: "exited", exit: 0 } })
+ expect(shell?.output?.output).toContain("hello")
+ expect(shell?.output?.truncated).toBe(false)
expect(shell?.time.completed).toBeDefined()
}),
),
@@ -513,7 +514,8 @@ describe("SessionV2.create", () => {
const messages = yield* session.messages({ sessionID: created.id, order: "asc" })
const shell = messages.find((message): message is SessionMessage.Shell => message.type === "shell")
- expect(shell).toMatchObject({ type: "shell", command: "false" })
+ expect(shell).toMatchObject({ type: "shell", shell: { command: "false", status: "exited" } })
+ expect(shell?.shell.exit).not.toBe(0)
expect(shell?.time.completed).toBeDefined()
}),
),
@@ -529,7 +531,7 @@ describe("SessionV2.create", () => {
expect(yield* session.get(created.id)).toMatchObject({ agent: "plan" })
expect(
Array.from(yield* logEvents(session, created.id, true).pipe(Stream.take(1), Stream.runCollect)),
- ).toMatchObject([{ type: "agent.selected", data: { agent: "plan" } }])
+ ).toMatchObject([{ type: "session.agent.selected", data: { agent: "plan" } }])
}),
)
@@ -562,7 +564,7 @@ describe("SessionV2.create", () => {
expect(yield* session.get(created.id)).toMatchObject({ model })
expect(
Array.from(yield* logEvents(session, created.id, true).pipe(Stream.take(1), Stream.runCollect)),
- ).toMatchObject([{ type: "model.selected", data: { model } }])
+ ).toMatchObject([{ type: "session.model.selected", data: { model } }])
}),
)
diff --git a/packages/core/test/session-log.test.ts b/packages/core/test/session-log.test.ts
index 8c49b94582..ed8dda7f4d 100644
--- a/packages/core/test/session-log.test.ts
+++ b/packages/core/test/session-log.test.ts
@@ -40,14 +40,14 @@ describe("SessionV2.log", () => {
const session = yield* SessionV2.Service
const events = yield* EventV2.Service
const created = yield* session.create({ location })
- yield* session.rename({ sessionID: created.id, title: "renamed" })
+ yield* session.rename({ sessionID: created.id, title: "session.renamed" })
const items = Array.from(yield* Stream.runCollect(session.log({ sessionID: created.id })))
const watermark = (yield* events.sequences([created.id])).get(created.id)
// Session creation commits a non-public durable event, so the marker's
// seq covers more of the aggregate than the public events emitted.
- expect(items.map((item) => item.type)).toEqual(["renamed", "log.synced"])
+ expect(items.map((item) => item.type)).toEqual(["session.renamed", "log.synced"])
expect(items.at(-1)).toEqual({ type: "log.synced", aggregateID: created.id, seq: watermark })
}),
)
@@ -64,7 +64,7 @@ describe("SessionV2.log", () => {
yield* session.rename({ sessionID: created.id, title: "renamed live" })
const items = Array.from(yield* Fiber.join(fiber))
- expect(items.map((item) => item.type)).toEqual(["log.synced", "renamed"])
+ expect(items.map((item) => item.type)).toEqual(["log.synced", "session.renamed"])
}),
)
@@ -137,7 +137,7 @@ describe("SessionV2 watermarks", () => {
const events = yield* EventV2.Service
const first = yield* session.create({ location })
const second = yield* session.create({ location })
- yield* session.rename({ sessionID: first.id, title: "renamed" })
+ yield* session.rename({ sessionID: first.id, title: "session.renamed" })
const page = yield* session.list()
const sequences = yield* events.sequences([first.id, second.id])
diff --git a/packages/core/test/session-projector.test.ts b/packages/core/test/session-projector.test.ts
index c0d172088e..c17b979076 100644
--- a/packages/core/test/session-projector.test.ts
+++ b/packages/core/test/session-projector.test.ts
@@ -19,6 +19,7 @@ import { SessionMessageUpdater } from "@opencode-ai/core/session/message-updater
import { SessionProjector } from "@opencode-ai/core/session/projector"
import { SessionExecution } from "@opencode-ai/core/session/execution"
import { SessionInput } from "@opencode-ai/core/session/input"
+import { Shell } from "@opencode-ai/schema/shell"
import {
SessionContextCheckpointTable,
SessionInputTable,
@@ -257,15 +258,32 @@ describe("SessionProjector", () => {
})
yield* events.publish(SessionEvent.Shell.Started, {
sessionID,
- callID: "shell-1",
- command: "pwd",
+ shell: Shell.Info.make({
+ id: Shell.ID.make("sh_projector"),
+ status: "running",
+ command: "pwd",
+ cwd: "/project",
+ shell: "/bin/sh",
+ file: "/tmp/sh_projector.out",
+ metadata: {},
+ time: { started: 0 },
+ }),
})
yield* events.publish(SessionEvent.Shell.Ended, {
sessionID,
- callID: "shell-1",
- output: "/project",
+ shell: Shell.Info.make({
+ id: Shell.ID.make("sh_projector"),
+ status: "exited",
+ command: "pwd",
+ cwd: "/project",
+ shell: "/bin/sh",
+ file: "/tmp/sh_projector.out",
+ exit: 0,
+ metadata: {},
+ time: { started: 0, completed: 1 },
+ }),
+ output: { output: "/project", cursor: 8, size: 8, truncated: false },
})
- const compactionID = SessionMessage.ID.create()
yield* events.publish(SessionEvent.Compaction.Started, {
sessionID,
reason: "manual",
@@ -320,7 +338,8 @@ describe("SessionProjector", () => {
metadata: { source: "projector-test" },
})
expect(messages.find((message) => message.type === "shell")).toMatchObject({
- output: "/project",
+ shell: { command: "pwd", status: "exited", exit: 0 },
+ output: { output: "/project", truncated: false },
time: { completed: DateTime.makeUnsafe(0) },
})
expect(messages.find((message) => message.type === "compaction")).toMatchObject({
diff --git a/packages/core/test/session-prompt.test.ts b/packages/core/test/session-prompt.test.ts
index 58a613a324..e7d3f5189f 100644
--- a/packages/core/test/session-prompt.test.ts
+++ b/packages/core/test/session-prompt.test.ts
@@ -256,16 +256,16 @@ describe("SessionV2.prompt", () => {
const streamed = Array.from(yield* Fiber.join(fiber))
expect(streamed.map((event): [number | undefined, string] => [event.durable?.seq, event.type])).toEqual([
- [0, "prompt.admitted"],
- [1, "prompt.admitted"],
- [2, "prompt.promoted"],
- [3, "prompt.promoted"],
+ [0, "session.prompt.admitted"],
+ [1, "session.prompt.admitted"],
+ [2, "session.prompt.promoted"],
+ [3, "session.prompt.promoted"],
])
expect(
Array.from(
yield* publicEvents({ sessionID, after: streamed[0].durable?.seq }).pipe(Stream.take(1), Stream.runCollect),
).map((event): [number | undefined, string] => [event.durable?.seq, event.type]),
- ).toEqual([[1, "prompt.admitted"]])
+ ).toEqual([[1, "session.prompt.admitted"]])
}),
)
diff --git a/packages/core/test/session-runner-message.test.ts b/packages/core/test/session-runner-message.test.ts
index d33b44728d..9aed484858 100644
--- a/packages/core/test/session-runner-message.test.ts
+++ b/packages/core/test/session-runner-message.test.ts
@@ -7,6 +7,7 @@ import { SessionMessage } from "@opencode-ai/core/session/message"
import { AgentAttachment, FileAttachment } from "@opencode-ai/core/session/prompt"
import { toLLMMessages } from "@opencode-ai/core/session/runner/to-llm-message"
import { SessionV2 } from "@opencode-ai/core/session"
+import { Shell } from "@opencode-ai/schema/shell"
import { DateTime } from "effect"
const created = DateTime.makeUnsafe(0)
@@ -87,9 +88,18 @@ describe("toLLMMessages", () => {
SessionMessage.Shell.make({
id: id("shell"),
type: "shell",
- callID: "shell-1",
- command: "pwd",
- output: "/project",
+ shell: Shell.Info.make({
+ id: Shell.ID.make("sh_test"),
+ status: "exited",
+ command: "pwd",
+ cwd: "/project",
+ shell: "/bin/sh",
+ file: "/tmp/sh_test.out",
+ exit: 0,
+ metadata: {},
+ time: { started: 0, completed: 0 },
+ }),
+ output: { output: "/project", cursor: 8, size: 8, truncated: false },
time: { created, completed: created },
}),
SessionMessage.Compaction.make({
diff --git a/packages/core/test/session-runner-recorded.test.ts b/packages/core/test/session-runner-recorded.test.ts
index 4f82baba96..35e84fcb6c 100644
--- a/packages/core/test/session-runner-recorded.test.ts
+++ b/packages/core/test/session-runner-recorded.test.ts
@@ -193,12 +193,12 @@ describe("SessionRunnerLLM recorded", () => {
.orderBy(EventTable.seq)
.all()).map((event) => event.type),
).toEqual([
- "prompt.admitted.1",
- "prompt.promoted.1",
- "step.started.1",
- "text.started.1",
- "text.ended.1",
- "step.ended.1",
+ "session.prompt.admitted.1",
+ "session.prompt.promoted.1",
+ "session.step.started.1",
+ "session.text.started.1",
+ "session.text.ended.1",
+ "session.step.ended.1",
])
}),
)
diff --git a/packages/core/test/session-runner-tool-events.test.ts b/packages/core/test/session-runner-tool-events.test.ts
index 5c8d7e07f4..d016b2694b 100644
--- a/packages/core/test/session-runner-tool-events.test.ts
+++ b/packages/core/test/session-runner-tool-events.test.ts
@@ -76,7 +76,7 @@ test("local tool success serializes media base64 once and reconstructs from stru
await Effect.runPromise(publisher.publish(call))
await Effect.runPromise(publisher.publish(result))
- const success = published.find((event) => event.type === "tool.success.1")
+ const success = published.find((event) => event.type === "session.tool.success.1")
expect(success).toBeDefined()
const serialized = JSON.stringify(success)
expect(serialized.split(base64)).toHaveLength(2)
@@ -94,7 +94,7 @@ test("provider-executed success retains its compatibility result", async () => {
const { published, publisher } = capture()
await Effect.runPromise(publisher.publish(LLMEvent.toolCall({ ...call, providerExecuted: true })))
await Effect.runPromise(publisher.publish(LLMEvent.toolResult({ ...result, providerExecuted: true })))
- const success = published.find((event) => event.type === "tool.success.1")
+ const success = published.find((event) => event.type === "session.tool.success.1")
expect(success?.data).toHaveProperty("result")
})
@@ -110,8 +110,8 @@ test("binary failure emits no success event", async () => {
}),
),
)
- expect(published.some((event) => event.type === "tool.success.1")).toBe(false)
- expect(published.some((event) => event.type === "tool.failed.1")).toBe(true)
+ expect(published.some((event) => event.type === "session.tool.success.1")).toBe(false)
+ expect(published.some((event) => event.type === "session.tool.failed.1")).toBe(true)
})
test("old success event data containing result still decodes", () => {
diff --git a/packages/core/test/session-runner.test.ts b/packages/core/test/session-runner.test.ts
index e6f14c8e19..6856b6a7ce 100644
--- a/packages/core/test/session-runner.test.ts
+++ b/packages/core/test/session-runner.test.ts
@@ -2985,7 +2985,7 @@ describe("SessionRunnerLLM", () => {
{ type: "user", text: "Interrupt provider" },
{ type: "assistant", finish: "error", error: { type: "unknown", message: "Step interrupted" } },
])
- expect(yield* recordedEventTypes(sessionID)).toContain("step.failed.1")
+ expect(yield* recordedEventTypes(sessionID)).toContain("session.step.failed.1")
yield* session.interrupt(sessionID)
}),
)
@@ -3029,8 +3029,8 @@ describe("SessionRunnerLLM", () => {
},
])
const eventTypes = yield* recordedEventTypes(sessionID)
- expect(eventTypes).toContain("step.failed.1")
- expect(eventTypes).not.toContain("step.ended.1")
+ expect(eventTypes).toContain("session.step.failed.1")
+ expect(eventTypes).not.toContain("session.step.ended.1")
}),
)
diff --git a/packages/opencode/src/cli/cmd/run/noninteractive.ts b/packages/opencode/src/cli/cmd/run/noninteractive.ts
index 60ded4ebd9..6874527222 100644
--- a/packages/opencode/src/cli/cmd/run/noninteractive.ts
+++ b/packages/opencode/src/cli/cmd/run/noninteractive.ts
@@ -158,14 +158,14 @@ export async function runNonInteractivePrompt(input: Input) {
if (!("sessionID" in event.data) || event.data.sessionID !== input.sessionID) continue
const time = toMillis(event.created)
- if (event.type === "prompt.promoted") {
+ if (event.type === "session.prompt.promoted") {
if (event.data.inputID === messageID) {
promoted = true
continue
}
}
if (
- event.type === "execution.settled" &&
+ event.type === "session.execution.settled" &&
event.data.outcome === "interrupted" &&
(interrupted || permissionRejected || questionRejected || formCancelled)
) {
@@ -173,7 +173,7 @@ export async function runNonInteractivePrompt(input: Input) {
}
if (!promoted) continue
- if (event.type === "step.started") {
+ if (event.type === "session.step.started") {
const part: StepStartPart = {
id: partID(event.id),
sessionID: input.sessionID,
@@ -189,11 +189,11 @@ export async function runNonInteractivePrompt(input: Input) {
continue
}
- if (event.type === "text.started") {
+ if (event.type === "session.text.started") {
starts.set(event.data.textID, { id: partID(event.id), timestamp: time })
continue
}
- if (event.type === "text.ended") {
+ if (event.type === "session.text.ended") {
const started = starts.get(event.data.textID)
const part: TextPart = {
id: started?.id ?? partID(event.id),
@@ -207,11 +207,11 @@ export async function runNonInteractivePrompt(input: Input) {
continue
}
- if (event.type === "reasoning.started") {
+ if (event.type === "session.reasoning.started") {
starts.set(event.data.reasoningID, { id: partID(event.id), timestamp: time })
continue
}
- if (event.type === "reasoning.ended" && input.thinking) {
+ if (event.type === "session.reasoning.ended" && input.thinking) {
const started = starts.get(event.data.reasoningID)
const part: ReasoningPart = {
id: started?.id ?? partID(event.id),
@@ -236,7 +236,7 @@ export async function runNonInteractivePrompt(input: Input) {
continue
}
- if (event.type === "tool.input.started") {
+ if (event.type === "session.tool.input.started") {
tools.set(event.data.callID, {
id: partID(event.id),
timestamp: time,
@@ -246,12 +246,12 @@ export async function runNonInteractivePrompt(input: Input) {
})
continue
}
- if (event.type === "tool.input.ended") {
+ if (event.type === "session.tool.input.ended") {
const current = tools.get(event.data.callID)
if (current) current.raw = event.data.text
continue
}
- if (event.type === "tool.called") {
+ if (event.type === "session.tool.called") {
const current = tools.get(event.data.callID)
tools.set(event.data.callID, {
id: current?.id ?? partID(event.id),
@@ -264,7 +264,7 @@ export async function runNonInteractivePrompt(input: Input) {
})
continue
}
- if (event.type === "tool.success") {
+ if (event.type === "session.tool.success") {
const current = tools.get(event.data.callID) ?? fallbackTool(event)
const part: ToolPart = {
id: current.id,
@@ -297,7 +297,7 @@ export async function runNonInteractivePrompt(input: Input) {
if (!emit("tool_use", time, { part })) await input.renderTool(part)
continue
}
- if (event.type === "tool.failed") {
+ if (event.type === "session.tool.failed") {
const current = tools.get(event.data.callID) ?? fallbackTool(event)
const error = event.data.error.message
const part: ToolPart = {
@@ -328,7 +328,7 @@ export async function runNonInteractivePrompt(input: Input) {
continue
}
- if (event.type === "step.ended") {
+ if (event.type === "session.step.ended") {
const part: StepFinishPart = {
id: partID(event.id),
sessionID: input.sessionID,
@@ -342,14 +342,14 @@ export async function runNonInteractivePrompt(input: Input) {
emit("step_finish", time, { part })
continue
}
- if (event.type === "step.failed") {
+ if (event.type === "session.step.failed") {
if (interrupted || permissionRejected || questionRejected || formCancelled) continue
emittedError = true
process.exitCode = 1
if (!emit("error", time, { error: event.data.error })) UI.error(event.data.error.message)
continue
}
- if (event.type === "execution.settled") {
+ if (event.type === "session.execution.settled") {
if (event.data.outcome === "failure" && !emittedError && !questionRejected && !formCancelled) {
emittedError = true
process.exitCode = 1
diff --git a/packages/opencode/src/cli/cmd/run/session-data.ts b/packages/opencode/src/cli/cmd/run/session-data.ts
index 9450f6cf78..ffce45bc94 100644
--- a/packages/opencode/src/cli/cmd/run/session-data.ts
+++ b/packages/opencode/src/cli/cmd/run/session-data.ts
@@ -62,7 +62,7 @@ type SessionCommit = StreamCommit
// - sent: part ID → byte offset of last flushed text (for incremental output)
// - visible: part ID → rendered text for an active part after display transforms
// - end: part IDs whose time.end has arrived (part is finished)
-// - shell: shell call ID → chosen transcript source for direct shell calls
+// - shell: shell ID → chosen transcript source for direct shell calls
// - echo: message ID → bash outputs to strip from the next assistant chunk
type ShellCall = {
source: "shell" | "tool"
@@ -607,12 +607,12 @@ function toolCommit(
}
}
-function shellPartID(callID: string): string {
- return `shell:${callID}`
+function shellPartID(shellID: string): string {
+ return `shell:${shellID}`
}
-function claimShell(data: SessionData, callID: string, source: ShellCall["source"], command?: string): ShellCall {
- const current = data.shell.get(callID)
+function claimShell(data: SessionData, shellID: string, source: ShellCall["source"], command?: string): ShellCall {
+ const current = data.shell.get(shellID)
if (current) {
if (command && !current.command) {
current.command = command
@@ -625,7 +625,7 @@ function claimShell(data: SessionData, callID: string, source: ShellCall["source
source,
...(command ? { command } : {}),
} satisfies ShellCall
- data.shell.set(callID, next)
+ data.shell.set(shellID, next)
return next
}
@@ -728,37 +728,37 @@ export function reduceSessionData(input: SessionDataInput): SessionDataOutput {
const data = input.data
const event = input.event
- if (event.type === "shell.started") {
+ if (event.type === "session.shell.started") {
if (event.properties.sessionID !== input.sessionID) {
return out(data, commits)
}
- const shell = claimShell(data, event.properties.callID, "shell", event.properties.command)
+ const shell = claimShell(data, event.properties.shell.id, "shell", event.properties.shell.command)
if (shell.source !== "shell") {
return out(data, commits)
}
- const partID = shellPartID(event.properties.callID)
+ const partID = shellPartID(event.properties.shell.id)
if (data.ids.has(partID) || data.tools.has(partID)) {
return out(data, commits, patch({ status: "running shell" }))
}
data.tools.add(partID)
- commits.push(startShell(event.properties.callID, shell.command ?? event.properties.command))
+ commits.push(startShell(event.properties.shell.id, shell.command ?? event.properties.shell.command))
return out(data, commits, patch({ status: "running shell" }))
}
- if (event.type === "shell.ended") {
+ if (event.type === "session.shell.ended") {
if (event.properties.sessionID !== input.sessionID) {
return out(data, commits)
}
- const shell = claimShell(data, event.properties.callID, "shell")
+ const shell = claimShell(data, event.properties.shell.id, "shell")
if (shell.source !== "shell") {
return out(data, commits)
}
- const partID = shellPartID(event.properties.callID)
+ const partID = shellPartID(event.properties.shell.id)
const seen = data.tools.has(partID)
const command = shell.command ?? ""
data.tools.delete(partID)
@@ -767,11 +767,11 @@ export function reduceSessionData(input: SessionDataInput): SessionDataOutput {
}
if (!seen && command) {
- commits.push(startShell(event.properties.callID, command))
+ commits.push(startShell(event.properties.shell.id, command))
}
data.ids.add(partID)
- commits.push(doneShell(event.properties.callID, command, event.properties.output))
+ commits.push(doneShell(event.properties.shell.id, command, event.properties.output.output))
return out(data, commits)
}
diff --git a/packages/opencode/src/cli/cmd/run/stream-v2.subagent.ts b/packages/opencode/src/cli/cmd/run/stream-v2.subagent.ts
index ac652423a1..1e7b039fd8 100644
--- a/packages/opencode/src/cli/cmd/run/stream-v2.subagent.ts
+++ b/packages/opencode/src/cli/cmd/run/stream-v2.subagent.ts
@@ -424,21 +424,21 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
}
const reduce = (child: ChildState, event: V2Event) => {
- if (event.type === "prompt.promoted") {
+ if (event.type === "session.prompt.promoted") {
if (userFrame(child, event.data.inputID, "")) {
touch(child, event.created)
notifyDetail(child)
}
return
}
- if (event.type === "step.started") {
+ if (event.type === "session.step.started") {
touch(child, event.created)
if (child.label === FALLBACK_LABEL && event.data.agent) child.label = Locale.titlecase(event.data.agent)
if (child.status !== "running") child.status = "running"
input.emit()
return
}
- if (event.type === "text.delta") {
+ if (event.type === "session.text.delta") {
const projected = child.projectedText.get(event.data.textID)
const covered = projected?.indexOf(event.data.delta) ?? -1
if (projected && covered >= 0) {
@@ -459,7 +459,7 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
notifyDetail(child)
return
}
- if (event.type === "text.ended") {
+ if (event.type === "session.text.ended") {
child.text.set(event.data.textID, event.data.text)
child.projectedText.delete(event.data.textID)
setFrame(child, `text:${event.data.textID}`, {
@@ -474,7 +474,7 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
notifyDetail(child)
return
}
- if (event.type === "reasoning.delta") {
+ if (event.type === "session.reasoning.delta") {
const projected = child.projectedReasoning.get(event.data.reasoningID)
const covered = projected?.indexOf(event.data.delta) ?? -1
if (projected && covered >= 0) {
@@ -495,7 +495,7 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
notifyDetail(child)
return
}
- if (event.type === "reasoning.ended") {
+ if (event.type === "session.reasoning.ended") {
child.reasoning.set(event.data.reasoningID, event.data.text)
child.projectedReasoning.delete(event.data.reasoningID)
if (!input.thinking) return
@@ -510,11 +510,11 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
notifyDetail(child)
return
}
- if (event.type === "tool.input.started") {
+ if (event.type === "session.tool.input.started") {
child.tools.set(event.data.callID, { name: event.data.name, input: {}, started: event.created })
return
}
- if (event.type === "tool.called") {
+ if (event.type === "session.tool.called") {
const current = child.tools.get(event.data.callID)
child.tools.set(event.data.callID, {
name: event.data.tool,
@@ -537,10 +537,10 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
notifyDetail(child)
return
}
- if (event.type === "tool.success" || event.type === "tool.failed") {
+ if (event.type === "session.tool.success" || event.type === "session.tool.failed") {
if (child.finishedTools.has(event.data.callID)) return
const current = child.tools.get(event.data.callID)
- const failed = event.type === "tool.failed"
+ const failed = event.type === "session.tool.failed"
childTool(
child,
{
@@ -577,7 +577,7 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
notifyDetail(child)
return
}
- if (event.type === "step.failed") {
+ if (event.type === "session.step.failed") {
setFrame(child, `error:step:${event.data.assistantMessageID}`, {
kind: "error",
source: "system",
@@ -589,7 +589,7 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
notifyDetail(child)
return
}
- if (event.type === "execution.settled") {
+ if (event.type === "session.execution.settled") {
child.status =
event.data.outcome === "success" ? "completed" : event.data.outcome === "interrupted" ? "cancelled" : "error"
touch(child, event.created)
@@ -613,15 +613,15 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
return {
main(event) {
- if (event.type === "tool.called") {
+ if (event.type === "session.tool.called") {
if (event.data.tool === "subagent") pendingCalls.set(event.data.callID, event.data.input)
return
}
- if (event.type === "tool.failed") {
+ if (event.type === "session.tool.failed") {
pendingCalls.delete(event.data.callID)
return
}
- if (event.type !== "tool.success") return
+ if (event.type !== "session.tool.success") return
const pending = pendingCalls.get(event.data.callID)
pendingCalls.delete(event.data.callID)
const found = childSessionID(record(event.data.structured))
diff --git a/packages/opencode/src/cli/cmd/run/stream-v2.transport.ts b/packages/opencode/src/cli/cmd/run/stream-v2.transport.ts
index c15ed48e5b..42e2c7bd53 100644
--- a/packages/opencode/src/cli/cmd/run/stream-v2.transport.ts
+++ b/packages/opencode/src/cli/cmd/run/stream-v2.transport.ts
@@ -213,7 +213,9 @@ function promptAgents(next: SessionTurnInput) {
? [
{
name: part.name,
- source: part.source ? { start: part.source.start, end: part.source.end, text: part.source.value } : undefined,
+ source: part.source
+ ? { start: part.source.start, end: part.source.end, text: part.source.value }
+ : undefined,
},
]
: [],
@@ -404,27 +406,39 @@ export async function createSessionTransport(input: StreamInput): Promise previous.length)
@@ -604,7 +636,7 @@ export async function createSessionTransport(input: StreamInput): Promise previous.length)
@@ -645,7 +677,7 @@ export async function createSessionTransport(input: StreamInput): Promise (file.text ? [file.text] : [])),
- ].join("\n\n"),
+ text: [next.prompt.text, ...prepared.flatMap((file) => (file.text ? [file.text] : []))].join("\n\n"),
files: attachments.length ? attachments : undefined,
agents: agents.length ? agents : undefined,
},
diff --git a/packages/opencode/test/cli/run/noninteractive.test.ts b/packages/opencode/test/cli/run/noninteractive.test.ts
index 839b99656b..4462c53a97 100644
--- a/packages/opencode/test/cli/run/noninteractive.test.ts
+++ b/packages/opencode/test/cli/run/noninteractive.test.ts
@@ -25,7 +25,7 @@ function prompted(inputID: string): V2Event {
return {
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: { aggregateID: "ses_1", seq: 0, version: 1 },
data: { sessionID: "ses_1", inputID },
}
@@ -35,7 +35,7 @@ function settled(outcome: "success" | "interrupted" = "success"): V2Event {
return {
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome },
}
}
diff --git a/packages/opencode/test/cli/run/session-data.test.ts b/packages/opencode/test/cli/run/session-data.test.ts
index 89a6751d1b..805bcd486f 100644
--- a/packages/opencode/test/cli/run/session-data.test.ts
+++ b/packages/opencode/test/cli/run/session-data.test.ts
@@ -329,7 +329,7 @@ describe("run session data", () => {
test("renders direct shell mode from first-class shell events", () => {
let data = createSessionData()
const started = reduce(data, {
- type: "shell.started",
+ type: "session.shell.started",
properties: {
sessionID: "session-1",
timestamp: 1,
@@ -353,7 +353,7 @@ describe("run session data", () => {
data = started.data
const ended = reduce(data, {
- type: "shell.ended",
+ type: "session.shell.ended",
properties: {
sessionID: "session-1",
timestamp: 2,
@@ -380,7 +380,7 @@ describe("run session data", () => {
test("suppresses legacy bash part updates once shell events claim the call", () => {
let data = reduce(createSessionData(), {
- type: "shell.started",
+ type: "session.shell.started",
properties: {
sessionID: "session-1",
timestamp: 1,
@@ -409,7 +409,7 @@ describe("run session data", () => {
).toEqual([])
data = reduce(data, {
- type: "shell.ended",
+ type: "session.shell.ended",
properties: {
sessionID: "session-1",
timestamp: 2,
@@ -463,7 +463,7 @@ describe("run session data", () => {
expect(
reduce(data, {
- type: "shell.started",
+ type: "session.shell.started",
properties: {
sessionID: "session-1",
timestamp: 1,
@@ -497,7 +497,7 @@ describe("run session data", () => {
expect(
reduce(data, {
- type: "shell.ended",
+ type: "session.shell.ended",
properties: {
sessionID: "session-1",
timestamp: 2,
diff --git a/packages/opencode/test/cli/run/stream-v2.transport.test.ts b/packages/opencode/test/cli/run/stream-v2.transport.test.ts
index e43e88f934..cd2d131642 100644
--- a/packages/opencode/test/cli/run/stream-v2.transport.test.ts
+++ b/packages/opencode/test/cli/run/stream-v2.transport.test.ts
@@ -200,7 +200,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -210,7 +210,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_text",
created: 0,
- type: "text.delta",
+ type: "session.text.delta",
data: {
sessionID: "ses_1",
assistantMessageID: "msg_assistant",
@@ -221,7 +221,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
await turn
@@ -259,7 +259,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -269,7 +269,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
})
@@ -353,7 +353,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -363,7 +363,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
})
@@ -450,7 +450,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -460,7 +460,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
})
@@ -724,7 +724,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_text",
created: 0,
- type: "text.delta",
+ type: "session.text.delta",
data: {
sessionID: "ses_1",
assistantMessageID: "msg_assistant",
@@ -809,7 +809,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_reasoning",
created: 0,
- type: "reasoning.ended",
+ type: "session.reasoning.ended",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -865,7 +865,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
await turn
@@ -921,7 +921,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -931,7 +931,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
await turn
@@ -981,7 +981,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -993,7 +993,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
await turn
@@ -1021,16 +1021,42 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_shell_start",
created: 0,
- type: "shell.started",
+ type: "session.shell.started",
durable: durable("ses_1"),
- data: { sessionID: "ses_1", callID: "call_shell", command: "ls" },
+ data: {
+ sessionID: "ses_1",
+ shell: {
+ id: "sh_shell",
+ status: "running",
+ command: "ls",
+ cwd: "/tmp",
+ shell: "/bin/sh",
+ file: "/tmp/opencode-shell",
+ metadata: {},
+ time: { started: 0 },
+ },
+ },
})
events.push({
id: "evt_shell_end",
created: 0,
- type: "shell.ended",
+ type: "session.shell.ended",
durable: durable("ses_1", 1),
- data: { sessionID: "ses_1", callID: "call_shell", output: "file.txt" },
+ data: {
+ sessionID: "ses_1",
+ shell: {
+ id: "sh_shell",
+ status: "exited",
+ command: "ls",
+ cwd: "/tmp",
+ shell: "/bin/sh",
+ file: "/tmp/opencode-shell",
+ exit: 0,
+ metadata: {},
+ time: { started: 0, completed: 1 },
+ },
+ output: { output: "file.txt", cursor: 8, size: 8, truncated: false },
+ },
})
})
return ok(undefined) as never
@@ -1047,8 +1073,8 @@ describe("V2 mini transport", () => {
expect(request).toMatchObject({ sessionID: "ses_1", command: "ls" })
expect(ui.commits.filter((item) => item.shell)).toMatchObject([
- { phase: "start", tool: "bash", toolState: "running", shell: { callID: "call_shell", command: "ls" } },
- { phase: "progress", text: "file.txt", toolState: "completed", shell: { callID: "call_shell", command: "ls" } },
+ { phase: "start", tool: "bash", toolState: "running", shell: { callID: "sh_shell", command: "ls" } },
+ { phase: "progress", text: "file.txt", toolState: "completed", shell: { callID: "sh_shell", command: "ls" } },
])
expect(ui.events).toContainEqual({ type: "stream.patch", patch: { phase: "running", status: "running shell" } })
await transport.close()
@@ -1107,9 +1133,18 @@ describe("V2 mini transport", () => {
{
id: "msg_shell",
type: "shell" as const,
- callID: "call_1",
- command: "ls",
- output: "file.txt",
+ shell: {
+ id: "sh_1",
+ status: "exited",
+ command: "ls",
+ cwd: "/tmp",
+ shell: "/bin/sh",
+ file: "/tmp/opencode-shell",
+ exit: 0,
+ metadata: {},
+ time: { started: 0, completed: 1 },
+ },
+ output: { output: "file.txt", cursor: 8, size: 8, truncated: false },
time: { created: 1, completed: 2 },
},
],
@@ -1127,15 +1162,29 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_shell_end",
created: 0,
- type: "shell.ended",
+ type: "session.shell.ended",
durable: durable("ses_1", 1),
- data: { sessionID: "ses_1", callID: "call_1", output: "file.txt" },
+ data: {
+ sessionID: "ses_1",
+ shell: {
+ id: "sh_1",
+ status: "exited",
+ command: "ls",
+ cwd: "/tmp",
+ shell: "/bin/sh",
+ file: "/tmp/opencode-shell",
+ exit: 0,
+ metadata: {},
+ time: { started: 0, completed: 1 },
+ },
+ output: { output: "file.txt", cursor: 8, size: 8, truncated: false },
+ },
})
await Bun.sleep(0)
await Bun.sleep(0)
expect(ui.commits.filter((item) => item.shell)).toMatchObject([
- { phase: "start", shell: { callID: "call_1", command: "ls" } },
+ { phase: "start", shell: { callID: "sh_1", command: "ls" } },
{ phase: "progress", text: "file.txt", toolState: "completed" },
])
await transport.close()
@@ -1160,7 +1209,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_prompted",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -1170,7 +1219,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
})
@@ -1236,7 +1285,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_skill",
created: 0,
- type: "skill.activated",
+ type: "session.skill.activated",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -1247,7 +1296,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
})
@@ -1317,7 +1366,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_unrelated_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
await Bun.sleep(0)
@@ -1327,7 +1376,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_skill",
created: 0,
- type: "skill.activated",
+ type: "session.skill.activated",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -1338,7 +1387,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_skill_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_1", outcome: "success" },
})
await turn
@@ -1376,7 +1425,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_skill",
created: 0,
- type: "skill.activated",
+ type: "session.skill.activated",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -1438,7 +1487,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_child_step",
created: 0,
- type: "step.started",
+ type: "session.step.started",
durable: durable("ses_child"),
data: {
sessionID: "ses_child",
@@ -1456,7 +1505,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_child_text",
created: 0,
- type: "text.delta",
+ type: "session.text.delta",
data: {
sessionID: "ses_child",
assistantMessageID: "msg_child_a",
@@ -1470,7 +1519,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_child_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_child", outcome: "success" },
})
while (!states().some((state) => state.tabs.some((tab) => tab.status === "completed"))) await Bun.sleep(0)
@@ -1515,7 +1564,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_child_step",
created: 0,
- type: "step.started",
+ type: "session.step.started",
durable: durable("ses_child"),
data: {
sessionID: "ses_child",
@@ -1527,7 +1576,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_child_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_child", outcome: "interrupted" },
})
await Bun.sleep(0)
@@ -1574,7 +1623,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_child_step",
created: 0,
- type: "step.started",
+ type: "session.step.started",
durable: durable("ses_child"),
data: {
sessionID: "ses_child",
@@ -1587,7 +1636,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_parent_call",
created: 0,
- type: "tool.called",
+ type: "session.tool.called",
durable: durable("ses_1"),
data: {
sessionID: "ses_1",
@@ -1601,7 +1650,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_parent_success",
created: 0,
- type: "tool.success",
+ type: "session.tool.success",
durable: durable("ses_1", 1),
data: {
sessionID: "ses_1",
@@ -1616,7 +1665,7 @@ describe("V2 mini transport", () => {
events.push({
id: "evt_child_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: { sessionID: "ses_child", outcome: "interrupted" },
})
while (!states().some((state) => state.tabs.some((tab) => tab.status === "cancelled"))) await Bun.sleep(0)
diff --git a/packages/opencode/test/server/httpapi-pty.test.ts b/packages/opencode/test/server/httpapi-pty.test.ts
index 3eec0c9682..ac18a8a2cf 100644
--- a/packages/opencode/test/server/httpapi-pty.test.ts
+++ b/packages/opencode/test/server/httpapi-pty.test.ts
@@ -99,10 +99,10 @@ describe("pty HttpApi bridge", () => {
const updated = await app().request(PtyPaths.update.replace(":ptyID", info.id), {
method: "PUT",
headers: { ...headers, "content-type": "application/json" },
- body: JSON.stringify({ title: "renamed", size: { cols: 80, rows: 24 } }),
+ body: JSON.stringify({ title: "session.renamed", size: { cols: 80, rows: 24 } }),
})
expect(updated.status).toBe(200)
- expect(await updated.json()).toMatchObject({ id: info.id, title: "renamed" })
+ expect(await updated.json()).toMatchObject({ id: info.id, title: "session.renamed" })
} finally {
await app().request(PtyPaths.remove.replace(":ptyID", info.id), { method: "DELETE", headers })
}
diff --git a/packages/opencode/test/server/httpapi-sdk.test.ts b/packages/opencode/test/server/httpapi-sdk.test.ts
index c81b3b771b..0af92ae382 100644
--- a/packages/opencode/test/server/httpapi-sdk.test.ts
+++ b/packages/opencode/test/server/httpapi-sdk.test.ts
@@ -573,7 +573,7 @@ describe("HttpApi SDK", () => {
const child = yield* capture(() => sdk.session.create({ title: "child", parentID }))
const childID = String(record(child.data).id)
const get = yield* capture(() => sdk.session.get({ sessionID: parentID }))
- const update = yield* capture(() => sdk.session.update({ sessionID: parentID, title: "renamed" }))
+ const update = yield* capture(() => sdk.session.update({ sessionID: parentID, title: "session.renamed" }))
const roots = yield* capture(() => sdk.session.list({ roots: true, limit: 10 }))
const all = yield* capture(() => sdk.session.list({ roots: false, limit: 10 }))
const children = yield* capture(() => sdk.session.children({ sessionID: parentID }))
diff --git a/packages/opencode/test/tool/apply_patch.test.ts b/packages/opencode/test/tool/apply_patch.test.ts
index e394d8084f..57febfa06e 100644
--- a/packages/opencode/test/tool/apply_patch.test.ts
+++ b/packages/opencode/test/tool/apply_patch.test.ts
@@ -271,7 +271,7 @@ describe("tool.apply_patch freeform", () => {
yield* execute({ patchText }, ctx)
- const moved = path.join(test.directory, "renamed", "dir", "name.txt")
+ const moved = path.join(test.directory, "session.renamed", "dir", "name.txt")
yield* expectReadFailure(original)
expect(yield* readText(moved)).toBe("new content\n")
}),
@@ -282,7 +282,7 @@ describe("tool.apply_patch freeform", () => {
const test = yield* TestInstance
const { ctx } = makeCtx()
const original = path.join(test.directory, "old", "name.txt")
- const destination = path.join(test.directory, "renamed", "dir", "name.txt")
+ const destination = path.join(test.directory, "session.renamed", "dir", "name.txt")
yield* makeDir(path.dirname(original))
yield* makeDir(path.dirname(destination))
yield* writeText(original, "from\n")
diff --git a/packages/opencode/test/tool/fixtures/models-api.json b/packages/opencode/test/tool/fixtures/models-api.json
index 6302a951dd..9432ee6635 100644
--- a/packages/opencode/test/tool/fixtures/models-api.json
+++ b/packages/opencode/test/tool/fixtures/models-api.json
@@ -79593,8 +79593,8 @@
}
}
},
- "synthetic": {
- "id": "synthetic",
+ "session.synthetic": {
+ "id": "session.synthetic",
"env": ["SYNTHETIC_API_KEY"],
"npm": "@ai-sdk/openai-compatible",
"api": "https://api.synthetic.new/openai/v1",
diff --git a/packages/opencode/test/v2/session-message-updater.test.ts b/packages/opencode/test/v2/session-message-updater.test.ts
index 4da4dc9d13..1fc3dda0df 100644
--- a/packages/opencode/test/v2/session-message-updater.test.ts
+++ b/packages/opencode/test/v2/session-message-updater.test.ts
@@ -22,7 +22,7 @@ test.skip("step snapshots carry over to assistant messages", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "step.started",
+ type: "session.step.started",
durable: durable(sessionID),
data: {
sessionID,
@@ -44,7 +44,7 @@ test.skip("step snapshots carry over to assistant messages", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "step.ended",
+ type: "session.step.ended",
durable: durable(sessionID, 1, 2),
data: {
sessionID,
@@ -77,7 +77,7 @@ test.skip("text ended populates assistant text content", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "step.started",
+ type: "session.step.started",
durable: durable(sessionID),
data: {
sessionID,
@@ -96,7 +96,7 @@ test.skip("text ended populates assistant text content", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "text.started",
+ type: "session.text.started",
durable: durable(sessionID, 1),
data: {
sessionID,
@@ -110,7 +110,7 @@ test.skip("text ended populates assistant text content", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "text.ended",
+ type: "session.text.ended",
durable: durable(sessionID, 2),
data: {
sessionID,
@@ -136,7 +136,7 @@ test.skip("tool completion stores completed timestamp", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "step.started",
+ type: "session.step.started",
durable: durable(sessionID),
data: {
sessionID,
@@ -155,7 +155,7 @@ test.skip("tool completion stores completed timestamp", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "tool.input.started",
+ type: "session.tool.input.started",
durable: durable(sessionID, 1),
data: {
sessionID,
@@ -170,7 +170,7 @@ test.skip("tool completion stores completed timestamp", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "tool.called",
+ type: "session.tool.called",
durable: durable(sessionID, 2),
data: {
sessionID,
@@ -187,7 +187,7 @@ test.skip("tool completion stores completed timestamp", () => {
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "tool.success",
+ type: "session.tool.success",
durable: durable(sessionID, 3),
data: {
sessionID,
@@ -218,7 +218,7 @@ test("compaction events reduce to compaction message only when completed", () =>
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id,
created: DateTime.makeUnsafe(0),
- type: "compaction.started",
+ type: "session.compaction.started",
durable: durable(sessionID),
data: {
sessionID,
@@ -233,7 +233,7 @@ test("compaction events reduce to compaction message only when completed", () =>
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "compaction.delta",
+ type: "session.compaction.delta",
data: {
sessionID,
text: "hello ",
@@ -245,7 +245,7 @@ test("compaction events reduce to compaction message only when completed", () =>
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: EventV2.ID.create(),
created: DateTime.makeUnsafe(0),
- type: "compaction.delta",
+ type: "session.compaction.delta",
data: {
sessionID,
text: "summary",
@@ -257,7 +257,7 @@ test("compaction events reduce to compaction message only when completed", () =>
SessionMessageUpdater.update(SessionMessageUpdater.memory(state), {
id: endedID,
created: DateTime.makeUnsafe(0),
- type: "compaction.ended",
+ type: "session.compaction.ended",
durable: durable(sessionID, 1),
data: {
sessionID,
diff --git a/packages/schema/src/session-event.ts b/packages/schema/src/session-event.ts
index fce091545a..824b1690db 100644
--- a/packages/schema/src/session-event.ts
+++ b/packages/schema/src/session-event.ts
@@ -12,6 +12,7 @@ import { SessionID } from "./session-id.js"
import { Location } from "./location.js"
import { SessionMessage } from "./session-message.js"
import { Revert } from "./revert.js"
+import { Shell as ShellSchema } from "./shell.js"
export { FileAttachment }
@@ -51,7 +52,7 @@ export const UnknownError = SessionMessage.UnknownError
export type UnknownError = SessionMessage.UnknownError
export const AgentSelected = Event.durable({
- type: "agent.selected",
+ type: "session.agent.selected",
...options,
schema: {
...Base,
@@ -61,7 +62,7 @@ export const AgentSelected = Event.durable({
export type AgentSelected = typeof AgentSelected.Type
export const ModelSelected = Event.durable({
- type: "model.selected",
+ type: "session.model.selected",
...options,
schema: {
...Base,
@@ -82,7 +83,7 @@ export const Moved = Event.durable({
export type Moved = typeof Moved.Type
export const Renamed = Event.durable({
- type: "renamed",
+ type: "session.renamed",
...options,
schema: {
...Base,
@@ -92,7 +93,7 @@ export const Renamed = Event.durable({
export type Renamed = typeof Renamed.Type
export const Forked = Event.durable({
- type: "forked",
+ type: "session.forked",
...options,
schema: {
...Base,
@@ -103,7 +104,7 @@ export const Forked = Event.durable({
export type Forked = typeof Forked.Type
export const PromptPromoted = Event.durable({
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
...options,
schema: {
sessionID: SessionID,
@@ -113,14 +114,14 @@ export const PromptPromoted = Event.durable({
export type PromptPromoted = typeof PromptPromoted.Type
export const PromptAdmitted = Event.durable({
- type: "prompt.admitted",
+ type: "session.prompt.admitted",
...options,
schema: PromptFields,
})
export type PromptAdmitted = typeof PromptAdmitted.Type
export const ExecutionSettled = Event.ephemeral({
- type: "execution.settled",
+ type: "session.execution.settled",
schema: {
...Base,
outcome: Schema.Literals(["success", "failure", "interrupted"]),
@@ -140,7 +141,7 @@ export const ContextUpdated = Event.durable({
export type ContextUpdated = typeof ContextUpdated.Type
export const Synthetic = Event.durable({
- type: "synthetic",
+ type: "session.synthetic",
...options,
schema: {
...Base,
@@ -153,7 +154,7 @@ export type Synthetic = typeof Synthetic.Type
export namespace Skill {
export const Activated = Event.durable({
- type: "skill.activated",
+ type: "session.skill.activated",
...options,
schema: {
...Base,
@@ -166,23 +167,22 @@ export namespace Skill {
export namespace Shell {
export const Started = Event.durable({
- type: "shell.started",
+ type: "session.shell.started",
...options,
schema: {
...Base,
- callID: Schema.String,
- command: Schema.String,
+ shell: ShellSchema.Info,
},
})
export type Started = typeof Started.Type
export const Ended = Event.durable({
- type: "shell.ended",
+ type: "session.shell.ended",
...options,
schema: {
...Base,
- callID: Schema.String,
- output: Schema.String,
+ shell: ShellSchema.Info,
+ output: ShellSchema.Output,
},
})
export type Ended = typeof Ended.Type
@@ -190,7 +190,7 @@ export namespace Shell {
export namespace Step {
export const Started = Event.durable({
- type: "step.started",
+ type: "session.step.started",
...options,
schema: {
...Base,
@@ -203,7 +203,7 @@ export namespace Step {
export type Started = typeof Started.Type
export const Ended = Event.durable({
- type: "step.ended",
+ type: "session.step.ended",
...stepSettlementOptions,
schema: {
...Base,
@@ -226,7 +226,7 @@ export namespace Step {
export type Ended = typeof Ended.Type
export const Failed = Event.durable({
- type: "step.failed",
+ type: "session.step.failed",
...stepSettlementOptions,
schema: {
...Base,
@@ -239,7 +239,7 @@ export namespace Step {
export namespace Text {
export const Started = Event.durable({
- type: "text.started",
+ type: "session.text.started",
...options,
schema: {
...Base,
@@ -251,7 +251,7 @@ export namespace Text {
// Stream fragments are live-only; Text.Ended is the replayable full-value boundary.
export const Delta = Event.ephemeral({
- type: "text.delta",
+ type: "session.text.delta",
schema: {
...Base,
assistantMessageID: SessionMessage.ID,
@@ -262,7 +262,7 @@ export namespace Text {
export type Delta = typeof Delta.Type
export const Ended = Event.durable({
- type: "text.ended",
+ type: "session.text.ended",
...options,
schema: {
...Base,
@@ -276,7 +276,7 @@ export namespace Text {
export namespace Reasoning {
export const Started = Event.durable({
- type: "reasoning.started",
+ type: "session.reasoning.started",
...options,
schema: {
...Base,
@@ -289,7 +289,7 @@ export namespace Reasoning {
// Stream fragments are live-only; Reasoning.Ended is the replayable full-value boundary.
export const Delta = Event.ephemeral({
- type: "reasoning.delta",
+ type: "session.reasoning.delta",
schema: {
...Base,
assistantMessageID: SessionMessage.ID,
@@ -300,7 +300,7 @@ export namespace Reasoning {
export type Delta = typeof Delta.Type
export const Ended = Event.durable({
- type: "reasoning.ended",
+ type: "session.reasoning.ended",
...options,
schema: {
...Base,
@@ -322,7 +322,7 @@ export namespace Tool {
export namespace Input {
export const Started = Event.durable({
- type: "tool.input.started",
+ type: "session.tool.input.started",
...options,
schema: {
...ToolBase,
@@ -333,7 +333,7 @@ export namespace Tool {
// Stream fragments are live-only; Input.Ended is the replayable raw-input boundary.
export const Delta = Event.ephemeral({
- type: "tool.input.delta",
+ type: "session.tool.input.delta",
schema: {
...ToolBase,
delta: Schema.String,
@@ -342,7 +342,7 @@ export namespace Tool {
export type Delta = typeof Delta.Type
export const Ended = Event.durable({
- type: "tool.input.ended",
+ type: "session.tool.input.ended",
...options,
schema: {
...ToolBase,
@@ -353,7 +353,7 @@ export namespace Tool {
}
export const Called = Event.durable({
- type: "tool.called",
+ type: "session.tool.called",
...options,
schema: {
...ToolBase,
@@ -372,7 +372,7 @@ export namespace Tool {
* transitions or at a bounded cadence, not persist every stdout/stderr chunk.
*/
export const Progress = Event.durable({
- type: "tool.progress",
+ type: "session.tool.progress",
...options,
schema: {
...ToolBase,
@@ -383,7 +383,7 @@ export namespace Tool {
export type Progress = typeof Progress.Type
export const Success = Event.durable({
- type: "tool.success",
+ type: "session.tool.success",
...options,
schema: {
...ToolBase,
@@ -400,7 +400,7 @@ export namespace Tool {
export type Success = typeof Success.Type
export const Failed = Event.durable({
- type: "tool.failed",
+ type: "session.tool.failed",
...options,
schema: {
...ToolBase,
@@ -428,7 +428,7 @@ export const RetryError = Schema.Struct({
export interface RetryError extends Schema.Schema.Type {}
export const Retried = Event.durable({
- type: "retried",
+ type: "session.retried",
...options,
schema: {
...Base,
@@ -440,7 +440,7 @@ export type Retried = typeof Retried.Type
export namespace Compaction {
export const Started = Event.durable({
- type: "compaction.started",
+ type: "session.compaction.started",
...options,
schema: {
...Base,
@@ -450,7 +450,7 @@ export namespace Compaction {
export type Started = typeof Started.Type
export const Delta = Event.ephemeral({
- type: "compaction.delta",
+ type: "session.compaction.delta",
schema: {
...Base,
text: Schema.String,
@@ -459,7 +459,7 @@ export namespace Compaction {
export type Delta = typeof Delta.Type
export const Ended = Event.durable({
- type: "compaction.ended",
+ type: "session.compaction.ended",
...options,
schema: {
...Base,
@@ -473,13 +473,13 @@ export namespace Compaction {
export namespace RevertEvent {
export const Staged = Event.durable({
- type: "revert.staged",
+ type: "session.revert.staged",
...options,
schema: { ...Base, revert: Revert.State },
})
- export const Cleared = Event.durable({ type: "revert.cleared", ...options, schema: Base })
+ export const Cleared = Event.durable({ type: "session.revert.cleared", ...options, schema: Base })
export const Committed = Event.durable({
- type: "revert.committed",
+ type: "session.revert.committed",
...options,
schema: { ...Base, messageID: SessionMessage.ID },
})
diff --git a/packages/schema/src/session-message.ts b/packages/schema/src/session-message.ts
index 349d04d06e..e3d81a31d7 100644
--- a/packages/schema/src/session-message.ts
+++ b/packages/schema/src/session-message.ts
@@ -9,6 +9,7 @@ import { DateTimeUtcFromMillis, RelativePath, statics } from "./schema.js"
import { SessionID } from "./session-id.js"
import { ascending } from "./identifier.js"
import { Event } from "./event.js"
+import { Shell as ShellSchema } from "./shell.js"
export const ID = Schema.String.check(Schema.isStartsWith("msg_")).pipe(
Schema.brand("Session.Message.ID"),
@@ -82,9 +83,8 @@ export interface Shell extends Schema.Schema.Type {}
export const Shell = Schema.Struct({
...Base,
type: Schema.Literal("shell"),
- callID: Schema.String,
- command: Schema.String,
- output: Schema.String,
+ shell: ShellSchema.Info,
+ output: ShellSchema.Output.pipe(optional),
time: Schema.Struct({
created: DateTimeUtcFromMillis,
completed: DateTimeUtcFromMillis.pipe(optional),
diff --git a/packages/schema/test/event-manifest.test.ts b/packages/schema/test/event-manifest.test.ts
index 4fa23e75f7..873e415c61 100644
--- a/packages/schema/test/event-manifest.test.ts
+++ b/packages/schema/test/event-manifest.test.ts
@@ -53,7 +53,7 @@ describe("public event manifest", () => {
expect(Session.Event.Definitions).toBe(SessionEvent.Definitions)
expect(Workspace.Event).toBe(WorkspaceEvent)
expect(Workspace.Event.Definitions).toBe(WorkspaceEvent.Definitions)
- expect(EventManifest.Latest.get("step.ended")).toBe(SessionEvent.Step.Ended)
+ expect(EventManifest.Latest.get("session.step.ended")).toBe(SessionEvent.Step.Ended)
expect(EventManifest.Latest.get("todo.updated")).toBe(SessionTodo.Event.Updated)
expect(EventManifest.Latest.get("agent.updated")).toBe(Agent.Event.Updated)
expect(EventManifest.Latest.get("project.updated")).toBe(Project.Event.Updated)
@@ -74,8 +74,8 @@ describe("public event manifest", () => {
SessionV1.Event.Diff,
SessionV1.Event.Error,
])
- expect(EventManifest.Durable.get("step.ended.1")).toBe(SessionEvent.Step.Ended)
- expect(EventManifest.Durable.has("step.ended.2")).toBe(false)
+ expect(EventManifest.Durable.get("session.step.ended.1")).toBe(SessionEvent.Step.Ended)
+ expect(EventManifest.Durable.has("session.step.ended.2")).toBe(false)
})
test("derives durable definitions from explicit definition durability", () => {
@@ -88,37 +88,37 @@ describe("public event manifest", () => {
"message.removed.1",
"message.part.updated.1",
"message.part.removed.1",
- "agent.selected.1",
- "model.selected.1",
+ "session.agent.selected.1",
+ "session.model.selected.1",
"session.moved.1",
- "renamed.1",
- "forked.1",
- "prompt.promoted.1",
- "prompt.admitted.1",
+ "session.renamed.1",
+ "session.forked.1",
+ "session.prompt.promoted.1",
+ "session.prompt.admitted.1",
"session.context.updated.1",
- "synthetic.1",
- "skill.activated.1",
- "shell.started.1",
- "shell.ended.1",
- "step.started.1",
- "step.ended.1",
- "step.failed.1",
- "text.started.1",
- "text.ended.1",
- "tool.input.started.1",
- "tool.input.ended.1",
- "tool.called.1",
- "tool.progress.1",
- "tool.success.1",
- "tool.failed.1",
- "reasoning.started.1",
- "reasoning.ended.1",
- "retried.1",
- "compaction.started.1",
- "compaction.ended.1",
- "revert.staged.1",
- "revert.cleared.1",
- "revert.committed.1",
+ "session.synthetic.1",
+ "session.skill.activated.1",
+ "session.shell.started.1",
+ "session.shell.ended.1",
+ "session.step.started.1",
+ "session.step.ended.1",
+ "session.step.failed.1",
+ "session.text.started.1",
+ "session.text.ended.1",
+ "session.tool.input.started.1",
+ "session.tool.input.ended.1",
+ "session.tool.called.1",
+ "session.tool.progress.1",
+ "session.tool.success.1",
+ "session.tool.failed.1",
+ "session.reasoning.started.1",
+ "session.reasoning.ended.1",
+ "session.retried.1",
+ "session.compaction.started.1",
+ "session.compaction.ended.1",
+ "session.revert.staged.1",
+ "session.revert.cleared.1",
+ "session.revert.committed.1",
].toSorted(),
)
expect(SessionEvent.DurableDefinitions).toEqual(
diff --git a/packages/sdk-next/test/embedded.test.ts b/packages/sdk-next/test/embedded.test.ts
index 5419b7e838..4ac31b70ab 100644
--- a/packages/sdk-next/test/embedded.test.ts
+++ b/packages/sdk-next/test/embedded.test.ts
@@ -78,7 +78,7 @@ it.live(
prompt: fixture.sdk.Prompt.make({ text: "Promote this input" }),
})
const prompted = yield* opencode.sessions.log({ sessionID: id, follow: true }).pipe(
- Stream.filter((event) => event.type === "prompt.promoted" && event.data.inputID === wake.id),
+ Stream.filter((event) => event.type === "session.prompt.promoted" && event.data.inputID === wake.id),
Stream.runHead,
Effect.timeout("10 seconds"),
Effect.map(Option.getOrThrow),
@@ -119,7 +119,7 @@ it.live(
expect(page.data.some((session) => session.id === id)).toBe(true)
expect(active).toEqual({ data: {}, watermarks: {} })
expect(admitted.sessionID).toBe(id)
- expect(prompted.type).toBe("prompt.promoted")
+ expect(prompted.type).toBe("session.prompt.promoted")
expect(wakeContext).toContainEqual(expect.objectContaining({ id: wake.id, type: "user" }))
expect(contextEntries).toEqual([
{ key: "deploy-target", value: "production" },
@@ -127,7 +127,7 @@ it.live(
])
expect(remainingContextEntries).toEqual([{ key: "deploy-target", value: "production" }])
expect(context.some((message) => message.type === "model-switched")).toBe(true)
- expect(event).toMatchObject({ type: "model.selected", durable: { seq: 1 } })
+ expect(event).toMatchObject({ type: "session.model.selected", durable: { seq: 1 } })
expect(message).toEqual(modelMessage)
expect(missing.map((error) => error._tag)).toEqual([
"SessionNotFoundError",
@@ -149,13 +149,13 @@ it.live(
const opencode = yield* fixture.sdk.OpenCode.create()
const id = sessionID(fixture)
const connected = yield* Latch.make(false)
- const prompted = yield* Deferred.make>()
+ const prompted = yield* Deferred.make>()
yield* opencode.events.subscribe().pipe(
Stream.runForEach((event) =>
event.type === "server.connected"
? connected.open
- : event.type === "prompt.promoted" && event.data.sessionID === id
+ : event.type === "session.prompt.promoted" && event.data.sessionID === id
? Deferred.succeed(prompted, event).pipe(Effect.asVoid)
: Effect.void,
),
@@ -191,7 +191,7 @@ it.live(
Stream.runForEach((notification: OpenCodeEvent) =>
notification.type === "server.connected"
? ready.open
- : notification.type === "agent.selected" && notification.data.sessionID === id
+ : notification.type === "session.agent.selected" && notification.data.sessionID === id
? event.open
: Effect.void,
)
diff --git a/packages/sdk/js/script/build.ts b/packages/sdk/js/script/build.ts
index d87f8bf98a..220bf43da3 100755
--- a/packages/sdk/js/script/build.ts
+++ b/packages/sdk/js/script/build.ts
@@ -60,7 +60,7 @@ if (schemas) {
visit({ ...document, components: { ...document.components, schemas: undefined } })
for (const name of Object.keys(schemas)) {
if (
- /^(AgentSelected|ModelSelected|SessionMoved|Renamed|Forked|PromptPromoted|PromptAdmitted|ExecutionSettled|ContextUpdated|Synthetic|SkillActivated|ShellStarted|ShellEnded|StepStarted|StepEnded|StepFailed|TextStarted|TextDelta|TextEnded|ReasoningStarted|ReasoningDelta|ReasoningEnded|ToolInputStarted|ToolInputDelta|ToolInputEnded|ToolCalled|ToolProgress|ToolSuccess|ToolFailed|Retried|CompactionStarted|CompactionDelta|CompactionEnded|RevertStaged|RevertCleared|RevertCommitted)1$/.test(
+ /^(SessionAgentSelected|SessionModelSelected|SessionMoved|SessionRenamed|SessionForked|SessionPromptPromoted|SessionPromptAdmitted|SessionExecutionSettled|SessionContextUpdated|SessionSynthetic|SessionSkillActivated|SessionShellStarted|SessionShellEnded|SessionStepStarted|SessionStepEnded|SessionStepFailed|SessionTextStarted|SessionTextDelta|SessionTextEnded|SessionReasoningStarted|SessionReasoningDelta|SessionReasoningEnded|SessionToolInputStarted|SessionToolInputDelta|SessionToolInputEnded|SessionToolCalled|SessionToolProgress|SessionToolSuccess|SessionToolFailed|SessionRetried|SessionCompactionStarted|SessionCompactionDelta|SessionCompactionEnded|SessionRevertStaged|SessionRevertCleared|SessionRevertCommitted)1$/.test(
name,
) &&
!reachable.has(name)
@@ -100,7 +100,7 @@ await createClient({
const generatedTypesPath = "./src/v2/gen/types.gen.ts"
const generatedTypes = await Bun.file(generatedTypesPath).text()
if (
- /export type (AgentSelected|ModelSelected|SessionMoved|Renamed|Forked|PromptPromoted|PromptAdmitted|ExecutionSettled|ContextUpdated|Synthetic|SkillActivated|ShellStarted|ShellEnded|StepStarted|StepEnded|StepFailed|TextStarted|TextDelta|TextEnded|ReasoningStarted|ReasoningDelta|ReasoningEnded|ToolInputStarted|ToolInputDelta|ToolInputEnded|ToolCalled|ToolProgress|ToolSuccess|ToolFailed|Retried|CompactionStarted|CompactionDelta|CompactionEnded|RevertStaged|RevertCleared|RevertCommitted)1 =/.test(
+ /export type (SessionAgentSelected|SessionModelSelected|SessionMoved|SessionRenamed|SessionForked|SessionPromptPromoted|SessionPromptAdmitted|SessionExecutionSettled|SessionContextUpdated|SessionSynthetic|SessionSkillActivated|SessionShellStarted|SessionShellEnded|SessionStepStarted|SessionStepEnded|SessionStepFailed|SessionTextStarted|SessionTextDelta|SessionTextEnded|SessionReasoningStarted|SessionReasoningDelta|SessionReasoningEnded|SessionToolInputStarted|SessionToolInputDelta|SessionToolInputEnded|SessionToolCalled|SessionToolProgress|SessionToolSuccess|SessionToolFailed|SessionRetried|SessionCompactionStarted|SessionCompactionDelta|SessionCompactionEnded|SessionRevertStaged|SessionRevertCleared|SessionRevertCommitted)1 =/.test(
generatedTypes,
)
) {
diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts
index 56cdccf087..27ca0f00cd 100644
--- a/packages/sdk/js/src/v2/gen/types.gen.ts
+++ b/packages/sdk/js/src/v2/gen/types.gen.ts
@@ -17,42 +17,42 @@ export type Event =
| EventMessageRemoved
| EventMessagePartUpdated
| EventMessagePartRemoved
- | EventAgentSelected
- | EventModelSelected
+ | EventSessionAgentSelected
+ | EventSessionModelSelected
| EventSessionMoved
- | EventRenamed
- | EventForked
- | EventPromptPromoted
- | EventPromptAdmitted
- | EventExecutionSettled
+ | EventSessionRenamed
+ | EventSessionForked
+ | EventSessionPromptPromoted
+ | EventSessionPromptAdmitted
+ | EventSessionExecutionSettled
| EventSessionContextUpdated
- | EventSynthetic
- | EventSkillActivated
- | EventShellStarted
- | EventShellEnded
- | EventStepStarted
- | EventStepEnded
- | EventStepFailed
- | EventTextStarted
- | EventTextDelta
- | EventTextEnded
- | EventReasoningStarted
- | EventReasoningDelta
- | EventReasoningEnded
- | EventToolInputStarted
- | EventToolInputDelta
- | EventToolInputEnded
- | EventToolCalled
- | EventToolProgress
- | EventToolSuccess
- | EventToolFailed
- | EventRetried
- | EventCompactionStarted
- | EventCompactionDelta
- | EventCompactionEnded
- | EventRevertStaged
- | EventRevertCleared
- | EventRevertCommitted
+ | EventSessionSynthetic
+ | EventSessionSkillActivated
+ | EventSessionShellStarted
+ | EventSessionShellEnded
+ | EventSessionStepStarted
+ | EventSessionStepEnded
+ | EventSessionStepFailed
+ | EventSessionTextStarted
+ | EventSessionTextDelta
+ | EventSessionTextEnded
+ | EventSessionReasoningStarted
+ | EventSessionReasoningDelta
+ | EventSessionReasoningEnded
+ | EventSessionToolInputStarted
+ | EventSessionToolInputDelta
+ | EventSessionToolInputEnded
+ | EventSessionToolCalled
+ | EventSessionToolProgress
+ | EventSessionToolSuccess
+ | EventSessionToolFailed
+ | EventSessionRetried
+ | EventSessionCompactionStarted
+ | EventSessionCompactionDelta
+ | EventSessionCompactionEnded
+ | EventSessionRevertStaged
+ | EventSessionRevertCleared
+ | EventSessionRevertCommitted
| EventMessagePartDelta
| EventSessionDiff
| EventSessionError
@@ -657,17 +657,6 @@ export type Prompt = {
agents?: Array
}
-export type Pty = {
- id: string
- title: string
- command: string
- args: Array
- cwd: string
- status: "running" | "exited"
- pid: number
- exitCode?: number
-}
-
export type Shell = {
id: string
status: "running" | "exited" | "timeout" | "killed"
@@ -686,6 +675,17 @@ export type Shell = {
}
}
+export type Pty = {
+ id: string
+ title: string
+ command: string
+ args: Array
+ cwd: string
+ status: "running" | "exited"
+ pid: number
+ exitCode?: number
+}
+
export type Todo = {
/**
* Brief description of the task
@@ -858,7 +858,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "agent.selected"
+ type: "session.agent.selected"
properties: {
sessionID: string
agent: string
@@ -866,7 +866,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "model.selected"
+ type: "session.model.selected"
properties: {
sessionID: string
model: ModelRef
@@ -883,7 +883,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "renamed"
+ type: "session.renamed"
properties: {
sessionID: string
title: string
@@ -891,7 +891,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "forked"
+ type: "session.forked"
properties: {
sessionID: string
parentID: string
@@ -900,7 +900,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "prompt.promoted"
+ type: "session.prompt.promoted"
properties: {
sessionID: string
inputID: string
@@ -908,7 +908,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "prompt.admitted"
+ type: "session.prompt.admitted"
properties: {
sessionID: string
inputID: string
@@ -918,7 +918,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "execution.settled"
+ type: "session.execution.settled"
properties: {
sessionID: string
outcome: "success" | "failure" | "interrupted"
@@ -935,7 +935,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "synthetic"
+ type: "session.synthetic"
properties: {
sessionID: string
text: string
@@ -947,7 +947,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "skill.activated"
+ type: "session.skill.activated"
properties: {
sessionID: string
name: string
@@ -956,25 +956,29 @@ export type GlobalEvent = {
}
| {
id: string
- type: "shell.started"
+ type: "session.shell.started"
properties: {
sessionID: string
- callID: string
- command: string
+ shell: Shell
}
}
| {
id: string
- type: "shell.ended"
+ type: "session.shell.ended"
properties: {
sessionID: string
- callID: string
- output: string
+ shell: Shell
+ output: {
+ output: string
+ cursor: number
+ size: number
+ truncated: boolean
+ }
}
}
| {
id: string
- type: "step.started"
+ type: "session.step.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -985,7 +989,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "step.ended"
+ type: "session.step.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -1006,7 +1010,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "step.failed"
+ type: "session.step.failed"
properties: {
sessionID: string
assistantMessageID: string
@@ -1015,7 +1019,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "text.started"
+ type: "session.text.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -1024,7 +1028,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "text.delta"
+ type: "session.text.delta"
properties: {
sessionID: string
assistantMessageID: string
@@ -1034,7 +1038,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "text.ended"
+ type: "session.text.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -1044,7 +1048,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "reasoning.started"
+ type: "session.reasoning.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -1054,7 +1058,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "reasoning.delta"
+ type: "session.reasoning.delta"
properties: {
sessionID: string
assistantMessageID: string
@@ -1064,7 +1068,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "reasoning.ended"
+ type: "session.reasoning.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -1075,7 +1079,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "tool.input.started"
+ type: "session.tool.input.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -1085,7 +1089,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "tool.input.delta"
+ type: "session.tool.input.delta"
properties: {
sessionID: string
assistantMessageID: string
@@ -1095,7 +1099,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "tool.input.ended"
+ type: "session.tool.input.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -1105,7 +1109,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "tool.called"
+ type: "session.tool.called"
properties: {
sessionID: string
assistantMessageID: string
@@ -1122,7 +1126,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "tool.progress"
+ type: "session.tool.progress"
properties: {
sessionID: string
assistantMessageID: string
@@ -1135,7 +1139,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "tool.success"
+ type: "session.tool.success"
properties: {
sessionID: string
assistantMessageID: string
@@ -1154,7 +1158,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "tool.failed"
+ type: "session.tool.failed"
properties: {
sessionID: string
assistantMessageID: string
@@ -1169,7 +1173,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "retried"
+ type: "session.retried"
properties: {
sessionID: string
attempt: number
@@ -1178,7 +1182,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "compaction.started"
+ type: "session.compaction.started"
properties: {
sessionID: string
reason: "auto" | "manual"
@@ -1186,7 +1190,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "compaction.delta"
+ type: "session.compaction.delta"
properties: {
sessionID: string
text: string
@@ -1194,7 +1198,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "compaction.ended"
+ type: "session.compaction.ended"
properties: {
sessionID: string
reason: "auto" | "manual"
@@ -1204,7 +1208,7 @@ export type GlobalEvent = {
}
| {
id: string
- type: "revert.staged"
+ type: "session.revert.staged"
properties: {
sessionID: string
revert: RevertState
@@ -1212,14 +1216,14 @@ export type GlobalEvent = {
}
| {
id: string
- type: "revert.cleared"
+ type: "session.revert.cleared"
properties: {
sessionID: string
}
}
| {
id: string
- type: "revert.committed"
+ type: "session.revert.committed"
properties: {
sessionID: string
messageID: string
@@ -1704,37 +1708,37 @@ export type GlobalEvent = {
| SyncEventMessageRemoved
| SyncEventMessagePartUpdated
| SyncEventMessagePartRemoved
- | SyncEventAgentSelected
- | SyncEventModelSelected
+ | SyncEventSessionAgentSelected
+ | SyncEventSessionModelSelected
| SyncEventSessionMoved
- | SyncEventRenamed
- | SyncEventForked
- | SyncEventPromptPromoted
- | SyncEventPromptAdmitted
+ | SyncEventSessionRenamed
+ | SyncEventSessionForked
+ | SyncEventSessionPromptPromoted
+ | SyncEventSessionPromptAdmitted
| SyncEventSessionContextUpdated
- | SyncEventSynthetic
- | SyncEventSkillActivated
- | SyncEventShellStarted
- | SyncEventShellEnded
- | SyncEventStepStarted
- | SyncEventStepEnded
- | SyncEventStepFailed
- | SyncEventTextStarted
- | SyncEventTextEnded
- | SyncEventReasoningStarted
- | SyncEventReasoningEnded
- | SyncEventToolInputStarted
- | SyncEventToolInputEnded
- | SyncEventToolCalled
- | SyncEventToolProgress
- | SyncEventToolSuccess
- | SyncEventToolFailed
- | SyncEventRetried
- | SyncEventCompactionStarted
- | SyncEventCompactionEnded
- | SyncEventRevertStaged
- | SyncEventRevertCleared
- | SyncEventRevertCommitted
+ | SyncEventSessionSynthetic
+ | SyncEventSessionSkillActivated
+ | SyncEventSessionShellStarted
+ | SyncEventSessionShellEnded
+ | SyncEventSessionStepStarted
+ | SyncEventSessionStepEnded
+ | SyncEventSessionStepFailed
+ | SyncEventSessionTextStarted
+ | SyncEventSessionTextEnded
+ | SyncEventSessionReasoningStarted
+ | SyncEventSessionReasoningEnded
+ | SyncEventSessionToolInputStarted
+ | SyncEventSessionToolInputEnded
+ | SyncEventSessionToolCalled
+ | SyncEventSessionToolProgress
+ | SyncEventSessionToolSuccess
+ | SyncEventSessionToolFailed
+ | SyncEventSessionRetried
+ | SyncEventSessionCompactionStarted
+ | SyncEventSessionCompactionEnded
+ | SyncEventSessionRevertStaged
+ | SyncEventSessionRevertCleared
+ | SyncEventSessionRevertCommitted
}
/**
@@ -2854,120 +2858,56 @@ export type UnknownError1 = {
ref?: string
}
-export type Renamed = {
+export type Shell1 = {
id: string
- created: number
- metadata?: {
+ status: "running" | "exited" | "timeout" | "killed"
+ command: string
+ cwd: string
+ shell: string
+ file: string
+ pid?: number
+ exit?: number | "NaN" | "Infinity" | "-Infinity"
+ metadata: {
[key: string]: unknown
}
- type: "renamed"
- durable: {
- aggregateID: string
- seq: number
- version: number
- }
- location?: LocationRef
- data: {
- sessionID: string
- title: string
- }
-}
-
-export type Forked = {
- id: string
- created: number
- metadata?: {
- [key: string]: unknown
- }
- type: "forked"
- durable: {
- aggregateID: string
- seq: number
- version: number
- }
- location?: LocationRef
- data: {
- sessionID: string
- parentID: string
- from?: string
- }
-}
-
-export type Synthetic = {
- id: string
- created: number
- metadata?: {
- [key: string]: unknown
- }
- type: "synthetic"
- durable: {
- aggregateID: string
- seq: number
- version: number
- }
- location?: LocationRef
- data: {
- sessionID: string
- text: string
- description?: string
- metadata?: {
- [key: string]: unknown
- }
- }
-}
-
-export type Retried = {
- id: string
- created: number
- metadata?: {
- [key: string]: unknown
- }
- type: "retried"
- durable: {
- aggregateID: string
- seq: number
- version: number
- }
- location?: LocationRef
- data: {
- sessionID: string
- attempt: number
- error: SessionRetryError
+ time: {
+ started: number | "NaN" | "Infinity" | "-Infinity"
+ completed?: number | "NaN" | "Infinity" | "-Infinity"
}
}
export type SessionDurableEvent =
- | AgentSelected
- | ModelSelected
+ | SessionAgentSelected
+ | SessionModelSelected
| SessionMoved
- | Renamed
- | Forked
- | PromptPromoted
- | PromptAdmitted
+ | SessionRenamed
+ | SessionForked
+ | SessionPromptPromoted
+ | SessionPromptAdmitted
| SessionContextUpdated
- | Synthetic
- | SkillActivated
- | ShellStarted
- | ShellEnded
- | StepStarted
- | StepEnded
- | StepFailed
- | TextStarted
- | TextEnded
- | ReasoningStarted
- | ReasoningEnded
- | ToolInputStarted
- | ToolInputEnded
- | ToolCalled
- | ToolProgress
- | ToolSuccess
- | ToolFailed
- | Retried
- | CompactionStarted
- | CompactionEnded
- | RevertStaged
- | RevertCleared
- | RevertCommitted
+ | SessionSynthetic
+ | SessionSkillActivated
+ | SessionShellStarted
+ | SessionShellEnded
+ | SessionStepStarted
+ | SessionStepEnded
+ | SessionStepFailed
+ | SessionTextStarted
+ | SessionTextEnded
+ | SessionReasoningStarted
+ | SessionReasoningEnded
+ | SessionToolInputStarted
+ | SessionToolInputEnded
+ | SessionToolCalled
+ | SessionToolProgress
+ | SessionToolSuccess
+ | SessionToolFailed
+ | SessionRetried
+ | SessionCompactionStarted
+ | SessionCompactionEnded
+ | SessionRevertStaged
+ | SessionRevertCleared
+ | SessionRevertCommitted
export type SessionLogItem = SessionDurableEvent | EventLogSynced
@@ -3022,24 +2962,6 @@ export type OutputFormat1 =
retryCount?: number
}
-export type Shell1 = {
- id: string
- status: "running" | "exited" | "timeout" | "killed"
- command: string
- cwd: string
- shell: string
- file: string
- pid?: number
- exit?: number | "NaN" | "Infinity" | "-Infinity"
- metadata: {
- [key: string]: unknown
- }
- time: {
- started: number | "NaN" | "Infinity" | "-Infinity"
- completed?: number | "NaN" | "Infinity" | "-Infinity"
- }
-}
-
export type SessionStatus2 = {
id: string
created: number
@@ -3096,42 +3018,42 @@ export type V2Event =
| MessageRemoved
| MessagePartUpdated
| MessagePartRemoved
- | AgentSelected
- | ModelSelected
+ | SessionAgentSelected
+ | SessionModelSelected
| SessionMoved
- | Renamed
- | Forked
- | PromptPromoted
- | PromptAdmitted
- | ExecutionSettled
+ | SessionRenamed
+ | SessionForked
+ | SessionPromptPromoted
+ | SessionPromptAdmitted
+ | SessionExecutionSettled
| SessionContextUpdated
- | Synthetic
- | SkillActivated
- | ShellStarted
- | ShellEnded
- | StepStarted
- | StepEnded
- | StepFailed
- | TextStarted
- | TextDelta
- | TextEnded
- | ReasoningStarted
- | ReasoningDelta
- | ReasoningEnded
- | ToolInputStarted
- | ToolInputDelta
- | ToolInputEnded
- | ToolCalled
- | ToolProgress
- | ToolSuccess
- | ToolFailed
- | Retried
- | CompactionStarted
- | CompactionDelta
- | CompactionEnded
- | RevertStaged
- | RevertCleared
- | RevertCommitted
+ | SessionSynthetic
+ | SessionSkillActivated
+ | SessionShellStarted
+ | SessionShellEnded
+ | SessionStepStarted
+ | SessionStepEnded
+ | SessionStepFailed
+ | SessionTextStarted
+ | SessionTextDelta
+ | SessionTextEnded
+ | SessionReasoningStarted
+ | SessionReasoningDelta
+ | SessionReasoningEnded
+ | SessionToolInputStarted
+ | SessionToolInputDelta
+ | SessionToolInputEnded
+ | SessionToolCalled
+ | SessionToolProgress
+ | SessionToolSuccess
+ | SessionToolFailed
+ | SessionRetried
+ | SessionCompactionStarted
+ | SessionCompactionDelta
+ | SessionCompactionEnded
+ | SessionRevertStaged
+ | SessionRevertCleared
+ | SessionRevertCommitted
| MessagePartDelta
| SessionDiff
| SessionError
@@ -3689,11 +3611,11 @@ export type SyncEventMessagePartRemoved = {
}
}
-export type SyncEventAgentSelected = {
+export type SyncEventSessionAgentSelected = {
type: "sync"
id: string
syncEvent: {
- type: "agent.selected.1"
+ type: "session.agent.selected.1"
id: string
seq: number
aggregateID: string
@@ -3704,11 +3626,11 @@ export type SyncEventAgentSelected = {
}
}
-export type SyncEventModelSelected = {
+export type SyncEventSessionModelSelected = {
type: "sync"
id: string
syncEvent: {
- type: "model.selected.1"
+ type: "session.model.selected.1"
id: string
seq: number
aggregateID: string
@@ -3735,11 +3657,11 @@ export type SyncEventSessionMoved = {
}
}
-export type SyncEventRenamed = {
+export type SyncEventSessionRenamed = {
type: "sync"
id: string
syncEvent: {
- type: "renamed.1"
+ type: "session.renamed.1"
id: string
seq: number
aggregateID: string
@@ -3750,11 +3672,11 @@ export type SyncEventRenamed = {
}
}
-export type SyncEventForked = {
+export type SyncEventSessionForked = {
type: "sync"
id: string
syncEvent: {
- type: "forked.1"
+ type: "session.forked.1"
id: string
seq: number
aggregateID: string
@@ -3766,11 +3688,11 @@ export type SyncEventForked = {
}
}
-export type SyncEventPromptPromoted = {
+export type SyncEventSessionPromptPromoted = {
type: "sync"
id: string
syncEvent: {
- type: "prompt.promoted.1"
+ type: "session.prompt.promoted.1"
id: string
seq: number
aggregateID: string
@@ -3781,11 +3703,11 @@ export type SyncEventPromptPromoted = {
}
}
-export type SyncEventPromptAdmitted = {
+export type SyncEventSessionPromptAdmitted = {
type: "sync"
id: string
syncEvent: {
- type: "prompt.admitted.1"
+ type: "session.prompt.admitted.1"
id: string
seq: number
aggregateID: string
@@ -3813,11 +3735,11 @@ export type SyncEventSessionContextUpdated = {
}
}
-export type SyncEventSynthetic = {
+export type SyncEventSessionSynthetic = {
type: "sync"
id: string
syncEvent: {
- type: "synthetic.1"
+ type: "session.synthetic.1"
id: string
seq: number
aggregateID: string
@@ -3832,11 +3754,11 @@ export type SyncEventSynthetic = {
}
}
-export type SyncEventSkillActivated = {
+export type SyncEventSessionSkillActivated = {
type: "sync"
id: string
syncEvent: {
- type: "skill.activated.1"
+ type: "session.skill.activated.1"
id: string
seq: number
aggregateID: string
@@ -3848,43 +3770,47 @@ export type SyncEventSkillActivated = {
}
}
-export type SyncEventShellStarted = {
+export type SyncEventSessionShellStarted = {
type: "sync"
id: string
syncEvent: {
- type: "shell.started.1"
+ type: "session.shell.started.1"
id: string
seq: number
aggregateID: string
data: {
sessionID: string
- callID: string
- command: string
+ shell: Shell
}
}
}
-export type SyncEventShellEnded = {
+export type SyncEventSessionShellEnded = {
type: "sync"
id: string
syncEvent: {
- type: "shell.ended.1"
+ type: "session.shell.ended.1"
id: string
seq: number
aggregateID: string
data: {
sessionID: string
- callID: string
- output: string
+ shell: Shell
+ output: {
+ output: string
+ cursor: number
+ size: number
+ truncated: boolean
+ }
}
}
}
-export type SyncEventStepStarted = {
+export type SyncEventSessionStepStarted = {
type: "sync"
id: string
syncEvent: {
- type: "step.started.1"
+ type: "session.step.started.1"
id: string
seq: number
aggregateID: string
@@ -3898,11 +3824,11 @@ export type SyncEventStepStarted = {
}
}
-export type SyncEventStepEnded = {
+export type SyncEventSessionStepEnded = {
type: "sync"
id: string
syncEvent: {
- type: "step.ended.1"
+ type: "session.step.ended.1"
id: string
seq: number
aggregateID: string
@@ -3926,11 +3852,11 @@ export type SyncEventStepEnded = {
}
}
-export type SyncEventStepFailed = {
+export type SyncEventSessionStepFailed = {
type: "sync"
id: string
syncEvent: {
- type: "step.failed.1"
+ type: "session.step.failed.1"
id: string
seq: number
aggregateID: string
@@ -3942,11 +3868,11 @@ export type SyncEventStepFailed = {
}
}
-export type SyncEventTextStarted = {
+export type SyncEventSessionTextStarted = {
type: "sync"
id: string
syncEvent: {
- type: "text.started.1"
+ type: "session.text.started.1"
id: string
seq: number
aggregateID: string
@@ -3958,11 +3884,11 @@ export type SyncEventTextStarted = {
}
}
-export type SyncEventTextEnded = {
+export type SyncEventSessionTextEnded = {
type: "sync"
id: string
syncEvent: {
- type: "text.ended.1"
+ type: "session.text.ended.1"
id: string
seq: number
aggregateID: string
@@ -3975,11 +3901,11 @@ export type SyncEventTextEnded = {
}
}
-export type SyncEventReasoningStarted = {
+export type SyncEventSessionReasoningStarted = {
type: "sync"
id: string
syncEvent: {
- type: "reasoning.started.1"
+ type: "session.reasoning.started.1"
id: string
seq: number
aggregateID: string
@@ -3992,11 +3918,11 @@ export type SyncEventReasoningStarted = {
}
}
-export type SyncEventReasoningEnded = {
+export type SyncEventSessionReasoningEnded = {
type: "sync"
id: string
syncEvent: {
- type: "reasoning.ended.1"
+ type: "session.reasoning.ended.1"
id: string
seq: number
aggregateID: string
@@ -4010,11 +3936,11 @@ export type SyncEventReasoningEnded = {
}
}
-export type SyncEventToolInputStarted = {
+export type SyncEventSessionToolInputStarted = {
type: "sync"
id: string
syncEvent: {
- type: "tool.input.started.1"
+ type: "session.tool.input.started.1"
id: string
seq: number
aggregateID: string
@@ -4027,11 +3953,11 @@ export type SyncEventToolInputStarted = {
}
}
-export type SyncEventToolInputEnded = {
+export type SyncEventSessionToolInputEnded = {
type: "sync"
id: string
syncEvent: {
- type: "tool.input.ended.1"
+ type: "session.tool.input.ended.1"
id: string
seq: number
aggregateID: string
@@ -4044,11 +3970,11 @@ export type SyncEventToolInputEnded = {
}
}
-export type SyncEventToolCalled = {
+export type SyncEventSessionToolCalled = {
type: "sync"
id: string
syncEvent: {
- type: "tool.called.1"
+ type: "session.tool.called.1"
id: string
seq: number
aggregateID: string
@@ -4068,11 +3994,11 @@ export type SyncEventToolCalled = {
}
}
-export type SyncEventToolProgress = {
+export type SyncEventSessionToolProgress = {
type: "sync"
id: string
syncEvent: {
- type: "tool.progress.1"
+ type: "session.tool.progress.1"
id: string
seq: number
aggregateID: string
@@ -4088,11 +4014,11 @@ export type SyncEventToolProgress = {
}
}
-export type SyncEventToolSuccess = {
+export type SyncEventSessionToolSuccess = {
type: "sync"
id: string
syncEvent: {
- type: "tool.success.1"
+ type: "session.tool.success.1"
id: string
seq: number
aggregateID: string
@@ -4114,11 +4040,11 @@ export type SyncEventToolSuccess = {
}
}
-export type SyncEventToolFailed = {
+export type SyncEventSessionToolFailed = {
type: "sync"
id: string
syncEvent: {
- type: "tool.failed.1"
+ type: "session.tool.failed.1"
id: string
seq: number
aggregateID: string
@@ -4136,11 +4062,11 @@ export type SyncEventToolFailed = {
}
}
-export type SyncEventRetried = {
+export type SyncEventSessionRetried = {
type: "sync"
id: string
syncEvent: {
- type: "retried.1"
+ type: "session.retried.1"
id: string
seq: number
aggregateID: string
@@ -4152,11 +4078,11 @@ export type SyncEventRetried = {
}
}
-export type SyncEventCompactionStarted = {
+export type SyncEventSessionCompactionStarted = {
type: "sync"
id: string
syncEvent: {
- type: "compaction.started.1"
+ type: "session.compaction.started.1"
id: string
seq: number
aggregateID: string
@@ -4167,11 +4093,11 @@ export type SyncEventCompactionStarted = {
}
}
-export type SyncEventCompactionEnded = {
+export type SyncEventSessionCompactionEnded = {
type: "sync"
id: string
syncEvent: {
- type: "compaction.ended.1"
+ type: "session.compaction.ended.1"
id: string
seq: number
aggregateID: string
@@ -4184,11 +4110,11 @@ export type SyncEventCompactionEnded = {
}
}
-export type SyncEventRevertStaged = {
+export type SyncEventSessionRevertStaged = {
type: "sync"
id: string
syncEvent: {
- type: "revert.staged.1"
+ type: "session.revert.staged.1"
id: string
seq: number
aggregateID: string
@@ -4199,11 +4125,11 @@ export type SyncEventRevertStaged = {
}
}
-export type SyncEventRevertCleared = {
+export type SyncEventSessionRevertCleared = {
type: "sync"
id: string
syncEvent: {
- type: "revert.cleared.1"
+ type: "session.revert.cleared.1"
id: string
seq: number
aggregateID: string
@@ -4213,11 +4139,11 @@ export type SyncEventRevertCleared = {
}
}
-export type SyncEventRevertCommitted = {
+export type SyncEventSessionRevertCommitted = {
type: "sync"
id: string
syncEvent: {
- type: "revert.committed.1"
+ type: "session.revert.committed.1"
id: string
seq: number
aggregateID: string
@@ -4449,9 +4375,13 @@ export type SessionMessageShell = {
completed?: number
}
type: "shell"
- callID: string
- command: string
- output: string
+ shell: Shell
+ output?: {
+ output: string
+ cursor: number
+ size: number
+ truncated: boolean
+ }
}
export type SessionMessageAssistantText = {
@@ -4600,13 +4530,13 @@ export type SessionContextEntryInfo = {
value: unknown
}
-export type AgentSelected = {
+export type SessionAgentSelected = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "agent.selected"
+ type: "session.agent.selected"
durable: {
aggregateID: string
seq: number
@@ -4619,13 +4549,13 @@ export type AgentSelected = {
}
}
-export type ModelSelected = {
+export type SessionModelSelected = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "model.selected"
+ type: "session.model.selected"
durable: {
aggregateID: string
seq: number
@@ -4658,13 +4588,52 @@ export type SessionMoved = {
}
}
-export type PromptPromoted = {
+export type SessionRenamed = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "prompt.promoted"
+ type: "session.renamed"
+ durable: {
+ aggregateID: string
+ seq: number
+ version: number
+ }
+ location?: LocationRef
+ data: {
+ sessionID: string
+ title: string
+ }
+}
+
+export type SessionForked = {
+ id: string
+ created: number
+ metadata?: {
+ [key: string]: unknown
+ }
+ type: "session.forked"
+ durable: {
+ aggregateID: string
+ seq: number
+ version: number
+ }
+ location?: LocationRef
+ data: {
+ sessionID: string
+ parentID: string
+ from?: string
+ }
+}
+
+export type SessionPromptPromoted = {
+ id: string
+ created: number
+ metadata?: {
+ [key: string]: unknown
+ }
+ type: "session.prompt.promoted"
durable: {
aggregateID: string
seq: number
@@ -4677,13 +4646,13 @@ export type PromptPromoted = {
}
}
-export type PromptAdmitted = {
+export type SessionPromptAdmitted = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "prompt.admitted"
+ type: "session.prompt.admitted"
durable: {
aggregateID: string
seq: number
@@ -4717,13 +4686,36 @@ export type SessionContextUpdated = {
}
}
-export type SkillActivated = {
+export type SessionSynthetic = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "skill.activated"
+ type: "session.synthetic"
+ durable: {
+ aggregateID: string
+ seq: number
+ version: number
+ }
+ location?: LocationRef
+ data: {
+ sessionID: string
+ text: string
+ description?: string
+ metadata?: {
+ [key: string]: unknown
+ }
+ }
+}
+
+export type SessionSkillActivated = {
+ id: string
+ created: number
+ metadata?: {
+ [key: string]: unknown
+ }
+ type: "session.skill.activated"
durable: {
aggregateID: string
seq: number
@@ -4737,13 +4729,13 @@ export type SkillActivated = {
}
}
-export type ShellStarted = {
+export type SessionShellStarted = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "shell.started"
+ type: "session.shell.started"
durable: {
aggregateID: string
seq: number
@@ -4752,18 +4744,17 @@ export type ShellStarted = {
location?: LocationRef
data: {
sessionID: string
- callID: string
- command: string
+ shell: Shell1
}
}
-export type ShellEnded = {
+export type SessionShellEnded = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "shell.ended"
+ type: "session.shell.ended"
durable: {
aggregateID: string
seq: number
@@ -4772,18 +4763,23 @@ export type ShellEnded = {
location?: LocationRef
data: {
sessionID: string
- callID: string
- output: string
+ shell: Shell1
+ output: {
+ output: string
+ cursor: number
+ size: number
+ truncated: boolean
+ }
}
}
-export type StepStarted = {
+export type SessionStepStarted = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "step.started"
+ type: "session.step.started"
durable: {
aggregateID: string
seq: number
@@ -4799,13 +4795,13 @@ export type StepStarted = {
}
}
-export type StepEnded = {
+export type SessionStepEnded = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "step.ended"
+ type: "session.step.ended"
durable: {
aggregateID: string
seq: number
@@ -4831,13 +4827,13 @@ export type StepEnded = {
}
}
-export type StepFailed = {
+export type SessionStepFailed = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "step.failed"
+ type: "session.step.failed"
durable: {
aggregateID: string
seq: number
@@ -4851,13 +4847,13 @@ export type StepFailed = {
}
}
-export type TextStarted = {
+export type SessionTextStarted = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "text.started"
+ type: "session.text.started"
durable: {
aggregateID: string
seq: number
@@ -4871,13 +4867,13 @@ export type TextStarted = {
}
}
-export type TextEnded = {
+export type SessionTextEnded = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "text.ended"
+ type: "session.text.ended"
durable: {
aggregateID: string
seq: number
@@ -4892,13 +4888,13 @@ export type TextEnded = {
}
}
-export type ReasoningStarted = {
+export type SessionReasoningStarted = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "reasoning.started"
+ type: "session.reasoning.started"
durable: {
aggregateID: string
seq: number
@@ -4913,13 +4909,13 @@ export type ReasoningStarted = {
}
}
-export type ReasoningEnded = {
+export type SessionReasoningEnded = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "reasoning.ended"
+ type: "session.reasoning.ended"
durable: {
aggregateID: string
seq: number
@@ -4935,13 +4931,13 @@ export type ReasoningEnded = {
}
}
-export type ToolInputStarted = {
+export type SessionToolInputStarted = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.input.started"
+ type: "session.tool.input.started"
durable: {
aggregateID: string
seq: number
@@ -4956,13 +4952,13 @@ export type ToolInputStarted = {
}
}
-export type ToolInputEnded = {
+export type SessionToolInputEnded = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.input.ended"
+ type: "session.tool.input.ended"
durable: {
aggregateID: string
seq: number
@@ -4977,13 +4973,13 @@ export type ToolInputEnded = {
}
}
-export type ToolCalled = {
+export type SessionToolCalled = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.called"
+ type: "session.tool.called"
durable: {
aggregateID: string
seq: number
@@ -5005,13 +5001,13 @@ export type ToolCalled = {
}
}
-export type ToolProgress = {
+export type SessionToolProgress = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.progress"
+ type: "session.tool.progress"
durable: {
aggregateID: string
seq: number
@@ -5029,13 +5025,13 @@ export type ToolProgress = {
}
}
-export type ToolSuccess = {
+export type SessionToolSuccess = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.success"
+ type: "session.tool.success"
durable: {
aggregateID: string
seq: number
@@ -5059,13 +5055,13 @@ export type ToolSuccess = {
}
}
-export type ToolFailed = {
+export type SessionToolFailed = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.failed"
+ type: "session.tool.failed"
durable: {
aggregateID: string
seq: number
@@ -5085,13 +5081,33 @@ export type ToolFailed = {
}
}
-export type CompactionStarted = {
+export type SessionRetried = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "compaction.started"
+ type: "session.retried"
+ durable: {
+ aggregateID: string
+ seq: number
+ version: number
+ }
+ location?: LocationRef
+ data: {
+ sessionID: string
+ attempt: number
+ error: SessionRetryError
+ }
+}
+
+export type SessionCompactionStarted = {
+ id: string
+ created: number
+ metadata?: {
+ [key: string]: unknown
+ }
+ type: "session.compaction.started"
durable: {
aggregateID: string
seq: number
@@ -5104,13 +5120,13 @@ export type CompactionStarted = {
}
}
-export type CompactionEnded = {
+export type SessionCompactionEnded = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "compaction.ended"
+ type: "session.compaction.ended"
durable: {
aggregateID: string
seq: number
@@ -5125,13 +5141,13 @@ export type CompactionEnded = {
}
}
-export type RevertStaged = {
+export type SessionRevertStaged = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "revert.staged"
+ type: "session.revert.staged"
durable: {
aggregateID: string
seq: number
@@ -5144,13 +5160,13 @@ export type RevertStaged = {
}
}
-export type RevertCleared = {
+export type SessionRevertCleared = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "revert.cleared"
+ type: "session.revert.cleared"
durable: {
aggregateID: string
seq: number
@@ -5162,13 +5178,13 @@ export type RevertCleared = {
}
}
-export type RevertCommitted = {
+export type SessionRevertCommitted = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "revert.committed"
+ type: "session.revert.committed"
durable: {
aggregateID: string
seq: number
@@ -5708,13 +5724,13 @@ export type MessagePartRemoved = {
}
}
-export type ExecutionSettled = {
+export type SessionExecutionSettled = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "execution.settled"
+ type: "session.execution.settled"
location?: LocationRef
data: {
sessionID: string
@@ -5723,13 +5739,13 @@ export type ExecutionSettled = {
}
}
-export type TextDelta = {
+export type SessionTextDelta = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "text.delta"
+ type: "session.text.delta"
location?: LocationRef
data: {
sessionID: string
@@ -5739,13 +5755,13 @@ export type TextDelta = {
}
}
-export type ReasoningDelta = {
+export type SessionReasoningDelta = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "reasoning.delta"
+ type: "session.reasoning.delta"
location?: LocationRef
data: {
sessionID: string
@@ -5755,13 +5771,13 @@ export type ReasoningDelta = {
}
}
-export type ToolInputDelta = {
+export type SessionToolInputDelta = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.input.delta"
+ type: "session.tool.input.delta"
location?: LocationRef
data: {
sessionID: string
@@ -5771,13 +5787,13 @@ export type ToolInputDelta = {
}
}
-export type CompactionDelta = {
+export type SessionCompactionDelta = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "compaction.delta"
+ type: "session.compaction.delta"
location?: LocationRef
data: {
sessionID: string
@@ -6730,18 +6746,18 @@ export type EventMessagePartRemoved = {
}
}
-export type EventAgentSelected = {
+export type EventSessionAgentSelected = {
id: string
- type: "agent.selected"
+ type: "session.agent.selected"
properties: {
sessionID: string
agent: string
}
}
-export type EventModelSelected = {
+export type EventSessionModelSelected = {
id: string
- type: "model.selected"
+ type: "session.model.selected"
properties: {
sessionID: string
model: ModelRef
@@ -6758,18 +6774,18 @@ export type EventSessionMoved = {
}
}
-export type EventRenamed = {
+export type EventSessionRenamed = {
id: string
- type: "renamed"
+ type: "session.renamed"
properties: {
sessionID: string
title: string
}
}
-export type EventForked = {
+export type EventSessionForked = {
id: string
- type: "forked"
+ type: "session.forked"
properties: {
sessionID: string
parentID: string
@@ -6777,18 +6793,18 @@ export type EventForked = {
}
}
-export type EventPromptPromoted = {
+export type EventSessionPromptPromoted = {
id: string
- type: "prompt.promoted"
+ type: "session.prompt.promoted"
properties: {
sessionID: string
inputID: string
}
}
-export type EventPromptAdmitted = {
+export type EventSessionPromptAdmitted = {
id: string
- type: "prompt.admitted"
+ type: "session.prompt.admitted"
properties: {
sessionID: string
inputID: string
@@ -6797,9 +6813,9 @@ export type EventPromptAdmitted = {
}
}
-export type EventExecutionSettled = {
+export type EventSessionExecutionSettled = {
id: string
- type: "execution.settled"
+ type: "session.execution.settled"
properties: {
sessionID: string
outcome: "success" | "failure" | "interrupted"
@@ -6816,9 +6832,9 @@ export type EventSessionContextUpdated = {
}
}
-export type EventSynthetic = {
+export type EventSessionSynthetic = {
id: string
- type: "synthetic"
+ type: "session.synthetic"
properties: {
sessionID: string
text: string
@@ -6829,9 +6845,9 @@ export type EventSynthetic = {
}
}
-export type EventSkillActivated = {
+export type EventSessionSkillActivated = {
id: string
- type: "skill.activated"
+ type: "session.skill.activated"
properties: {
sessionID: string
name: string
@@ -6839,29 +6855,33 @@ export type EventSkillActivated = {
}
}
-export type EventShellStarted = {
+export type EventSessionShellStarted = {
id: string
- type: "shell.started"
+ type: "session.shell.started"
properties: {
sessionID: string
- callID: string
- command: string
+ shell: Shell2
}
}
-export type EventShellEnded = {
+export type EventSessionShellEnded = {
id: string
- type: "shell.ended"
+ type: "session.shell.ended"
properties: {
sessionID: string
- callID: string
- output: string
+ shell: Shell2
+ output: {
+ output: string
+ cursor: number
+ size: number
+ truncated: boolean
+ }
}
}
-export type EventStepStarted = {
+export type EventSessionStepStarted = {
id: string
- type: "step.started"
+ type: "session.step.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -6871,9 +6891,9 @@ export type EventStepStarted = {
}
}
-export type EventStepEnded = {
+export type EventSessionStepEnded = {
id: string
- type: "step.ended"
+ type: "session.step.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -6893,9 +6913,9 @@ export type EventStepEnded = {
}
}
-export type EventStepFailed = {
+export type EventSessionStepFailed = {
id: string
- type: "step.failed"
+ type: "session.step.failed"
properties: {
sessionID: string
assistantMessageID: string
@@ -6903,9 +6923,9 @@ export type EventStepFailed = {
}
}
-export type EventTextStarted = {
+export type EventSessionTextStarted = {
id: string
- type: "text.started"
+ type: "session.text.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -6913,9 +6933,9 @@ export type EventTextStarted = {
}
}
-export type EventTextDelta = {
+export type EventSessionTextDelta = {
id: string
- type: "text.delta"
+ type: "session.text.delta"
properties: {
sessionID: string
assistantMessageID: string
@@ -6924,9 +6944,9 @@ export type EventTextDelta = {
}
}
-export type EventTextEnded = {
+export type EventSessionTextEnded = {
id: string
- type: "text.ended"
+ type: "session.text.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -6935,9 +6955,9 @@ export type EventTextEnded = {
}
}
-export type EventReasoningStarted = {
+export type EventSessionReasoningStarted = {
id: string
- type: "reasoning.started"
+ type: "session.reasoning.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -6946,9 +6966,9 @@ export type EventReasoningStarted = {
}
}
-export type EventReasoningDelta = {
+export type EventSessionReasoningDelta = {
id: string
- type: "reasoning.delta"
+ type: "session.reasoning.delta"
properties: {
sessionID: string
assistantMessageID: string
@@ -6957,9 +6977,9 @@ export type EventReasoningDelta = {
}
}
-export type EventReasoningEnded = {
+export type EventSessionReasoningEnded = {
id: string
- type: "reasoning.ended"
+ type: "session.reasoning.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -6969,9 +6989,9 @@ export type EventReasoningEnded = {
}
}
-export type EventToolInputStarted = {
+export type EventSessionToolInputStarted = {
id: string
- type: "tool.input.started"
+ type: "session.tool.input.started"
properties: {
sessionID: string
assistantMessageID: string
@@ -6980,9 +7000,9 @@ export type EventToolInputStarted = {
}
}
-export type EventToolInputDelta = {
+export type EventSessionToolInputDelta = {
id: string
- type: "tool.input.delta"
+ type: "session.tool.input.delta"
properties: {
sessionID: string
assistantMessageID: string
@@ -6991,9 +7011,9 @@ export type EventToolInputDelta = {
}
}
-export type EventToolInputEnded = {
+export type EventSessionToolInputEnded = {
id: string
- type: "tool.input.ended"
+ type: "session.tool.input.ended"
properties: {
sessionID: string
assistantMessageID: string
@@ -7002,9 +7022,9 @@ export type EventToolInputEnded = {
}
}
-export type EventToolCalled = {
+export type EventSessionToolCalled = {
id: string
- type: "tool.called"
+ type: "session.tool.called"
properties: {
sessionID: string
assistantMessageID: string
@@ -7020,9 +7040,9 @@ export type EventToolCalled = {
}
}
-export type EventToolProgress = {
+export type EventSessionToolProgress = {
id: string
- type: "tool.progress"
+ type: "session.tool.progress"
properties: {
sessionID: string
assistantMessageID: string
@@ -7034,9 +7054,9 @@ export type EventToolProgress = {
}
}
-export type EventToolSuccess = {
+export type EventSessionToolSuccess = {
id: string
- type: "tool.success"
+ type: "session.tool.success"
properties: {
sessionID: string
assistantMessageID: string
@@ -7054,9 +7074,9 @@ export type EventToolSuccess = {
}
}
-export type EventToolFailed = {
+export type EventSessionToolFailed = {
id: string
- type: "tool.failed"
+ type: "session.tool.failed"
properties: {
sessionID: string
assistantMessageID: string
@@ -7070,9 +7090,9 @@ export type EventToolFailed = {
}
}
-export type EventRetried = {
+export type EventSessionRetried = {
id: string
- type: "retried"
+ type: "session.retried"
properties: {
sessionID: string
attempt: number
@@ -7080,27 +7100,27 @@ export type EventRetried = {
}
}
-export type EventCompactionStarted = {
+export type EventSessionCompactionStarted = {
id: string
- type: "compaction.started"
+ type: "session.compaction.started"
properties: {
sessionID: string
reason: "auto" | "manual"
}
}
-export type EventCompactionDelta = {
+export type EventSessionCompactionDelta = {
id: string
- type: "compaction.delta"
+ type: "session.compaction.delta"
properties: {
sessionID: string
text: string
}
}
-export type EventCompactionEnded = {
+export type EventSessionCompactionEnded = {
id: string
- type: "compaction.ended"
+ type: "session.compaction.ended"
properties: {
sessionID: string
reason: "auto" | "manual"
@@ -7109,26 +7129,26 @@ export type EventCompactionEnded = {
}
}
-export type EventRevertStaged = {
+export type EventSessionRevertStaged = {
id: string
- type: "revert.staged"
+ type: "session.revert.staged"
properties: {
sessionID: string
revert: RevertState
}
}
-export type EventRevertCleared = {
+export type EventSessionRevertCleared = {
id: string
- type: "revert.cleared"
+ type: "session.revert.cleared"
properties: {
sessionID: string
}
}
-export type EventRevertCommitted = {
+export type EventSessionRevertCommitted = {
id: string
- type: "revert.committed"
+ type: "session.revert.committed"
properties: {
sessionID: string
messageID: string
@@ -7999,6 +8019,24 @@ export type SessionMessageSkill2 = {
text: string
}
+export type ShellV2 = {
+ id: string
+ status: "running" | "exited" | "timeout" | "killed"
+ command: string
+ cwd: string
+ shell: string
+ file: string
+ pid?: number
+ exit?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
+ metadata: {
+ [key: string]: unknown
+ }
+ time: {
+ started: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
+ completed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
+ }
+}
+
export type SessionMessageShell2 = {
id: string
metadata?: {
@@ -8009,9 +8047,13 @@ export type SessionMessageShell2 = {
completed?: number
}
type: "shell"
- callID: string
- command: string
- output: string
+ shell: ShellV2
+ output?: {
+ output: string
+ cursor: number
+ size: number
+ truncated: boolean
+ }
}
export type SessionMessageAssistantText2 = {
@@ -8188,13 +8230,13 @@ export type SessionContextEntryInfo2 = {
value: unknown
}
-export type AgentSelected2 = {
+export type SessionAgentSelected2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "agent.selected"
+ type: "session.agent.selected"
durable: {
aggregateID: string
seq: number
@@ -8207,13 +8249,13 @@ export type AgentSelected2 = {
}
}
-export type ModelSelected2 = {
+export type SessionModelSelected2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "model.selected"
+ type: "session.model.selected"
durable: {
aggregateID: string
seq: number
@@ -8246,13 +8288,13 @@ export type SessionMoved2 = {
}
}
-export type RenamedV2 = {
+export type SessionRenamed2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "renamed"
+ type: "session.renamed"
durable: {
aggregateID: string
seq: number
@@ -8265,13 +8307,13 @@ export type RenamedV2 = {
}
}
-export type ForkedV2 = {
+export type SessionForked2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "forked"
+ type: "session.forked"
durable: {
aggregateID: string
seq: number
@@ -8285,13 +8327,13 @@ export type ForkedV2 = {
}
}
-export type PromptPromoted2 = {
+export type SessionPromptPromoted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "prompt.promoted"
+ type: "session.prompt.promoted"
durable: {
aggregateID: string
seq: number
@@ -8304,13 +8346,13 @@ export type PromptPromoted2 = {
}
}
-export type PromptAdmitted2 = {
+export type SessionPromptAdmitted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "prompt.admitted"
+ type: "session.prompt.admitted"
durable: {
aggregateID: string
seq: number
@@ -8344,13 +8386,13 @@ export type SessionContextUpdated2 = {
}
}
-export type SyntheticV2 = {
+export type SessionSynthetic2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "synthetic"
+ type: "session.synthetic"
durable: {
aggregateID: string
seq: number
@@ -8367,13 +8409,13 @@ export type SyntheticV2 = {
}
}
-export type SkillActivated2 = {
+export type SessionSkillActivated2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "skill.activated"
+ type: "session.skill.activated"
durable: {
aggregateID: string
seq: number
@@ -8387,13 +8429,31 @@ export type SkillActivated2 = {
}
}
-export type ShellStarted2 = {
+export type Shell1V2 = {
+ id: string
+ status: "running" | "exited" | "timeout" | "killed"
+ command: string
+ cwd: string
+ shell: string
+ file: string
+ pid?: number
+ exit?: number | "NaN" | "Infinity" | "-Infinity"
+ metadata: {
+ [key: string]: unknown
+ }
+ time: {
+ started: number | "NaN" | "Infinity" | "-Infinity"
+ completed?: number | "NaN" | "Infinity" | "-Infinity"
+ }
+}
+
+export type SessionShellStarted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "shell.started"
+ type: "session.shell.started"
durable: {
aggregateID: string
seq: number
@@ -8402,18 +8462,17 @@ export type ShellStarted2 = {
location?: LocationRef2
data: {
sessionID: string
- callID: string
- command: string
+ shell: Shell1V2
}
}
-export type ShellEnded2 = {
+export type SessionShellEnded2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "shell.ended"
+ type: "session.shell.ended"
durable: {
aggregateID: string
seq: number
@@ -8422,18 +8481,23 @@ export type ShellEnded2 = {
location?: LocationRef2
data: {
sessionID: string
- callID: string
- output: string
+ shell: Shell1V2
+ output: {
+ output: string
+ cursor: number
+ size: number
+ truncated: boolean
+ }
}
}
-export type StepStarted2 = {
+export type SessionStepStarted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "step.started"
+ type: "session.step.started"
durable: {
aggregateID: string
seq: number
@@ -8449,13 +8513,13 @@ export type StepStarted2 = {
}
}
-export type StepEnded2 = {
+export type SessionStepEnded2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "step.ended"
+ type: "session.step.ended"
durable: {
aggregateID: string
seq: number
@@ -8481,13 +8545,13 @@ export type StepEnded2 = {
}
}
-export type StepFailed2 = {
+export type SessionStepFailed2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "step.failed"
+ type: "session.step.failed"
durable: {
aggregateID: string
seq: number
@@ -8501,13 +8565,13 @@ export type StepFailed2 = {
}
}
-export type TextStarted2 = {
+export type SessionTextStarted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "text.started"
+ type: "session.text.started"
durable: {
aggregateID: string
seq: number
@@ -8521,13 +8585,13 @@ export type TextStarted2 = {
}
}
-export type TextEnded2 = {
+export type SessionTextEnded2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "text.ended"
+ type: "session.text.ended"
durable: {
aggregateID: string
seq: number
@@ -8548,13 +8612,13 @@ export type LlmProviderMetadata3 = {
}
}
-export type ReasoningStarted2 = {
+export type SessionReasoningStarted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "reasoning.started"
+ type: "session.reasoning.started"
durable: {
aggregateID: string
seq: number
@@ -8575,13 +8639,13 @@ export type LlmProviderMetadata4 = {
}
}
-export type ReasoningEnded2 = {
+export type SessionReasoningEnded2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "reasoning.ended"
+ type: "session.reasoning.ended"
durable: {
aggregateID: string
seq: number
@@ -8597,13 +8661,13 @@ export type ReasoningEnded2 = {
}
}
-export type ToolInputStarted2 = {
+export type SessionToolInputStarted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.input.started"
+ type: "session.tool.input.started"
durable: {
aggregateID: string
seq: number
@@ -8618,13 +8682,13 @@ export type ToolInputStarted2 = {
}
}
-export type ToolInputEnded2 = {
+export type SessionToolInputEnded2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.input.ended"
+ type: "session.tool.input.ended"
durable: {
aggregateID: string
seq: number
@@ -8645,13 +8709,13 @@ export type LlmProviderMetadata5 = {
}
}
-export type ToolCalled2 = {
+export type SessionToolCalled2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.called"
+ type: "session.tool.called"
durable: {
aggregateID: string
seq: number
@@ -8673,13 +8737,13 @@ export type ToolCalled2 = {
}
}
-export type ToolProgress2 = {
+export type SessionToolProgress2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.progress"
+ type: "session.tool.progress"
durable: {
aggregateID: string
seq: number
@@ -8703,13 +8767,13 @@ export type LlmProviderMetadata6 = {
}
}
-export type ToolSuccess2 = {
+export type SessionToolSuccess2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.success"
+ type: "session.tool.success"
durable: {
aggregateID: string
seq: number
@@ -8739,13 +8803,13 @@ export type LlmProviderMetadata7 = {
}
}
-export type ToolFailed2 = {
+export type SessionToolFailed2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.failed"
+ type: "session.tool.failed"
durable: {
aggregateID: string
seq: number
@@ -8778,13 +8842,13 @@ export type SessionRetryError2 = {
}
}
-export type RetriedV2 = {
+export type SessionRetried2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "retried"
+ type: "session.retried"
durable: {
aggregateID: string
seq: number
@@ -8798,13 +8862,13 @@ export type RetriedV2 = {
}
}
-export type CompactionStarted2 = {
+export type SessionCompactionStarted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "compaction.started"
+ type: "session.compaction.started"
durable: {
aggregateID: string
seq: number
@@ -8817,13 +8881,13 @@ export type CompactionStarted2 = {
}
}
-export type CompactionEnded2 = {
+export type SessionCompactionEnded2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "compaction.ended"
+ type: "session.compaction.ended"
durable: {
aggregateID: string
seq: number
@@ -8838,13 +8902,13 @@ export type CompactionEnded2 = {
}
}
-export type RevertStaged2 = {
+export type SessionRevertStaged2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "revert.staged"
+ type: "session.revert.staged"
durable: {
aggregateID: string
seq: number
@@ -8857,13 +8921,13 @@ export type RevertStaged2 = {
}
}
-export type RevertCleared2 = {
+export type SessionRevertCleared2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "revert.cleared"
+ type: "session.revert.cleared"
durable: {
aggregateID: string
seq: number
@@ -8875,13 +8939,13 @@ export type RevertCleared2 = {
}
}
-export type RevertCommitted2 = {
+export type SessionRevertCommitted2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "revert.committed"
+ type: "session.revert.committed"
durable: {
aggregateID: string
seq: number
@@ -8895,37 +8959,37 @@ export type RevertCommitted2 = {
}
export type SessionDurableEventV2 =
- | AgentSelected2
- | ModelSelected2
+ | SessionAgentSelected2
+ | SessionModelSelected2
| SessionMoved2
- | RenamedV2
- | ForkedV2
- | PromptPromoted2
- | PromptAdmitted2
+ | SessionRenamed2
+ | SessionForked2
+ | SessionPromptPromoted2
+ | SessionPromptAdmitted2
| SessionContextUpdated2
- | SyntheticV2
- | SkillActivated2
- | ShellStarted2
- | ShellEnded2
- | StepStarted2
- | StepEnded2
- | StepFailed2
- | TextStarted2
- | TextEnded2
- | ReasoningStarted2
- | ReasoningEnded2
- | ToolInputStarted2
- | ToolInputEnded2
- | ToolCalled2
- | ToolProgress2
- | ToolSuccess2
- | ToolFailed2
- | RetriedV2
- | CompactionStarted2
- | CompactionEnded2
- | RevertStaged2
- | RevertCleared2
- | RevertCommitted2
+ | SessionSynthetic2
+ | SessionSkillActivated2
+ | SessionShellStarted2
+ | SessionShellEnded2
+ | SessionStepStarted2
+ | SessionStepEnded2
+ | SessionStepFailed2
+ | SessionTextStarted2
+ | SessionTextEnded2
+ | SessionReasoningStarted2
+ | SessionReasoningEnded2
+ | SessionToolInputStarted2
+ | SessionToolInputEnded2
+ | SessionToolCalled2
+ | SessionToolProgress2
+ | SessionToolSuccess2
+ | SessionToolFailed2
+ | SessionRetried2
+ | SessionCompactionStarted2
+ | SessionCompactionEnded2
+ | SessionRevertStaged2
+ | SessionRevertCleared2
+ | SessionRevertCommitted2
/**
* Marker emitted once when a log read reaches its captured watermark. The reader holds every event committed at or below seq.
@@ -10138,13 +10202,13 @@ export type MessagePartRemoved2 = {
}
}
-export type ExecutionSettled2 = {
+export type SessionExecutionSettled2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "execution.settled"
+ type: "session.execution.settled"
location?: LocationRef2
data: {
sessionID: string
@@ -10153,13 +10217,13 @@ export type ExecutionSettled2 = {
}
}
-export type TextDelta2 = {
+export type SessionTextDelta2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "text.delta"
+ type: "session.text.delta"
location?: LocationRef2
data: {
sessionID: string
@@ -10169,13 +10233,13 @@ export type TextDelta2 = {
}
}
-export type ReasoningDelta2 = {
+export type SessionReasoningDelta2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "reasoning.delta"
+ type: "session.reasoning.delta"
location?: LocationRef2
data: {
sessionID: string
@@ -10185,13 +10249,13 @@ export type ReasoningDelta2 = {
}
}
-export type ToolInputDelta2 = {
+export type SessionToolInputDelta2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "tool.input.delta"
+ type: "session.tool.input.delta"
location?: LocationRef2
data: {
sessionID: string
@@ -10201,13 +10265,13 @@ export type ToolInputDelta2 = {
}
}
-export type CompactionDelta2 = {
+export type SessionCompactionDelta2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
- type: "compaction.delta"
+ type: "session.compaction.delta"
location?: LocationRef2
data: {
sessionID: string
@@ -10413,24 +10477,6 @@ export type PtyDeleted2 = {
}
}
-export type ShellV2 = {
- id: string
- status: "running" | "exited" | "timeout" | "killed"
- command: string
- cwd: string
- shell: string
- file: string
- pid?: number
- exit?: number | "NaN" | "Infinity" | "-Infinity"
- metadata: {
- [key: string]: unknown
- }
- time: {
- started: number | "NaN" | "Infinity" | "-Infinity"
- completed?: number | "NaN" | "Infinity" | "-Infinity"
- }
-}
-
export type ShellCreated2 = {
id: string
created: number
@@ -10440,7 +10486,7 @@ export type ShellCreated2 = {
type: "shell.created"
location?: LocationRef2
data: {
- info: ShellV2
+ info: Shell1V2
}
}
@@ -11080,42 +11126,42 @@ export type V2EventV2 =
| MessageRemoved2
| MessagePartUpdated2
| MessagePartRemoved2
- | AgentSelected2
- | ModelSelected2
+ | SessionAgentSelected2
+ | SessionModelSelected2
| SessionMoved2
- | RenamedV2
- | ForkedV2
- | PromptPromoted2
- | PromptAdmitted2
- | ExecutionSettled2
+ | SessionRenamed2
+ | SessionForked2
+ | SessionPromptPromoted2
+ | SessionPromptAdmitted2
+ | SessionExecutionSettled2
| SessionContextUpdated2
- | SyntheticV2
- | SkillActivated2
- | ShellStarted2
- | ShellEnded2
- | StepStarted2
- | StepEnded2
- | StepFailed2
- | TextStarted2
- | TextDelta2
- | TextEnded2
- | ReasoningStarted2
- | ReasoningDelta2
- | ReasoningEnded2
- | ToolInputStarted2
- | ToolInputDelta2
- | ToolInputEnded2
- | ToolCalled2
- | ToolProgress2
- | ToolSuccess2
- | ToolFailed2
- | RetriedV2
- | CompactionStarted2
- | CompactionDelta2
- | CompactionEnded2
- | RevertStaged2
- | RevertCleared2
- | RevertCommitted2
+ | SessionSynthetic2
+ | SessionSkillActivated2
+ | SessionShellStarted2
+ | SessionShellEnded2
+ | SessionStepStarted2
+ | SessionStepEnded2
+ | SessionStepFailed2
+ | SessionTextStarted2
+ | SessionTextDelta2
+ | SessionTextEnded2
+ | SessionReasoningStarted2
+ | SessionReasoningDelta2
+ | SessionReasoningEnded2
+ | SessionToolInputStarted2
+ | SessionToolInputDelta2
+ | SessionToolInputEnded2
+ | SessionToolCalled2
+ | SessionToolProgress2
+ | SessionToolSuccess2
+ | SessionToolFailed2
+ | SessionRetried2
+ | SessionCompactionStarted2
+ | SessionCompactionDelta2
+ | SessionCompactionEnded2
+ | SessionRevertStaged2
+ | SessionRevertCleared2
+ | SessionRevertCommitted2
| FileEdited2
| ReferenceUpdated2
| PermissionV2Asked2
@@ -11195,24 +11241,6 @@ export type ForbiddenErrorV2 = {
message: string
}
-export type Shell1V2 = {
- id: string
- status: "running" | "exited" | "timeout" | "killed"
- command: string
- cwd: string
- shell: string
- file: string
- pid?: number
- exit?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
- metadata: {
- [key: string]: unknown
- }
- time: {
- started: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
- completed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
- }
-}
-
export type ShellNotFoundErrorV2 = {
_tag: "ShellNotFoundError"
id: string
@@ -18444,7 +18472,7 @@ export type V2ShellListResponses = {
*/
200: {
location: LocationInfo2
- data: Array
+ data: Array
}
}
@@ -18488,7 +18516,7 @@ export type V2ShellCreateResponses = {
*/
200: {
location: LocationInfo2
- data: Shell1V2
+ data: ShellV2
}
}
@@ -18571,7 +18599,7 @@ export type V2ShellGetResponses = {
*/
200: {
location: LocationInfo2
- data: Shell1V2
+ data: ShellV2
}
}
diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json
index b30c3beb35..e136ef6836 100644
--- a/packages/sdk/openapi.json
+++ b/packages/sdk/openapi.json
@@ -16410,7 +16410,7 @@
"text": {
"type": "string"
},
- "synthetic": {
+ "session.synthetic": {
"type": "boolean"
},
"ignored": {
@@ -23071,7 +23071,7 @@
"text": {
"type": "string"
},
- "synthetic": {
+ "session.synthetic": {
"type": "boolean"
},
"ignored": {
@@ -27479,7 +27479,7 @@
},
"type": {
"type": "string",
- "enum": ["synthetic"]
+ "enum": ["session.synthetic"]
}
},
"required": ["id", "time", "sessionID", "text", "type"],
diff --git a/packages/tui/src/context/data.tsx b/packages/tui/src/context/data.tsx
index cc9378dbac..0ed464e561 100644
--- a/packages/tui/src/context/data.tsx
+++ b/packages/tui/src/context/data.tsx
@@ -126,8 +126,8 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
const item = position === undefined ? undefined : messages[position]
return item?.type === "assistant" ? item : undefined
},
- activeShell(messages: SessionMessage[], callID: string) {
- const item = messages.findLast((item) => item.type === "shell" && item.callID === callID)
+ shell(messages: SessionMessage[], shellID: string) {
+ const item = messages.findLast((item) => item.type === "shell" && item.shell.id === shellID)
return item?.type === "shell" ? item : undefined
},
latestTool(assistant: SessionMessageAssistant | undefined, callID?: string) {
@@ -220,7 +220,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
case "skill.updated":
void result.location.skill.refresh(event.location)
break
- case "agent.selected":
+ case "session.agent.selected":
if (store.session.info[event.data.sessionID])
setStore("session", "info", event.data.sessionID, "agent", event.data.agent)
message.update(event.data.sessionID, (draft, index) => {
@@ -232,7 +232,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "model.selected":
+ case "session.model.selected":
if (store.session.info[event.data.sessionID])
setStore("session", "info", event.data.sessionID, "model", event.data.model)
message.update(event.data.sessionID, (draft, index) => {
@@ -244,11 +244,11 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "renamed":
+ case "session.renamed":
if (store.session.info[event.data.sessionID])
setStore("session", "info", event.data.sessionID, "title", event.data.title)
break
- case "prompt.promoted": {
+ case "session.prompt.promoted": {
setStore("session", "status", event.data.sessionID, "running")
message.update(event.data.sessionID, (draft, index) => {
const position = index.get(event.data.inputID)
@@ -264,7 +264,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
break
}
- case "prompt.admitted":
+ case "session.prompt.admitted":
message.update(event.data.sessionID, (draft, index) => {
message.append(draft, index, {
id: event.data.inputID,
@@ -287,7 +287,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "synthetic":
+ case "session.synthetic":
message.update(event.data.sessionID, (draft, index) => {
message.append(draft, index, {
id: messageIDFromEvent(event.id),
@@ -299,29 +299,28 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "shell.started":
+ case "session.shell.started":
setStore("session", "status", event.data.sessionID, "running")
message.update(event.data.sessionID, (draft, index) => {
message.append(draft, index, {
id: messageIDFromEvent(event.id),
type: "shell",
- callID: event.data.callID,
- command: event.data.command,
- output: "",
+ shell: event.data.shell,
time: { created: event.created },
})
})
break
- case "shell.ended":
+ case "session.shell.ended":
setStore("session", "status", event.data.sessionID, "idle")
- message.update(event.data.sessionID, (draft, index) => {
- const match = message.activeShell(draft, event.data.callID)
+ message.update(event.data.sessionID, (draft) => {
+ const match = message.shell(draft, event.data.shell.id)
if (!match) return
+ match.shell = event.data.shell
match.output = event.data.output
match.time.completed = event.created
})
break
- case "step.started":
+ case "session.step.started":
setStore("session", "status", event.data.sessionID, "running")
message.update(event.data.sessionID, (draft, index) => {
if (index.has(event.data.assistantMessageID)) return
@@ -338,7 +337,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "step.ended":
+ case "session.step.ended":
setStore("session", "status", event.data.sessionID, "running")
message.update(event.data.sessionID, (draft, index) => {
const currentAssistant = message.assistant(draft, index, event.data.assistantMessageID)
@@ -351,7 +350,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
currentAssistant.snapshot = { ...currentAssistant.snapshot, end: event.data.snapshot }
})
break
- case "step.failed":
+ case "session.step.failed":
message.update(event.data.sessionID, (draft, index) => {
const currentAssistant = message.assistant(draft, index, event.data.assistantMessageID)
if (!currentAssistant) return
@@ -360,7 +359,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
currentAssistant.error = event.data.error
})
break
- case "text.started":
+ case "session.text.started":
message.update(event.data.sessionID, (draft, index) => {
message.assistant(draft, index, event.data.assistantMessageID)?.content.push({
type: "text",
@@ -369,7 +368,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "text.delta":
+ case "session.text.delta":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestText(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -378,7 +377,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
if (match) match.text += event.data.delta
})
break
- case "text.ended":
+ case "session.text.ended":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestText(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -387,7 +386,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
if (match) match.text = event.data.text
})
break
- case "tool.input.started":
+ case "session.tool.input.started":
message.update(event.data.sessionID, (draft, index) => {
message.assistant(draft, index, event.data.assistantMessageID)?.content.push({
type: "tool",
@@ -398,7 +397,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "tool.input.delta":
+ case "session.tool.input.delta":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestTool(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -407,7 +406,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
if (match?.state.status === "pending") match.state.input += event.data.delta
})
break
- case "tool.input.ended":
+ case "session.tool.input.ended":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestTool(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -416,7 +415,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
if (match?.state.status === "pending") match.state.input = event.data.text
})
break
- case "tool.called":
+ case "session.tool.called":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestTool(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -428,7 +427,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
match.state = { status: "running", input: event.data.input, structured: {}, content: [] }
})
break
- case "tool.progress":
+ case "session.tool.progress":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestTool(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -439,7 +438,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
match.state.content = [...event.data.content]
})
break
- case "tool.success":
+ case "session.tool.success":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestTool(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -461,7 +460,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
match.time.completed = event.created
})
break
- case "tool.failed":
+ case "session.tool.failed":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestTool(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -484,7 +483,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
match.time.completed = event.created
})
break
- case "reasoning.started":
+ case "session.reasoning.started":
message.update(event.data.sessionID, (draft, index) => {
message.assistant(draft, index, event.data.assistantMessageID)?.content.push({
type: "reasoning",
@@ -495,7 +494,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
})
})
break
- case "reasoning.delta":
+ case "session.reasoning.delta":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestReasoning(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -504,7 +503,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
if (match) match.text += event.data.delta
})
break
- case "reasoning.ended":
+ case "session.reasoning.ended":
message.update(event.data.sessionID, (draft, index) => {
const match = message.latestReasoning(
message.assistant(draft, index, event.data.assistantMessageID),
@@ -517,25 +516,25 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
}
})
break
- case "retried":
- case "compaction.started":
+ case "session.retried":
+ case "session.compaction.started":
setStore("session", "status", event.data.sessionID, "running")
break
- case "execution.settled":
+ case "session.execution.settled":
setStore("session", "status", event.data.sessionID, "idle")
break
- case "revert.staged":
+ case "session.revert.staged":
if (store.session.info[event.data.sessionID])
setStore("session", "info", event.data.sessionID, "revert", event.data.revert)
break
- case "revert.cleared":
- case "revert.committed":
+ case "session.revert.cleared":
+ case "session.revert.committed":
if (store.session.info[event.data.sessionID])
setStore("session", "info", event.data.sessionID, "revert", undefined)
break
- case "compaction.delta":
+ case "session.compaction.delta":
break
- case "compaction.ended":
+ case "session.compaction.ended":
message.update(event.data.sessionID, (draft, index) => {
message.append(draft, index, {
id: messageIDFromEvent(event.id),
diff --git a/packages/tui/src/feature-plugins/system/notifications.ts b/packages/tui/src/feature-plugins/system/notifications.ts
index aa8dcace19..416ba8c466 100644
--- a/packages/tui/src/feature-plugins/system/notifications.ts
+++ b/packages/tui/src/feature-plugins/system/notifications.ts
@@ -74,17 +74,17 @@ const tui: TuiPlugin = async (api) => {
notify(api, sessionID, "Session done", session?.parentID ? "subagent_done" : "done")
}
- api.event.on("prompt.promoted", (event) => started(event.data.sessionID))
- api.event.on("shell.started", (event) => started(event.data.sessionID))
- api.event.on("step.started", (event) => started(event.data.sessionID))
- api.event.on("retried", (event) => started(event.data.sessionID))
- api.event.on("compaction.started", (event) => started(event.data.sessionID))
- api.event.on("shell.ended", (event) => ended(event.data.sessionID))
- api.event.on("step.ended", (event) => {
+ api.event.on("session.prompt.promoted", (event) => started(event.data.sessionID))
+ api.event.on("session.shell.started", (event) => started(event.data.sessionID))
+ api.event.on("session.step.started", (event) => started(event.data.sessionID))
+ api.event.on("session.retried", (event) => started(event.data.sessionID))
+ api.event.on("session.compaction.started", (event) => started(event.data.sessionID))
+ api.event.on("session.shell.ended", (event) => ended(event.data.sessionID))
+ api.event.on("session.step.ended", (event) => {
if (event.data.finish === "tool-calls") return
ended(event.data.sessionID)
})
- api.event.on("step.failed", (event) => {
+ api.event.on("session.step.failed", (event) => {
const sessionID = event.data.sessionID
if (!active.has(sessionID)) return
errored.add(sessionID)
diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx
index b0f337c2d4..b968f13cd3 100644
--- a/packages/tui/src/routes/session/index.tsx
+++ b/packages/tui/src/routes/session/index.tsx
@@ -1346,7 +1346,7 @@ function RevertMessage(props: {
function ShellMessage(props: { message: Extract }) {
const { theme } = useTheme()
- const output = createMemo(() => stripAnsi(props.message.output.trim()))
+ const output = createMemo(() => stripAnsi(props.message.output?.output.trim() ?? ""))
return (
- $ {props.message.command}
+ $ {props.message.shell.command}
{output()}
@@ -1408,13 +1408,7 @@ function UserMessage(props: { message: SessionMessageUser }) {
>
{props.message.text}
-
+
{(file) => {
const directory = file.mime === "application/x-directory"
@@ -1744,7 +1738,8 @@ function ToolPart(props: { part: SessionMessageAssistantTool }) {
return Boolean(shellID && data.shell.get(shellID))
}
if (display() === "subagent") {
- const sessionID = stringValue(props.part.state.structured.sessionID) ?? stringValue(props.part.state.structured.sessionId)
+ const sessionID =
+ stringValue(props.part.state.structured.sessionID) ?? stringValue(props.part.state.structured.sessionId)
return Boolean(sessionID && data.session.status(sessionID) === "running")
}
return false
@@ -2660,7 +2655,8 @@ function formatSessionTranscript(
) {
const body = messages.flatMap((message) => {
if (message.type === "user") return [`## User\n\n${message.text}`]
- if (message.type === "shell") return [`## Shell\n\n\`\`\`\n$ ${message.command}\n${message.output}\n\`\`\``]
+ if (message.type === "shell")
+ return [`## Shell\n\n\`\`\`\n$ ${message.shell.command}\n${message.output?.output ?? ""}\n\`\`\``]
if (message.type !== "assistant") return []
const content = message.content.flatMap((item) => {
if (item.type === "text") return [item.text]
diff --git a/packages/tui/src/routes/session/rows.ts b/packages/tui/src/routes/session/rows.ts
index 23b43c3b17..783b2805f4 100644
--- a/packages/tui/src/routes/session/rows.ts
+++ b/packages/tui/src/routes/session/rows.ts
@@ -133,42 +133,42 @@ export function createSessionRows(sessionID: Accessor) {
if (event.data.sessionID === sessionID()) appendMessage(event.data.inputID)
}
const subscriptions = [
- data.on("prompt.admitted", input),
- data.on("prompt.promoted", input),
+ data.on("session.prompt.admitted", input),
+ data.on("session.prompt.promoted", input),
data.on("session.context.updated", message),
- data.on("synthetic", (event) => {
+ data.on("session.synthetic", (event) => {
if (event.data.sessionID === sessionID() && event.data.description?.trim())
appendMessage(event.id.replace(/^evt_/, "msg_"))
}),
- data.on("shell.started", message),
- data.on("agent.selected", message),
- data.on("model.selected", message),
- data.on("compaction.ended", message),
- data.on("text.delta", (event) => {
+ data.on("session.shell.started", message),
+ data.on("session.agent.selected", message),
+ data.on("session.model.selected", message),
+ data.on("session.compaction.ended", message),
+ data.on("session.text.delta", (event) => {
if (event.data.sessionID === sessionID())
appendPart({ messageID: event.data.assistantMessageID, partID: event.data.textID })
}),
- data.on("text.ended", (event) => {
+ data.on("session.text.ended", (event) => {
if (event.data.sessionID === sessionID() && event.data.text.trim())
appendPart({ messageID: event.data.assistantMessageID, partID: event.data.textID })
}),
- data.on("reasoning.delta", (event) => {
+ data.on("session.reasoning.delta", (event) => {
if (event.data.sessionID === sessionID())
appendPart({ messageID: event.data.assistantMessageID, partID: event.data.reasoningID })
}),
- data.on("reasoning.ended", (event) => {
+ data.on("session.reasoning.ended", (event) => {
if (event.data.sessionID === sessionID() && event.data.text.trim())
appendPart({ messageID: event.data.assistantMessageID, partID: event.data.reasoningID })
}),
- data.on("tool.input.started", (event) => {
+ data.on("session.tool.input.started", (event) => {
if (event.data.sessionID === sessionID())
appendPart({ messageID: event.data.assistantMessageID, partID: event.data.callID }, event.data.name)
}),
- data.on("step.ended", (event) => {
+ data.on("session.step.ended", (event) => {
if (event.data.sessionID !== sessionID() || ["tool-calls", "unknown"].includes(event.data.finish)) return
appendFooter(event.data.assistantMessageID)
}),
- data.on("step.failed", (event) => {
+ data.on("session.step.failed", (event) => {
if (event.data.sessionID === sessionID()) appendFooter(event.data.assistantMessageID)
}),
]
diff --git a/packages/tui/test/cli/cmd/tui/notifications.test.ts b/packages/tui/test/cli/cmd/tui/notifications.test.ts
index 5f1c6355b3..44cd98b133 100644
--- a/packages/tui/test/cli/cmd/tui/notifications.test.ts
+++ b/packages/tui/test/cli/cmd/tui/notifications.test.ts
@@ -91,7 +91,7 @@ function stepStarted(id: string, sessionID = "session"): V2Event {
return {
id,
created: 0,
- type: "step.started",
+ type: "session.step.started",
durable: durable(sessionID),
data: {
sessionID,
@@ -106,7 +106,7 @@ function stepEnded(id: string, sessionID = "session", finish = "stop"): V2Event
return {
id,
created: 0,
- type: "step.ended",
+ type: "session.step.ended",
durable: durable(sessionID),
data: {
sessionID,
@@ -122,7 +122,7 @@ function stepFailed(id: string, sessionID = "session"): V2Event {
return {
id,
created: 0,
- type: "step.failed",
+ type: "session.step.failed",
durable: durable(sessionID),
data: {
sessionID,
diff --git a/packages/tui/test/cli/tui/data.test.tsx b/packages/tui/test/cli/tui/data.test.tsx
index a71bdc47d8..0587662dc3 100644
--- a/packages/tui/test/cli/tui/data.test.tsx
+++ b/packages/tui/test/cli/tui/data.test.tsx
@@ -269,7 +269,7 @@ test("tracks session status from active sessions and execution events", async ()
emitEvent(events, {
id: "evt_step_started",
created: 0,
- type: "step.started",
+ type: "session.step.started",
durable: durable("session-live"),
data: {
sessionID: "session-live",
@@ -283,7 +283,7 @@ test("tracks session status from active sessions and execution events", async ()
emitEvent(events, {
id: "evt_step_ended",
created: 0,
- type: "step.ended",
+ type: "session.step.ended",
durable: durable("session-live", 1, 2),
data: {
sessionID: "session-live",
@@ -302,7 +302,7 @@ test("tracks session status from active sessions and execution events", async ()
emitEvent(events, {
id: "evt_execution_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: {
sessionID: "session-live",
outcome: "success",
@@ -313,7 +313,7 @@ test("tracks session status from active sessions and execution events", async ()
emitEvent(events, {
id: "evt_failed_step_started",
created: 0,
- type: "step.started",
+ type: "session.step.started",
durable: durable("session-failed"),
data: {
sessionID: "session-failed",
@@ -327,7 +327,7 @@ test("tracks session status from active sessions and execution events", async ()
emitEvent(events, {
id: "evt_step_failed",
created: 0,
- type: "step.failed",
+ type: "session.step.failed",
durable: durable("session-failed", 1, 2),
data: {
sessionID: "session-failed",
@@ -344,7 +344,7 @@ test("tracks session status from active sessions and execution events", async ()
emitEvent(events, {
id: "evt_failed_execution_settled",
created: 0,
- type: "execution.settled",
+ type: "session.execution.settled",
data: {
sessionID: "session-failed",
outcome: "failure",
@@ -797,14 +797,14 @@ test("settles pending tools when a live failure arrives", async () => {
emitEvent(events, {
id: "evt_agent_1",
created: 0,
- type: "agent.selected",
+ type: "session.agent.selected",
durable: durable("session-1"),
data: { sessionID: "session-1", agent: "build" },
})
emitEvent(events, {
id: "evt_model_1",
created: 0,
- type: "model.selected",
+ type: "session.model.selected",
durable: durable("session-1", 1),
data: {
sessionID: "session-1",
@@ -814,7 +814,7 @@ test("settles pending tools when a live failure arrives", async () => {
emitEvent(events, {
id: "evt_step_started_1",
created: 0,
- type: "step.started",
+ type: "session.step.started",
durable: durable("session-1", 2),
data: {
sessionID: "session-1",
@@ -826,7 +826,7 @@ test("settles pending tools when a live failure arrives", async () => {
emitEvent(events, {
id: "evt_input_1",
created: 0,
- type: "tool.input.started",
+ type: "session.tool.input.started",
durable: durable("session-1", 3),
data: {
sessionID: "session-1",
@@ -838,7 +838,7 @@ test("settles pending tools when a live failure arrives", async () => {
emitEvent(events, {
id: "evt_called_1",
created: 0,
- type: "tool.called",
+ type: "session.tool.called",
durable: durable("session-1", 4),
data: {
sessionID: "session-1",
@@ -852,7 +852,7 @@ test("settles pending tools when a live failure arrives", async () => {
emitEvent(events, {
id: "evt_failed_1",
created: 0,
- type: "tool.failed",
+ type: "session.tool.failed",
durable: durable("session-1", 5),
data: {
sessionID: "session-1",
@@ -942,7 +942,7 @@ test("renders admitted prompts immediately with queued marker and clears when pr
emitEvent(events, {
id: "evt_admitted_1",
created: 0,
- type: "prompt.admitted",
+ type: "session.prompt.admitted",
durable: durable(sessionID),
data: {
sessionID,
@@ -961,7 +961,7 @@ test("renders admitted prompts immediately with queued marker and clears when pr
emitEvent(events, {
id: "evt_prompted_1",
created: 0,
- type: "prompt.promoted",
+ type: "session.prompt.promoted",
durable: durable(sessionID, 1),
data: {
sessionID,
@@ -969,8 +969,8 @@ test("renders admitted prompts immediately with queued marker and clears when pr
},
})
- await wait(() => received.at(-1) === "prompt.promoted")
- expect(received.slice(-2)).toEqual(["prompt.admitted", "prompt.promoted"])
+ await wait(() => received.at(-1) === "session.prompt.promoted")
+ expect(received.slice(-2)).toEqual(["session.prompt.admitted", "session.prompt.promoted"])
unsubscribe()
const message = sync.session.message.list(sessionID)?.[0]
expect(message?.type).toBe("user")
diff --git a/packages/ui/src/components/provider-icon.tsx b/packages/ui/src/components/provider-icon.tsx
index 7c0eb3d047..46fb7fb6f2 100644
--- a/packages/ui/src/components/provider-icon.tsx
+++ b/packages/ui/src/components/provider-icon.tsx
@@ -9,7 +9,7 @@ export type ProviderIconProps = JSX.SVGElementTags["svg"] & {
export const ProviderIcon: Component = (props) => {
const [local, rest] = splitProps(props, ["id", "class", "classList"])
- const resolved = createMemo(() => (iconNames.includes(local.id as IconName) ? local.id : "synthetic"))
+ const resolved = createMemo(() => (iconNames.includes(local.id as IconName) ? local.id : "session.synthetic"))
return (