Defining an agent
import { createSchemaAgent } from "@hackdance/agents"
import { coreAgentSchema } from "./schema"
export const primaryIdentity = `
You are an ai agent tasked with creating mock data
`
export const exampleAgent = createSchemaAgent({
config: {
model: "gpt-4",
max_tokens: 650,
temperature: 0.7
},
// identityMessages are just optional messages
// that get prepended to every completion request on the instance.
identityMessages: [
{
role: "system",
content: primaryIdentity
}
],
schema: coreAgentSchema
})
// ./schema.ts (defined in sep file since
// we import both into a client component and a server context)
import z from "zod"
export const coreAgentSchema = z.object({
listOfRandomDogNames: z.array(z.string()).min(10),
listOfRandomUsers: z
.array(
z.object({
name: z.object({
first: z.string(),
last: z.string(),
displayName: z.string()
}),
email: z.string(),
phone: z.string()
})
)
.min(10)
})
Completion stream endpoint
(example using Next.js api route on vercel)import { createSchemaAgent } from "@hackdance/agents"
import { exampleAgent } from "@/ai/agents/core/schema"
export const runtime = "edge"
export async function POST(request: Request): Promise<Response> {
const { messages, prompt } = await request.json()
const stream = await exampleAgent.completionStream({
messages: messages.map(message => ({
content: message.content,
role: message.role
}))
// we filter back down to valid OAI messages
// in case we store anything else on the
// message to persist elsewhere.
})
return new Response(stream)
}
Consuming the stream in the ui
import { exampleAgent } from "@/ai/agents/core/schema"
import { useState } from "react"
export function StreamTest() {
const [result, setResult] = useState({})
const {
startStream,
stopStream,
loading,
activeKey,
completedKeys
} = useJsonStream({
schema: coreAgentSchema,
onReceive: data => {
setResult(data)
},
onEnd: data => {
setResult(data)
}
})
const go = async () => {
try {
await startStream({
url: "/api/ai/chat",
body: {
key: key,
prompt: prompt,
messages: []
}
})
} catch (e) {
stopStream()
}
}
return (
<div>
<div>
{
Object.keys(result)
.map(key => (
`key ${key === activeKey && "(active)"}:
${result[key]}`)
))
}
</div>
<button onClick={go}>Go</button>
</div>
)
}