simple daytona example

This commit is contained in:
gabriel ruttner
2025-10-20 09:39:46 -04:00
parent c6e154fd03
commit 4374bb32b3
8 changed files with 2444 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
import { Hatchet } from '@hatchet-dev/typescript-sdk';
import { Daytona } from '@daytonaio/sdk'
export const hatchet = Hatchet.init();
export const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY });

View File

@@ -0,0 +1,27 @@
import { hatchet } from './clients';
import { generate, execute } from './tasks'
export type OrchestrationTaskInput = {
prompt: string;
};
export const orchestrate = hatchet.durableTask({
name: 'orchestration-task',
fn: async ({ prompt }: OrchestrationTaskInput) => {
const { code } = await generate.run({
prompt
})
// NOTE: uncomment this line for the demo of durable execution
// throw new Error("🐛")
const result = await execute.run({
code
})
return {
result
};
},
});

View File

@@ -0,0 +1,15 @@
{
"type": "module",
"scripts": {
"dev": "dotenv -- npx tsx --watch worker.mts"
},
"dependencies": {
"@ai-sdk/openai": "^2.0.14",
"@daytonaio/sdk": "^0.25.5",
"@hatchet-dev/typescript-sdk": "^1.9.3",
"ai": "^5.0.14"
},
"devDependencies": {
"dotenv-cli": "^10.0.0"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
import { hatchet, daytona } from '../clients';
export type ExecuteCodeInput = {
code: string;
};
export const execute = hatchet.task({
name: 'execute-code',
retries: 3,
fn: async (input: ExecuteCodeInput) => {
// Create the Sandbox instance
const sandbox = await daytona.create({
user: 'hatchet',
language: 'python',
});
try {
// Run the provided code securely inside the Sandbox
const response = await sandbox.process.codeRun(input.code);
console.log('Code execution result:', response.result);
return {
result: response.result.trim()
};
} catch (error) {
console.error('Code execution failed:', error);
return {
result: `Error executing code: ${error instanceof Error ? error.message : String(error)}`
};
} finally {
// Stop the Sandbox
await sandbox.stop();
}
},
});

View File

@@ -0,0 +1,32 @@
import { hatchet } from '../clients';
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
export type GenerateCodeInput = {
prompt: string;
};
export const generate = hatchet.task({
name: 'generate',
retries: 3,
fn: async (input: GenerateCodeInput) => {
const { text: code } = await generateText({
model: openai('gpt-4o-mini'),
messages: [
{
role: 'system',
content: 'You are a Python code generator. Generate only pure Python code that satisfies the user\'s request. Do not include any explanations, markdown formatting, or code blocks - just return the raw Python code that can be executed directly.'
},
{
role: 'user',
content: input.prompt
}
],
temperature: 0.7,
});
return {
code
};
},
});

View File

@@ -0,0 +1,2 @@
export * from "./execute-code"
export * from "./generate-code"

View File

@@ -0,0 +1,14 @@
import { hatchet } from './clients';
import { orchestrate } from './orchestration';
import { generate, execute } from './tasks';
async function main() {
const worker = await hatchet.worker('simple-worker', {
workflows: [generate, execute, orchestrate],
});
await worker.start();
}
// Run main function when this file is executed directly
main().catch(console.error);