Преглед на файлове

feat(plugin): expose session rename

Kit Langton преди 1 месец
родител
ревизия
5910c5049e

+ 1 - 0
packages/core/src/plugin/host.ts

@@ -378,6 +378,7 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
       get: (input) => runtime.session.get(input.sessionID),
       prompt: runtime.session.prompt,
       command: runtime.session.command,
+      rename: runtime.session.rename,
       interrupt: (input) => runtime.session.interrupt(input.sessionID),
     },
   } satisfies Plugin.Context

+ 12 - 2
packages/core/src/plugin/promise.ts

@@ -70,7 +70,8 @@ export function fromPromise(plugin: Plugin) {
           catalog: {
             provider: {
               list: (input) => run(host.catalog.provider.list(input)),
-              get: (input) => run(host.catalog.provider.get({ ...input, providerID: Provider.ID.make(input.providerID) })),
+              get: (input) =>
+                run(host.catalog.provider.get({ ...input, providerID: Provider.ID.make(input.providerID) })),
             },
             model: {
               list: (input) => run(host.catalog.model.list(input)),
@@ -96,7 +97,9 @@ export function fromPromise(plugin: Plugin) {
               ),
             connect: {
               key: (input) =>
-                run(host.integration.connect.key({ ...input, integrationID: Integration.ID.make(input.integrationID) })),
+                run(
+                  host.integration.connect.key({ ...input, integrationID: Integration.ID.make(input.integrationID) }),
+                ),
               oauth: (input) =>
                 run(
                   host.integration.connect.oauth({
@@ -208,6 +211,13 @@ export function fromPromise(plugin: Plugin) {
                   resume: input.resume ?? undefined,
                 }),
               ),
+            rename: (input) =>
+              run(
+                host.session.rename({
+                  ...input,
+                  sessionID: Session.ID.make(input.sessionID),
+                }),
+              ),
             interrupt: (input) => run(host.session.interrupt({ sessionID: Session.ID.make(input.sessionID) })),
           },
         }

+ 2 - 1
packages/core/src/plugin/runtime.ts

@@ -11,7 +11,7 @@ import { SessionV2 } from "../session"
 export interface Interface {
   readonly session: Pick<
     SessionV2.Interface,
-    "get" | "create" | "messages" | "prompt" | "command" | "resume" | "interrupt" | "synthetic"
+    "get" | "create" | "messages" | "prompt" | "command" | "rename" | "resume" | "interrupt" | "synthetic"
   >
   readonly job: Pick<Job.Interface, "start" | "wait" | "block" | "background" | "cancel">
   readonly location: {
@@ -51,6 +51,7 @@ export const layerWithCell = (cell: Cell) =>
         messages: (input) => require(cell, (runtime) => runtime.session.messages(input)),
         prompt: (input) => require(cell, (runtime) => runtime.session.prompt(input)),
         command: (input) => require(cell, (runtime) => runtime.session.command(input)),
+        rename: (input) => require(cell, (runtime) => runtime.session.rename(input)),
         resume: (sessionID) => require(cell, (runtime) => runtime.session.resume(sessionID)),
         interrupt: (sessionID) => require(cell, (runtime) => runtime.session.interrupt(sessionID)),
         synthetic: (input) => require(cell, (runtime) => runtime.session.synthetic(input)),

+ 1 - 0
packages/core/test/plugin/host.ts

@@ -82,6 +82,7 @@ export function host(overrides: Overrides = {}): PluginContext {
       get: () => Effect.die("unused session.get"),
       prompt: () => Effect.die("unused session.prompt"),
       command: () => Effect.die("unused session.command"),
+      rename: () => Effect.die("unused session.rename"),
       interrupt: () => Effect.die("unused session.interrupt"),
     },
   }

+ 32 - 0
packages/core/test/plugin/promise.test.ts

@@ -4,6 +4,7 @@ import { AgentV2 } from "@opencode-ai/core/agent"
 import { PluginV2 } from "@opencode-ai/core/plugin"
 import { PluginHost } from "@opencode-ai/core/plugin/host"
 import { PluginPromise } from "@opencode-ai/core/plugin/promise"
+import { PluginRuntime } from "@opencode-ai/core/plugin/runtime"
 import { SessionV2 } from "@opencode-ai/core/session"
 import { SessionMessage } from "@opencode-ai/core/session/message"
 import { ToolRegistry } from "@opencode-ai/core/tool/registry"
@@ -43,6 +44,37 @@ describe("fromPromise", () => {
     }),
   )
 
+  it.effect("forwards session rename", () =>
+    Effect.gen(function* () {
+      const plugin = yield* PluginV2.Service
+      const runtime = yield* PluginRuntime.Service
+      const renamed: { sessionID: SessionV2.ID; title: string }[] = []
+      const host = yield* PluginHost.make(plugin).pipe(
+        Effect.provideService(
+          PluginRuntime.Service,
+          PluginRuntime.Service.of({
+            ...runtime,
+            session: {
+              ...runtime.session,
+              rename: (input) =>
+                Effect.sync(() => {
+                  renamed.push(input)
+                }),
+            },
+          }),
+        ),
+      )
+      const promisePlugin = Plugin.define({
+        id: "promise-session-rename",
+        setup: (ctx) => ctx.session.rename({ sessionID: "ses_plugin_rename", title: "Updated scope" }),
+      })
+
+      yield* PluginPromise.fromPromise(promisePlugin).effect(host)
+
+      expect(renamed).toEqual([{ sessionID: SessionV2.ID.make("ses_plugin_rename"), title: "Updated scope" }])
+    }),
+  )
+
   it.effect("loads a promise plugin and registers a transform hook", () =>
     Effect.gen(function* () {
       const agents = yield* AgentV2.Service

+ 1 - 1
packages/docs/build/plugins.mdx

@@ -177,7 +177,7 @@ and plugin options.
 | `ctx.integration`      | `list`, `get`, `connect`, `attempt`, `transform`, `reload`, and connection lookup/resolution |
 | `ctx.plugin`           | `list` currently active plugin IDs                                                           |
 | `ctx.reference`        | `list`, `transform`, `reload`                                                                |
-| `ctx.session`          | `create`, `get`, `prompt`, `command`, `interrupt`, and `hook`                                |
+| `ctx.session`          | `create`, `get`, `prompt`, `command`, `rename`, `interrupt`, and `hook`                      |
 | `ctx.skill`            | `list`, `transform`, `reload`                                                                |
 | `ctx.tool`             | `transform` and `hook`                                                                       |
 | `ctx.aisdk`            | `hook`                                                                                       |

+ 1 - 1
packages/plugin/src/v2/effect/session.ts

@@ -1,3 +1,3 @@
 import type { SessionApi } from "@opencode-ai/client/effect/api"
 
-export type SessionDomain = Pick<SessionApi<unknown>, "create" | "get" | "prompt" | "command" | "interrupt">
+export type SessionDomain = Pick<SessionApi<unknown>, "create" | "get" | "prompt" | "command" | "rename" | "interrupt">

+ 1 - 1
packages/plugin/src/v2/promise/session.ts

@@ -1,3 +1,3 @@
 import type { SessionApi } from "@opencode-ai/client/promise/api"
 
-export type SessionDomain = Pick<SessionApi, "create" | "get" | "prompt" | "command" | "interrupt">
+export type SessionDomain = Pick<SessionApi, "create" | "get" | "prompt" | "command" | "rename" | "interrupt">