refactor(instance): remove legacy runtime fallback (#27757)
This commit is contained in:
@@ -4,8 +4,9 @@ import { tool, type ModelMessage } from "ai"
|
||||
import { Cause, Effect, Exit, Stream } from "effect"
|
||||
import z from "zod"
|
||||
import { makeRuntime } from "../../src/effect/run-service"
|
||||
import { InstanceRef } from "../../src/effect/instance-ref"
|
||||
import { LLM } from "../../src/session/llm"
|
||||
import { Instance } from "../../src/project/instance"
|
||||
import type { InstanceContext } from "../../src/project/instance-context"
|
||||
import { WithInstance } from "../../src/project/with-instance"
|
||||
import { Provider } from "@/provider/provider"
|
||||
import { ProviderTransform } from "@/provider/transform"
|
||||
@@ -18,19 +19,21 @@ import { MessageV2 } from "../../src/session/message-v2"
|
||||
import { SessionID, MessageID } from "../../src/session/schema"
|
||||
import { AppRuntime } from "../../src/effect/app-runtime"
|
||||
|
||||
async function getModel(providerID: ProviderID, modelID: ModelID) {
|
||||
return AppRuntime.runPromise(
|
||||
Effect.gen(function* () {
|
||||
const provider = yield* Provider.Service
|
||||
return yield* provider.getModel(providerID, modelID)
|
||||
}),
|
||||
)
|
||||
async function getModel(providerID: ProviderID, modelID: ModelID, ctx: InstanceContext) {
|
||||
const effect = Effect.gen(function* () {
|
||||
const provider = yield* Provider.Service
|
||||
return yield* provider.getModel(providerID, modelID)
|
||||
})
|
||||
return AppRuntime.runPromise(effect.pipe(Effect.provideService(InstanceRef, ctx)))
|
||||
}
|
||||
|
||||
const llm = makeRuntime(LLM.Service, LLM.defaultLayer)
|
||||
|
||||
async function drain(input: LLM.StreamInput) {
|
||||
return llm.runPromise((svc) => svc.stream(input).pipe(Stream.runDrain))
|
||||
async function drain(input: LLM.StreamInput, ctx: InstanceContext) {
|
||||
return llm.runPromise((svc) => {
|
||||
const effect = svc.stream(input).pipe(Stream.runDrain)
|
||||
return effect.pipe(Effect.provideService(InstanceRef, ctx))
|
||||
})
|
||||
}
|
||||
|
||||
describe("session.llm.hasToolCalls", () => {
|
||||
@@ -360,8 +363,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-1")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -381,15 +384,18 @@ describe("session.llm.stream", () => {
|
||||
model: { providerID: ProviderID.make(providerID), modelID: resolved.id, variant: "high" },
|
||||
} satisfies MessageV2.User
|
||||
|
||||
await drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
})
|
||||
await drain(
|
||||
{
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
|
||||
const capture = await request
|
||||
const body = capture.body
|
||||
@@ -447,8 +453,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-service-abort")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -478,7 +484,7 @@ describe("session.llm.stream", () => {
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
})
|
||||
.pipe(Stream.runDrain),
|
||||
.pipe(Stream.runDrain, Effect.provideService(InstanceRef, ctx)),
|
||||
{ signal: ctrl.signal },
|
||||
)
|
||||
|
||||
@@ -537,8 +543,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-tools")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -557,22 +563,25 @@ describe("session.llm.stream", () => {
|
||||
tools: { question: true },
|
||||
} satisfies MessageV2.User
|
||||
|
||||
await drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
permission: [{ permission: "question", pattern: "*", action: "allow" }],
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {
|
||||
question: tool({
|
||||
description: "Ask a question",
|
||||
inputSchema: z.object({}),
|
||||
execute: async () => ({ output: "" }),
|
||||
}),
|
||||
await drain(
|
||||
{
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
permission: [{ permission: "question", pattern: "*", action: "allow" }],
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {
|
||||
question: tool({
|
||||
description: "Ask a question",
|
||||
inputSchema: z.object({}),
|
||||
execute: async () => ({ output: "" }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
})
|
||||
ctx,
|
||||
)
|
||||
|
||||
const capture = await request
|
||||
const tools = capture.body.tools as Array<{ function?: { name?: string } }> | undefined
|
||||
@@ -651,8 +660,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.openai, ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.openai, ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-2")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -671,15 +680,18 @@ describe("session.llm.stream", () => {
|
||||
model: { providerID: ProviderID.make("openai"), modelID: resolved.id, variant: "high" },
|
||||
} satisfies MessageV2.User
|
||||
|
||||
await drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
})
|
||||
await drain(
|
||||
{
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
|
||||
const capture = await request
|
||||
const body = capture.body
|
||||
@@ -767,8 +779,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.openai, ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.openai, ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-data-url")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -786,28 +798,31 @@ describe("session.llm.stream", () => {
|
||||
model: { providerID: ProviderID.make("openai"), modelID: resolved.id },
|
||||
} satisfies MessageV2.User
|
||||
|
||||
await drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{ type: "text", text: "Describe this image" },
|
||||
{
|
||||
type: "file",
|
||||
mediaType: "image/png",
|
||||
filename: "large-image.png",
|
||||
data: image,
|
||||
},
|
||||
],
|
||||
},
|
||||
] as ModelMessage[],
|
||||
tools: {},
|
||||
})
|
||||
await drain(
|
||||
{
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{ type: "text", text: "Describe this image" },
|
||||
{
|
||||
type: "file",
|
||||
mediaType: "image/png",
|
||||
filename: "large-image.png",
|
||||
data: image,
|
||||
},
|
||||
],
|
||||
},
|
||||
] as ModelMessage[],
|
||||
tools: {},
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
|
||||
const capture = await request
|
||||
expect(capture.url.pathname.endsWith("/responses")).toBe(true)
|
||||
@@ -886,8 +901,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-3")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -907,15 +922,18 @@ describe("session.llm.stream", () => {
|
||||
model: { providerID: ProviderID.make("minimax"), modelID: ModelID.make("MiniMax-M2.5") },
|
||||
} satisfies MessageV2.User
|
||||
|
||||
await drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
})
|
||||
await drain(
|
||||
{
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
|
||||
const capture = await request
|
||||
const body = capture.body
|
||||
@@ -1004,8 +1022,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.make("anthropic"), ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make("anthropic"), ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-anthropic-tools")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -1110,31 +1128,34 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
] as any[]
|
||||
|
||||
await drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: [],
|
||||
messages: await MessageV2.toModelMessages(input as any, resolved),
|
||||
tools: {
|
||||
read: tool({
|
||||
description: "Stub read tool",
|
||||
inputSchema: z.object({
|
||||
filePath: z.string(),
|
||||
await drain(
|
||||
{
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: [],
|
||||
messages: await MessageV2.toModelMessages(input as any, resolved),
|
||||
tools: {
|
||||
read: tool({
|
||||
description: "Stub read tool",
|
||||
inputSchema: z.object({
|
||||
filePath: z.string(),
|
||||
}),
|
||||
execute: async () => ({ output: "stub" }),
|
||||
}),
|
||||
execute: async () => ({ output: "stub" }),
|
||||
}),
|
||||
glob: tool({
|
||||
description: "Stub glob tool",
|
||||
inputSchema: z.object({
|
||||
pattern: z.string(),
|
||||
path: z.string().optional(),
|
||||
glob: tool({
|
||||
description: "Stub glob tool",
|
||||
inputSchema: z.object({
|
||||
pattern: z.string(),
|
||||
path: z.string().optional(),
|
||||
}),
|
||||
execute: async () => ({ output: "stub" }),
|
||||
}),
|
||||
execute: async () => ({ output: "stub" }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
})
|
||||
ctx,
|
||||
)
|
||||
|
||||
const capture = await request
|
||||
const body = capture.body
|
||||
@@ -1245,8 +1266,8 @@ describe("session.llm.stream", () => {
|
||||
|
||||
await WithInstance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id))
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
const sessionID = SessionID.make("session-test-4")
|
||||
const agent = {
|
||||
name: "test",
|
||||
@@ -1266,15 +1287,18 @@ describe("session.llm.stream", () => {
|
||||
model: { providerID: ProviderID.make(providerID), modelID: resolved.id },
|
||||
} satisfies MessageV2.User
|
||||
|
||||
await drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
})
|
||||
await drain(
|
||||
{
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
|
||||
const capture = await request
|
||||
const body = capture.body
|
||||
|
||||
Reference in New Issue
Block a user