summaryrefslogtreecommitdiffhomepage
path: root/packages/console/app
diff options
context:
space:
mode:
Diffstat (limited to 'packages/console/app')
-rw-r--r--packages/console/app/src/routes/zen/util/dataDumper.ts26
-rw-r--r--packages/console/app/src/routes/zen/util/handler.ts22
-rw-r--r--packages/console/app/sst-env.d.ts2
3 files changed, 44 insertions, 6 deletions
diff --git a/packages/console/app/src/routes/zen/util/dataDumper.ts b/packages/console/app/src/routes/zen/util/dataDumper.ts
new file mode 100644
index 000000000..6a064138a
--- /dev/null
+++ b/packages/console/app/src/routes/zen/util/dataDumper.ts
@@ -0,0 +1,26 @@
+import { Resource, waitUntil } from "@opencode-ai/console-resource"
+
+export function createDataDumper(sessionId: string, requestId: string) {
+ if (Resource.App.stage !== "production") return
+
+ let data: Record<string, any> = {}
+ let modelName: string | undefined
+
+ return {
+ provideModel: (model?: string) => (modelName = model),
+ provideRequest: (request: string) => (data.request = request),
+ provideResponse: (response: string) => (data.response = response),
+ provideStream: (chunk: string) => (data.response = (data.response ?? "") + chunk),
+ flush: () => {
+ if (!modelName) return
+
+ const str = new Date().toISOString().replace(/[^0-9]/g, "")
+ const yyyymmdd = str.substring(0, 8)
+ const hh = str.substring(8, 10)
+
+ waitUntil(
+ Resource.ConsoleData.put(`${yyyymmdd}/${hh}/${modelName}/${sessionId}/${requestId}.json`, JSON.stringify(data)),
+ )
+ },
+ }
+}
diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts
index 3453a6d38..c40db6e1d 100644
--- a/packages/console/app/src/routes/zen/util/handler.ts
+++ b/packages/console/app/src/routes/zen/util/handler.ts
@@ -19,6 +19,7 @@ import { googleHelper } from "./provider/google"
import { openaiHelper } from "./provider/openai"
import { oaCompatHelper } from "./provider/openai-compatible"
import { createRateLimiter } from "./rateLimiter"
+import { createDataDumper } from "./dataDumper"
type ZenData = Awaited<ReturnType<typeof ZenData.list>>
type RetryOptions = {
@@ -48,16 +49,19 @@ export async function handler(
try {
const url = input.request.url
const body = await input.request.json()
- const ip = input.request.headers.get("x-real-ip") ?? ""
const model = opts.parseModel(url, body)
const isStream = opts.parseIsStream(url, body)
+ const ip = input.request.headers.get("x-real-ip") ?? ""
+ const sessionId = input.request.headers.get("x-opencode-session")
+ const requestId = input.request.headers.get("x-opencode-request")
logger.metric({
is_tream: isStream,
- session: input.request.headers.get("x-opencode-session"),
- request: input.request.headers.get("x-opencode-request"),
+ session: sessionId,
+ request: requestId,
})
const zenData = ZenData.list()
const modelInfo = validateModel(zenData, model)
+ const dataDumper = createDataDumper(sessionId, requestId)
const rateLimiter = createRateLimiter(modelInfo.id, modelInfo.rateLimit, ip)
await rateLimiter?.check()
@@ -104,10 +108,14 @@ export async function handler(
})
}
- return { providerInfo, authInfo, res, startTimestamp }
+ return { providerInfo, authInfo, reqBody, res, startTimestamp }
}
- const { providerInfo, authInfo, res, startTimestamp } = await retriableRequest()
+ const { providerInfo, authInfo, reqBody, res, startTimestamp } = await retriableRequest()
+
+ // Store model request
+ dataDumper?.provideModel(providerInfo.storeModel)
+ dataDumper?.provideRequest(reqBody)
// Scrub response headers
const resHeaders = new Headers()
@@ -126,6 +134,8 @@ export async function handler(
const body = JSON.stringify(responseConverter(json))
logger.metric({ response_length: body.length })
logger.debug("RESPONSE: " + body)
+ dataDumper?.provideResponse(body)
+ dataDumper?.flush()
await rateLimiter?.track()
await trackUsage(authInfo, modelInfo, providerInfo, json.usage)
await reload(authInfo)
@@ -155,6 +165,7 @@ export async function handler(
response_length: responseLength,
"timestamp.last_byte": Date.now(),
})
+ dataDumper?.flush()
await rateLimiter?.track()
const usage = usageParser.retrieve()
if (usage) {
@@ -174,6 +185,7 @@ export async function handler(
}
responseLength += value.length
buffer += decoder.decode(value, { stream: true })
+ dataDumper?.provideStream(buffer)
const parts = buffer.split(providerInfo.streamSeparator)
buffer = parts.pop() ?? ""
diff --git a/packages/console/app/sst-env.d.ts b/packages/console/app/sst-env.d.ts
index bd5588217..9b9de7327 100644
--- a/packages/console/app/sst-env.d.ts
+++ b/packages/console/app/sst-env.d.ts
@@ -6,4 +6,4 @@
/// <reference path="../../../sst-env.d.ts" />
import "sst"
-export {}
+export {} \ No newline at end of file