fix(release): repair validation blockers (#156082)

This commit is contained in:
Dallin Romney 2026-09-22 19:08:15 -07:00 • committed by GitHub
parent 1a94a1e236
commit e96300a5a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 41 additions and 25 deletions

View file

@ -123,6 +123,10 @@ private final class ApprovalGatewayFixture: @unchecked Sendable {
socket.emitReceiveSuccessOnce(.data(Data(event.utf8)))
}
func waitUntilReady() async throws {
_ = try await self.readySocket()
}
private func readySocket() async throws -> GatewayTestWebSocketTask {
let deadline = ContinuousClock.now + .seconds(2)
while ContinuousClock.now < deadline {
@ -210,16 +214,20 @@ struct ExecApprovalQueueStoreTests {
try #require(await self.waitUntil { store.requests.isEmpty })
}
@Test func `expired requests disappear without a gateway resolution event`() async throws {
let fixture = ApprovalGatewayFixture(initialRequests: [
ApprovalFixtureRequest(id: "short-lived", expiresOffsetMs: 500),
])
@Test func `live requests disappear at expiry without a gateway resolution event`() async throws {
let fixture = ApprovalGatewayFixture()
let store = ExecApprovalQueueStore(gateway: fixture.gateway)
defer { store.stop() }
store.start()
await store.refresh()
#expect(store.requests.map(\.id) == ["short-lived"])
try await fixture.waitUntilReady()
let request = ApprovalFixtureRequest(id: "short-lived", expiresOffsetMs: 500)
try await fixture.sendEvent(name: "exec.approval.requested", payload: request.json)
try #require(await self.waitUntil { store.requests.map(\.id) == ["short-lived"] })
try #require(await self.waitUntil { store.requests.isEmpty })
#expect(await fixture.requestLog.requests(method: "exec.approval.resolve").isEmpty)
}
@Test func `explicit decision policy excludes allow always and blocks unavailable decisions`() async {

View file

@ -598,25 +598,32 @@ describe("opencode-go provider plugin", () => {
});
it.each([
["openai-completions", "https://opencode.ai/zen/go/v1"],
["anthropic-messages", "https://opencode.ai/zen/go"],
] as const)("sends stable conversation identity to the %s endpoint", async (api, baseUrl) => {
const provider = await registerSingleProviderPlugin(plugin);
const streamFn = vi.fn(() => ({}) as never);
const wrapped = provider.wrapStreamFn?.({ streamFn } as never);
["stream", "openai-completions", "https://opencode.ai/zen/go/v1"],
["stream", "anthropic-messages", "https://opencode.ai/zen/go"],
["simple completion", "openai-completions", "https://opencode.ai/zen/go/v1"],
["simple completion", "anthropic-messages", "https://opencode.ai/zen/go"],
] as const)(
"sends stable conversation identity through the %s %s endpoint",
async (surface, api, baseUrl) => {
const provider = await registerSingleProviderPlugin(plugin);
const streamFn = vi.fn(() => ({}) as never);
const wrapper =
surface === "stream" ? provider.wrapStreamFn : provider.wrapSimpleCompletionStreamFn;
const wrapped = wrapper?.({ streamFn } as never);
await wrapped?.(
{ provider: "opencode-go", id: "fixture", api, baseUrl } as never,
{ messages: [] } as never,
{ sessionId: "conversation-123" },
);
await wrapped?.(
{ provider: "opencode-go", id: "fixture", api, baseUrl } as never,
{ messages: [] } as never,
{ sessionId: "conversation-123" },
);
expect(streamFn).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
expect.objectContaining({ headers: { "x-opencode-session": "conversation-123" } }),
);
});
expect(streamFn).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
expect.objectContaining({ headers: { "x-opencode-session": "conversation-123" } }),
);
},
);
it("preserves explicit session routing and leaves custom proxies unchanged", async () => {
const provider = await registerSingleProviderPlugin(plugin);

View file

@ -14,7 +14,7 @@ import {
resolveOpencodeGoStarterModel,
} from "./provider-catalog.js";
import { resolveThinkingProfile } from "./provider-policy-api.js";
import { createOpencodeGoWrapper } from "./stream.js";
import { createOpencodeGoSessionHeaderWrapper, createOpencodeGoWrapper } from "./stream.js";
const PROVIDER_ID = "opencode-go";
type OpencodeGoCatalogAuth = { apiKey?: string; discoveryApiKey?: string };
@ -119,6 +119,7 @@ export default defineSingleProviderPluginEntry({
...buildProviderReplayFamilyHooks({ family: "passthrough-gemini" }),
resolveThinkingProfile,
wrapStreamFn: (ctx) => createOpencodeGoWrapper(ctx.streamFn, ctx.thinkingLevel),
wrapSimpleCompletionStreamFn: (ctx) => createOpencodeGoSessionHeaderWrapper(ctx.streamFn),
isModernModelRef: () => true,
},
register(api) {

View file

@ -24,7 +24,7 @@ function hasOpencodeSessionHeader(headers: Record<string, string> | undefined):
return Object.keys(headers ?? {}).some((name) => name.toLowerCase() === OPENCODE_SESSION_HEADER);
}
function createOpencodeGoSessionHeaderWrapper(
export function createOpencodeGoSessionHeaderWrapper(
baseStreamFn: ProviderWrapStreamFnContext["streamFn"],
): ProviderWrapStreamFnContext["streamFn"] {
if (!baseStreamFn) {