Source HTTP API ID path patterns (#26623)

This commit is contained in:
Kit Langton
2026-05-09 22:58:47 -04:00
committed by GitHub
parent 2f11c9f7ed
commit 67b9c9c027
25 changed files with 127 additions and 90 deletions
@@ -105,11 +105,11 @@ Verification:
Concrete first targets: Concrete first targets:
- `sessionID` - `[x]` `sessionID`
- `messageID` - `[x]` `messageID`
- `partID` - `[x]` `partID`
- `permissionID` - `[x]` `permissionID`
- `ptyID` - `[x]` `ptyID`
Leave ambiguous route-local `id` overrides for workspace routes until they are renamed or explicitly typed in endpoint params. Leave ambiguous route-local `id` overrides for workspace routes until they are renamed or explicitly typed in endpoint params.
+3 -1
View File
@@ -4,7 +4,9 @@ import { Identifier } from "@/id/id"
import { zod, ZodOverride } from "@opencode-ai/core/effect-zod" import { zod, ZodOverride } from "@opencode-ai/core/effect-zod"
import { withStatics } from "@opencode-ai/core/schema" import { withStatics } from "@opencode-ai/core/schema"
const ptyIdSchema = Schema.String.annotate({ [ZodOverride]: Identifier.schema("pty") }).pipe(Schema.brand("PtyID")) const ptyIdSchema = Schema.String.check(Schema.isStartsWith("pty"))
.annotate({ [ZodOverride]: Identifier.schema("pty") })
.pipe(Schema.brand("PtyID"))
export type PtyID = typeof ptyIdSchema.Type export type PtyID = typeof ptyIdSchema.Type
@@ -69,14 +69,6 @@ const QueryParameterSchemas: Record<string, OpenApiSchema> = {
"GET /api/session/{sessionID}/message limit": { type: "number" }, "GET /api/session/{sessionID}/message limit": { type: "number" },
} }
const PathParameterSchemas: Record<string, OpenApiSchema> = {
sessionID: { type: "string", pattern: "^ses.*" },
messageID: { type: "string", pattern: "^msg.*" },
partID: { type: "string", pattern: "^prt.*" },
permissionID: { type: "string", pattern: "^per.*" },
ptyID: { type: "string", pattern: "^pty.*" },
}
const LegacyComponentDescriptions: Record<string, string> = { const LegacyComponentDescriptions: Record<string, string> = {
LogLevel: "Log level", LogLevel: "Log level",
ServerConfig: "Server configuration for opencode serve and web commands", ServerConfig: "Server configuration for opencode serve and web commands",
@@ -506,11 +498,8 @@ function normalizeParameter(param: OpenApiParameter, route: string) {
} }
function pathParameterSchema(route: string, name: string) { function pathParameterSchema(route: string, name: string) {
if (name in PathParameterSchemas) return PathParameterSchemas[name]
if (name === "id" && route.startsWith("DELETE /experimental/workspace/")) return { type: "string", pattern: "^wrk.*" } if (name === "id" && route.startsWith("DELETE /experimental/workspace/")) return { type: "string", pattern: "^wrk.*" }
if (name === "id" && route.startsWith("POST /experimental/workspace/")) return { type: "string", pattern: "^wrk.*" } if (name === "id" && route.startsWith("POST /experimental/workspace/")) return { type: "string", pattern: "^wrk.*" }
if (name === "requestID" && route.startsWith("POST /permission/")) return { type: "string", pattern: "^per.*" }
if (name === "requestID" && route.startsWith("POST /question/")) return { type: "string", pattern: "^que.*" }
return undefined return undefined
} }
+18 -6
View File
@@ -4,32 +4,44 @@ import { Identifier } from "@/id/id"
import { zod, ZodOverride } from "@opencode-ai/core/effect-zod" import { zod, ZodOverride } from "@opencode-ai/core/effect-zod"
import { withStatics } from "@opencode-ai/core/schema" import { withStatics } from "@opencode-ai/core/schema"
export const SessionID = Schema.String.annotate({ [ZodOverride]: Identifier.schema("session") }).pipe( export const SessionID = Schema.String.check(Schema.isStartsWith("ses"))
.annotate({
[ZodOverride]: Identifier.schema("session"),
})
.pipe(
Schema.brand("SessionID"), Schema.brand("SessionID"),
withStatics((s) => ({ withStatics((s) => ({
descending: (id?: string) => s.make(Identifier.descending("session", id)), descending: (id?: string) => s.make(Identifier.descending("session", id)),
zod: zod(s), zod: zod(s),
})), })),
) )
export type SessionID = Schema.Schema.Type<typeof SessionID> export type SessionID = Schema.Schema.Type<typeof SessionID>
export const MessageID = Schema.String.annotate({ [ZodOverride]: Identifier.schema("message") }).pipe( export const MessageID = Schema.String.check(Schema.isStartsWith("msg"))
.annotate({
[ZodOverride]: Identifier.schema("message"),
})
.pipe(
Schema.brand("MessageID"), Schema.brand("MessageID"),
withStatics((s) => ({ withStatics((s) => ({
ascending: (id?: string) => s.make(Identifier.ascending("message", id)), ascending: (id?: string) => s.make(Identifier.ascending("message", id)),
zod: zod(s), zod: zod(s),
})), })),
) )
export type MessageID = Schema.Schema.Type<typeof MessageID> export type MessageID = Schema.Schema.Type<typeof MessageID>
export const PartID = Schema.String.annotate({ [ZodOverride]: Identifier.schema("part") }).pipe( export const PartID = Schema.String.check(Schema.isStartsWith("prt"))
.annotate({
[ZodOverride]: Identifier.schema("part"),
})
.pipe(
Schema.brand("PartID"), Schema.brand("PartID"),
withStatics((s) => ({ withStatics((s) => ({
ascending: (id?: string) => s.make(Identifier.ascending("part", id)), ascending: (id?: string) => s.make(Identifier.ascending("part", id)),
zod: zod(s), zod: zod(s),
})), })),
) )
export type PartID = Schema.Schema.Type<typeof PartID> export type PartID = Schema.Schema.Type<typeof PartID>
@@ -7,8 +7,8 @@ import { SessionID, MessageID, PartID } from "../../src/session/schema"
function createTextPart(text: string): MessageV2.Part { function createTextPart(text: string): MessageV2.Part {
return { return {
id: PartID.ascending(), id: PartID.ascending(),
sessionID: SessionID.make("s"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make("m"), messageID: MessageID.make("msg_test"),
type: "text" as const, type: "text" as const,
text, text,
} }
@@ -17,8 +17,8 @@ function createTextPart(text: string): MessageV2.Part {
function createReasoningPart(text: string): MessageV2.Part { function createReasoningPart(text: string): MessageV2.Part {
return { return {
id: PartID.ascending(), id: PartID.ascending(),
sessionID: SessionID.make("s"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make("m"), messageID: MessageID.make("msg_test"),
type: "reasoning" as const, type: "reasoning" as const,
text, text,
time: { start: 0 }, time: { start: 0 },
@@ -29,8 +29,8 @@ function createToolPart(tool: string, title: string, status: "completed" | "runn
if (status === "completed") { if (status === "completed") {
return { return {
id: PartID.ascending(), id: PartID.ascending(),
sessionID: SessionID.make("s"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make("m"), messageID: MessageID.make("msg_test"),
type: "tool" as const, type: "tool" as const,
callID: "c1", callID: "c1",
tool, tool,
@@ -46,8 +46,8 @@ function createToolPart(tool: string, title: string, status: "completed" | "runn
} }
return { return {
id: PartID.ascending(), id: PartID.ascending(),
sessionID: SessionID.make("s"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make("m"), messageID: MessageID.make("msg_test"),
type: "tool" as const, type: "tool" as const,
callID: "c1", callID: "c1",
tool, tool,
@@ -62,8 +62,8 @@ function createToolPart(tool: string, title: string, status: "completed" | "runn
function createStepStartPart(): MessageV2.Part { function createStepStartPart(): MessageV2.Part {
return { return {
id: PartID.ascending(), id: PartID.ascending(),
sessionID: SessionID.make("s"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make("m"), messageID: MessageID.make("msg_test"),
type: "step-start" as const, type: "step-start" as const,
} }
} }
@@ -71,8 +71,8 @@ function createStepStartPart(): MessageV2.Part {
function createStepFinishPart(): MessageV2.Part { function createStepFinishPart(): MessageV2.Part {
return { return {
id: PartID.ascending(), id: PartID.ascending(),
sessionID: SessionID.make("s"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make("m"), messageID: MessageID.make("msg_test"),
type: "step-finish" as const, type: "step-finish" as const,
reason: "done", reason: "done",
cost: 0, cost: 0,
@@ -22,8 +22,9 @@ function run<A>(fn: (svc: Project.Interface) => Effect.Effect<A>) {
) )
} }
function uid() { function legacySessionID() {
return SessionID.make(crypto.randomUUID()) // Global-session migration covers persisted IDs from before prefixed session IDs.
return crypto.randomUUID() as SessionID
} }
function seed(opts: { id: SessionID; dir: string; project: ProjectID }) { function seed(opts: { id: SessionID; dir: string; project: ProjectID }) {
@@ -73,7 +74,7 @@ describe("migrateFromGlobal", () => {
expect(pre.id).toBe(ProjectID.global) expect(pre.id).toBe(ProjectID.global)
// 2. Seed a session under "global" with matching directory // 2. Seed a session under "global" with matching directory
const id = uid() const id = legacySessionID()
seed({ id, dir: tmp.path, project: ProjectID.global }) seed({ id, dir: tmp.path, project: ProjectID.global })
// 3. Make a commit so the project gets a real ID // 3. Make a commit so the project gets a real ID
@@ -100,7 +101,7 @@ describe("migrateFromGlobal", () => {
// 3. Seed a session under "global" with matching directory. // 3. Seed a session under "global" with matching directory.
// This simulates a session created before git init that wasn't // This simulates a session created before git init that wasn't
// present when the real project row was first created. // present when the real project row was first created.
const id = uid() const id = legacySessionID()
seed({ id, dir: tmp.path, project: ProjectID.global }) seed({ id, dir: tmp.path, project: ProjectID.global })
// 4. Call fromDirectory again — project row already exists, // 4. Call fromDirectory again — project row already exists,
@@ -121,7 +122,7 @@ describe("migrateFromGlobal", () => {
// Legacy sessions may lack a directory value. // Legacy sessions may lack a directory value.
// Without a matching origin directory, they should remain global. // Without a matching origin directory, they should remain global.
const id = uid() const id = legacySessionID()
seed({ id, dir: "", project: ProjectID.global }) seed({ id, dir: "", project: ProjectID.global })
await run((svc) => svc.fromDirectory(tmp.path)) await run((svc) => svc.fromDirectory(tmp.path))
@@ -139,7 +140,7 @@ describe("migrateFromGlobal", () => {
ensureGlobal() ensureGlobal()
// Seed a session under "global" but for a DIFFERENT directory // Seed a session under "global" but for a DIFFERENT directory
const id = uid() const id = legacySessionID()
seed({ id, dir: "/some/other/dir", project: ProjectID.global }) seed({ id, dir: "/some/other/dir", project: ProjectID.global })
await run((svc) => svc.fromDirectory(tmp.path)) await run((svc) => svc.fromDirectory(tmp.path))
@@ -22,6 +22,7 @@ import {
MessagesQuery, MessagesQuery,
SessionPaths, SessionPaths,
} from "../../src/server/routes/instance/httpapi/groups/session" } from "../../src/server/routes/instance/httpapi/groups/session"
import { PtyPaths } from "../../src/server/routes/instance/httpapi/groups/pty"
import { MessagesQuery as V2MessagesQuery } from "../../src/server/routes/instance/httpapi/groups/v2/message" import { MessagesQuery as V2MessagesQuery } from "../../src/server/routes/instance/httpapi/groups/v2/message"
import { SessionsQuery as V2SessionsQuery } from "../../src/server/routes/instance/httpapi/groups/v2/session" import { SessionsQuery as V2SessionsQuery } from "../../src/server/routes/instance/httpapi/groups/v2/session"
import { QueryBoolean } from "../../src/server/routes/instance/httpapi/groups/query" import { QueryBoolean } from "../../src/server/routes/instance/httpapi/groups/query"
@@ -33,7 +34,12 @@ const originalWorkspaces = Flag.OPENCODE_EXPERIMENTAL_WORKSPACES
type Method = "get" | "post" | "put" | "delete" | "patch" type Method = "get" | "post" | "put" | "delete" | "patch"
type QuerySchema = { readonly fields: Record<string, unknown> } type QuerySchema = { readonly fields: Record<string, unknown> }
type OpenApiSchema = { readonly maximum?: number; readonly minimum?: number; readonly type?: string } type OpenApiSchema = {
readonly maximum?: number
readonly minimum?: number
readonly pattern?: string
readonly type?: string
}
type OpenApiParameter = { readonly name: string; readonly in: string; readonly schema?: OpenApiSchema } type OpenApiParameter = { readonly name: string; readonly in: string; readonly schema?: OpenApiSchema }
type OpenApiOperation = { readonly parameters?: readonly OpenApiParameter[] } type OpenApiOperation = { readonly parameters?: readonly OpenApiParameter[] }
@@ -68,6 +74,16 @@ const numericSdkQueryParams = [
{ method: "get", path: "/api/session/:sessionID/message", name: "limit", schema: { type: "number" } }, { method: "get", path: "/api/session/:sessionID/message", name: "limit", schema: { type: "number" } },
] satisfies Array<{ method: Method; path: string; name: string; schema: OpenApiSchema }> ] satisfies Array<{ method: Method; path: string; name: string; schema: OpenApiSchema }>
const pathParamPatterns = [
{ method: "get", path: SessionPaths.get, name: "sessionID", pattern: "^ses" },
{ method: "get", path: SessionPaths.message, name: "messageID", pattern: "^msg" },
{ method: "patch", path: SessionPaths.updatePart, name: "partID", pattern: "^prt" },
{ method: "post", path: SessionPaths.permissions, name: "permissionID", pattern: "^per" },
{ method: "post", path: "/permission/:requestID/reply", name: "requestID", pattern: "^per" },
{ method: "post", path: "/question/:requestID/reply", name: "requestID", pattern: "^que" },
{ method: "put", path: PtyPaths.update, name: "ptyID", pattern: "^pty" },
] satisfies Array<{ method: Method; path: string; name: string; pattern: string }>
function app() { function app() {
return Server.Default().app return Server.Default().app
} }
@@ -98,6 +114,10 @@ function queryParameter(operation: OpenApiOperation | undefined, name: string) {
return (operation?.parameters ?? []).find((param) => param.in === "query" && param.name === name) return (operation?.parameters ?? []).find((param) => param.in === "query" && param.name === name)
} }
function pathParameter(operation: OpenApiOperation | undefined, name: string) {
return (operation?.parameters ?? []).find((param) => param.in === "path" && param.name === name)
}
function assertAdvertisedQueryParamsAreRuntimeFields(input: { function assertAdvertisedQueryParamsAreRuntimeFields(input: {
readonly method: Method readonly method: Method
readonly operation: OpenApiOperation | undefined readonly operation: OpenApiOperation | undefined
@@ -173,6 +193,19 @@ describe("httpapi query schema drift", () => {
}), }),
) )
it.effect(
"OpenAPI path parameter patterns come from runtime schemas",
Effect.sync(() => {
const spec = OpenApi.fromApi(PublicApi)
for (const expected of pathParamPatterns) {
expect(
pathParameter(spec.paths[openApiPath(expected.path)]?.[expected.method], expected.name)?.schema,
`${expected.method.toUpperCase()} ${expected.path} ${expected.name}`,
).toEqual({ type: "string", pattern: expected.pattern })
}
}),
)
it.effect( it.effect(
"drift assertion catches spec-only workspace query params", "drift assertion catches spec-only workspace query params",
Effect.sync(() => { Effect.sync(() => {
@@ -287,7 +287,7 @@ describe("HttpApi UI fallback", () => {
}) })
test("keeps matched API routes ahead of the UI fallback", async () => { test("keeps matched API routes ahead of the UI fallback", async () => {
const response = await Server.Default().app.request("/session/nope") const response = await Server.Default().app.request("/session/ses_nope")
expect(response.status).toBe(404) expect(response.status).toBe(404)
}) })
@@ -61,7 +61,7 @@ const tmpWithFiles = (files: Record<string, string>) =>
function loaded(filepath: string): MessageV2.WithParts[] { function loaded(filepath: string): MessageV2.WithParts[] {
const sessionID = SessionID.make("session-loaded-1") const sessionID = SessionID.make("session-loaded-1")
const messageID = MessageID.make("message-loaded-1") const messageID = MessageID.make("msg_message-loaded-1")
return [ return [
{ {
@@ -78,7 +78,7 @@ function loaded(filepath: string): MessageV2.WithParts[] {
}, },
parts: [ parts: [
{ {
id: PartID.make("part-loaded-1"), id: PartID.make("prt_part-loaded-1"),
messageID, messageID,
sessionID, sessionID,
type: "tool", type: "tool",
@@ -106,7 +106,7 @@ describe("Instruction.resolve", () => {
const system = yield* svc.systemPaths() const system = yield* svc.systemPaths()
expect(system.has(path.join(dir, "AGENTS.md"))).toBe(true) expect(system.has(path.join(dir, "AGENTS.md"))).toBe(true)
const results = yield* svc.resolve([], path.join(dir, "src", "file.ts"), MessageID.make("message-test-1")) const results = yield* svc.resolve([], path.join(dir, "src", "file.ts"), MessageID.make("msg_message-test-1"))
expect(results).toEqual([]) expect(results).toEqual([])
}), }),
), ),
@@ -122,7 +122,7 @@ describe("Instruction.resolve", () => {
const results = yield* svc.resolve( const results = yield* svc.resolve(
[], [],
path.join(dir, "subdir", "nested", "file.ts"), path.join(dir, "subdir", "nested", "file.ts"),
MessageID.make("message-test-2"), MessageID.make("msg_message-test-2"),
) )
expect(results.length).toBe(1) expect(results.length).toBe(1)
expect(results[0].filepath).toBe(path.join(dir, "subdir", "AGENTS.md")) expect(results[0].filepath).toBe(path.join(dir, "subdir", "AGENTS.md"))
@@ -138,7 +138,7 @@ describe("Instruction.resolve", () => {
const system = yield* svc.systemPaths() const system = yield* svc.systemPaths()
expect(system.has(filepath)).toBe(false) expect(system.has(filepath)).toBe(false)
const results = yield* svc.resolve([], filepath, MessageID.make("message-test-3")) const results = yield* svc.resolve([], filepath, MessageID.make("msg_message-test-3"))
expect(results).toEqual([]) expect(results).toEqual([])
}), }),
), ),
@@ -149,7 +149,7 @@ describe("Instruction.resolve", () => {
Effect.gen(function* () { Effect.gen(function* () {
const svc = yield* Instruction.Service const svc = yield* Instruction.Service
const filepath = path.join(dir, "subdir", "nested", "file.ts") const filepath = path.join(dir, "subdir", "nested", "file.ts")
const id = MessageID.make("message-claim-1") const id = MessageID.make("msg_message-claim-1")
const first = yield* svc.resolve([], filepath, id) const first = yield* svc.resolve([], filepath, id)
const second = yield* svc.resolve([], filepath, id) const second = yield* svc.resolve([], filepath, id)
@@ -166,7 +166,7 @@ describe("Instruction.resolve", () => {
Effect.gen(function* () { Effect.gen(function* () {
const svc = yield* Instruction.Service const svc = yield* Instruction.Service
const filepath = path.join(dir, "subdir", "nested", "file.ts") const filepath = path.join(dir, "subdir", "nested", "file.ts")
const id = MessageID.make("message-claim-2") const id = MessageID.make("msg_message-claim-2")
const first = yield* svc.resolve([], filepath, id) const first = yield* svc.resolve([], filepath, id)
yield* svc.clear(id) yield* svc.clear(id)
@@ -185,7 +185,7 @@ describe("Instruction.resolve", () => {
const svc = yield* Instruction.Service const svc = yield* Instruction.Service
const agents = path.join(dir, "subdir", "AGENTS.md") const agents = path.join(dir, "subdir", "AGENTS.md")
const filepath = path.join(dir, "subdir", "nested", "file.ts") const filepath = path.join(dir, "subdir", "nested", "file.ts")
const id = MessageID.make("message-claim-3") const id = MessageID.make("msg_message-claim-3")
const results = yield* svc.resolve(loaded(agents), filepath, id) const results = yield* svc.resolve(loaded(agents), filepath, id)
expect(results).toEqual([]) expect(results).toEqual([])
+8 -8
View File
@@ -354,7 +354,7 @@ describe("session.llm.stream", () => {
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-1"), id: MessageID.make("msg_user-1"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -438,7 +438,7 @@ describe("session.llm.stream", () => {
permission: [{ permission: "*", pattern: "*", action: "allow" }], permission: [{ permission: "*", pattern: "*", action: "allow" }],
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-service-abort"), id: MessageID.make("msg_user-service-abort"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -529,7 +529,7 @@ describe("session.llm.stream", () => {
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-tools"), id: MessageID.make("msg_user-tools"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -644,7 +644,7 @@ describe("session.llm.stream", () => {
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-2"), id: MessageID.make("msg_user-2"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -759,7 +759,7 @@ describe("session.llm.stream", () => {
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-data-url"), id: MessageID.make("msg_user-data-url"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -880,7 +880,7 @@ describe("session.llm.stream", () => {
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-3"), id: MessageID.make("msg_user-3"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -995,7 +995,7 @@ describe("session.llm.stream", () => {
permission: [{ permission: "*", pattern: "*", action: "allow" }], permission: [{ permission: "*", pattern: "*", action: "allow" }],
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-anthropic-tools"), id: MessageID.make("msg_user-anthropic-tools"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -1239,7 +1239,7 @@ describe("session.llm.stream", () => {
} satisfies Agent.Info } satisfies Agent.Info
const user = { const user = {
id: MessageID.make("user-4"), id: MessageID.make("msg_user-4"),
sessionID, sessionID,
role: "user", role: "user",
time: { created: Date.now() }, time: { created: Date.now() },
@@ -102,9 +102,9 @@ function assistantInfo(
function basePart(messageID: string, id: string) { function basePart(messageID: string, id: string) {
return { return {
id: PartID.make(id), id: PartID.make(id.startsWith("prt") ? id : `prt_${id}`),
sessionID, sessionID,
messageID: MessageID.make(messageID), messageID: MessageID.make(messageID.startsWith("msg") ? messageID : `msg_${messageID}`),
} }
} }
@@ -27,7 +27,7 @@ const runtime = ManagedRuntime.make(
const baseCtx = { const baseCtx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -17,7 +17,7 @@ import { SessionID, MessageID } from "../../src/session/schema"
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test-edit-session"), sessionID: SessionID.make("ses_test-edit-session"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
@@ -12,7 +12,7 @@ import { SessionID, MessageID } from "../../src/session/schema"
const baseCtx: Omit<Tool.Context, "ask"> = { const baseCtx: Omit<Tool.Context, "ask"> = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -23,7 +23,7 @@ const it = testEffect(
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -23,7 +23,7 @@ const it = testEffect(
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -20,7 +20,7 @@ afterEach(async () => {
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -10,7 +10,7 @@ import { testEffect } from "../lib/effect"
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test-session"), sessionID: SessionID.make("ses_test-session"),
messageID: MessageID.make("test-message"), messageID: MessageID.make("msg_test-message"),
callID: "test-call", callID: "test-call",
agent: "test-agent", agent: "test-agent",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -24,7 +24,7 @@ afterEach(async () => {
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
@@ -19,7 +19,7 @@ afterEach(async () => {
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "scout", agent: "scout",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
@@ -18,7 +18,7 @@ afterEach(async () => {
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "scout", agent: "scout",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -36,7 +36,7 @@ const initShell = initBash
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -14,7 +14,7 @@ import { testEffect } from "../lib/effect"
const baseCtx: Omit<Tool.Context, "ask"> = { const baseCtx: Omit<Tool.Context, "ask"> = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -13,7 +13,7 @@ const projectRoot = path.join(import.meta.dir, "../..")
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test"), sessionID: SessionID.make("ses_test"),
messageID: MessageID.make("message"), messageID: MessageID.make("msg_message"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),
+1 -1
View File
@@ -18,7 +18,7 @@ import { testEffect } from "../lib/effect"
const ctx = { const ctx = {
sessionID: SessionID.make("ses_test-write-session"), sessionID: SessionID.make("ses_test-write-session"),
messageID: MessageID.make(""), messageID: MessageID.make("msg_test"),
callID: "", callID: "",
agent: "build", agent: "build",
abort: AbortSignal.any([]), abort: AbortSignal.any([]),