|
1 | | -import { NodeFileSystem } from "@effect/platform-node" |
2 | | -import { FetchHttpClient } from "effect/unstable/http" |
3 | 1 | import { expect } from "bun:test" |
4 | | -import { Cause, Effect, Exit, Fiber, Layer } from "effect" |
| 2 | +import { Cause, Effect, Exit, Fiber } from "effect" |
5 | 3 | import path from "path" |
6 | 4 | import { fileURLToPath } from "url" |
7 | 5 | import { NamedError } from "@opencode-ai/shared/util/error" |
8 | | -import { Agent as AgentSvc } from "../../src/agent/agent" |
9 | | -import { Bus } from "../../src/bus" |
10 | | -import { Command } from "../../src/command" |
11 | | -import { Config } from "../../src/config" |
12 | | -import { LSP } from "../../src/lsp" |
13 | | -import { MCP } from "../../src/mcp" |
14 | | -import { Permission } from "../../src/permission" |
15 | | -import { Plugin } from "../../src/plugin" |
16 | | -import { Provider as ProviderSvc } from "../../src/provider" |
17 | | -import { Env } from "../../src/env" |
18 | 6 | import { ModelID, ProviderID } from "../../src/provider/schema" |
19 | | -import { Question } from "../../src/question" |
20 | | -import { Todo } from "../../src/session/todo" |
21 | 7 | import { Session } from "../../src/session" |
22 | | -import { LLM } from "../../src/session/llm" |
23 | 8 | import { MessageV2 } from "../../src/session/message-v2" |
24 | | -import { AppFileSystem } from "@opencode-ai/shared/filesystem" |
25 | | -import { SessionCompaction } from "../../src/session/compaction" |
26 | | -import { SessionSummary } from "../../src/session/summary" |
27 | | -import { Instruction } from "../../src/session/instruction" |
28 | | -import { SessionProcessor } from "../../src/session/processor" |
29 | 9 | import { SessionPrompt } from "../../src/session/prompt" |
30 | | -import { SessionRevert } from "../../src/session/revert" |
31 | 10 | import { SessionRunState } from "../../src/session/run-state" |
32 | 11 | import { MessageID, PartID, SessionID } from "../../src/session/schema" |
33 | 12 | import { SessionStatus } from "../../src/session/status" |
34 | | -import { Skill } from "../../src/skill" |
35 | | -import { SystemPrompt } from "../../src/session/system" |
36 | 13 | import { Shell } from "../../src/shell/shell" |
37 | | -import { Snapshot } from "../../src/snapshot" |
38 | 14 | import { ToolRegistry } from "../../src/tool" |
39 | | -import { Truncate } from "../../src/tool" |
40 | 15 | import { Log } from "../../src/util" |
41 | | -import * as CrossSpawnSpawner from "../../src/effect/cross-spawn-spawner" |
42 | | -import { Ripgrep } from "../../src/file/ripgrep" |
43 | | -import { Format } from "../../src/format" |
44 | 16 | import { provideTmpdirInstance, provideTmpdirServer } from "../fixture/fixture" |
45 | 17 | import { testEffect } from "../lib/effect" |
46 | | -import { reply, TestLLMServer } from "../lib/llm-server" |
| 18 | +import { reply } from "../lib/llm-server" |
| 19 | +import { makePromptLayer } from "../lib/prompt-harness" |
47 | 20 |
|
48 | 21 | void Log.init({ print: false }) |
49 | 22 |
|
50 | | -const summary = Layer.succeed( |
51 | | - SessionSummary.Service, |
52 | | - SessionSummary.Service.of({ |
53 | | - summarize: () => Effect.void, |
54 | | - diff: () => Effect.succeed([]), |
55 | | - computeDiff: () => Effect.succeed([]), |
56 | | - }), |
57 | | -) |
58 | | - |
59 | 23 | const ref = { |
60 | 24 | providerID: ProviderID.make("test"), |
61 | 25 | modelID: ModelID.make("test-model"), |
@@ -106,102 +70,7 @@ function errorTool(parts: MessageV2.Part[]) { |
106 | 70 | return part?.state.status === "error" ? (part as ErrorToolPart) : undefined |
107 | 71 | } |
108 | 72 |
|
109 | | -const mcp = Layer.succeed( |
110 | | - MCP.Service, |
111 | | - MCP.Service.of({ |
112 | | - status: () => Effect.succeed({}), |
113 | | - clients: () => Effect.succeed({}), |
114 | | - tools: () => Effect.succeed({}), |
115 | | - prompts: () => Effect.succeed({}), |
116 | | - resources: () => Effect.succeed({}), |
117 | | - add: () => Effect.succeed({ status: { status: "disabled" as const } }), |
118 | | - connect: () => Effect.void, |
119 | | - disconnect: () => Effect.void, |
120 | | - getPrompt: () => Effect.succeed(undefined), |
121 | | - readResource: () => Effect.succeed(undefined), |
122 | | - startAuth: () => Effect.die("unexpected MCP auth in prompt-effect tests"), |
123 | | - authenticate: () => Effect.die("unexpected MCP auth in prompt-effect tests"), |
124 | | - finishAuth: () => Effect.die("unexpected MCP auth in prompt-effect tests"), |
125 | | - removeAuth: () => Effect.void, |
126 | | - supportsOAuth: () => Effect.succeed(false), |
127 | | - hasStoredTokens: () => Effect.succeed(false), |
128 | | - getAuthStatus: () => Effect.succeed("not_authenticated" as const), |
129 | | - }), |
130 | | -) |
131 | | - |
132 | | -const lsp = Layer.succeed( |
133 | | - LSP.Service, |
134 | | - LSP.Service.of({ |
135 | | - init: () => Effect.void, |
136 | | - status: () => Effect.succeed([]), |
137 | | - hasClients: () => Effect.succeed(false), |
138 | | - touchFile: () => Effect.void, |
139 | | - diagnostics: () => Effect.succeed({}), |
140 | | - hover: () => Effect.succeed(undefined), |
141 | | - definition: () => Effect.succeed([]), |
142 | | - references: () => Effect.succeed([]), |
143 | | - implementation: () => Effect.succeed([]), |
144 | | - documentSymbol: () => Effect.succeed([]), |
145 | | - workspaceSymbol: () => Effect.succeed([]), |
146 | | - prepareCallHierarchy: () => Effect.succeed([]), |
147 | | - incomingCalls: () => Effect.succeed([]), |
148 | | - outgoingCalls: () => Effect.succeed([]), |
149 | | - }), |
150 | | -) |
151 | | - |
152 | | -const status = SessionStatus.layer.pipe(Layer.provideMerge(Bus.layer)) |
153 | | -const run = SessionRunState.layer.pipe(Layer.provide(status)) |
154 | | -const infra = Layer.mergeAll(NodeFileSystem.layer, CrossSpawnSpawner.defaultLayer) |
155 | | -function makeHttp() { |
156 | | - const deps = Layer.mergeAll( |
157 | | - Session.defaultLayer, |
158 | | - Snapshot.defaultLayer, |
159 | | - LLM.defaultLayer, |
160 | | - Env.defaultLayer, |
161 | | - AgentSvc.defaultLayer, |
162 | | - Command.defaultLayer, |
163 | | - Permission.defaultLayer, |
164 | | - Plugin.defaultLayer, |
165 | | - Config.defaultLayer, |
166 | | - ProviderSvc.defaultLayer, |
167 | | - lsp, |
168 | | - mcp, |
169 | | - AppFileSystem.defaultLayer, |
170 | | - status, |
171 | | - ).pipe(Layer.provideMerge(infra)) |
172 | | - const question = Question.layer.pipe(Layer.provideMerge(deps)) |
173 | | - const todo = Todo.layer.pipe(Layer.provideMerge(deps)) |
174 | | - const registry = ToolRegistry.layer.pipe( |
175 | | - Layer.provide(Skill.defaultLayer), |
176 | | - Layer.provide(FetchHttpClient.layer), |
177 | | - Layer.provide(CrossSpawnSpawner.defaultLayer), |
178 | | - Layer.provide(Ripgrep.defaultLayer), |
179 | | - Layer.provide(Format.defaultLayer), |
180 | | - Layer.provideMerge(todo), |
181 | | - Layer.provideMerge(question), |
182 | | - Layer.provideMerge(deps), |
183 | | - ) |
184 | | - const trunc = Truncate.layer.pipe(Layer.provideMerge(deps)) |
185 | | - const proc = SessionProcessor.layer.pipe(Layer.provide(summary), Layer.provideMerge(deps)) |
186 | | - const compact = SessionCompaction.layer.pipe(Layer.provideMerge(proc), Layer.provideMerge(deps)) |
187 | | - return Layer.mergeAll( |
188 | | - TestLLMServer.layer, |
189 | | - SessionPrompt.layer.pipe( |
190 | | - Layer.provide(SessionRevert.defaultLayer), |
191 | | - Layer.provide(summary), |
192 | | - Layer.provideMerge(run), |
193 | | - Layer.provideMerge(compact), |
194 | | - Layer.provideMerge(proc), |
195 | | - Layer.provideMerge(registry), |
196 | | - Layer.provideMerge(trunc), |
197 | | - Layer.provide(Instruction.defaultLayer), |
198 | | - Layer.provide(SystemPrompt.defaultLayer), |
199 | | - Layer.provideMerge(deps), |
200 | | - ), |
201 | | - ).pipe(Layer.provide(summary)) |
202 | | -} |
203 | | - |
204 | | -const it = testEffect(makeHttp()) |
| 73 | +const it = testEffect(makePromptLayer()) |
205 | 74 | const unix = process.platform !== "win32" ? it.live : it.live.skip |
206 | 75 |
|
207 | 76 | // Config that registers a custom "test" provider with a "test-model" model |
|
0 commit comments