فهرست منبع

chore: generate

opencode-agent[bot] 4 ماه پیش
والد
کامیت
3a78fb1f42

+ 3 - 4
packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts

@@ -270,10 +270,9 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session",
           Effect.provideService(WorkspaceRef, workspace),
           Effect.mapError(() => new HttpApiError.BadRequest({})),
         )
-      return HttpServerResponse.stream(
-        Stream.make(JSON.stringify(message)).pipe(Stream.encodeText),
-        { contentType: "application/json" },
-      )
+      return HttpServerResponse.stream(Stream.make(JSON.stringify(message)).pipe(Stream.encodeText), {
+        contentType: "application/json",
+      })
     })
 
     const promptAsync = Effect.fn("SessionHttpApi.promptAsync")(function* (ctx: {

+ 4 - 6
packages/opencode/src/session/processor.ts

@@ -389,12 +389,10 @@ export const layer: Layer.Layer<
                 typeof attachment.mime === "string" &&
                 typeof attachment.url === "string",
             )
-            const normalized = yield* Effect.forEach(
-              toolAttachments,
-              (attachment) =>
-                attachment.mime.startsWith("image/")
-                  ? image.normalize(attachment).pipe(Effect.exit)
-                  : Effect.succeed(Exit.succeed<MessageV2.FilePart>(attachment)),
+            const normalized = yield* Effect.forEach(toolAttachments, (attachment) =>
+              attachment.mime.startsWith("image/")
+                ? image.normalize(attachment).pipe(Effect.exit)
+                : Effect.succeed(Exit.succeed<MessageV2.FilePart>(attachment)),
             )
             const omitted = normalized.filter(Exit.isFailure).length
             const attachments = normalized.filter(Exit.isSuccess).map((item) => item.value)

+ 20 - 22
packages/opencode/src/session/prompt.ts

@@ -1278,9 +1278,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
       )
 
       const parts = yield* Effect.forEach(resolvedParts, (part) =>
-        part.type === "file" && part.mime.startsWith("image/")
-          ? image.normalize(part)
-          : Effect.succeed(part),
+        part.type === "file" && part.mime.startsWith("image/") ? image.normalize(part) : Effect.succeed(part),
       )
 
       const parsed = MessageV2.Info.zod.safeParse(info)
@@ -1376,26 +1374,26 @@ NOTE: At any point in time through this workflow you should feel free to ask the
       return { info, parts }
     }, Effect.scoped)
 
-    const prompt: (input: PromptInput) => Effect.Effect<MessageV2.WithParts, Image.Error> = Effect.fn("SessionPrompt.prompt")(
-      function* (input: PromptInput) {
-        const session = yield* sessions.get(input.sessionID).pipe(Effect.orDie)
-        yield* revert.cleanup(session)
-        const message = yield* createUserMessage(input)
-        yield* sessions.touch(input.sessionID)
-
-        const permissions: Permission.Ruleset = []
-        for (const [t, enabled] of Object.entries(input.tools ?? {})) {
-          permissions.push({ permission: t, action: enabled ? "allow" : "deny", pattern: "*" })
-        }
-        if (permissions.length > 0) {
-          session.permission = permissions
-          yield* sessions.setPermission({ sessionID: session.id, permission: permissions })
-        }
+    const prompt: (input: PromptInput) => Effect.Effect<MessageV2.WithParts, Image.Error> = Effect.fn(
+      "SessionPrompt.prompt",
+    )(function* (input: PromptInput) {
+      const session = yield* sessions.get(input.sessionID).pipe(Effect.orDie)
+      yield* revert.cleanup(session)
+      const message = yield* createUserMessage(input)
+      yield* sessions.touch(input.sessionID)
+
+      const permissions: Permission.Ruleset = []
+      for (const [t, enabled] of Object.entries(input.tools ?? {})) {
+        permissions.push({ permission: t, action: enabled ? "allow" : "deny", pattern: "*" })
+      }
+      if (permissions.length > 0) {
+        session.permission = permissions
+        yield* sessions.setPermission({ sessionID: session.id, permission: permissions })
+      }
 
-        if (input.noReply === true) return message
-        return yield* loop({ sessionID: input.sessionID })
-      },
-    )
+      if (input.noReply === true) return message
+      return yield* loop({ sessionID: input.sessionID })
+    })
 
     const lastAssistant = Effect.fnUntraced(function* (sessionID: SessionID) {
       const match = yield* sessions.findMessage(sessionID, (m) => m.info.role !== "user")

+ 6 - 2
packages/opencode/test/image/image.test.ts

@@ -9,7 +9,9 @@ const it = testEffect(Layer.mergeAll(Image.layer.pipe(Layer.provide(TestConfig.l
 const tiny = testEffect(
   Layer.mergeAll(
     Image.layer.pipe(
-      Layer.provide(TestConfig.layer({ get: () => Effect.succeed({ attachment: { image: { max_base64_bytes: 1 } } }) })),
+      Layer.provide(
+        TestConfig.layer({ get: () => Effect.succeed({ attachment: { image: { max_base64_bytes: 1 } } }) }),
+      ),
     ),
   ),
 )
@@ -60,7 +62,9 @@ describe("Image", () => {
       const photon = yield* Effect.promise(() => import("@silvia-odwyer/photon-node"))
       const source = new photon.PhotonImage(new Uint8Array(Array.from({ length: 4 }, () => 255)), 1, 1)
       const image = yield* Image.Service
-      const exit = yield* image.normalize(part("image/png", Buffer.from(source.get_bytes()).toString("base64"))).pipe(Effect.exit)
+      const exit = yield* image
+        .normalize(part("image/png", Buffer.from(source.get_bytes()).toString("base64")))
+        .pipe(Effect.exit)
 
       source.free()
       expect(Exit.isFailure(exit)).toBe(true)

+ 4 - 1
packages/opencode/test/session/compaction.test.ts

@@ -279,7 +279,10 @@ function llm() {
 function liveRuntime(layer: Layer.Layer<LLM.Service>, provider = ProviderTest.fake(), config = Config.defaultLayer) {
   const bus = Bus.layer
   const status = SessionStatus.layer.pipe(Layer.provide(bus))
-  const processor = SessionProcessorModule.SessionProcessor.layer.pipe(Layer.provide(summary), Layer.provide(Image.defaultLayer))
+  const processor = SessionProcessorModule.SessionProcessor.layer.pipe(
+    Layer.provide(summary),
+    Layer.provide(Image.defaultLayer),
+  )
   return ManagedRuntime.make(
     Layer.mergeAll(SessionCompaction.layer.pipe(Layer.provide(processor)), processor, bus, status).pipe(
       Layer.provide(provider.layer),

+ 5 - 1
packages/opencode/test/session/prompt.test.ts

@@ -188,7 +188,11 @@ function makeHttp() {
     Layer.provideMerge(deps),
   )
   const trunc = Truncate.layer.pipe(Layer.provideMerge(deps))
-  const proc = SessionProcessor.layer.pipe(Layer.provide(summary), Layer.provide(Image.defaultLayer), Layer.provideMerge(deps))
+  const proc = SessionProcessor.layer.pipe(
+    Layer.provide(summary),
+    Layer.provide(Image.defaultLayer),
+    Layer.provideMerge(deps),
+  )
   const compact = SessionCompaction.layer.pipe(Layer.provideMerge(proc), Layer.provideMerge(deps))
   return Layer.mergeAll(
     TestLLMServer.layer,

+ 33 - 0
packages/sdk/openapi.json

@@ -12010,6 +12010,36 @@
         "enum": ["auto", "stretch"],
         "description": "@deprecated Always uses stretch layout."
       },
+      "ImageAttachmentConfig": {
+        "type": "object",
+        "properties": {
+          "auto_resize": {
+            "type": "boolean"
+          },
+          "max_width": {
+            "type": "integer",
+            "exclusiveMinimum": 0
+          },
+          "max_height": {
+            "type": "integer",
+            "exclusiveMinimum": 0
+          },
+          "max_base64_bytes": {
+            "type": "integer",
+            "exclusiveMinimum": 0
+          }
+        },
+        "additionalProperties": false
+      },
+      "AttachmentConfig": {
+        "type": "object",
+        "properties": {
+          "image": {
+            "$ref": "#/components/schemas/ImageAttachmentConfig"
+          }
+        },
+        "additionalProperties": false
+      },
       "Config": {
         "type": "object",
         "properties": {
@@ -12340,6 +12370,9 @@
               "type": "boolean"
             }
           },
+          "attachment": {
+            "$ref": "#/components/schemas/AttachmentConfig"
+          },
           "enterprise": {
             "type": "object",
             "properties": {