|
|
@@ -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
|