Skip to content

Commit ca3548a

Browse files
committed
feat(web): redirect agent page to latest version
1 parent 7ec5eee commit ca3548a

File tree

1 file changed

+101
-0
lines changed
  • web/src/app/publishers/[id]/agents/[agentId]

1 file changed

+101
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { env } from '@codebuff/common/env'
2+
import db from '@codebuff/internal/db'
3+
import * as schema from '@codebuff/internal/db/schema'
4+
import { and, desc, eq } from 'drizzle-orm'
5+
import { notFound, redirect } from 'next/navigation'
6+
7+
interface AgentRedirectPageProps {
8+
params: {
9+
id: string // publisher id
10+
agentId: string
11+
}
12+
}
13+
14+
export async function generateMetadata({ params }: AgentRedirectPageProps) {
15+
const agent = await db
16+
.select({
17+
data: schema.agentConfig.data,
18+
version: schema.agentConfig.version,
19+
})
20+
.from(schema.agentConfig)
21+
.where(
22+
and(
23+
eq(schema.agentConfig.publisher_id, params.id),
24+
eq(schema.agentConfig.id, params.agentId),
25+
),
26+
)
27+
.orderBy(desc(schema.agentConfig.created_at))
28+
.limit(1)
29+
30+
if (agent.length === 0) {
31+
return {
32+
title: 'Agent Not Found',
33+
}
34+
}
35+
36+
const agentData =
37+
typeof agent[0].data === 'string'
38+
? JSON.parse(agent[0].data)
39+
: agent[0].data
40+
const agentName = agentData.name || params.agentId
41+
42+
// Fetch publisher for OG image
43+
const pub = await db
44+
.select()
45+
.from(schema.publisher)
46+
.where(eq(schema.publisher.id, params.id))
47+
.limit(1)
48+
49+
const title = `${agentName} - Agent Details`
50+
const description =
51+
agentData.description || `View details for ${agentName} agent`
52+
const ogImages = (pub?.[0]?.avatar_url ? [pub[0].avatar_url] : []) as string[]
53+
54+
// Canonical URL points to the versioned page to avoid duplicate content
55+
const canonicalUrl = `${env.NEXT_PUBLIC_CODEBUFF_APP_URL}/publishers/${params.id}/agents/${params.agentId}/${agent[0].version}`
56+
57+
return {
58+
title,
59+
description,
60+
alternates: {
61+
canonical: canonicalUrl,
62+
},
63+
openGraph: {
64+
title,
65+
description,
66+
type: 'article',
67+
images: ogImages,
68+
},
69+
}
70+
}
71+
72+
/**
73+
* This page redirects to the latest version of an agent.
74+
* URL: /publishers/{publisherId}/agents/{agentId}
75+
* Redirects to: /publishers/{publisherId}/agents/{agentId}/{latestVersion}
76+
*/
77+
const AgentRedirectPage = async ({ params }: AgentRedirectPageProps) => {
78+
// Get the latest version of this agent (most recent by created_at)
79+
const latestVersion = await db
80+
.select({
81+
version: schema.agentConfig.version,
82+
})
83+
.from(schema.agentConfig)
84+
.where(
85+
and(
86+
eq(schema.agentConfig.publisher_id, params.id),
87+
eq(schema.agentConfig.id, params.agentId),
88+
),
89+
)
90+
.orderBy(desc(schema.agentConfig.created_at))
91+
.limit(1)
92+
93+
if (latestVersion.length === 0) {
94+
notFound()
95+
}
96+
97+
// Redirect to the latest version
98+
redirect(`/publishers/${params.id}/agents/${params.agentId}/${latestVersion[0].version}`)
99+
}
100+
101+
export default AgentRedirectPage

0 commit comments

Comments
 (0)