|
|
@@ -1,5 +1,6 @@
|
|
|
import { DurableObject } from "cloudflare:workers"
|
|
|
import { randomUUID } from "node:crypto"
|
|
|
+import { Base64 } from "js-base64"
|
|
|
|
|
|
type Env = {
|
|
|
SYNC_SERVER: DurableObjectNamespace<SyncServer>
|
|
|
@@ -180,8 +181,12 @@ export default {
|
|
|
return new Response("Error: Share ID is required", { status: 400 })
|
|
|
const stub = env.SYNC_SERVER.get(env.SYNC_SERVER.idFromName(id))
|
|
|
const data = await stub.getData()
|
|
|
+
|
|
|
let info
|
|
|
- const messages = {}
|
|
|
+ const messages: Record<string, any> = {}
|
|
|
+ let cost = 0
|
|
|
+ const models: Set<string> = new Set()
|
|
|
+ const version = "v0.1.1"
|
|
|
data.forEach((d) => {
|
|
|
const [root, type, ...splits] = d.key.split("/")
|
|
|
if (root !== "session") return
|
|
|
@@ -192,12 +197,36 @@ export default {
|
|
|
if (type === "message") {
|
|
|
const [, messageID] = splits
|
|
|
messages[messageID] = d.content
|
|
|
+
|
|
|
+ const assistant = d.content.metadata?.assistant
|
|
|
+ if (assistant) {
|
|
|
+ cost += assistant.cost
|
|
|
+ models.add(assistant.modelID)
|
|
|
+ }
|
|
|
}
|
|
|
})
|
|
|
|
|
|
- return new Response(JSON.stringify({ info, messages }), {
|
|
|
- headers: { "Content-Type": "application/json" },
|
|
|
- })
|
|
|
+ const encodedTitle = encodeURIComponent(
|
|
|
+ Base64.encode(
|
|
|
+ // Convert to ASCII
|
|
|
+ encodeURIComponent(
|
|
|
+ // Truncate to fit S3's max key size
|
|
|
+ info.title.substring(0, 700),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ const encodedCost = encodeURIComponent(`$${cost.toFixed(2)}`)
|
|
|
+
|
|
|
+ return new Response(
|
|
|
+ JSON.stringify({
|
|
|
+ info,
|
|
|
+ messages,
|
|
|
+ ogImage: `https://social-cards.sst.dev/opencode-share/${encodedTitle}.png?cost=${encodedCost}&model=${Array.from(models).join(",")}&version=${version}&id=${id}`,
|
|
|
+ }),
|
|
|
+ {
|
|
|
+ headers: { "Content-Type": "application/json" },
|
|
|
+ },
|
|
|
+ )
|
|
|
}
|
|
|
},
|
|
|
}
|