refactor(schema): extract shared public schemas (#33571)
This commit is contained in:
parent
60aba622ab
commit
516cfe4e09
130 changed files with 2014 additions and 1593 deletions
|
|
@ -61,7 +61,7 @@ describe("CatalogV2", () => {
|
|||
yield* credentials.create({
|
||||
integrationID,
|
||||
label: "First",
|
||||
value: new Credential.Key({ type: "key", key: "first", metadata: { tenant: "one" } }),
|
||||
value: Credential.Key.make({ type: "key", key: "first", metadata: { tenant: "one" } }),
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.available()).map((provider) => provider.id)).toEqual([ProviderV2.ID.make("test")])
|
||||
|
|
@ -69,7 +69,7 @@ describe("CatalogV2", () => {
|
|||
yield* credentials.create({
|
||||
integrationID,
|
||||
label: "Second",
|
||||
value: new Credential.Key({ type: "key", key: "second", metadata: { tenant: "two" } }),
|
||||
value: Credential.Key.make({ type: "key", key: "second", metadata: { tenant: "two" } }),
|
||||
})
|
||||
expect((yield* catalog.provider.available()).map((provider) => provider.id)).toEqual([ProviderV2.ID.make("test")])
|
||||
expect(required(yield* catalog.provider.get(ProviderV2.ID.make("test"))).request.body).toEqual({})
|
||||
|
|
@ -98,7 +98,7 @@ describe("CatalogV2", () => {
|
|||
|
||||
yield* (yield* Credential.Service).create({
|
||||
integrationID,
|
||||
value: new Credential.Key({ type: "key", key: "secret" }),
|
||||
value: Credential.Key.make({ type: "key", key: "secret" }),
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.available()).map((provider) => provider.id)).toEqual([providerID])
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ describe("CommandV2", () => {
|
|||
})
|
||||
|
||||
expect(yield* command.get("review")).toEqual(
|
||||
new CommandV2.Info({
|
||||
CommandV2.Info.make({
|
||||
name: "review",
|
||||
template: "Second",
|
||||
description: "Review code",
|
||||
|
|
@ -39,7 +39,7 @@ describe("CommandV2", () => {
|
|||
}),
|
||||
)
|
||||
expect(yield* command.list()).toEqual([
|
||||
new CommandV2.Info({
|
||||
CommandV2.Info.make({
|
||||
name: "review",
|
||||
template: "Second",
|
||||
description: "Review code",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ Review files`,
|
|||
)
|
||||
|
||||
expect(yield* command.list()).toEqual([
|
||||
new CommandV2.Info({
|
||||
CommandV2.Info.make({
|
||||
name: "review",
|
||||
template: "Review files",
|
||||
description: "File review",
|
||||
|
|
@ -71,8 +71,8 @@ Review files`,
|
|||
},
|
||||
subtask: true,
|
||||
}),
|
||||
new CommandV2.Info({ name: "empty", template: "" }),
|
||||
new CommandV2.Info({ name: "nested/docs", template: "Write docs" }),
|
||||
CommandV2.Info.make({ name: "empty", template: "" }),
|
||||
CommandV2.Info.make({ name: "nested/docs", template: "Write docs" }),
|
||||
])
|
||||
}),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -59,21 +59,21 @@ describe("ConfigSkillPlugin.Plugin", () => {
|
|||
)
|
||||
|
||||
expect(sources).toEqual([
|
||||
new SkillV2.DirectorySource({
|
||||
SkillV2.DirectorySource.make({
|
||||
type: "directory",
|
||||
path: AbsolutePath.make(path.join("/repo/.opencode", "skill")),
|
||||
}),
|
||||
new SkillV2.DirectorySource({
|
||||
SkillV2.DirectorySource.make({
|
||||
type: "directory",
|
||||
path: AbsolutePath.make(path.join("/repo/.opencode", "skills")),
|
||||
}),
|
||||
new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make(path.join(directory, "skills")) }),
|
||||
new SkillV2.DirectorySource({
|
||||
SkillV2.DirectorySource.make({ type: "directory", path: AbsolutePath.make(path.join(directory, "skills")) }),
|
||||
SkillV2.DirectorySource.make({
|
||||
type: "directory",
|
||||
path: AbsolutePath.make(path.join("/home/test", "shared-skills")),
|
||||
}),
|
||||
new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make("/opt/skills") }),
|
||||
new SkillV2.UrlSource({ type: "url", url: "https://example.test/skills/" }),
|
||||
SkillV2.DirectorySource.make({ type: "directory", path: AbsolutePath.make("/opt/skills") }),
|
||||
SkillV2.UrlSource.make({ type: "url", url: "https://example.test/skills/" }),
|
||||
])
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ describe("Credential", () => {
|
|||
const created = yield* credentials.create({
|
||||
integrationID,
|
||||
label: "Work",
|
||||
value: new Credential.Key({ type: "key", key: "secret" }),
|
||||
value: Credential.Key.make({ type: "key", key: "secret" }),
|
||||
})
|
||||
|
||||
expect(yield* credentials.list(integrationID)).toEqual([created])
|
||||
|
|
@ -24,7 +24,7 @@ describe("Credential", () => {
|
|||
const replacement = yield* credentials.create({
|
||||
integrationID,
|
||||
label: "Replacement",
|
||||
value: new Credential.Key({ type: "key", key: "replacement" }),
|
||||
value: Credential.Key.make({ type: "key", key: "replacement" }),
|
||||
})
|
||||
expect(yield* credentials.list(integrationID)).toEqual([replacement])
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@ import { EventV2 } from "@opencode-ai/core/event"
|
|||
import { Database } from "@opencode-ai/core/database/database"
|
||||
import { EventSequenceTable, EventTable } from "@opencode-ai/core/event/sql"
|
||||
import { Location } from "@opencode-ai/core/location"
|
||||
import { AbsolutePath } from "@opencode-ai/core/schema"
|
||||
import { AbsolutePath, DateTimeUtcFromMillis } from "@opencode-ai/core/schema"
|
||||
import { WorkspaceV2 } from "@opencode-ai/core/workspace"
|
||||
import { V2Schema } from "@opencode-ai/core/v2-schema"
|
||||
import { eq } from "drizzle-orm"
|
||||
import { location } from "./fixture/location"
|
||||
import { testEffect } from "./lib/effect"
|
||||
|
|
@ -79,24 +78,11 @@ const SyncTimestamp = EventV2.define({
|
|||
},
|
||||
schema: {
|
||||
id: Schema.String,
|
||||
timestamp: V2Schema.DateTimeUtcFromMillis,
|
||||
timestamp: DateTimeUtcFromMillis,
|
||||
},
|
||||
})
|
||||
|
||||
describe("EventV2", () => {
|
||||
it.effect("derives stable namespaced external IDs", () =>
|
||||
Effect.sync(() => {
|
||||
const input = { namespace: "opencord.agent-input", key: "input-1" }
|
||||
|
||||
expect(EventV2.ID.fromExternal(input)).toBe(EventV2.ID.fromExternal(input))
|
||||
expect(EventV2.ID.fromExternal(input)).toMatch(/^evt_[a-f0-9]{64}$/)
|
||||
expect(EventV2.ID.fromExternal({ ...input, namespace: "another-app" })).not.toBe(EventV2.ID.fromExternal(input))
|
||||
expect(EventV2.ID.fromExternal({ namespace: "a:b", key: "c" })).not.toBe(
|
||||
EventV2.ID.fromExternal({ namespace: "a", key: "b:c" }),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("publishes events with the current location", () =>
|
||||
Effect.gen(function* () {
|
||||
const events = yield* EventV2.Service
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ describe("Integration", () => {
|
|||
expect.objectContaining({
|
||||
integrationID,
|
||||
label: "Work",
|
||||
value: new Credential.Key({ type: "key", key: "secret" }),
|
||||
value: Credential.Key.make({ type: "key", key: "secret" }),
|
||||
}),
|
||||
])
|
||||
expect((yield* Fiber.join(updated)).length).toBe(1)
|
||||
|
|
@ -149,7 +149,7 @@ describe("Integration", () => {
|
|||
instructions: "Paste the code",
|
||||
callback: (code: string) =>
|
||||
Effect.succeed(
|
||||
new Credential.OAuth({
|
||||
Credential.OAuth.make({
|
||||
type: "oauth",
|
||||
methodID,
|
||||
access: "access",
|
||||
|
|
@ -175,7 +175,7 @@ describe("Integration", () => {
|
|||
expect.objectContaining({
|
||||
integrationID,
|
||||
label: "Personal",
|
||||
value: new Credential.OAuth({
|
||||
value: Credential.OAuth.make({
|
||||
type: "oauth",
|
||||
methodID,
|
||||
access: "access",
|
||||
|
|
@ -238,7 +238,7 @@ describe("Integration", () => {
|
|||
url: "https://example.com/authorize",
|
||||
instructions: "Sign in",
|
||||
callback: Effect.succeed(
|
||||
new Credential.OAuth({ type: "oauth", methodID, access: "access", refresh: "refresh", expires: 1 }),
|
||||
Credential.OAuth.make({ type: "oauth", methodID, access: "access", refresh: "refresh", expires: 1 }),
|
||||
),
|
||||
}),
|
||||
}),
|
||||
|
|
@ -315,12 +315,12 @@ describe("Integration", () => {
|
|||
const work = yield* credentials.create({
|
||||
integrationID,
|
||||
label: "Work",
|
||||
value: new Credential.Key({ type: "key", key: "a" }),
|
||||
value: Credential.Key.make({ type: "key", key: "a" }),
|
||||
})
|
||||
const personal = yield* credentials.create({
|
||||
integrationID,
|
||||
label: "Personal",
|
||||
value: new Credential.Key({ type: "key", key: "b" }),
|
||||
value: Credential.Key.make({ type: "key", key: "b" }),
|
||||
})
|
||||
|
||||
// Stored credentials and detected env vars appear as connections.
|
||||
|
|
|
|||
|
|
@ -52,14 +52,28 @@ const it = testEffect(
|
|||
)
|
||||
|
||||
describe("LocationServiceMap", () => {
|
||||
it.effect("compares equivalent location refs by value", () =>
|
||||
Effect.sync(() => {
|
||||
const directory = AbsolutePath.make("/project")
|
||||
expect(Equal.equals(Location.Ref.make({ directory }), Location.Ref.make({ directory }))).toBe(true)
|
||||
expect(Hash.hash(Location.Ref.make({ directory }))).toBe(
|
||||
Hash.hash(Location.Ref.make({ directory, workspaceID: undefined })),
|
||||
)
|
||||
}),
|
||||
it.live("reuses cached services for constructed and decoded location refs", () =>
|
||||
Effect.acquireRelease(
|
||||
Effect.promise(() => tmpdir()),
|
||||
(dir) => Effect.promise(() => dir[Symbol.asyncDispose]()),
|
||||
).pipe(
|
||||
Effect.flatMap((dir) =>
|
||||
Effect.scoped(
|
||||
Effect.gen(function* () {
|
||||
const locations = yield* LocationServiceMap
|
||||
const directory = AbsolutePath.make(dir.path)
|
||||
const constructed = Location.Ref.make({ directory })
|
||||
const decoded = Schema.decodeUnknownSync(Location.Ref)({ directory })
|
||||
|
||||
expect(constructed).toEqual({ directory, workspaceID: undefined })
|
||||
expect(decoded).toEqual(constructed)
|
||||
expect(Equal.equals(constructed, decoded)).toBe(true)
|
||||
expect(Hash.hash(constructed)).toBe(Hash.hash(decoded))
|
||||
expect(yield* locations.contextEffect(constructed)).toBe(yield* locations.contextEffect(decoded))
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
it.live("isolates location state while sharing location policy with catalog", () =>
|
||||
|
|
|
|||
|
|
@ -176,12 +176,11 @@ export function integrationHost(integration: Integration.Interface): PluginConte
|
|||
return {
|
||||
...authorization,
|
||||
callback: authorization.callback.pipe(
|
||||
Effect.map(
|
||||
(credential) =>
|
||||
new Credential.OAuth({
|
||||
...credential,
|
||||
methodID: Integration.MethodID.make(credential.methodID),
|
||||
}),
|
||||
Effect.map((credential) =>
|
||||
Credential.OAuth.make({
|
||||
...credential,
|
||||
methodID: Integration.MethodID.make(credential.methodID),
|
||||
}),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
|
@ -190,12 +189,11 @@ export function integrationHost(integration: Integration.Interface): PluginConte
|
|||
...authorization,
|
||||
callback: (code: string) =>
|
||||
authorization.callback(code).pipe(
|
||||
Effect.map(
|
||||
(credential) =>
|
||||
new Credential.OAuth({
|
||||
...credential,
|
||||
methodID: Integration.MethodID.make(credential.methodID),
|
||||
}),
|
||||
Effect.map((credential) =>
|
||||
Credential.OAuth.make({
|
||||
...credential,
|
||||
methodID: Integration.MethodID.make(credential.methodID),
|
||||
}),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
|
@ -205,12 +203,11 @@ export function integrationHost(integration: Integration.Interface): PluginConte
|
|||
? {
|
||||
refresh: (value: Credential.OAuth) =>
|
||||
refresh(value).pipe(
|
||||
Effect.map(
|
||||
(next) =>
|
||||
new Credential.OAuth({
|
||||
...next,
|
||||
methodID: Integration.MethodID.make(next.methodID),
|
||||
}),
|
||||
Effect.map((next) =>
|
||||
Credential.OAuth.make({
|
||||
...next,
|
||||
methodID: Integration.MethodID.make(next.methodID),
|
||||
}),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ describe("AlibabaPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("alibaba"), ModelV2.ID.make("qwen")),
|
||||
api: { id: ModelV2.ID.make("qwen"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -43,7 +43,7 @@ describe("AlibabaPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("alibaba"), ModelV2.ID.make("qwen")),
|
||||
api: { id: ModelV2.ID.make("qwen"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -60,7 +60,7 @@ describe("AlibabaPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-alibaba"), ModelV2.ID.make("qwen")),
|
||||
api: { id: ModelV2.ID.make("qwen"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -79,7 +79,7 @@ describe("AlibabaPlugin", () => {
|
|||
const plugin = yield* PluginV2.Service
|
||||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const item = new ModelV2.Info({
|
||||
const item = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("alibaba"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("qwen-plus"), type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const bedrock = new ProviderV2.Info({
|
||||
const bedrock = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.amazonBedrock),
|
||||
api: { type: "aisdk", package: "@ai-sdk/amazon-bedrock" },
|
||||
request: {
|
||||
|
|
@ -114,7 +114,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -139,7 +139,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -173,7 +173,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"),
|
||||
|
|
@ -197,7 +197,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -216,7 +216,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -235,7 +235,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -255,7 +255,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const headers: Array<string | null> = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -284,7 +284,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const headers: Array<string | null> = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -312,7 +312,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("openai.gpt-5.5")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("openai.gpt-5.5"),
|
||||
|
|
@ -343,7 +343,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("openai.gpt-5.5")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("openai.gpt-5.5"),
|
||||
|
|
@ -355,7 +355,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
options: { baseURL: "https://bedrock-mantle.us-east-2.api.aws/openai/v1", region: "us-east-2" },
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("openai.gpt-oss-safeguard-120b")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("openai.gpt-oss-safeguard-120b"),
|
||||
|
|
@ -376,7 +376,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"),
|
||||
|
|
@ -407,7 +407,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const headers: Array<string | null> = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"),
|
||||
|
|
@ -442,7 +442,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -450,7 +450,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -458,7 +458,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
options: { region: "eu-west-1" },
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("global.anthropic.claude-sonnet-4-5")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("global.anthropic.claude-sonnet-4-5"),
|
||||
|
|
@ -470,7 +470,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
options: { region: "eu-west-1" },
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -478,7 +478,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
options: { region: "ap-northeast-1" },
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -503,7 +503,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -589,7 +589,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
yield* addPlugin()
|
||||
for (const item of cases) {
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make(item.modelID)),
|
||||
api: { id: ModelV2.ID.make(item.modelID), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -608,7 +608,7 @@ describe("AmazonBedrockPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("anthropic.claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe("AnthropicPlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const item = new ProviderV2.Info({
|
||||
const item = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.anthropic),
|
||||
api: { type: "aisdk", package: "@ai-sdk/anthropic" },
|
||||
request: { headers: { Existing: "1" }, body: {} },
|
||||
|
|
@ -64,7 +64,7 @@ describe("AnthropicPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-anthropic"), ModelV2.ID.make("claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-5"), type: "aisdk", package: "@ai-sdk/anthropic" },
|
||||
}),
|
||||
|
|
@ -81,7 +81,7 @@ describe("AnthropicPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-5"), type: "aisdk", package: "@ai-sdk/anthropic" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -87,11 +87,11 @@ describe("AzureCognitiveServicesPlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const azure = new ProviderV2.Info({
|
||||
const azure = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services")),
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible" },
|
||||
})
|
||||
const openai = new ProviderV2.Info({
|
||||
const openai = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.openai),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
|
|
@ -120,7 +120,7 @@ describe("AzureCognitiveServicesPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -138,7 +138,7 @@ describe("AzureCognitiveServicesPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -146,7 +146,7 @@ describe("AzureCognitiveServicesPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
const ignored = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -166,7 +166,7 @@ describe("AzureCognitiveServicesPlugin", () => {
|
|||
const sdk = fakeSelectorSdk(calls)
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("messages-deployment")),
|
||||
api: { id: ModelV2.ID.make("messages-deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -174,7 +174,7 @@ describe("AzureCognitiveServicesPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("chat-deployment")),
|
||||
api: { id: ModelV2.ID.make("chat-deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -182,7 +182,7 @@ describe("AzureCognitiveServicesPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("language-deployment")),
|
||||
api: { id: ModelV2.ID.make("language-deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ describe("AzurePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const azure = new ProviderV2.Info({
|
||||
const azure = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.azure),
|
||||
api: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
request: { headers: {}, body: { resourceName: "from-config" } },
|
||||
|
|
@ -103,7 +103,7 @@ describe("AzurePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const azure = new ProviderV2.Info({
|
||||
const azure = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.azure),
|
||||
api: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
request: { headers: {}, body: { resourceName: "" } },
|
||||
|
|
@ -124,7 +124,7 @@ describe("AzurePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const azure = new ProviderV2.Info({
|
||||
const azure = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.azure),
|
||||
api: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
request: { headers: {}, body: { resourceName: " " } },
|
||||
|
|
@ -147,7 +147,7 @@ describe("AzurePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -166,7 +166,7 @@ describe("AzurePlugin", () => {
|
|||
yield* addPlugin()
|
||||
const exit = yield* aisdk
|
||||
.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -186,7 +186,7 @@ describe("AzurePlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -204,7 +204,7 @@ describe("AzurePlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -222,7 +222,7 @@ describe("AzurePlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
request: { headers: {}, body: { useCompletionUrls: true } },
|
||||
|
|
@ -241,7 +241,7 @@ describe("AzurePlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -249,7 +249,7 @@ describe("AzurePlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
const ignored = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("deployment")),
|
||||
api: { id: ModelV2.ID.make("deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -272,7 +272,7 @@ describe("AzurePlugin", () => {
|
|||
}
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("messages-deployment")),
|
||||
api: { id: ModelV2.ID.make("messages-deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -280,7 +280,7 @@ describe("AzurePlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("language-deployment")),
|
||||
api: { id: ModelV2.ID.make("language-deployment"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ describe("CerebrasPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(
|
||||
ProviderV2.ID.make("custom-cerebras"),
|
||||
ModelV2.ID.make("llama-4-scout-17b-16e-instruct"),
|
||||
|
|
@ -90,7 +90,7 @@ describe("CerebrasPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(
|
||||
ProviderV2.ID.make("custom-cerebras"),
|
||||
ModelV2.ID.make("llama-4-scout-17b-16e-instruct"),
|
||||
|
|
@ -115,7 +115,7 @@ describe("CerebrasPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(
|
||||
ProviderV2.ID.make("custom-cerebras"),
|
||||
ModelV2.ID.make("llama-4-scout-17b-16e-instruct"),
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -137,7 +137,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -181,7 +181,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -210,7 +210,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -247,7 +247,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -278,7 +278,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -300,7 +300,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -323,7 +323,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -352,7 +352,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -375,7 +375,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(
|
||||
ProviderV2.ID.make("cloudflare-ai-gateway"),
|
||||
ModelV2.ID.make("anthropic/claude-sonnet-4-5"),
|
||||
|
|
@ -410,7 +410,7 @@ describe("CloudflareAIGatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
|||
yield* addPlugin()
|
||||
const provider = required(yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai")))
|
||||
const sdk = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")),
|
||||
api: { id: ModelV2.ID.make("@cf/model"), ...provider.api },
|
||||
}),
|
||||
|
|
@ -136,7 +136,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("@cf/model"),
|
||||
|
|
@ -180,7 +180,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("@cf/model"),
|
||||
|
|
@ -212,7 +212,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("@cf/model"),
|
||||
|
|
@ -241,7 +241,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("@cf/api-model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -260,7 +260,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("@cf/model"),
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ describe("CoherePlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const ignored = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cohere"), ModelV2.ID.make("command")),
|
||||
api: { id: ModelV2.ID.make("command"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -64,7 +64,7 @@ describe("CoherePlugin", () => {
|
|||
expect(ignored.sdk).toBeUndefined()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cohere"), ModelV2.ID.make("command")),
|
||||
api: { id: ModelV2.ID.make("command"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -81,7 +81,7 @@ describe("CoherePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-cohere"), ModelV2.ID.make("command-r-plus")),
|
||||
api: { id: ModelV2.ID.make("command-r-plus"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -106,7 +106,7 @@ describe("CoherePlugin", () => {
|
|||
const sdk = fakeSelectorSdk(calls)
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cohere"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("command-r-plus"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ describe("DeepInfraPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "@ai-sdk/deepinfra" },
|
||||
}),
|
||||
|
|
@ -64,7 +64,7 @@ describe("DeepInfraPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-deepinfra"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "@ai-sdk/deepinfra" },
|
||||
}),
|
||||
|
|
@ -83,7 +83,7 @@ describe("DeepInfraPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "@ai-sdk/deepinfra" },
|
||||
}),
|
||||
|
|
@ -109,7 +109,7 @@ describe("DeepInfraPlugin", () => {
|
|||
yield* Effect.forEach(packages, (item) =>
|
||||
Effect.gen(function* () {
|
||||
const ignored = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "@ai-sdk/deepinfra" },
|
||||
}),
|
||||
|
|
@ -120,7 +120,7 @@ describe("DeepInfraPlugin", () => {
|
|||
}),
|
||||
)
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "@ai-sdk/deepinfra" },
|
||||
}),
|
||||
|
|
@ -139,7 +139,7 @@ describe("DeepInfraPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const sdkEvent = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("meta-llama/Llama-3.3-70B-Instruct")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("meta-llama/Llama-3.3-70B-Instruct"),
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")),
|
||||
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
|
||||
}),
|
||||
|
|
@ -69,7 +69,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
const sdk = { marker: "existing" }
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")),
|
||||
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
|
||||
}),
|
||||
|
|
@ -86,7 +86,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-provider"), ModelV2.ID.make("test-model")),
|
||||
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
|
||||
}),
|
||||
|
|
@ -102,7 +102,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin(npmEntrypoint(fixtureProviderPath))
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("npm-provider"), ModelV2.ID.make("test-model")),
|
||||
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: "fixture-provider" },
|
||||
}),
|
||||
|
|
@ -119,7 +119,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
yield* addPlugin(npmEntrypoint())
|
||||
const exit = yield* aisdk
|
||||
.language(
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("missing-entrypoint"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("alias"), type: "aisdk", package: "fixture-provider" },
|
||||
}),
|
||||
|
|
@ -136,7 +136,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
yield* addPlugin()
|
||||
const exit = yield* aisdk
|
||||
.language(
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("bad-import"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("alias"), type: "aisdk", package: "file:///missing/provider-factory.js" },
|
||||
}),
|
||||
|
|
@ -155,7 +155,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
yield* addPlugin(npmEntrypoint(tmp.entrypoint))
|
||||
const exit = yield* aisdk
|
||||
.language(
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("missing-factory"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("alias"), type: "aisdk", package: "fixture-provider" },
|
||||
}),
|
||||
|
|
@ -172,7 +172,7 @@ describe("DynamicProviderPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const language = yield* aisdk.language(
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("test-model-api"), type: "aisdk", package: fixtureProvider },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ describe("GatewayPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gateway"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -63,7 +63,7 @@ describe("GatewayPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("vercel"), ModelV2.ID.make("anthropic/claude-sonnet-4")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("anthropic/claude-sonnet-4"),
|
||||
|
|
@ -89,7 +89,7 @@ describe("GatewayPlugin", () => {
|
|||
|
||||
for (const modelID of vercelGatewayModels) {
|
||||
const ignored = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("vercel"), ModelV2.ID.make(modelID)),
|
||||
api: { id: ModelV2.ID.make(modelID), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -99,7 +99,7 @@ describe("GatewayPlugin", () => {
|
|||
expect(ignored.sdk).toBeUndefined()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("vercel"), ModelV2.ID.make(modelID)),
|
||||
api: { id: ModelV2.ID.make(modelID), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const ignored = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -53,7 +53,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
options: { name: "github-copilot" },
|
||||
})
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -72,7 +72,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("claude-sonnet-4")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -90,7 +90,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -108,7 +108,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -116,7 +116,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5.1-codex")),
|
||||
api: { id: ModelV2.ID.make("gpt-5.1-codex"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -124,7 +124,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-4o")),
|
||||
api: { id: ModelV2.ID.make("gpt-4o"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -132,7 +132,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-mini")),
|
||||
api: { id: ModelV2.ID.make("gpt-5-mini"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -140,7 +140,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-mini-2025-08-07")),
|
||||
api: { id: ModelV2.ID.make("gpt-5-mini-2025-08-07"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -164,7 +164,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("default")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -172,7 +172,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("small")),
|
||||
api: { id: ModelV2.ID.make("gpt-5-mini"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -180,7 +180,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("sonnet")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -228,7 +228,7 @@ describe("GithubCopilotPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("openai"), ModelV2.ID.make("gpt-5")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ describe("GitLabPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")),
|
||||
api: { id: ModelV2.ID.make("claude"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -105,7 +105,7 @@ describe("GitLabPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")),
|
||||
api: { id: ModelV2.ID.make("claude"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -130,7 +130,7 @@ describe("GitLabPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")),
|
||||
api: { id: ModelV2.ID.make("claude"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -171,7 +171,7 @@ describe("GitLabPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")),
|
||||
api: { id: ModelV2.ID.make("claude"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -190,7 +190,7 @@ describe("GitLabPlugin", () => {
|
|||
const calls: [string, unknown][] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("duo-workflow-custom")),
|
||||
api: { id: ModelV2.ID.make("duo-workflow-custom"), type: "aisdk", package: "test-provider" },
|
||||
request: {
|
||||
|
|
@ -225,7 +225,7 @@ describe("GitLabPlugin", () => {
|
|||
const calls: [string, unknown][] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("duo-workflow-exact")),
|
||||
api: { id: ModelV2.ID.make("duo-workflow-exact"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -252,7 +252,7 @@ describe("GitLabPlugin", () => {
|
|||
const calls: [string, unknown][] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("duo-workflow-custom")),
|
||||
api: { id: ModelV2.ID.make("duo-workflow-custom"), type: "aisdk", package: "test-provider" },
|
||||
request: {
|
||||
|
|
@ -280,7 +280,7 @@ describe("GitLabPlugin", () => {
|
|||
const calls: [string, unknown][] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")),
|
||||
api: { id: ModelV2.ID.make("claude"), type: "aisdk", package: "test-provider" },
|
||||
request: { headers: { h: "v" }, body: {} },
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin(GoogleVertexAnthropicPlugin)
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(
|
||||
ProviderV2.ID.make("google-vertex-anthropic"),
|
||||
ModelV2.ID.make("claude-sonnet-4-5"),
|
||||
|
|
@ -142,7 +142,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin(GoogleVertexAnthropicPlugin)
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(
|
||||
ProviderV2.ID.make("google-vertex-anthropic"),
|
||||
ModelV2.ID.make("claude-sonnet-4-5"),
|
||||
|
|
@ -165,7 +165,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin(GoogleVertexAnthropicPlugin)
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -184,7 +184,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin(GoogleVertexAnthropicPlugin)
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -202,7 +202,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
yield* addPlugin(GoogleVertexPlugin)
|
||||
yield* addPlugin(GoogleVertexAnthropicPlugin)
|
||||
const sdkResult = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make(" claude-sonnet-4-5 ")),
|
||||
api: { id: ModelV2.ID.make(" claude-sonnet-4-5 "), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -210,7 +210,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
options: { name: "google-vertex", project: "project", location: "us" },
|
||||
})
|
||||
const languageResult = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make(" claude-sonnet-4-5 ")),
|
||||
api: { id: ModelV2.ID.make(" claude-sonnet-4-5 "), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -232,7 +232,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin(GoogleVertexAnthropicPlugin)
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex-anthropic"), ModelV2.ID.make(" claude-sonnet-4-5 ")),
|
||||
api: { id: ModelV2.ID.make(" claude-sonnet-4-5 "), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -250,7 +250,7 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin(GoogleVertexAnthropicPlugin)
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("claude-sonnet-4-5")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ describe("GoogleVertexPlugin", () => {
|
|||
yield* addPlugin()
|
||||
const provider = required(yield* catalog.provider.get(ProviderV2.ID.make("google-vertex")))
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("gemini")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("gemini"),
|
||||
|
|
@ -295,7 +295,7 @@ describe("GoogleVertexPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("gemini")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("gemini"),
|
||||
|
|
@ -343,7 +343,7 @@ describe("GoogleVertexPlugin", () => {
|
|||
Effect.void,
|
||||
() =>
|
||||
aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("gemini")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("gemini"),
|
||||
|
|
@ -374,7 +374,7 @@ describe("GoogleVertexPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make(" gemini-2.5-pro ")),
|
||||
api: { id: ModelV2.ID.make(" gemini-2.5-pro "), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ describe("GooglePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-google"), ModelV2.ID.make("gemini")),
|
||||
api: { id: ModelV2.ID.make("gemini"), type: "aisdk", package: "@ai-sdk/google" },
|
||||
}),
|
||||
|
|
@ -43,7 +43,7 @@ describe("GooglePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("google"), ModelV2.ID.make("gemini")),
|
||||
api: { id: ModelV2.ID.make("gemini"), type: "aisdk", package: "@ai-sdk/google" },
|
||||
}),
|
||||
|
|
@ -60,7 +60,7 @@ describe("GooglePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const sdkEvent = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-google"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("gemini-api"), type: "aisdk", package: "@ai-sdk/google" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ describe("GroqPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("llama")),
|
||||
api: { id: ModelV2.ID.make("llama"), type: "aisdk", package: "@ai-sdk/groq" },
|
||||
}),
|
||||
|
|
@ -43,7 +43,7 @@ describe("GroqPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("llama")),
|
||||
api: { id: ModelV2.ID.make("llama"), type: "aisdk", package: "@ai-sdk/groq" },
|
||||
}),
|
||||
|
|
@ -60,7 +60,7 @@ describe("GroqPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("llama")),
|
||||
api: { id: ModelV2.ID.make("llama"), type: "aisdk", package: "@ai-sdk/groq" },
|
||||
}),
|
||||
|
|
@ -77,7 +77,7 @@ describe("GroqPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-groq"), ModelV2.ID.make("llama")),
|
||||
api: { id: ModelV2.ID.make("llama"), type: "aisdk", package: "@ai-sdk/groq" },
|
||||
}),
|
||||
|
|
@ -102,7 +102,7 @@ describe("GroqPlugin", () => {
|
|||
name: string
|
||||
})
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("alias")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("llama-api"),
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ describe("MistralPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("mistral-large")),
|
||||
api: { id: ModelV2.ID.make("mistral-large"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -43,7 +43,7 @@ describe("MistralPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("mistral-large")),
|
||||
api: { id: ModelV2.ID.make("mistral-large"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -66,7 +66,7 @@ describe("MistralPlugin", () => {
|
|||
}),
|
||||
)
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("mistral-large")),
|
||||
api: { id: ModelV2.ID.make("mistral-large"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -90,7 +90,7 @@ describe("MistralPlugin", () => {
|
|||
}),
|
||||
)
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-mistral"), ModelV2.ID.make("mistral-large")),
|
||||
api: { id: ModelV2.ID.make("mistral-large"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -114,7 +114,7 @@ describe("MistralPlugin", () => {
|
|||
}
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("mistral-large"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ describe("OpenAICompatiblePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const defaulted = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -33,7 +33,7 @@ describe("OpenAICompatiblePlugin", () => {
|
|||
options: { name: "custom" },
|
||||
})
|
||||
const disabled = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -51,7 +51,7 @@ describe("OpenAICompatiblePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -74,7 +74,7 @@ describe("OpenAICompatiblePlugin", () => {
|
|||
}),
|
||||
)
|
||||
yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-provider"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -94,7 +94,7 @@ describe("OpenAICompatiblePlugin", () => {
|
|||
})
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ describe("OpenAIPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-openai"), ModelV2.ID.make("gpt-5")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -82,7 +82,7 @@ describe("OpenAIPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("gpt-5")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -100,7 +100,7 @@ describe("OpenAIPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -119,7 +119,7 @@ describe("OpenAIPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.anthropic, ModelV2.ID.make("gpt-5")),
|
||||
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -135,7 +135,7 @@ describe("OpenAIPlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const item = new ProviderV2.Info({
|
||||
const item = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.openai),
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai" },
|
||||
})
|
||||
|
|
@ -157,7 +157,7 @@ describe("OpenAIPlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const item = new ProviderV2.Info({
|
||||
const item = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.make("custom-openai")),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ describe("OpencodePlugin", () => {
|
|||
})
|
||||
yield* credentials.create({
|
||||
integrationID: Integration.ID.make("opencode"),
|
||||
value: new Credential.Key({
|
||||
value: Credential.Key.make({
|
||||
type: "key",
|
||||
key: "secret",
|
||||
metadata: { server: server.url.origin },
|
||||
|
|
@ -176,11 +176,11 @@ describe("OpencodePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const provider = new ProviderV2.Info({
|
||||
const provider = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.opencode),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
const model = new ModelV2.Info({
|
||||
const model = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")),
|
||||
api: { id: ModelV2.ID.make("paid"), type: "aisdk", package: "test-provider" },
|
||||
cost: cost(1),
|
||||
|
|
@ -202,11 +202,11 @@ describe("OpencodePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const provider = new ProviderV2.Info({
|
||||
const provider = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.opencode),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
const model = new ModelV2.Info({
|
||||
const model = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(provider.id, ModelV2.ID.make("free")),
|
||||
api: { id: ModelV2.ID.make("free"), type: "aisdk", package: "test-provider" },
|
||||
cost: cost(0),
|
||||
|
|
@ -228,11 +228,11 @@ describe("OpencodePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const provider = new ProviderV2.Info({
|
||||
const provider = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.opencode),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
const model = new ModelV2.Info({
|
||||
const model = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(provider.id, ModelV2.ID.make("output-only")),
|
||||
api: { id: ModelV2.ID.make("output-only"), type: "aisdk", package: "test-provider" },
|
||||
cost: cost(0, 1),
|
||||
|
|
@ -256,11 +256,11 @@ describe("OpencodePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const provider = new ProviderV2.Info({
|
||||
const provider = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.opencode),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
const model = new ModelV2.Info({
|
||||
const model = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")),
|
||||
api: { id: ModelV2.ID.make("paid"), type: "aisdk", package: "test-provider" },
|
||||
cost: cost(1),
|
||||
|
|
@ -289,11 +289,11 @@ describe("OpencodePlugin", () => {
|
|||
})
|
||||
})
|
||||
yield* catalog.transform((catalog) => {
|
||||
const provider = new ProviderV2.Info({
|
||||
const provider = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.opencode),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
const model = new ModelV2.Info({
|
||||
const model = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")),
|
||||
api: { id: ModelV2.ID.make("paid"), type: "aisdk", package: "test-provider" },
|
||||
cost: cost(1),
|
||||
|
|
@ -315,7 +315,7 @@ describe("OpencodePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const provider = new ProviderV2.Info({
|
||||
const provider = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.opencode),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
request: {
|
||||
|
|
@ -323,7 +323,7 @@ describe("OpencodePlugin", () => {
|
|||
body: { apiKey: "configured" },
|
||||
},
|
||||
})
|
||||
const model = new ModelV2.Info({
|
||||
const model = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")),
|
||||
api: { id: ModelV2.ID.make("paid"), type: "aisdk", package: "test-provider" },
|
||||
cost: cost(1),
|
||||
|
|
@ -347,11 +347,11 @@ describe("OpencodePlugin", () => {
|
|||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
const provider = new ProviderV2.Info({
|
||||
const provider = ProviderV2.Info.make({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.openai),
|
||||
api: { type: "aisdk", package: "test-provider" },
|
||||
})
|
||||
const model = new ModelV2.Info({
|
||||
const model = ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")),
|
||||
api: { id: ModelV2.ID.make("paid"), type: "aisdk", package: "test-provider" },
|
||||
cost: cost(1),
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ describe("OpenRouterPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const ignored = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.openrouter, ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -63,7 +63,7 @@ describe("OpenRouterPlugin", () => {
|
|||
expect(ignored.sdk).toBeUndefined()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("openai/gpt-5")),
|
||||
api: { id: ModelV2.ID.make("openai/gpt-5"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ describe("PerplexityPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("sonar")),
|
||||
api: { id: ModelV2.ID.make("sonar"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -56,7 +56,7 @@ describe("PerplexityPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("sonar")),
|
||||
api: { id: ModelV2.ID.make("sonar"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -73,7 +73,7 @@ describe("PerplexityPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("sonar")),
|
||||
api: { id: ModelV2.ID.make("sonar"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -90,7 +90,7 @@ describe("PerplexityPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-perplexity"), ModelV2.ID.make("sonar")),
|
||||
api: { id: ModelV2.ID.make("sonar"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -108,7 +108,7 @@ describe("PerplexityPlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("sonar"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ function withEnv<A, E, R>(vars: Record<string, string | undefined>, effect: () =
|
|||
}
|
||||
|
||||
function model(providerID: string) {
|
||||
return new ModelV2.Info({
|
||||
return ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make(providerID), ModelV2.ID.make("sap-model")),
|
||||
api: { id: ModelV2.ID.make("sap-model"), type: "aisdk", package: fixtureProvider },
|
||||
})
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ describe("SnowflakeCortexPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("openai"), ModelV2.ID.make("gpt-4")),
|
||||
api: { id: ModelV2.ID.make("gpt-4"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -73,7 +73,7 @@ describe("SnowflakeCortexPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-6"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -92,7 +92,7 @@ describe("SnowflakeCortexPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-6"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -115,7 +115,7 @@ describe("SnowflakeCortexPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-6"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -134,7 +134,7 @@ describe("SnowflakeCortexPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-6"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -157,7 +157,7 @@ describe("SnowflakeCortexPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")),
|
||||
api: { id: ModelV2.ID.make("claude-sonnet-4-6"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ describe("TogetherAIPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("togetherai"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -57,7 +57,7 @@ describe("TogetherAIPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const ignored = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("togetherai"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -67,7 +67,7 @@ describe("TogetherAIPlugin", () => {
|
|||
expect(ignored.sdk).toBeUndefined()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("togetherai"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -85,7 +85,7 @@ describe("TogetherAIPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-togetherai"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -105,7 +105,7 @@ describe("TogetherAIPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(
|
||||
ProviderV2.ID.make("togetherai"),
|
||||
ModelV2.ID.make("meta-llama/Llama-3.3-70B-Instruct-Turbo"),
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ describe("VenicePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -56,7 +56,7 @@ describe("VenicePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-venice"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -74,7 +74,7 @@ describe("VenicePlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const similar = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -82,7 +82,7 @@ describe("VenicePlugin", () => {
|
|||
options: { name: "venice" },
|
||||
})
|
||||
const other = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")),
|
||||
api: { id: ModelV2.ID.make("model"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
@ -101,7 +101,7 @@ describe("VenicePlugin", () => {
|
|||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("alias"), type: "aisdk", package: "test-provider" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ describe("VercelPlugin", () => {
|
|||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const event = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-vercel"), ModelV2.ID.make("v0-1.0-md")),
|
||||
api: { id: ModelV2.ID.make("v0-1.0-md"), type: "aisdk", package: "@ai-sdk/vercel" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ describe("XAIPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const ignored = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")),
|
||||
api: { id: ModelV2.ID.make("grok-4"), type: "aisdk", package: "@ai-sdk/xai" },
|
||||
}),
|
||||
|
|
@ -49,7 +49,7 @@ describe("XAIPlugin", () => {
|
|||
})
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")),
|
||||
api: { id: ModelV2.ID.make("grok-4"), type: "aisdk", package: "@ai-sdk/xai" },
|
||||
}),
|
||||
|
|
@ -69,7 +69,7 @@ describe("XAIPlugin", () => {
|
|||
yield* addPlugin()
|
||||
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("custom-xai"), ModelV2.ID.make("grok-4")),
|
||||
api: { id: ModelV2.ID.make("grok-4"), type: "aisdk", package: "@ai-sdk/xai" },
|
||||
}),
|
||||
|
|
@ -89,7 +89,7 @@ describe("XAIPlugin", () => {
|
|||
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("alias")),
|
||||
api: { id: ModelV2.ID.make("grok-4"), type: "aisdk", package: "@ai-sdk/xai" },
|
||||
}),
|
||||
|
|
@ -110,7 +110,7 @@ describe("XAIPlugin", () => {
|
|||
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runLanguage({
|
||||
model: new ModelV2.Info({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("grok-4")),
|
||||
api: { id: ModelV2.ID.make("grok-4"), type: "aisdk", package: "@ai-sdk/xai" },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ describe("ReferenceGuidance", () => {
|
|||
name: "docs",
|
||||
path: AbsolutePath.make("/docs"),
|
||||
description: "Use for product documentation",
|
||||
source: new Reference.LocalSource({
|
||||
source: Reference.LocalSource.make({
|
||||
type: "local",
|
||||
path: AbsolutePath.make("/docs"),
|
||||
description: "Use for product documentation",
|
||||
|
|
@ -63,7 +63,7 @@ describe("ReferenceGuidance", () => {
|
|||
new Reference.Info({
|
||||
name: "docs",
|
||||
path: AbsolutePath.make("/docs"),
|
||||
source: new Reference.LocalSource({ type: "local", path: AbsolutePath.make("/docs") }),
|
||||
source: Reference.LocalSource.make({ type: "local", path: AbsolutePath.make("/docs") }),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ describe("Reference", () => {
|
|||
const references = yield* Reference.Service
|
||||
const scope = yield* Scope.make()
|
||||
const path = AbsolutePath.make("/docs")
|
||||
const source = new Reference.LocalSource({
|
||||
const source = Reference.LocalSource.make({
|
||||
type: "local",
|
||||
path,
|
||||
description: "Use for API documentation",
|
||||
|
|
@ -44,7 +44,7 @@ describe("Reference", () => {
|
|||
Effect.gen(function* () {
|
||||
const references = yield* Reference.Service
|
||||
const repository = Repository.parseRemote("owner/repo")
|
||||
const source = new Reference.GitSource({ type: "git", repository: "owner/repo", branch: "main" })
|
||||
const source = Reference.GitSource.make({ type: "git", repository: "owner/repo", branch: "main" })
|
||||
yield* references.transform((editor) => editor.add("sdk", source))
|
||||
|
||||
expect(yield* references.list()).toEqual([
|
||||
|
|
@ -67,7 +67,7 @@ describe("Reference", () => {
|
|||
Effect.gen(function* () {
|
||||
const references = yield* Reference.Service
|
||||
const repository = Repository.parseRemote("owner/repo")
|
||||
const source = new Reference.GitSource({
|
||||
const source = Reference.GitSource.make({
|
||||
type: "git",
|
||||
repository: "owner/repo",
|
||||
description: "Use for SDK implementation details",
|
||||
|
|
|
|||
|
|
@ -55,21 +55,6 @@ const location = Location.Ref.make({ directory: AbsolutePath.make("/project") })
|
|||
const id = SessionV2.ID.create()
|
||||
|
||||
describe("SessionV2.create", () => {
|
||||
it.effect("derives stable namespaced external IDs", () =>
|
||||
Effect.sync(() => {
|
||||
const input = { namespace: "opencord.agent-thread", key: "thread-1" }
|
||||
|
||||
expect(SessionV2.ID.fromExternal(input)).toBe(SessionV2.ID.fromExternal(input))
|
||||
expect(SessionV2.ID.fromExternal(input)).toMatch(/^ses_[a-f0-9]{64}$/)
|
||||
expect(SessionV2.ID.fromExternal({ ...input, namespace: "another-app" })).not.toBe(
|
||||
SessionV2.ID.fromExternal(input),
|
||||
)
|
||||
expect(SessionV2.ID.fromExternal({ namespace: "a:b", key: "c" })).not.toBe(
|
||||
SessionV2.ID.fromExternal({ namespace: "a", key: "b:c" }),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("creates a fresh projected session when the ID is omitted", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* SessionV2.Service
|
||||
|
|
@ -218,7 +203,7 @@ describe("SessionV2.create", () => {
|
|||
const events = yield* EventV2.Service
|
||||
const { db } = yield* Database.Service
|
||||
const created = yield* session.create({ location })
|
||||
yield* session.prompt({ sessionID: created.id, prompt: new Prompt({ text: "Hello" }), resume: false })
|
||||
yield* session.prompt({ sessionID: created.id, prompt: Prompt.make({ text: "Hello" }), resume: false })
|
||||
yield* SessionInput.promoteSteers(db, events, created.id, Number.MAX_SAFE_INTEGER)
|
||||
|
||||
expect(
|
||||
|
|
@ -238,7 +223,7 @@ describe("SessionV2.create", () => {
|
|||
const created = yield* session.create({ id: SessionV2.ID.make("ses_fresh_target_replay"), location })
|
||||
const admitted = yield* session.prompt({
|
||||
sessionID: created.id,
|
||||
prompt: new Prompt({ text: "Replay lifecycle" }),
|
||||
prompt: Prompt.make({ text: "Replay lifecycle" }),
|
||||
resume: false,
|
||||
})
|
||||
yield* SessionInput.promoteSteers(sourceDb, sourceEvents, created.id, Number.MAX_SAFE_INTEGER)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ const assistantRow = (
|
|||
id: _,
|
||||
type,
|
||||
...data
|
||||
} = encodeMessage(new SessionMessage.Assistant({ id, type: "assistant", agent: "build", model, content: [], time }))
|
||||
} = encodeMessage(SessionMessage.Assistant.make({ id, type: "assistant", agent: "build", model, content: [], time }))
|
||||
return { id, session_id: sessionID, type, seq, time_created: DateTime.toEpochMillis(time.created), data }
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ describe("SessionProjector", () => {
|
|||
sessionID,
|
||||
messageID: SessionMessage.ID.make("msg_first"),
|
||||
timestamp: created,
|
||||
prompt: new Prompt({ text: "first" }),
|
||||
prompt: Prompt.make({ text: "first" }),
|
||||
delivery: "steer",
|
||||
},
|
||||
{ id: EventV2.ID.make("evt_z") },
|
||||
|
|
@ -80,7 +80,7 @@ describe("SessionProjector", () => {
|
|||
sessionID,
|
||||
messageID: SessionMessage.ID.make("msg_second"),
|
||||
timestamp: created,
|
||||
prompt: new Prompt({ text: "second" }),
|
||||
prompt: Prompt.make({ text: "second" }),
|
||||
delivery: "steer",
|
||||
},
|
||||
{ id: EventV2.ID.make("evt_a") },
|
||||
|
|
@ -145,7 +145,7 @@ describe("SessionProjector", () => {
|
|||
const admitted = yield* SessionInput.admit(db, events, {
|
||||
id,
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "promote me" }),
|
||||
prompt: Prompt.make({ text: "promote me" }),
|
||||
delivery: "steer",
|
||||
})
|
||||
if (!admitted) return yield* Effect.die("Prompt admission failed")
|
||||
|
|
@ -154,7 +154,7 @@ describe("SessionProjector", () => {
|
|||
sessionID,
|
||||
timestamp: admitted.timeCreated,
|
||||
messageID: id,
|
||||
prompt: new Prompt({ text: "promote me" }),
|
||||
prompt: Prompt.make({ text: "promote me" }),
|
||||
delivery: "steer",
|
||||
})
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ describe("SessionProjector", () => {
|
|||
|
||||
it.effect("does not revive a stale incomplete in-memory assistant projection", () =>
|
||||
Effect.gen(function* () {
|
||||
const stale = new SessionMessage.Assistant({
|
||||
const stale = SessionMessage.Assistant.make({
|
||||
id: SessionMessage.ID.make("msg_assistant_stale"),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
|
|
@ -342,7 +342,7 @@ describe("SessionProjector", () => {
|
|||
content: [],
|
||||
time: { created },
|
||||
})
|
||||
const completed = new SessionMessage.Assistant({
|
||||
const completed = SessionMessage.Assistant.make({
|
||||
id: SessionMessage.ID.make("msg_assistant_completed"),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
|
|
@ -466,15 +466,15 @@ describe("SessionProjector", () => {
|
|||
Schema.decodeUnknownSync(SessionMessage.Message)({ ...row.data, id: row.id, type: row.type }),
|
||||
)
|
||||
expect(messages).toEqual([
|
||||
new SessionMessage.Assistant({
|
||||
SessionMessage.Assistant.make({
|
||||
id: SessionMessage.ID.make("msg_assistant_completed"),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
model,
|
||||
content: [new SessionMessage.AssistantText({ type: "text", id: "text-stale", text: "" })],
|
||||
content: [SessionMessage.AssistantText.make({ type: "text", id: "text-stale", text: "" })],
|
||||
time: { created: DateTime.makeUnsafe(1), completed: DateTime.makeUnsafe(2) },
|
||||
}),
|
||||
new SessionMessage.Assistant({
|
||||
SessionMessage.Assistant.make({
|
||||
id: SessionMessage.ID.make("msg_assistant_stale"),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ describe("SessionV2.prompt", () => {
|
|||
|
||||
const message = yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Fix the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Fix the failing tests" }),
|
||||
resume: false,
|
||||
})
|
||||
|
||||
|
|
@ -171,8 +171,8 @@ describe("SessionV2.prompt", () => {
|
|||
const fiber = yield* session.events({ sessionID }).pipe(Stream.take(4), Stream.runCollect, Effect.forkScoped)
|
||||
yield* Effect.yieldNow
|
||||
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* SessionInput.promoteSteers(db, events, sessionID, Number.MAX_SAFE_INTEGER)
|
||||
const streamed = Array.from(yield* Fiber.join(fiber))
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ describe("SessionV2.prompt", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
const message = yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Fix the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Fix the failing tests" }),
|
||||
resume: false,
|
||||
})
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ describe("SessionV2.prompt", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const input = { sessionID, prompt: new Prompt({ text: "Fix the failing tests" }), resume: false }
|
||||
const input = { sessionID, prompt: Prompt.make({ text: "Fix the failing tests" }), resume: false }
|
||||
|
||||
const first = yield* session.prompt(input)
|
||||
const second = yield* session.prompt(input)
|
||||
|
|
@ -235,7 +235,7 @@ describe("SessionV2.prompt", () => {
|
|||
const input = {
|
||||
sessionID,
|
||||
id: messageID,
|
||||
prompt: new Prompt({ text: "Fix the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Fix the failing tests" }),
|
||||
resume: false,
|
||||
}
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ describe("SessionV2.prompt", () => {
|
|||
const input = {
|
||||
sessionID,
|
||||
id: messageID,
|
||||
prompt: new Prompt({ text: "Recover committed prompt" }),
|
||||
prompt: Prompt.make({ text: "Recover committed prompt" }),
|
||||
resume: false,
|
||||
}
|
||||
const first = yield* session.prompt(input)
|
||||
|
|
@ -276,13 +276,13 @@ describe("SessionV2.prompt", () => {
|
|||
yield* session.prompt({
|
||||
sessionID,
|
||||
id: messageID,
|
||||
prompt: new Prompt({ text: "Fix the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Fix the failing tests" }),
|
||||
})
|
||||
const failure = yield* session
|
||||
.prompt({
|
||||
sessionID,
|
||||
id: messageID,
|
||||
prompt: new Prompt({ text: "Delete the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Delete the failing tests" }),
|
||||
resume: false,
|
||||
})
|
||||
.pipe(Effect.flip)
|
||||
|
|
@ -301,14 +301,14 @@ describe("SessionV2.prompt", () => {
|
|||
yield* session.prompt({
|
||||
id: messageID,
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Fix the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Fix the failing tests" }),
|
||||
resume: false,
|
||||
})
|
||||
const failure = yield* session
|
||||
.prompt({
|
||||
id: messageID,
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Fix the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Fix the failing tests" }),
|
||||
delivery: "queue",
|
||||
resume: false,
|
||||
})
|
||||
|
|
@ -325,7 +325,7 @@ describe("SessionV2.prompt", () => {
|
|||
const input = {
|
||||
sessionID,
|
||||
id: messageID,
|
||||
prompt: new Prompt({ text: "Fix the failing tests" }),
|
||||
prompt: Prompt.make({ text: "Fix the failing tests" }),
|
||||
resume: false,
|
||||
}
|
||||
|
||||
|
|
@ -344,7 +344,7 @@ describe("SessionV2.prompt", () => {
|
|||
const { db } = yield* Database.Service
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt: new Prompt({ text: "Promote once" }), resume: false })
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt: Prompt.make({ text: "Promote once" }), resume: false })
|
||||
|
||||
yield* Effect.all(
|
||||
[
|
||||
|
|
@ -368,9 +368,9 @@ describe("SessionV2.prompt", () => {
|
|||
const { db } = yield* Database.Service
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
const first = yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Before cutoff" }), resume: false })
|
||||
const first = yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Before cutoff" }), resume: false })
|
||||
const cutoff = first.admittedSeq
|
||||
const second = yield* session.prompt({ sessionID, prompt: new Prompt({ text: "After cutoff" }), resume: false })
|
||||
const second = yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "After cutoff" }), resume: false })
|
||||
|
||||
yield* SessionInput.promoteSteers(db, events, sessionID, cutoff)
|
||||
|
||||
|
|
@ -386,7 +386,12 @@ describe("SessionV2.prompt", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
wakeCalls.length = 0
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt: new Prompt({ text: "Replay pending" }), resume: false })
|
||||
yield* session.prompt({
|
||||
id: messageID,
|
||||
sessionID,
|
||||
prompt: Prompt.make({ text: "Replay pending" }),
|
||||
resume: false,
|
||||
})
|
||||
const recorded = yield* db
|
||||
.select()
|
||||
.from(EventTable)
|
||||
|
|
@ -422,7 +427,7 @@ describe("SessionV2.prompt", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
const prompt = new Prompt({ text: "Historical prompt" })
|
||||
const prompt = Prompt.make({ text: "Historical prompt" })
|
||||
yield* events.publish(SessionEvent.Prompted, {
|
||||
sessionID,
|
||||
messageID,
|
||||
|
|
@ -443,7 +448,7 @@ describe("SessionV2.prompt", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
const prompt = new Prompt({ text: "Historical queued prompt" })
|
||||
const prompt = Prompt.make({ text: "Historical queued prompt" })
|
||||
yield* events.publish(SessionEvent.Prompted, {
|
||||
sessionID,
|
||||
messageID,
|
||||
|
|
@ -478,7 +483,7 @@ describe("SessionV2.prompt", () => {
|
|||
.onConflictDoNothing()
|
||||
.run()
|
||||
.pipe(Effect.orDie)
|
||||
const prompt = new Prompt({ text: "Fix the failing tests" })
|
||||
const prompt = Prompt.make({ text: "Fix the failing tests" })
|
||||
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt, resume: false })
|
||||
const failure = yield* session
|
||||
|
|
@ -502,7 +507,7 @@ describe("SessionV2.prompt", () => {
|
|||
})
|
||||
|
||||
const failure = yield* session
|
||||
.prompt({ id: messageID, sessionID, prompt: new Prompt({ text: "Conflicting prompt" }), resume: false })
|
||||
.prompt({ id: messageID, sessionID, prompt: Prompt.make({ text: "Conflicting prompt" }), resume: false })
|
||||
.pipe(Effect.flip)
|
||||
|
||||
expect(failure).toMatchObject({ _tag: "Session.PromptConflictError", sessionID, messageID })
|
||||
|
|
@ -517,7 +522,7 @@ describe("SessionV2.prompt", () => {
|
|||
executionCalls.length = 0
|
||||
wakeCalls.length = 0
|
||||
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Run by default" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Run by default" }) })
|
||||
|
||||
expect(executionCalls).toEqual([])
|
||||
expect(wakeCalls).toEqual([sessionID])
|
||||
|
|
@ -533,7 +538,7 @@ describe("SessionV2.prompt", () => {
|
|||
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Run explicitly" }),
|
||||
prompt: Prompt.make({ text: "Run explicitly" }),
|
||||
resume: true,
|
||||
})
|
||||
|
||||
|
|
@ -549,7 +554,7 @@ describe("SessionV2.prompt", () => {
|
|||
executionCalls.length = 0
|
||||
wakeCalls.length = 0
|
||||
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Do not run" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Do not run" }), resume: false })
|
||||
|
||||
expect(executionCalls).toEqual([])
|
||||
expect(wakeCalls).toEqual([])
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ const model = Model.make({ id: "model", provider: "provider", route: OpenAIChat.
|
|||
describe("toLLMMessages", () => {
|
||||
test("omits empty assistant turns", () => {
|
||||
const assistant = (value: string, content: SessionMessage.Assistant["content"]) =>
|
||||
new SessionMessage.Assistant({
|
||||
SessionMessage.Assistant.make({
|
||||
id: id(value),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
|
|
@ -27,13 +27,13 @@ describe("toLLMMessages", () => {
|
|||
const messages = toLLMMessages(
|
||||
[
|
||||
assistant("empty", []),
|
||||
assistant("empty-text", [new SessionMessage.AssistantText({ type: "text", id: "empty", text: "" })]),
|
||||
assistant("empty-text", [SessionMessage.AssistantText.make({ type: "text", id: "empty", text: "" })]),
|
||||
assistant("empty-reasoning", [
|
||||
new SessionMessage.AssistantReasoning({ type: "reasoning", id: "empty-reasoning", text: "" }),
|
||||
SessionMessage.AssistantReasoning.make({ type: "reasoning", id: "empty-reasoning", text: "" }),
|
||||
]),
|
||||
assistant("text", [new SessionMessage.AssistantText({ type: "text", id: "text", text: "Partial" })]),
|
||||
assistant("text", [SessionMessage.AssistantText.make({ type: "text", id: "text", text: "Partial" })]),
|
||||
assistant("reasoning", [
|
||||
new SessionMessage.AssistantReasoning({
|
||||
SessionMessage.AssistantReasoning.make({
|
||||
type: "reasoning",
|
||||
id: "reasoning",
|
||||
text: "",
|
||||
|
|
@ -48,43 +48,43 @@ describe("toLLMMessages", () => {
|
|||
})
|
||||
|
||||
test("maps every top-level V2 Session message type", () => {
|
||||
const file = new FileAttachment({ uri: "data:image/png;base64,aGVsbG8=", mime: "image/png", name: "hello.png" })
|
||||
const file = FileAttachment.make({ uri: "data:image/png;base64,aGVsbG8=", mime: "image/png", name: "hello.png" })
|
||||
const messages = toLLMMessages(
|
||||
[
|
||||
new SessionMessage.AgentSwitched({
|
||||
SessionMessage.AgentSwitched.make({
|
||||
id: id("agent"),
|
||||
type: "agent-switched",
|
||||
agent: "build",
|
||||
time: { created },
|
||||
}),
|
||||
new SessionMessage.ModelSwitched({
|
||||
SessionMessage.ModelSwitched.make({
|
||||
id: id("model"),
|
||||
type: "model-switched",
|
||||
model: { id: ModelV2.ID.make("model"), providerID: ProviderV2.ID.make("provider") },
|
||||
time: { created },
|
||||
}),
|
||||
new SessionMessage.System({
|
||||
SessionMessage.System.make({
|
||||
id: id("system"),
|
||||
type: "system",
|
||||
text: "Updated context\n\nOther context",
|
||||
time: { created },
|
||||
}),
|
||||
new SessionMessage.User({
|
||||
SessionMessage.User.make({
|
||||
id: id("user"),
|
||||
type: "user",
|
||||
text: "Inspect this image",
|
||||
files: [file],
|
||||
agents: [new AgentAttachment({ name: "build" })],
|
||||
agents: [AgentAttachment.make({ name: "build" })],
|
||||
time: { created },
|
||||
}),
|
||||
new SessionMessage.Synthetic({
|
||||
SessionMessage.Synthetic.make({
|
||||
id: id("synthetic"),
|
||||
type: "synthetic",
|
||||
sessionID: SessionV2.ID.make("ses_translate"),
|
||||
text: "Synthetic context",
|
||||
time: { created },
|
||||
}),
|
||||
new SessionMessage.Shell({
|
||||
SessionMessage.Shell.make({
|
||||
id: id("shell"),
|
||||
type: "shell",
|
||||
callID: "shell-1",
|
||||
|
|
@ -92,7 +92,7 @@ describe("toLLMMessages", () => {
|
|||
output: "/project",
|
||||
time: { created, completed: created },
|
||||
}),
|
||||
new SessionMessage.Compaction({
|
||||
SessionMessage.Compaction.make({
|
||||
id: id("compaction"),
|
||||
type: "compaction",
|
||||
reason: "auto",
|
||||
|
|
@ -142,31 +142,31 @@ Recent work
|
|||
test("replays durable tool media into canonical tool messages without structured base64", () => {
|
||||
const messages = toLLMMessages(
|
||||
[
|
||||
new SessionMessage.Assistant({
|
||||
SessionMessage.Assistant.make({
|
||||
id: id("assistant"),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
model: { id: ModelV2.ID.make("model"), providerID: ProviderV2.ID.make("provider") },
|
||||
content: [
|
||||
new SessionMessage.AssistantText({ type: "text", id: "text-1", text: "Checking" }),
|
||||
new SessionMessage.AssistantReasoning({
|
||||
SessionMessage.AssistantText.make({ type: "text", id: "text-1", text: "Checking" }),
|
||||
SessionMessage.AssistantReasoning.make({
|
||||
type: "reasoning",
|
||||
id: "reasoning-1",
|
||||
text: "Think",
|
||||
providerMetadata: { anthropic: { signature: "sig_1" } },
|
||||
}),
|
||||
new SessionMessage.AssistantTool({
|
||||
SessionMessage.AssistantTool.make({
|
||||
type: "tool",
|
||||
id: "pending",
|
||||
name: "read",
|
||||
state: new SessionMessage.ToolStatePending({ status: "pending", input: '{"path":"README.md"}' }),
|
||||
state: SessionMessage.ToolStatePending.make({ status: "pending", input: '{"path":"README.md"}' }),
|
||||
time: { created },
|
||||
}),
|
||||
new SessionMessage.AssistantTool({
|
||||
SessionMessage.AssistantTool.make({
|
||||
type: "tool",
|
||||
id: "running",
|
||||
name: "read",
|
||||
state: new SessionMessage.ToolStateRunning({
|
||||
state: SessionMessage.ToolStateRunning.make({
|
||||
status: "running",
|
||||
input: { path: "README.md" },
|
||||
content: [],
|
||||
|
|
@ -174,11 +174,11 @@ Recent work
|
|||
}),
|
||||
time: { created },
|
||||
}),
|
||||
new SessionMessage.AssistantTool({
|
||||
SessionMessage.AssistantTool.make({
|
||||
type: "tool",
|
||||
id: "completed",
|
||||
name: "read",
|
||||
state: new SessionMessage.ToolStateCompleted({
|
||||
state: SessionMessage.ToolStateCompleted.make({
|
||||
status: "completed",
|
||||
input: { path: "README.md" },
|
||||
content: [
|
||||
|
|
@ -194,7 +194,7 @@ Recent work
|
|||
}),
|
||||
time: { created, completed: created },
|
||||
}),
|
||||
new SessionMessage.AssistantTool({
|
||||
SessionMessage.AssistantTool.make({
|
||||
type: "tool",
|
||||
id: "hosted",
|
||||
name: "web_search",
|
||||
|
|
@ -203,7 +203,7 @@ Recent work
|
|||
metadata: { fake: { continuation: "hosted-call" } },
|
||||
resultMetadata: { fake: { continuation: "hosted-result" } },
|
||||
},
|
||||
state: new SessionMessage.ToolStateCompleted({
|
||||
state: SessionMessage.ToolStateCompleted.make({
|
||||
status: "completed",
|
||||
input: { query: "Effect" },
|
||||
content: [{ type: "text", text: "Found it" }],
|
||||
|
|
@ -211,12 +211,12 @@ Recent work
|
|||
}),
|
||||
time: { created, completed: created },
|
||||
}),
|
||||
new SessionMessage.AssistantTool({
|
||||
SessionMessage.AssistantTool.make({
|
||||
type: "tool",
|
||||
id: "hosted-failed",
|
||||
name: "write",
|
||||
provider: { executed: true, metadata: { fake: { continuation: "failed" } } },
|
||||
state: new SessionMessage.ToolStateError({
|
||||
state: SessionMessage.ToolStateError.make({
|
||||
status: "error",
|
||||
input: { path: "README.md" },
|
||||
content: [],
|
||||
|
|
@ -299,13 +299,13 @@ Recent work
|
|||
test("restores OpenAI encrypted reasoning metadata", () => {
|
||||
const messages = toLLMMessages(
|
||||
[
|
||||
new SessionMessage.Assistant({
|
||||
SessionMessage.Assistant.make({
|
||||
id: id("assistant-openai-reasoning"),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
model: { id: ModelV2.ID.make("model"), providerID: ProviderV2.ID.make("provider") },
|
||||
content: [
|
||||
new SessionMessage.AssistantReasoning({
|
||||
SessionMessage.AssistantReasoning.make({
|
||||
type: "reasoning",
|
||||
id: "reasoning-openai",
|
||||
text: "Think",
|
||||
|
|
@ -330,19 +330,19 @@ Recent work
|
|||
test("drops provider-native continuation metadata after a model switch", () => {
|
||||
const messages = toLLMMessages(
|
||||
[
|
||||
new SessionMessage.Assistant({
|
||||
SessionMessage.Assistant.make({
|
||||
id: id("assistant-old-model"),
|
||||
type: "assistant",
|
||||
agent: "build",
|
||||
model: { id: ModelV2.ID.make("old-model"), providerID: ProviderV2.ID.make("provider") },
|
||||
content: [
|
||||
new SessionMessage.AssistantReasoning({
|
||||
SessionMessage.AssistantReasoning.make({
|
||||
type: "reasoning",
|
||||
id: "reasoning-old-model",
|
||||
text: "Visible thought",
|
||||
providerMetadata: { anthropic: { signature: "sig_old" } },
|
||||
}),
|
||||
new SessionMessage.AssistantTool({
|
||||
SessionMessage.AssistantTool.make({
|
||||
type: "tool",
|
||||
id: "hosted-old-model",
|
||||
name: "web_search",
|
||||
|
|
@ -351,7 +351,7 @@ Recent work
|
|||
metadata: { openai: { itemId: "hosted-old-model" } },
|
||||
resultMetadata: { openai: { itemId: "hosted-old-model" } },
|
||||
},
|
||||
state: new SessionMessage.ToolStateCompleted({
|
||||
state: SessionMessage.ToolStateCompleted.make({
|
||||
status: "completed",
|
||||
input: { query: "Effect" },
|
||||
content: [],
|
||||
|
|
@ -360,7 +360,7 @@ Recent work
|
|||
}),
|
||||
time: { created, completed: created },
|
||||
}),
|
||||
new SessionMessage.AssistantTool({
|
||||
SessionMessage.AssistantTool.make({
|
||||
type: "tool",
|
||||
id: "local-old-model",
|
||||
name: "read",
|
||||
|
|
@ -369,7 +369,7 @@ Recent work
|
|||
metadata: { fake: { call: "old" } },
|
||||
resultMetadata: { fake: { result: "old" } },
|
||||
},
|
||||
state: new SessionMessage.ToolStateCompleted({
|
||||
state: SessionMessage.ToolStateCompleted.make({
|
||||
status: "completed",
|
||||
input: { path: "README.md" },
|
||||
content: [],
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ type Api =
|
|||
| { readonly type: "native"; readonly url?: string; readonly settings: Record<string, unknown> }
|
||||
|
||||
const model = (api: Api, variants: ModelV2.Info["variants"] = []) =>
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
id: ModelV2.ID.make("test-model"),
|
||||
providerID: ProviderV2.ID.make("test-provider"),
|
||||
name: "Test model",
|
||||
|
|
@ -79,7 +79,7 @@ describe("SessionRunnerModel", () => {
|
|||
it.effect("uses merged API settings for OpenAI-compatible auth and request defaults", () =>
|
||||
Effect.gen(function* () {
|
||||
const resolved = yield* SessionRunnerModel.fromCatalogModel(
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
...model({
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
|
|
@ -114,7 +114,7 @@ describe("SessionRunnerModel", () => {
|
|||
options: { reasoningEffort: "high" },
|
||||
},
|
||||
])
|
||||
const catalog = new ModelV2.Info({
|
||||
const catalog = ModelV2.Info.make({
|
||||
...base,
|
||||
request: { ...base.request, options: { ...base.request.options, reasoningEffort: "medium" } },
|
||||
})
|
||||
|
|
@ -264,11 +264,11 @@ describe("SessionRunnerModel", () => {
|
|||
it.effect("uses resolved credentials for bearer auth", () =>
|
||||
Effect.gen(function* () {
|
||||
const resolved = yield* SessionRunnerModel.fromCatalogModel(
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
...model({ type: "aisdk", package: "@ai-sdk/openai", url: "https://openai.example/v1" }),
|
||||
request: { headers: {}, body: {}, generation: {}, options: {} },
|
||||
}),
|
||||
new Credential.Key({ type: "key", key: "secret" }),
|
||||
Credential.Key.make({ type: "key", key: "secret" }),
|
||||
)
|
||||
const request = LLM.request({ model: resolved, prompt: "Hello" })
|
||||
const headers = yield* resolved.route.auth.apply({
|
||||
|
|
@ -285,9 +285,9 @@ describe("SessionRunnerModel", () => {
|
|||
|
||||
it.effect("prefers stored credentials over configured auth", () =>
|
||||
Effect.gen(function* () {
|
||||
const credential = new Credential.Key({ type: "key", key: "stored-secret", metadata: { tenant: "work" } })
|
||||
const credential = Credential.Key.make({ type: "key", key: "stored-secret", metadata: { tenant: "work" } })
|
||||
const resolved = yield* SessionRunnerModel.fromCatalogModel(
|
||||
new ModelV2.Info({
|
||||
ModelV2.Info.make({
|
||||
...model({ type: "aisdk", package: "@ai-sdk/openai", url: "https://openai.example/v1" }),
|
||||
request: { headers: {}, body: { apiKey: "configured-secret" }, generation: {}, options: {} },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ describe("SessionRunnerLLM recorded", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
const prompt = yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Say hello in one short sentence." }),
|
||||
prompt: Prompt.make({ text: "Say hello in one short sentence." }),
|
||||
resume: false,
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import { SessionMessage } from "@opencode-ai/core/session/message"
|
|||
import { Prompt } from "@opencode-ai/core/session/prompt"
|
||||
import { SessionProjector } from "@opencode-ai/core/session/projector"
|
||||
import { SessionExecution } from "@opencode-ai/core/session/execution"
|
||||
import { SessionContextEpoch } from "@opencode-ai/core/session/context-epoch"
|
||||
import { SessionRunCoordinator } from "@opencode-ai/core/session/run-coordinator"
|
||||
import { SessionRunner } from "@opencode-ai/core/session/runner"
|
||||
import * as SessionRunnerLLM from "@opencode-ai/core/session/runner/llm"
|
||||
|
|
@ -351,7 +350,7 @@ const setupOverflowRecovery = Effect.gen(function* () {
|
|||
response = fragmentFixture("text", "text-earlier", ["Earlier answer"]).completeEvents
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Earlier question ".repeat(700) }),
|
||||
prompt: Prompt.make({ text: "Earlier question ".repeat(700) }),
|
||||
resume: false,
|
||||
})
|
||||
yield* session.resume(sessionID)
|
||||
|
|
@ -476,7 +475,7 @@ const verifyEphemeralDeltas = (kind: FragmentKind) =>
|
|||
const chunks = Array.from({ length: 32 }, (_, index) => `${index},`)
|
||||
const fixture = fragmentFixture(kind, fragmentID(kind, "many"), chunks)
|
||||
const expectedContext = [{ type: "user", text: prompt }, fixture.expectedAssistant]
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: prompt }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })
|
||||
const events = yield* EventV2.Service
|
||||
const live = yield* events.subscribe(fixture.delta).pipe(Stream.take(32), Stream.runCollect, Effect.forkScoped)
|
||||
yield* Effect.yieldNow
|
||||
|
|
@ -507,7 +506,7 @@ const verifyPartialFlushOnFailure = (kind: FragmentKind) =>
|
|||
const prompt = `Fail after ${kind}`
|
||||
const fixture = fragmentFixture(kind, fragmentID(kind, "partial"), ["Partial"])
|
||||
const failure = providerUnavailable()
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: prompt }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })
|
||||
responseStream = Stream.concat(Stream.fromIterable(fixture.partialEvents), Stream.fail(failure))
|
||||
|
||||
expect(yield* session.resume(sessionID).pipe(Effect.flip)).toBe(failure)
|
||||
|
|
@ -529,7 +528,7 @@ const verifyPartialFlushOnInterruption = (kind: FragmentKind) =>
|
|||
const prompt = `Interrupt after ${kind}`
|
||||
const fixture = fragmentFixture(kind, fragmentID(kind, "interrupted"), ["Partial"])
|
||||
const streamed = yield* Deferred.make<void>()
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: prompt }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })
|
||||
responseStream = Stream.concat(
|
||||
Stream.fromIterable(fixture.partialEvents),
|
||||
Stream.fromEffect(Deferred.succeed(streamed, undefined)).pipe(Stream.flatMap(() => Stream.never)),
|
||||
|
|
@ -573,7 +572,7 @@ describe("SessionRunnerLLM", () => {
|
|||
}),
|
||||
}),
|
||||
})
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Use application context" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Use application context" }), resume: false })
|
||||
responses = [
|
||||
[
|
||||
LLMEvent.stepStart({ index: 0 }),
|
||||
|
|
@ -621,7 +620,7 @@ describe("SessionRunnerLLM", () => {
|
|||
streamStarted = undefined
|
||||
response = []
|
||||
|
||||
const message = yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Run automatically" }) })
|
||||
const message = yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Run automatically" }) })
|
||||
|
||||
expect(requests).toHaveLength(1)
|
||||
expect(yield* session.messages({ sessionID })).toMatchObject([
|
||||
|
|
@ -634,8 +633,8 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = undefined
|
||||
|
|
@ -662,7 +661,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const { db } = yield* Database.Service
|
||||
const messageID = SessionMessage.ID.create()
|
||||
systemUnavailable = true
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
requests.length = 0
|
||||
|
||||
const exit = yield* session.resume(sessionID).pipe(Effect.exit)
|
||||
|
|
@ -680,7 +679,7 @@ describe("SessionRunnerLLM", () => {
|
|||
).toBeUndefined()
|
||||
|
||||
systemUnavailable = false
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt: new Prompt({ text: "First" }) })
|
||||
yield* session.prompt({ id: messageID, sessionID, prompt: Prompt.make({ text: "First" }) })
|
||||
|
||||
expect(requests).toHaveLength(1)
|
||||
expect(requests[0]?.messages.map((message) => message.role)).toEqual(["user"])
|
||||
|
|
@ -693,7 +692,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
const { db } = yield* Database.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
requests.length = 0
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
|
|
@ -711,7 +710,7 @@ describe("SessionRunnerLLM", () => {
|
|||
.get(),
|
||||
).toBeUndefined()
|
||||
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
const exit = yield* session.resume(sessionID).pipe(Effect.exit)
|
||||
|
||||
expect(Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause)).toBe(true)
|
||||
|
|
@ -725,7 +724,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const { db } = yield* Database.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
yield* db
|
||||
|
|
@ -734,7 +733,7 @@ describe("SessionRunnerLLM", () => {
|
|||
.where(eq(SessionContextEpochTable.session_id, sessionID))
|
||||
.run()
|
||||
.pipe(Effect.orDie)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
requests.length = 0
|
||||
|
||||
const exit = yield* session.resume(sessionID).pipe(Effect.exit)
|
||||
|
|
@ -749,13 +748,13 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
systemBaseline = "Changed context"
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests.map((request) => request.system.map((part) => part.text))).toEqual([
|
||||
|
|
@ -790,7 +789,7 @@ describe("SessionRunnerLLM", () => {
|
|||
}),
|
||||
)
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = fragmentFixture("text", "text-build", ["Done"]).completeEvents
|
||||
|
|
@ -816,7 +815,7 @@ describe("SessionRunnerLLM", () => {
|
|||
editor.default(AgentV2.ID.make("reviewer"))
|
||||
})
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = fragmentFixture("text", "text-reviewer", ["Done"]).completeEvents
|
||||
|
|
@ -845,7 +844,7 @@ describe("SessionRunnerLLM", () => {
|
|||
.run()
|
||||
.pipe(Effect.orDie)
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = fragmentFixture("text", "text-selected", ["Done"]).completeEvents
|
||||
|
|
@ -862,7 +861,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
skillBaselines.set(AgentV2.ID.make("build"), "Build skills")
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
|
|
@ -874,7 +873,7 @@ describe("SessionRunnerLLM", () => {
|
|||
timestamp: DateTime.makeUnsafe(1),
|
||||
agent: "reviewer",
|
||||
})
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests.map((request) => request.system.map((part) => part.text))).toEqual([
|
||||
|
|
@ -905,7 +904,7 @@ describe("SessionRunnerLLM", () => {
|
|||
})
|
||||
.pipe(Effect.asVoid)
|
||||
})
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
|
|
@ -935,7 +934,7 @@ describe("SessionRunnerLLM", () => {
|
|||
})
|
||||
.pipe(Effect.asVoid)
|
||||
})
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
|
|
@ -949,13 +948,13 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
systemRemoved = true
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests[1]?.messages.map((message) => message.role)).toEqual(["user", "user", "system"])
|
||||
|
|
@ -971,13 +970,13 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
systemBaseline = "Changed context"
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
yield* events.publish(SessionEvent.ModelSwitched, {
|
||||
sessionID,
|
||||
|
|
@ -986,7 +985,7 @@ describe("SessionRunnerLLM", () => {
|
|||
model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") },
|
||||
})
|
||||
systemBaseline = "Replacement context"
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Third" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Third" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests.map((request) => request.system.map((part) => part.text))).toEqual([
|
||||
|
|
@ -1006,7 +1005,7 @@ describe("SessionRunnerLLM", () => {
|
|||
])
|
||||
yield* replaySessionProjection(sessionID)
|
||||
expect(yield* session.messages({ sessionID })).toHaveLength(6)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Fourth" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Fourth" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
}),
|
||||
)
|
||||
|
|
@ -1016,7 +1015,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
|
|
@ -1028,11 +1027,11 @@ describe("SessionRunnerLLM", () => {
|
|||
model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") },
|
||||
})
|
||||
systemUnavailable = true
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
systemUnavailable = false
|
||||
systemBaseline = "Replacement context"
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Third" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Third" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests.map((request) => request.system.map((part) => part.text))).toEqual([
|
||||
|
|
@ -1048,7 +1047,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
|
|
@ -1069,7 +1068,7 @@ describe("SessionRunnerLLM", () => {
|
|||
recent: "",
|
||||
})
|
||||
systemBaseline = "Replacement context"
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests.map((request) => request.system.map((part) => part.text))).toEqual([
|
||||
|
|
@ -1077,7 +1076,7 @@ describe("SessionRunnerLLM", () => {
|
|||
["Replacement context"],
|
||||
])
|
||||
yield* replaySessionProjection(sessionID)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Third" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Third" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
}),
|
||||
)
|
||||
|
|
@ -1089,7 +1088,7 @@ describe("SessionRunnerLLM", () => {
|
|||
response = fragmentFixture("text", "text-first", ["Earlier answer"]).completeEvents
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Earlier question ".repeat(180) }),
|
||||
prompt: Prompt.make({ text: "Earlier question ".repeat(180) }),
|
||||
resume: false,
|
||||
})
|
||||
yield* session.resume(sessionID)
|
||||
|
|
@ -1102,7 +1101,7 @@ describe("SessionRunnerLLM", () => {
|
|||
]
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Recent exact request ".repeat(180) }),
|
||||
prompt: Prompt.make({ text: "Recent exact request ".repeat(180) }),
|
||||
resume: false,
|
||||
})
|
||||
yield* session.resume(sessionID)
|
||||
|
|
@ -1128,7 +1127,7 @@ describe("SessionRunnerLLM", () => {
|
|||
]
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Newest exact request ".repeat(180) }),
|
||||
prompt: Prompt.make({ text: "Newest exact request ".repeat(180) }),
|
||||
resume: false,
|
||||
})
|
||||
yield* session.resume(sessionID)
|
||||
|
|
@ -1156,7 +1155,7 @@ describe("SessionRunnerLLM", () => {
|
|||
fragmentFixture("text", "text-summary", ["## Goal\n- Recover overflow"]).completeEvents,
|
||||
fragmentFixture("text", "text-final", ["Recovered"]).completeEvents,
|
||||
]
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Continue" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Continue" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests).toHaveLength(3)
|
||||
|
|
@ -1186,7 +1185,7 @@ describe("SessionRunnerLLM", () => {
|
|||
fragmentFixture("text", "text-summary", ["## Goal\n- Recover once"]).completeEvents,
|
||||
overflow(),
|
||||
]
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Continue" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Continue" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests).toHaveLength(3)
|
||||
|
|
@ -1214,7 +1213,7 @@ describe("SessionRunnerLLM", () => {
|
|||
fragmentFixture("text", "text-summary", ["## Goal\n- Recover raw overflow"]).completeEvents,
|
||||
fragmentFixture("text", "text-final", ["Recovered"]).completeEvents,
|
||||
]
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Continue" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Continue" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests).toHaveLength(3)
|
||||
|
|
@ -1232,7 +1231,7 @@ describe("SessionRunnerLLM", () => {
|
|||
[LLMEvent.providerError({ message: "prompt too long", classification: "context-overflow" })],
|
||||
[LLMEvent.providerError({ message: "summary unavailable" })],
|
||||
]
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Continue" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Continue" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests).toHaveLength(2)
|
||||
|
|
@ -1255,7 +1254,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const firstGate = yield* Deferred.make<void>()
|
||||
const summaryGate = yield* Deferred.make<void>()
|
||||
streamGate = firstGate
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Continue" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Continue" }), resume: false })
|
||||
const run = yield* session.resume(sessionID).pipe(Effect.forkChild)
|
||||
while (requests.length < 1) yield* Effect.yieldNow
|
||||
streamGate = summaryGate
|
||||
|
|
@ -1275,13 +1274,13 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
systemBaseline = "Changed context"
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
const compactionID = SessionMessage.ID.create()
|
||||
yield* events.publish(SessionEvent.Compaction.Started, {
|
||||
|
|
@ -1299,7 +1298,7 @@ describe("SessionRunnerLLM", () => {
|
|||
recent: "",
|
||||
})
|
||||
systemUnavailable = true
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Third" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Third" }), resume: false })
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
expect(requests.at(-1)?.system.map((part) => part.text)).toEqual(["Initial context"])
|
||||
|
|
@ -1311,7 +1310,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Use tools" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Use tools" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = undefined
|
||||
|
|
@ -1409,7 +1408,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Echo this" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Echo this" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
authorizations.length = 0
|
||||
|
|
@ -1468,7 +1467,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Echo this" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Echo this" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -1512,7 +1511,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Think first" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Think first" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = [
|
||||
|
|
@ -1550,7 +1549,7 @@ describe("SessionRunnerLLM", () => {
|
|||
},
|
||||
])
|
||||
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Continue" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Continue" }), resume: false })
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
|
|
@ -1569,7 +1568,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Search first" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Search first" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = [
|
||||
|
|
@ -1594,7 +1593,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* session.resume(sessionID)
|
||||
yield* replaySessionProjection(sessionID)
|
||||
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Continue" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Continue" }), resume: false })
|
||||
response = []
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
|
|
@ -1624,7 +1623,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Echo five times" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Echo five times" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
executions.length = 0
|
||||
|
|
@ -1685,7 +1684,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Echo twice" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Echo twice" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
executions.length = 0
|
||||
|
|
@ -1773,7 +1772,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Run once" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Run once" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = undefined
|
||||
|
|
@ -1812,7 +1811,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start working" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start working" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -1832,7 +1831,7 @@ describe("SessionRunnerLLM", () => {
|
|||
|
||||
const first = yield* session.resume(sessionID).pipe(Effect.forkChild)
|
||||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Change direction" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Change direction" }) })
|
||||
yield* Deferred.succeed(streamGate, undefined)
|
||||
yield* Fiber.join(first)
|
||||
streamGate = undefined
|
||||
|
|
@ -1855,7 +1854,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start working" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start working" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -1883,7 +1882,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Wait until continuation ends" }),
|
||||
prompt: Prompt.make({ text: "Wait until continuation ends" }),
|
||||
delivery: "queue",
|
||||
})
|
||||
yield* Deferred.succeed(streamGate, undefined)
|
||||
|
|
@ -1903,7 +1902,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const { db } = yield* Database.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Interrupt current work" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Interrupt current work" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -1921,7 +1920,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Run after interrupt" }),
|
||||
prompt: Prompt.make({ text: "Run after interrupt" }),
|
||||
delivery: "queue",
|
||||
})
|
||||
yield* session.interrupt(sessionID)
|
||||
|
|
@ -1946,7 +1945,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const { db } = yield* Database.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Interrupt current work" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Interrupt current work" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -1964,7 +1963,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Steer after interrupt" }),
|
||||
prompt: Prompt.make({ text: "Steer after interrupt" }),
|
||||
})
|
||||
yield* session.interrupt(sessionID)
|
||||
expect(yield* Fiber.await(run)).toMatchObject({ _tag: "Failure" })
|
||||
|
|
@ -1988,7 +1987,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start working" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start working" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -2013,8 +2012,8 @@ describe("SessionRunnerLLM", () => {
|
|||
|
||||
const first = yield* session.resume(sessionID).pipe(Effect.forkChild)
|
||||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Queue first" }), delivery: "queue" })
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Queue second" }), delivery: "queue" })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Queue first" }), delivery: "queue" })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Queue second" }), delivery: "queue" })
|
||||
yield* Deferred.succeed(streamGate, undefined)
|
||||
yield* Fiber.join(first)
|
||||
streamGate = undefined
|
||||
|
|
@ -2031,10 +2030,10 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start steering" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start steering" }), resume: false })
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Queue for later" }),
|
||||
prompt: Prompt.make({ text: "Queue for later" }),
|
||||
delivery: "queue",
|
||||
resume: false,
|
||||
})
|
||||
|
|
@ -2065,7 +2064,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start working" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start working" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -2096,13 +2095,13 @@ describe("SessionRunnerLLM", () => {
|
|||
|
||||
const first = yield* session.resume(sessionID).pipe(Effect.forkChild)
|
||||
while (requests.length < 1) yield* Effect.yieldNow
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Queue first" }), delivery: "queue" })
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Queue second" }), delivery: "queue" })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Queue first" }), delivery: "queue" })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Queue second" }), delivery: "queue" })
|
||||
streamGate = secondGate
|
||||
yield* Deferred.succeed(firstGate, undefined)
|
||||
while (requests.length < 2) yield* Effect.yieldNow
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Steer before next queued input" }) })
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Also steer before next queued input" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Steer before next queued input" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Also steer before next queued input" }) })
|
||||
yield* Deferred.succeed(secondGate, undefined)
|
||||
yield* Fiber.join(first)
|
||||
streamGate = undefined
|
||||
|
|
@ -2130,7 +2129,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start working" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start working" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -2150,8 +2149,8 @@ describe("SessionRunnerLLM", () => {
|
|||
|
||||
const first = yield* session.resume(sessionID).pipe(Effect.forkChild)
|
||||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First steer" }) })
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second steer" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "First steer" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Second steer" }) })
|
||||
yield* Deferred.succeed(streamGate, undefined)
|
||||
yield* Fiber.join(first)
|
||||
streamGate = undefined
|
||||
|
|
@ -2170,7 +2169,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start working" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start working" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = undefined
|
||||
|
|
@ -2181,7 +2180,7 @@ describe("SessionRunnerLLM", () => {
|
|||
|
||||
const first = yield* session.resume(sessionID).pipe(Effect.forkChild)
|
||||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Recover with this" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Recover with this" }) })
|
||||
yield* Deferred.succeed(streamGate, undefined)
|
||||
expect(yield* Fiber.join(first).pipe(Effect.flip)).toBe(streamFailure)
|
||||
|
||||
|
|
@ -2200,7 +2199,7 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Recover interrupted tool" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Recover interrupted tool" }), resume: false })
|
||||
yield* SessionInput.promoteSteers((yield* Database.Service).db, events, sessionID, Number.MAX_SAFE_INTEGER)
|
||||
const assistantMessageID = SessionMessage.ID.create()
|
||||
yield* events.publish(SessionEvent.Step.Started, {
|
||||
|
|
@ -2262,7 +2261,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Recover interrupted hosted tool" }),
|
||||
prompt: Prompt.make({ text: "Recover interrupted hosted tool" }),
|
||||
resume: false,
|
||||
})
|
||||
yield* SessionInput.promoteSteers((yield* Database.Service).db, events, sessionID, Number.MAX_SAFE_INTEGER)
|
||||
|
|
@ -2322,7 +2321,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const events = yield* EventV2.Service
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Recover interrupted tool input" }),
|
||||
prompt: Prompt.make({ text: "Recover interrupted tool input" }),
|
||||
resume: false,
|
||||
})
|
||||
yield* SessionInput.promoteSteers((yield* Database.Service).db, events, sessionID, Number.MAX_SAFE_INTEGER)
|
||||
|
|
@ -2360,7 +2359,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Wait in queue" }),
|
||||
prompt: Prompt.make({ text: "Wait in queue" }),
|
||||
delivery: "queue",
|
||||
resume: false,
|
||||
})
|
||||
|
|
@ -2382,7 +2381,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const defect = new Error("fail after prompt promotion")
|
||||
let fail = true
|
||||
yield* events.project(SessionEvent.Prompted, () => (fail ? Effect.die(defect) : Effect.void))
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Recover promoted input" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Recover promoted input" }), resume: false })
|
||||
|
||||
expect(yield* session.resume(sessionID).pipe(Effect.catchDefect(Effect.succeed))).toBe(defect)
|
||||
fail = false
|
||||
|
|
@ -2410,7 +2409,7 @@ describe("SessionRunnerLLM", () => {
|
|||
)
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Run committed promotion" }),
|
||||
prompt: Prompt.make({ text: "Run committed promotion" }),
|
||||
resume: false,
|
||||
})
|
||||
|
||||
|
|
@ -2427,8 +2426,8 @@ describe("SessionRunnerLLM", () => {
|
|||
yield* setup
|
||||
yield* insertSession(otherSessionID)
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Run first" }), resume: false })
|
||||
yield* session.prompt({ sessionID: otherSessionID, prompt: new Prompt({ text: "Run second" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Run first" }), resume: false })
|
||||
yield* session.prompt({ sessionID: otherSessionID, prompt: Prompt.make({ text: "Run second" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = undefined
|
||||
|
|
@ -2454,37 +2453,31 @@ describe("SessionRunnerLLM", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("bounds external session prompt cache keys", () =>
|
||||
it.effect("bounds 64-character session prompt cache keys", () =>
|
||||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const externalSessionID = SessionV2.ID.fromExternal({
|
||||
namespace: "discord",
|
||||
key: "thread-one",
|
||||
})
|
||||
const otherExternalSessionID = SessionV2.ID.fromExternal({
|
||||
namespace: "discord",
|
||||
key: "thread-two",
|
||||
})
|
||||
yield* insertSession(externalSessionID)
|
||||
yield* insertSession(otherExternalSessionID)
|
||||
const longSessionID = SessionV2.ID.make(`ses_${"a".repeat(64)}`)
|
||||
const otherLongSessionID = SessionV2.ID.make(`ses_${"b".repeat(64)}`)
|
||||
yield* insertSession(longSessionID)
|
||||
yield* insertSession(otherLongSessionID)
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({
|
||||
sessionID: externalSessionID,
|
||||
prompt: new Prompt({ text: "Run external session" }),
|
||||
sessionID: longSessionID,
|
||||
prompt: Prompt.make({ text: "Run long session" }),
|
||||
resume: false,
|
||||
})
|
||||
yield* session.prompt({
|
||||
sessionID: otherExternalSessionID,
|
||||
prompt: new Prompt({ text: "Run other external session" }),
|
||||
sessionID: otherLongSessionID,
|
||||
prompt: Prompt.make({ text: "Run other long session" }),
|
||||
resume: false,
|
||||
})
|
||||
|
||||
requests.length = 0
|
||||
yield* session.resume(externalSessionID)
|
||||
yield* session.resume(otherExternalSessionID)
|
||||
yield* session.resume(longSessionID)
|
||||
yield* session.resume(otherLongSessionID)
|
||||
|
||||
const keys = requests.map((request) => request.providerOptions?.openai?.promptCacheKey)
|
||||
expect(keys).toEqual([externalSessionID.slice(4), otherExternalSessionID.slice(4)])
|
||||
expect(keys).toEqual([longSessionID.slice(4), otherLongSessionID.slice(4)])
|
||||
expect(keys.every((key) => typeof key === "string" && key.length === 64)).toBe(true)
|
||||
expect(keys[0]).not.toBe(keys[1])
|
||||
}),
|
||||
|
|
@ -2494,7 +2487,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Retry after failure" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Retry after failure" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = undefined
|
||||
|
|
@ -2525,7 +2518,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Call missing" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Call missing" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -2571,7 +2564,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Call defect" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Call defect" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -2620,7 +2613,7 @@ describe("SessionRunnerLLM", () => {
|
|||
questions.ask({ sessionID: context.sessionID, questions: [] }).pipe(Effect.as({}), Effect.orDie),
|
||||
}),
|
||||
})
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Ask then stop" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Ask then stop" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = [
|
||||
|
|
@ -2665,7 +2658,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Settle before failing" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Settle before failing" }), resume: false })
|
||||
const failure = providerUnavailable()
|
||||
toolExecutionGate = yield* Deferred.make<void>()
|
||||
responseStream = Stream.concat(
|
||||
|
|
@ -2699,7 +2692,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Interrupt blocked tool" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Interrupt blocked tool" }), resume: false })
|
||||
executions.length = 0
|
||||
toolExecutionGate = yield* Deferred.make<void>()
|
||||
responseStream = Stream.concat(
|
||||
|
|
@ -2749,7 +2742,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Interrupt provider" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Interrupt provider" }), resume: false })
|
||||
requests.length = 0
|
||||
response = []
|
||||
streamGate = yield* Deferred.make<void>()
|
||||
|
|
@ -2772,7 +2765,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Interrupt tool settlement" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Interrupt tool settlement" }), resume: false })
|
||||
executions.length = 0
|
||||
toolExecutionGate = yield* Deferred.make<void>()
|
||||
response = [
|
||||
|
|
@ -2815,7 +2808,7 @@ describe("SessionRunnerLLM", () => {
|
|||
}),
|
||||
)
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Finish at the limit" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Finish at the limit" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
executions.length = 0
|
||||
|
|
@ -2863,7 +2856,7 @@ describe("SessionRunnerLLM", () => {
|
|||
}),
|
||||
)
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Start work" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Start work" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
executions.length = 0
|
||||
|
|
@ -2891,7 +2884,7 @@ describe("SessionRunnerLLM", () => {
|
|||
|
||||
const run = yield* session.resume(sessionID).pipe(Effect.forkChild)
|
||||
yield* Deferred.await(streamStarted)
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Change direction" }) })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Change direction" }) })
|
||||
yield* Deferred.succeed(streamGate, undefined)
|
||||
yield* Fiber.join(run)
|
||||
streamGate = undefined
|
||||
|
|
@ -2909,7 +2902,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Fail durably" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Fail durably" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
responses = undefined
|
||||
|
|
@ -2931,7 +2924,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Fail before step" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Fail before step" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = [LLMEvent.providerError({ message: "Provider unavailable" })]
|
||||
|
|
@ -2950,7 +2943,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Fail after output" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Fail after output" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = [
|
||||
|
|
@ -2979,7 +2972,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Fail raw stream durably" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Fail raw stream durably" }), resume: false })
|
||||
const failure = providerUnavailable()
|
||||
responseStream = Stream.fail(failure)
|
||||
|
||||
|
|
@ -2998,7 +2991,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Do not continue failed provider" }),
|
||||
prompt: Prompt.make({ text: "Do not continue failed provider" }),
|
||||
resume: false,
|
||||
})
|
||||
|
||||
|
|
@ -3021,7 +3014,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Fail hosted tool durably" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Fail hosted tool durably" }), resume: false })
|
||||
|
||||
requests.length = 0
|
||||
response = [
|
||||
|
|
@ -3052,7 +3045,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Fail hosted tool at EOF" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Fail hosted tool at EOF" }), resume: false })
|
||||
response = [
|
||||
LLMEvent.stepStart({ index: 0 }),
|
||||
LLMEvent.toolCall({
|
||||
|
|
@ -3079,7 +3072,7 @@ describe("SessionRunnerLLM", () => {
|
|||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({
|
||||
sessionID,
|
||||
prompt: new Prompt({ text: "Fail hosted tool on raw failure" }),
|
||||
prompt: Prompt.make({ text: "Fail hosted tool on raw failure" }),
|
||||
resume: false,
|
||||
})
|
||||
const failure = providerUnavailable()
|
||||
|
|
@ -3114,7 +3107,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Two blocks" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Two blocks" }), resume: false })
|
||||
|
||||
responses = undefined
|
||||
streamGate = undefined
|
||||
|
|
@ -3177,7 +3170,7 @@ describe("SessionRunnerLLM", () => {
|
|||
Effect.gen(function* () {
|
||||
yield* setup
|
||||
const session = yield* SessionV2.Service
|
||||
yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Call provider tool" }), resume: false })
|
||||
yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Call provider tool" }), resume: false })
|
||||
|
||||
responses = undefined
|
||||
streamGate = undefined
|
||||
|
|
|
|||
183
packages/core/test/shared-schema.test.ts
Normal file
183
packages/core/test/shared-schema.test.ts
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { Schema } from "effect"
|
||||
import { AgentV2 } from "@opencode-ai/core/agent"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
import { SessionV2 } from "@opencode-ai/core/session"
|
||||
import { Agent } from "@opencode-ai/schema/agent"
|
||||
import { Location } from "@opencode-ai/schema/location"
|
||||
import { Model } from "@opencode-ai/schema/model"
|
||||
import { AgentAttachment, FileAttachment, Prompt, Source } from "@opencode-ai/schema/prompt"
|
||||
import { Provider } from "@opencode-ai/schema/provider"
|
||||
import { Project } from "@opencode-ai/schema/project"
|
||||
import { Session } from "@opencode-ai/schema/session"
|
||||
import { SessionInput } from "@opencode-ai/schema/session-input"
|
||||
import { SessionMessage } from "@opencode-ai/schema/session-message"
|
||||
import { Workspace } from "@opencode-ai/schema/workspace"
|
||||
import { Command } from "@opencode-ai/schema/command"
|
||||
import { Connection } from "@opencode-ai/schema/connection"
|
||||
import { Credential } from "@opencode-ai/schema/credential"
|
||||
import { FileSystem } from "@opencode-ai/schema/filesystem"
|
||||
import { Integration } from "@opencode-ai/schema/integration"
|
||||
import { LLM } from "@opencode-ai/schema/llm"
|
||||
import { ModelRequest } from "@opencode-ai/schema/model-request"
|
||||
import { Permission } from "@opencode-ai/schema/permission"
|
||||
import { Reference } from "@opencode-ai/schema/reference"
|
||||
import { Skill } from "@opencode-ai/schema/skill"
|
||||
import { AbsolutePath, DateTimeUtcFromMillis } from "@opencode-ai/schema/schema"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
|
||||
test("Core reuses the canonical shared schemas", async () => {
|
||||
const [
|
||||
coreCommand,
|
||||
coreConnection,
|
||||
coreCredential,
|
||||
coreFileSystem,
|
||||
coreIntegration,
|
||||
coreLocation,
|
||||
coreLLM,
|
||||
coreModelRequest,
|
||||
corePermission,
|
||||
coreProject,
|
||||
coreReference,
|
||||
coreSessionInput,
|
||||
coreSessionMessage,
|
||||
corePrompt,
|
||||
coreSkill,
|
||||
coreV2Schema,
|
||||
coreWorkspace,
|
||||
] = await Promise.all([
|
||||
import("@opencode-ai/core/command"),
|
||||
import("@opencode-ai/core/integration/connection"),
|
||||
import("@opencode-ai/core/credential"),
|
||||
import("@opencode-ai/core/filesystem/schema"),
|
||||
import("@opencode-ai/core/integration"),
|
||||
import("@opencode-ai/core/location"),
|
||||
import("@opencode-ai/llm"),
|
||||
import("@opencode-ai/core/model-request"),
|
||||
import("@opencode-ai/core/permission/schema"),
|
||||
import("@opencode-ai/core/project/schema"),
|
||||
import("@opencode-ai/core/reference"),
|
||||
import("@opencode-ai/core/session/input"),
|
||||
import("@opencode-ai/core/session/message"),
|
||||
import("@opencode-ai/core/session/prompt"),
|
||||
import("@opencode-ai/core/skill"),
|
||||
import("@opencode-ai/core/v2-schema"),
|
||||
import("@opencode-ai/core/workspace"),
|
||||
])
|
||||
|
||||
const schemas = [
|
||||
[AgentV2.ID, Agent.ID],
|
||||
[AgentV2.Color, Agent.Color],
|
||||
[AgentV2.Info, Agent.Info],
|
||||
[coreCommand.Info, Command.Info],
|
||||
[coreConnection.CredentialInfo, Connection.CredentialInfo],
|
||||
[coreConnection.EnvInfo, Connection.EnvInfo],
|
||||
[coreConnection.Info, Connection.Info],
|
||||
[coreCredential.ID, Credential.ID],
|
||||
[coreCredential.OAuth, Credential.OAuth],
|
||||
[coreCredential.Key, Credential.Key],
|
||||
[coreCredential.Value, Credential.Value],
|
||||
[coreFileSystem.Entry, FileSystem.Entry],
|
||||
[coreFileSystem.Submatch, FileSystem.Submatch],
|
||||
[coreFileSystem.Match, FileSystem.Match],
|
||||
[coreIntegration.When, Integration.When],
|
||||
[coreIntegration.TextPrompt, Integration.TextPrompt],
|
||||
[coreIntegration.SelectPrompt, Integration.SelectPrompt],
|
||||
[coreIntegration.Prompt, Integration.Prompt],
|
||||
[coreIntegration.OAuthMethod, Integration.OAuthMethod],
|
||||
[coreIntegration.KeyMethod, Integration.KeyMethod],
|
||||
[coreIntegration.EnvMethod, Integration.EnvMethod],
|
||||
[coreIntegration.Method, Integration.Method],
|
||||
[coreIntegration.Inputs, Integration.Inputs],
|
||||
[coreIntegration.Ref, Integration.Ref],
|
||||
[coreLocation.Ref, Location.Ref],
|
||||
[coreLLM.ProviderMetadata, LLM.ProviderMetadata],
|
||||
[coreLLM.ToolTextContent, LLM.ToolTextContent],
|
||||
[coreLLM.ToolFileContent, LLM.ToolFileContent],
|
||||
[coreLLM.ToolContent, LLM.ToolContent],
|
||||
[ModelV2.ID, Model.ID],
|
||||
[ModelV2.VariantID, Model.VariantID],
|
||||
[ModelV2.Ref, Model.Ref],
|
||||
[ModelV2.Family, Model.Family],
|
||||
[ModelV2.Capabilities, Model.Capabilities],
|
||||
[ModelV2.Cost, Model.Cost],
|
||||
[ModelV2.Api, Model.Api],
|
||||
[ModelV2.Info, Model.Info],
|
||||
[ProviderV2.ID, Provider.ID],
|
||||
[ProviderV2.AISDK, Provider.AISDK],
|
||||
[ProviderV2.Native, Provider.Native],
|
||||
[ProviderV2.Api, Provider.Api],
|
||||
[ProviderV2.Request, Provider.Request],
|
||||
[ProviderV2.Info, Provider.Info],
|
||||
[coreModelRequest.Generation, ModelRequest.Generation],
|
||||
[coreModelRequest.Request, ModelRequest.Request],
|
||||
[corePermission.Effect, Permission.Effect],
|
||||
[corePermission.Rule, Permission.Rule],
|
||||
[corePermission.Ruleset, Permission.Ruleset],
|
||||
[coreProject.ID, Project.ID],
|
||||
[coreReference.LocalSource, Reference.LocalSource],
|
||||
[coreReference.GitSource, Reference.GitSource],
|
||||
[coreReference.Source, Reference.Source],
|
||||
[SessionV2.ID, Session.ID],
|
||||
[SessionV2.Info, Session.Info],
|
||||
[SessionV2.ListAnchor, Session.ListAnchor],
|
||||
[coreSessionInput.Delivery, SessionInput.Delivery],
|
||||
[coreSessionInput.Admitted, SessionInput.Admitted],
|
||||
[coreSessionMessage.ID, SessionMessage.ID],
|
||||
[coreSessionMessage.UnknownError, SessionMessage.UnknownError],
|
||||
[coreSessionMessage.AgentSwitched, SessionMessage.AgentSwitched],
|
||||
[coreSessionMessage.ModelSwitched, SessionMessage.ModelSwitched],
|
||||
[coreSessionMessage.User, SessionMessage.User],
|
||||
[coreSessionMessage.Synthetic, SessionMessage.Synthetic],
|
||||
[coreSessionMessage.System, SessionMessage.System],
|
||||
[coreSessionMessage.Shell, SessionMessage.Shell],
|
||||
[coreSessionMessage.ToolStatePending, SessionMessage.ToolStatePending],
|
||||
[coreSessionMessage.ToolStateRunning, SessionMessage.ToolStateRunning],
|
||||
[coreSessionMessage.ToolStateCompleted, SessionMessage.ToolStateCompleted],
|
||||
[coreSessionMessage.ToolStateError, SessionMessage.ToolStateError],
|
||||
[coreSessionMessage.ToolState, SessionMessage.ToolState],
|
||||
[coreSessionMessage.AssistantTool, SessionMessage.AssistantTool],
|
||||
[coreSessionMessage.AssistantText, SessionMessage.AssistantText],
|
||||
[coreSessionMessage.AssistantReasoning, SessionMessage.AssistantReasoning],
|
||||
[coreSessionMessage.AssistantContent, SessionMessage.AssistantContent],
|
||||
[coreSessionMessage.Assistant, SessionMessage.Assistant],
|
||||
[coreSessionMessage.Compaction, SessionMessage.Compaction],
|
||||
[coreSessionMessage.Message, SessionMessage.Message],
|
||||
[corePrompt.Source, Source],
|
||||
[corePrompt.FileAttachment, FileAttachment],
|
||||
[corePrompt.AgentAttachment, AgentAttachment],
|
||||
[corePrompt.Prompt, Prompt],
|
||||
[coreSkill.DirectorySource, Skill.DirectorySource],
|
||||
[coreSkill.UrlSource, Skill.UrlSource],
|
||||
[coreSkill.EmbeddedSource, Skill.EmbeddedSource],
|
||||
[coreSkill.Source, Skill.Source],
|
||||
[coreSkill.Info, Skill.Info],
|
||||
[coreV2Schema.DateTimeUtcFromMillis, DateTimeUtcFromMillis],
|
||||
[coreWorkspace.ID, Workspace.ID],
|
||||
]
|
||||
for (const [core, shared] of schemas) expect(core).toBe(shared)
|
||||
|
||||
expect(Agent.Info.empty(Agent.ID.make("test"))).toEqual(AgentV2.Info.empty(AgentV2.ID.make("test")))
|
||||
expect(Model.Info.empty(Provider.ID.make("test"), Model.ID.make("model"))).toEqual(
|
||||
ModelV2.Info.empty(ProviderV2.ID.make("test"), ModelV2.ID.make("model")),
|
||||
)
|
||||
expect(Provider.Info.empty(Provider.ID.make("test"))).toEqual(ProviderV2.Info.empty(ProviderV2.ID.make("test")))
|
||||
expect(Skill.Source.key(Skill.DirectorySource.make({ type: "directory", path: AbsolutePath.make("/tmp") }))).toBe(
|
||||
"directory:/tmp",
|
||||
)
|
||||
})
|
||||
|
||||
test("shared record schemas construct and decode plain objects", () => {
|
||||
const made = Prompt.make({ text: "hello" })
|
||||
const decoded = Schema.decodeUnknownSync(Prompt)({ text: "hello" })
|
||||
const content = Schema.decodeUnknownSync(SessionMessage.AssistantText)({ type: "text", id: "part_1", text: "hi" })
|
||||
|
||||
expect(Object.getPrototypeOf(made)).toBe(Object.prototype)
|
||||
expect(Object.getPrototypeOf(decoded)).toBe(Object.prototype)
|
||||
expect(Object.getPrototypeOf(content)).toBe(Object.prototype)
|
||||
expect(Prompt.ast.annotations?.identifier).toBe("Prompt")
|
||||
expect(SessionMessage.AssistantText.ast.annotations?.identifier).toBe("Session.Message.Assistant.Text")
|
||||
expect(Prompt.equivalence(Prompt.make({ text: "hello" }), decoded)).toBe(true)
|
||||
expect(Prompt.fromUserMessage({ text: "hello" })).toEqual(made)
|
||||
expect(Workspace.ID.ascending("")).toStartWith("wrk_")
|
||||
})
|
||||
|
|
@ -74,7 +74,7 @@ describe("SkillV2", () => {
|
|||
{ type: "directory", path: AbsolutePath.make(second) },
|
||||
])
|
||||
expect(yield* skill.list()).toEqual([
|
||||
new SkillV2.Info({
|
||||
SkillV2.Info.make({
|
||||
name: "foo",
|
||||
slash: true,
|
||||
location: AbsolutePath.make(path.join(first, "foo.md")),
|
||||
|
|
|
|||
|
|
@ -9,18 +9,18 @@ import { SkillGuidance } from "@opencode-ai/core/skill/guidance"
|
|||
import { it } from "../lib/effect"
|
||||
|
||||
const build = AgentV2.ID.make("build")
|
||||
const effect = new SkillV2.Info({
|
||||
const effect = SkillV2.Info.make({
|
||||
name: "effect",
|
||||
description: "Build applications with Effect",
|
||||
location: AbsolutePath.make(path.resolve("/skills/effect/SKILL.md")),
|
||||
content: "Effect guidance",
|
||||
})
|
||||
const hidden = new SkillV2.Info({
|
||||
const hidden = SkillV2.Info.make({
|
||||
name: "hidden",
|
||||
location: AbsolutePath.make(path.resolve("/skills/hidden/SKILL.md")),
|
||||
content: "Undescribed guidance",
|
||||
})
|
||||
const denied = new SkillV2.Info({
|
||||
const denied = SkillV2.Info.make({
|
||||
name: "denied",
|
||||
description: "Must not be advertised",
|
||||
location: AbsolutePath.make(path.resolve("/skills/denied/SKILL.md")),
|
||||
|
|
@ -32,7 +32,7 @@ const layer = (list: () => SkillV2.Info[]) =>
|
|||
|
||||
describe("SkillGuidance", () => {
|
||||
it.effect("renders described agent skills and reconciles the complete available list", () => {
|
||||
const agent = new AgentV2.Info({
|
||||
const agent = AgentV2.Info.make({
|
||||
...AgentV2.Info.empty(build),
|
||||
permissions: [{ action: "skill", resource: "denied", effect: "deny" }],
|
||||
})
|
||||
|
|
@ -69,7 +69,7 @@ describe("SkillGuidance", () => {
|
|||
})
|
||||
|
||||
it.effect("omits guidance when the selected agent denies all skills", () => {
|
||||
const agent = new AgentV2.Info({
|
||||
const agent = AgentV2.Info.make({
|
||||
...AgentV2.Info.empty(build),
|
||||
permissions: [{ action: "skill", resource: "*", effect: "deny" }],
|
||||
})
|
||||
|
|
@ -85,7 +85,7 @@ describe("SkillGuidance", () => {
|
|||
})
|
||||
|
||||
it.effect("omits guidance when a resource-specific denial follows the global denial", () => {
|
||||
const agent = new AgentV2.Info({
|
||||
const agent = AgentV2.Info.make({
|
||||
...AgentV2.Info.empty(build),
|
||||
permissions: [
|
||||
{ action: "skill", resource: "*", effect: "deny" },
|
||||
|
|
@ -104,7 +104,7 @@ describe("SkillGuidance", () => {
|
|||
})
|
||||
|
||||
it.effect("retains specifically allowed skills after a global denial", () => {
|
||||
const agent = new AgentV2.Info({
|
||||
const agent = AgentV2.Info.make({
|
||||
...AgentV2.Info.empty(build),
|
||||
permissions: [
|
||||
{ action: "skill", resource: "*", effect: "deny" },
|
||||
|
|
@ -120,7 +120,7 @@ describe("SkillGuidance", () => {
|
|||
})
|
||||
|
||||
it.effect("omits guidance when a specifically allowed skill is denied again", () => {
|
||||
const agent = new AgentV2.Info({
|
||||
const agent = AgentV2.Info.make({
|
||||
...AgentV2.Info.empty(build),
|
||||
permissions: [
|
||||
{ action: "skill", resource: "*", effect: "deny" },
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ describe("SkillTool", () => {
|
|||
}),
|
||||
).toEqual({ type: "error", value: "Unable to load skill effect" })
|
||||
deny = false
|
||||
const flat = new SkillV2.Info({
|
||||
const flat = SkillV2.Info.make({
|
||||
name: "public",
|
||||
description: "Public guidance",
|
||||
location: AbsolutePath.make(path.join(tmp.path, "public.md")),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue