refactor(core): consolidate references (#31539)
This commit is contained in:
@@ -52,12 +52,10 @@ import { SessionEvent } from "@opencode-ai/core/session/event"
|
||||
import { SessionMessage } from "@opencode-ai/core/session/message"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { AgentAttachment, FileAttachment, Prompt, ReferenceAttachment, Source } from "@opencode-ai/core/session/prompt"
|
||||
import { Reference } from "@/reference/reference"
|
||||
import { AgentAttachment, FileAttachment, Prompt, Source } from "@opencode-ai/core/session/prompt"
|
||||
import * as DateTime from "effect/DateTime"
|
||||
import { eq } from "drizzle-orm"
|
||||
import { SessionTable } from "@opencode-ai/core/session/sql"
|
||||
import { referencePromptMetadata, referenceTextPart } from "./prompt/reference"
|
||||
import { SessionReminders } from "./reminders"
|
||||
import { SessionTools } from "./tools"
|
||||
import { LLMEvent } from "@opencode-ai/llm"
|
||||
@@ -122,7 +120,6 @@ export const layer = Layer.effect(
|
||||
const summary = yield* SessionSummary.Service
|
||||
const sys = yield* SystemPrompt.Service
|
||||
const llm = yield* LLM.Service
|
||||
const references = yield* Reference.Service
|
||||
const events = yield* EventV2Bridge.Service
|
||||
const flags = yield* RuntimeFlags.Service
|
||||
const database = yield* Database.Service
|
||||
@@ -140,46 +137,10 @@ export const layer = Layer.effect(
|
||||
yield* state.cancel(sessionID)
|
||||
})
|
||||
|
||||
const resolveReferenceParts = Effect.fnUntraced(function* (template: string) {
|
||||
const parts: Types.DeepMutable<PromptInput["parts"]> = []
|
||||
const seen = new Set<string>()
|
||||
yield* Effect.forEach(
|
||||
ConfigMarkdown.files(template),
|
||||
Effect.fnUntraced(function* (match) {
|
||||
const name = match[1]
|
||||
if (!name) return
|
||||
const alias = name.split("/")[0]
|
||||
if (!alias || seen.has(alias)) return
|
||||
const reference = yield* references.get(alias)
|
||||
if (!reference) return
|
||||
seen.add(alias)
|
||||
|
||||
const start = match.index ?? 0
|
||||
const source = { value: match[0], start, end: start + match[0].length }
|
||||
if (reference.kind === "invalid") {
|
||||
parts.push(referenceTextPart({ reference, source }))
|
||||
return
|
||||
}
|
||||
|
||||
yield* references.ensure(reference.path)
|
||||
parts.push({
|
||||
type: "file",
|
||||
url: pathToFileURL(reference.path).href,
|
||||
filename: alias,
|
||||
mime: "application/x-directory",
|
||||
source: { type: "file", text: source, path: alias },
|
||||
})
|
||||
}),
|
||||
{ concurrency: 1, discard: true },
|
||||
)
|
||||
return parts
|
||||
})
|
||||
|
||||
const resolvePromptParts = Effect.fn("SessionPrompt.resolvePromptParts")(function* (template: string) {
|
||||
const ctx = yield* InstanceState.context
|
||||
const parts: Types.DeepMutable<PromptInput["parts"]> = [
|
||||
{ type: "text", text: template },
|
||||
...(yield* resolveReferenceParts(template)),
|
||||
]
|
||||
const files = ConfigMarkdown.files(template)
|
||||
const seen = new Set<string>()
|
||||
@@ -191,10 +152,6 @@ export const layer = Layer.effect(
|
||||
if (seen.has(name)) return
|
||||
seen.add(name)
|
||||
|
||||
const slash = name.indexOf("/")
|
||||
const alias = slash === -1 ? name : name.slice(0, slash)
|
||||
if (yield* references.get(alias)) return
|
||||
|
||||
const filepath = name.startsWith("~/")
|
||||
? path.join(os.homedir(), name.slice(2))
|
||||
: path.resolve(ctx.worktree, name)
|
||||
@@ -1019,22 +976,7 @@ export const layer = Layer.effect(
|
||||
return [{ ...part, messageID: info.id, sessionID: input.sessionID }]
|
||||
})
|
||||
|
||||
const submittedParts: Types.DeepMutable<PromptInput["parts"]> = [...input.parts]
|
||||
const attachedReferences = new Set(
|
||||
input.parts.flatMap((part) =>
|
||||
part.type === "file" && part.mime === "application/x-directory" ? [part.url] : [],
|
||||
),
|
||||
)
|
||||
for (const part of input.parts) {
|
||||
if (part.type !== "text" || part.synthetic) continue
|
||||
for (const reference of yield* resolveReferenceParts(part.text)) {
|
||||
if (reference.type === "file" && attachedReferences.has(reference.url)) continue
|
||||
if (reference.type === "file") attachedReferences.add(reference.url)
|
||||
submittedParts.push(reference)
|
||||
}
|
||||
}
|
||||
|
||||
const resolvedParts = yield* Effect.forEach(submittedParts, resolvePart, { concurrency: "unbounded" }).pipe(
|
||||
const resolvedParts = yield* Effect.forEach(input.parts, resolvePart, { concurrency: "unbounded" }).pipe(
|
||||
Effect.map((x) => x.flat().map(assign)),
|
||||
)
|
||||
|
||||
@@ -1092,26 +1034,6 @@ export const layer = Layer.effect(
|
||||
if (part.type === "text") {
|
||||
if (part.synthetic) result.synthetic.push(part.text)
|
||||
else result.text.push(part.text)
|
||||
const reference = referencePromptMetadata(part.metadata?.reference)
|
||||
if (reference) {
|
||||
result.references.push(
|
||||
new ReferenceAttachment({
|
||||
name: reference.name,
|
||||
kind: reference.kind,
|
||||
uri: reference.path ? pathToFileURL(reference.path).href : undefined,
|
||||
repository: reference.repository,
|
||||
branch: reference.branch,
|
||||
target: reference.target,
|
||||
targetUri: reference.targetPath ? pathToFileURL(reference.targetPath).href : undefined,
|
||||
problem: reference.problem,
|
||||
source: new Source({
|
||||
start: reference.source.start,
|
||||
end: reference.source.end,
|
||||
text: reference.source.value,
|
||||
}),
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
if (part.type === "file") {
|
||||
result.files.push(
|
||||
@@ -1149,7 +1071,6 @@ export const layer = Layer.effect(
|
||||
text: [] as string[],
|
||||
files: [] as FileAttachment[],
|
||||
agents: [] as AgentAttachment[],
|
||||
references: [] as ReferenceAttachment[],
|
||||
synthetic: [] as string[],
|
||||
},
|
||||
)
|
||||
@@ -1164,7 +1085,6 @@ export const layer = Layer.effect(
|
||||
text: nextPrompt.text.join("\n"),
|
||||
files: nextPrompt.files,
|
||||
agents: nextPrompt.agents,
|
||||
references: nextPrompt.references,
|
||||
}),
|
||||
})
|
||||
}
|
||||
@@ -1642,7 +1562,6 @@ export const defaultLayer = Layer.suspend(() =>
|
||||
Database.defaultLayer,
|
||||
SystemPrompt.defaultLayer,
|
||||
LLM.defaultLayer,
|
||||
Reference.defaultLayer,
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
RuntimeFlags.defaultLayer,
|
||||
EventV2Bridge.defaultLayer,
|
||||
|
||||
Reference in New Issue
Block a user