Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/ai-agent/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# OpenAI Configuration
OPENAI_API_KEY=sk-xxxxxxxxxxxx
API_NINJA_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Optional [will give dummy weather if not (100 F)]
5 changes: 5 additions & 0 deletions examples/ai-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
build/
.turbo/
.env
.env.local
93 changes: 93 additions & 0 deletions examples/ai-agent/actors/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { actor, setup } from "actor-core";
import { generateText, jsonSchema, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { getWeather } from "../utils/weather";
import dotenv from "dotenv";

dotenv.config();

export type Message = { role: "user" | "assistant"; content: string; timestamp: number; }

const aiAgent = actor({
// State is automatically persisted
state: {
messages: [] as Message[]
},

actions: {
// Get conversation history
getMessages: (c) => c.state.messages,

// Send a message to the AI and get a response
sendMessage: async (c, userMessage: string) => {
// Add user message to conversation
const userMsg: Message = {
role: "user",
content: userMessage,
timestamp: Date.now()
};
c.state.messages.push(userMsg);

// Generate AI response using Vercel AI SDK with tools
const out = await generateText({
model: openai("o3-mini"),
messages: c.state.messages,
tools: {
weather: tool({
description: 'Get the weather in a location',
parameters: jsonSchema<{ coords: { longitude: number, latitude: number } }>({
type: 'object',
properties: {
coords: {
type: 'object',
description: 'The location to get the weather for',
properties: {
longitude: {
type: 'number',
description: 'Longitude of the location'
},
latitude: {
type: 'number',
description: 'Latitude of the location'
}
},
required: ['longitude', 'latitude'],
additionalProperties: false
}
},
required: ['coords'],
additionalProperties: false
}),
execute: async ({ coords }) => {
return await getWeather(coords);
}
}),
},
maxSteps: 2,
});

const { text } = out;

// Add AI response to conversation
const assistantMsg: Message = {
role: "assistant",
content: text,
timestamp: Date.now()
};
c.state.messages.push(assistantMsg);

// Broadcast the new message to all connected clients
c.broadcast("messageReceived", assistantMsg);

return assistantMsg;
},
}
});

// Create and export the app
export const app = setup({
actors: { aiAgent },
});

// Export type for client type checking
export type App = typeof app;
52 changes: 52 additions & 0 deletions examples/ai-agent/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "ai-agent",
"version": "0.8.0",
"private": true,
"type": "module",
"main": "src/index.ts",
"scripts": {
"dev:actors": "npx @actor-core/cli@latest dev actors/app.ts",
"dev:frontend": "react-scripts start",
"build": "react-scripts build",
"check-types": "tsc --noEmit",
"test": "vitest run"
},
"dependencies": {
"@actor-core/react": "workspace:*",
"@ai-sdk/openai": "^1.3.16",
"@types/react": "^19",
"@types/react-dom": "^19",
"actor-core": "workspace:*",
"dotenv": "^16.5.0",
"react": "^19",
"react-dom": "^19",
"react-scripts": "^5.0.1"
},
Comment on lines +14 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code in actors/app.ts imports generateText, jsonSchema, and tool from the ai package, but this dependency is missing from the package.json file. Please add "ai": "^4.3.9" to the dependencies section to ensure the project builds correctly.

Suggested change
"dependencies": {
"@actor-core/react": "workspace:*",
"@ai-sdk/openai": "^1.3.16",
"@types/react": "^19",
"@types/react-dom": "^19",
"actor-core": "workspace:*",
"dotenv": "^16.5.0",
"react": "^19",
"react-dom": "^19",
"react-scripts": "^5.0.1"
},
"dependencies": {
"@actor-core/react": "workspace:*",
"@ai-sdk/openai": "^1.3.16",
"@types/react": "^19",
"@types/react-dom": "^19",
"actor-core": "workspace:*",
"ai": "^4.3.9",
"dotenv": "^16.5.0",
"react": "^19",
"react-dom": "^19",
"react-scripts": "^5.0.1"
},

Spotted by Diamond

Is this helpful? React 👍 or 👎 to let us know.

"devDependencies": {
"@actor-core/cli": "workspace:*",
"actor-core": "workspace:*",
"typescript": "^5.5.2"
},
"example": {
"platforms": [
"*"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"resolutions": {
"react@^19": "^19.0.0",
"react-dom@^19": "^19.0.0",
"react@^18": "^18.3"
}
}
37 changes: 37 additions & 0 deletions examples/ai-agent/public/github.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
body, html {
margin: 0;
padding: 0;
padding-top: 16px;
width: 100%;
height: 100%;
}
#example--repo-ref {
position: fixed;
top: 0px;
left: 0px;
cursor: pointer;
background-color: rgb(243, 243, 243);
height: 24px;
width: 100%;
padding: 8px 8px;
}
#example--github-icon {
height: 24px;
float: left;
}
#example--repo-link {
height: 24px;
margin-left: 8px;
color: rgb(45, 50, 55);
font-weight: bold;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
font-size: 15px;
vertical-align: middle;
}

#example--repo-ref:hover #example--repo-link {
color: black;
}
#example--repo-ref:hover svg {
fill: black !important;
}
27 changes: 27 additions & 0 deletions examples/ai-agent/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<title>AI Agent</title>
</head>
<link rel="stylesheet" href="github.css">
<body>
<!-- Github Notch -->
<div id="example--repo-ref">
<a id="example--github-icon" href="https://github.com/rivet-gg/actor-core/tree/main/examples/ai-agent" target="_blank">
<svg height="24" width="24" viewBox="0 0 16 16" style="fill: #24292e;">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
</svg>
</a>
<a id="example--repo-link" href="https://github.com/rivet-gg/actor-core/tree/main/examples/ai-agent">@rivet-gg/actor-core</a>
</div>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>

<link rel="stylesheet" href="./main.css">
</body>
</html>
93 changes: 93 additions & 0 deletions examples/ai-agent/public/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
.app {
max-width: 800px;
margin: 0 auto;
padding: 20px;
font-family:system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif
}

h1 {
text-align: center;
color: #333;
}

.ai-chat {
display: flex;
flex-direction: column;
height: 80vh;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}

.messages {
flex: 1;
overflow-y: auto;
padding: 20px;
}

.message {
display: flex;
margin-bottom: 20px;
align-items: flex-start;
}

.message .avatar {
font-size: 24px;
margin-right: 12px;
}

.message .content {
background: #f5f5f5;
padding: 12px;
border-radius: 8px;
max-width: 70%;
}

.message.user .content {
background: #007bff;
color: white;
}

.message.assistant .content {
background: #f8f9fa;
}

.message.loading .content {
font-style: italic;
color: #666;
}

.empty-message {
text-align: center;
color: #666;
margin-top: 40px;
}

.input-area {
display: flex;
padding: 20px;
border-top: 1px solid #ddd;
background: white;
}

.input-area input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
margin-right: 10px;
}

.input-area button {
padding: 10px 20px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}

.input-area button:disabled {
background: #ccc;
cursor: not-allowed;
}
Loading
Loading