1import * as Schema from "effect/Schema";
2
3import {
4 IsoDateTime,
5 ProjectId,
6 ThreadId,
7 TrimmedNonEmptyString,
8 TrimmedString,
9} from "./baseSchemas.ts";
10
11export const OrchestrationThreadSearchSource = Schema.Literals(["user", "assistant"]);
12export type OrchestrationThreadSearchSource = typeof OrchestrationThreadSearchSource.Type;
13
14// The server's SQLite client is synchronous and single-connection. Bound both
15// scan input and response size so a search cannot monopolize that connection.
16export const OrchestrationSearchThreadsInput = Schema.Struct({
17 query: TrimmedString.check(Schema.isMinLength(2), Schema.isMaxLength(200)),
18 limit: Schema.optionalKey(Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 50 }))),
19});
20export type OrchestrationSearchThreadsInput = typeof OrchestrationSearchThreadsInput.Type;
21
22export const OrchestrationThreadSearchMatch = Schema.Struct({
23 threadId: ThreadId,
24 projectId: ProjectId,
25 source: OrchestrationThreadSearchSource,
26 snippet: Schema.String.check(Schema.isMaxLength(240)),
27 messageCreatedAt: Schema.NullOr(IsoDateTime),
28});
29export type OrchestrationThreadSearchMatch = typeof OrchestrationThreadSearchMatch.Type;
30
31export const OrchestrationSearchThreadsResult = Schema.Struct({
32 matches: Schema.Array(OrchestrationThreadSearchMatch),
33});
34export type OrchestrationSearchThreadsResult = typeof OrchestrationSearchThreadsResult.Type;
35
36export class OrchestrationSearchThreadsError extends Schema.TaggedError<OrchestrationSearchThreadsError>()(
37 "OrchestrationSearchThreadsError",
38 {
39 message: TrimmedNonEmptyString,
40 cause: Schema.optional(Schema.Defect()),
41 },
42) {}