Repository navigation
Expand file tree
/
Copy pathtest-host.ts
More file actions
72 lines (66 loc) · 2.81 KB
/
Copy pathtest-host.ts
File metadata and controls
72 lines (66 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { mkdtemp, mkdir } from "node:fs/promises"
import { tmpdir } from "node:os"
import path from "node:path"
import type { ReminderHost, SessionMessage, SessionStatus } from "./host"
import type { Reminder, State } from "./types"
export type FakeHost = ReminderHost & {
statuses: Map<string, SessionStatus>
prompts: any[]
agents: Map<string, string>
/** Messages returned by session.context; defaults to a matched assistant reply for the last prompt. */
contextFor?: (sessionID: string) => ReadonlyArray<SessionMessage>
}
let counter = 0
export const nextMessageID = () => `msg_${(++counter).toString(16).padStart(12, "0")}${crypto.randomUUID().replaceAll("-", "").slice(0, 14)}`
export function matchedContext(host: FakeHost, sessionID: string): SessionMessage[] {
const last = [...host.prompts].reverse().find((p) => p.sessionID === sessionID)
if (!last?.id) return []
return [
{ id: last.id, type: "user", text: last.text, time: { created: Date.now() } },
{ id: nextMessageID(), type: "assistant", agent: "build", model: { id: "test", providerID: "test" }, content: [{ type: "text", text: "done" }], finish: "stop", time: { created: Date.now(), completed: Date.now() } },
{ id: nextMessageID(), type: "idle", outcome: "succeeded", time: { created: Date.now() } },
]
}
export async function createFakeHost(directory?: string): Promise<FakeHost> {
const dir = directory ?? (await mkdtemp(path.join(tmpdir(), "opencode-reminders-")))
const projectID = crypto.randomUUID()
await mkdir(path.join(dir, ".opencode", "reminders", projectID), { recursive: true })
const host: FakeHost = {
directory: dir,
projectID,
statuses: new Map(),
prompts: [],
agents: new Map(),
status: (sessionID) => host.statuses.get(sessionID),
session: {
get: async ({ sessionID }) => ({ id: sessionID, agent: host.agents.get(sessionID) ?? "build" }),
switchAgent: async ({ sessionID, agent }) => {
host.agents.set(sessionID, agent)
},
prompt: async (request) => {
const id = nextMessageID()
host.prompts.push({ ...request, id })
return { id, sessionID: request.sessionID }
},
wait: async () => {},
context: async ({ sessionID }) => (host.contextFor ? host.contextFor(sessionID) : matchedContext(host, sessionID)),
},
}
return host
}
export function createState(projectID: string): State {
return { reminders: new Map(), timers: new Map(), projectID }
}
export function createReminder(projectID: string, type: Reminder["type"]): Reminder {
return {
id: crypto.randomUUID(),
sessionID: `ses_${crypto.randomUUID().replaceAll("-", "")}`,
projectID,
type,
interval: 30,
originalPrompt: "test prompt",
userDescription: "test reminder",
time: { created: Date.now(), nextExecution: Date.now() },
status: "active",
}
}