|
|
@@ -45,7 +45,7 @@ import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
|
|
import { Truncate } from "@/tool/truncate"
|
|
|
import { decodeDataUrl } from "@/util/data-url"
|
|
|
import { Process } from "@/util/process"
|
|
|
-import { Cause, Effect, Exit, Latch, Layer, Option, Scope, Context, Schema } from "effect"
|
|
|
+import { Cause, Effect, Exit, Latch, Layer, Option, Scope, Context, Schema, Types } from "effect"
|
|
|
import { zod } from "@/util/effect-zod"
|
|
|
import { withStatics } from "@/util/schema"
|
|
|
import * as EffectLogger from "@opencode-ai/core/effect/logger"
|
|
|
@@ -127,7 +127,7 @@ export const layer = Layer.effect(
|
|
|
|
|
|
const resolvePromptParts = Effect.fn("SessionPrompt.resolvePromptParts")(function* (template: string) {
|
|
|
const ctx = yield* InstanceState.context
|
|
|
- const parts: PromptInput["parts"] = [{ type: "text", text: template }]
|
|
|
+ const parts: Types.DeepMutable<PromptInput["parts"]> = [{ type: "text", text: template }]
|
|
|
const files = ConfigMarkdown.files(template)
|
|
|
const seen = new Set<string>()
|
|
|
yield* Effect.forEach(
|
|
|
@@ -1012,7 +1012,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
case "file:": {
|
|
|
log.info("file", { mime: part.mime })
|
|
|
const filepath = fileURLToPath(part.url)
|
|
|
- if (yield* fsys.isDir(filepath)) part.mime = "application/x-directory"
|
|
|
+ const mime = (yield* fsys.isDir(filepath)) ? "application/x-directory" : part.mime
|
|
|
|
|
|
const { read } = yield* registry.named()
|
|
|
const execRead = (args: Parameters<typeof read.execute>[0], extra?: Tool.Context["extra"]) => {
|
|
|
@@ -1031,7 +1031,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
.pipe(Effect.onInterrupt(() => Effect.sync(() => controller.abort())))
|
|
|
}
|
|
|
|
|
|
- if (part.mime === "text/plain") {
|
|
|
+ if (mime === "text/plain") {
|
|
|
let offset: number | undefined
|
|
|
let limit: number | undefined
|
|
|
const range = { start: url.searchParams.get("start"), end: url.searchParams.get("end") }
|
|
|
@@ -1089,7 +1089,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
})),
|
|
|
)
|
|
|
} else {
|
|
|
- pieces.push({ ...part, messageID: info.id, sessionID: input.sessionID })
|
|
|
+ pieces.push({ ...part, mime, messageID: info.id, sessionID: input.sessionID })
|
|
|
}
|
|
|
} else {
|
|
|
const error = Cause.squash(exit.cause)
|
|
|
@@ -1110,7 +1110,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
return pieces
|
|
|
}
|
|
|
|
|
|
- if (part.mime === "application/x-directory") {
|
|
|
+ if (mime === "application/x-directory") {
|
|
|
const args = { filePath: filepath }
|
|
|
const exit = yield* execRead(args).pipe(Effect.exit)
|
|
|
if (Exit.isFailure(exit)) {
|
|
|
@@ -1146,7 +1146,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
synthetic: true,
|
|
|
text: exit.value.output,
|
|
|
},
|
|
|
- { ...part, messageID: info.id, sessionID: input.sessionID },
|
|
|
+ { ...part, mime, messageID: info.id, sessionID: input.sessionID },
|
|
|
]
|
|
|
}
|
|
|
|
|
|
@@ -1164,9 +1164,9 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
sessionID: input.sessionID,
|
|
|
type: "file",
|
|
|
url:
|
|
|
- `data:${part.mime};base64,` +
|
|
|
+ `data:${mime};base64,` +
|
|
|
Buffer.from(yield* fsys.readFile(filepath).pipe(Effect.catch(Effect.die))).toString("base64"),
|
|
|
- mime: part.mime,
|
|
|
+ mime,
|
|
|
filename: part.filename!,
|
|
|
source: part.source,
|
|
|
},
|
|
|
@@ -1700,18 +1700,7 @@ export const PromptInput = Schema.Struct({
|
|
|
]).annotate({ discriminator: "type" }),
|
|
|
),
|
|
|
}).pipe(withStatics((s) => ({ zod: zod(s) })))
|
|
|
-// `z.discriminatedUnion` erases the discriminated members' shapes back to
|
|
|
-// `{}` when walked from the generic `z.ZodType` input. Restore the precise
|
|
|
-// `parts` type from the exported Schema input types so callers see a proper
|
|
|
-// tagged union.
|
|
|
-type PartInputUnion =
|
|
|
- | MessageV2.TextPartInput
|
|
|
- | MessageV2.FilePartInput
|
|
|
- | MessageV2.AgentPartInput
|
|
|
- | MessageV2.SubtaskPartInput
|
|
|
-export type PromptInput = Omit<Schema.Schema.Type<typeof PromptInput>, "parts"> & {
|
|
|
- parts: PartInputUnion[]
|
|
|
-}
|
|
|
+export type PromptInput = Schema.Schema.Type<typeof PromptInput>
|
|
|
|
|
|
export class LoopInput extends Schema.Class<LoopInput>("SessionPrompt.LoopInput")({
|
|
|
sessionID: SessionID,
|