feat(api): fall back for go plan accounts

This commit is contained in:
Patrick Wozniak
2026-08-18 12:11:47 +02:00
parent 864538e146
commit 89dc21bed2
17 changed files with 4782 additions and 3 deletions
+139
View File
@@ -0,0 +1,139 @@
import type {
AssistantMessageEvent,
AssistantMessageEventStreamLike,
ContextLike,
ModelLike,
StreamOptions,
} from "./types.ts"
export type CommandCodeTransport = "unknown" | "provider" | "generate"
interface TransportDependencies {
createStream: () => AssistantMessageEventStreamLike
streamProvider: (
model: ModelLike,
context: ContextLike,
options?: StreamOptions,
) => AssistantMessageEventStreamLike
streamGenerate: (
model: ModelLike,
context: ContextLike,
options?: StreamOptions,
) => AssistantMessageEventStreamLike
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value)
}
async function isUpgradeRequired(response: Response): Promise<boolean> {
if (response.status !== 403) return false
try {
const body: unknown = await response.clone().json()
if (!isRecord(body)) return false
const error = isRecord(body.error) ? body.error : body
return error.code === "upgrade_required"
} catch {
return false
}
}
export function createCommandCodeTransportRouter(deps: TransportDependencies) {
let transport: CommandCodeTransport = "unknown"
let apiKey: string | undefined
function pipe(
source: AssistantMessageEventStreamLike,
target: AssistantMessageEventStreamLike,
): Promise<void> {
return (async () => {
for await (const event of source) target.push(event)
})()
}
return {
getTransport(): CommandCodeTransport {
return transport
},
reset(): void {
transport = "unknown"
apiKey = undefined
},
stream(
model: ModelLike,
context: ContextLike,
options?: StreamOptions,
): AssistantMessageEventStreamLike {
if (options?.apiKey !== apiKey) {
apiKey = options?.apiKey
transport = "unknown"
}
if (transport === "generate") return deps.streamGenerate(model, context, options)
const output = deps.createStream()
let upgradeRequired = false
const fetchImpl = options?.fetch ?? fetch
const providerOptions: StreamOptions = {
...options,
fetch: async (input, init) => {
const response = await fetchImpl(input, init)
if (await isUpgradeRequired(response)) upgradeRequired = true
return response
},
onResponse: async (response, responseModel) => {
if (upgradeRequired) return
await options?.onResponse?.(response, responseModel)
},
}
const run = async () => {
const providerStream = deps.streamProvider(model, context, providerOptions)
for await (const event of providerStream) {
if (!upgradeRequired) {
transport = "provider"
output.push(event)
}
}
if (upgradeRequired) {
transport = "generate"
await pipe(deps.streamGenerate(model, context, options), output)
}
output.end()
}
run().catch((error: unknown) => {
const message = error instanceof Error ? error.message : String(error)
output.push({
type: "error",
reason: "error",
error: {
role: "assistant",
content: [],
api: model.api,
provider: model.provider,
model: model.id,
usage: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 0,
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
},
stopReason: "error",
errorMessage: message,
timestamp: Date.now(),
},
})
output.end()
})
return output
},
}
}