diff --git a/packages/iago/.env.example b/packages/iago/.env.example new file mode 100644 index 0000000..53cb43e --- /dev/null +++ b/packages/iago/.env.example @@ -0,0 +1,2 @@ +OPENAI_API_KEY=your-key +IAGO_CAMERA=Camera Name \ No newline at end of file diff --git a/packages/iago/package.json b/packages/iago/package.json index dcc030e..feecfe5 100644 --- a/packages/iago/package.json +++ b/packages/iago/package.json @@ -5,7 +5,10 @@ "private": true, "scripts": { "dev": "bun run --hot server.ts", - "start": "bun run server.ts" + "start": "bun run server.ts", + "mini:deploy": "bun scripts/deploy.ts deploy", + "mini:start": "bun scripts/deploy.ts start", + "mini:stop": "bun scripts/deploy.ts stop" }, "devDependencies": { "@types/bun": "latest" diff --git a/packages/iago/photo.jpg b/packages/iago/photo.jpg deleted file mode 100644 index 6041a65..0000000 Binary files a/packages/iago/photo.jpg and /dev/null differ diff --git a/packages/iago/scripts/deploy.ts b/packages/iago/scripts/deploy.ts new file mode 100644 index 0000000..f8e858f --- /dev/null +++ b/packages/iago/scripts/deploy.ts @@ -0,0 +1,33 @@ +import { $ } from "bun" + +const REMOTE = "iago@iago-mac-mini.local" +const REMOTE_PATH = "/Users/iago/iago" +const LOCAL_PATH = "." + +async function deploy() { + await $`rsync -avz --exclude=.env --exclude=node_modules --exclude=.git ${LOCAL_PATH} ${REMOTE}:${REMOTE_PATH}` +} + +async function start() { + await $`ssh ${REMOTE} 'cd ${REMOTE_PATH} && nohup bun run start > out.log 2>&1 &'` +} + +async function stop() { + await $`ssh ${REMOTE} 'pkill -f "bun run start" || true'` +} + +async function main() { + const cmd = Bun.argv[2] + if (cmd === "deploy") { + await deploy() + } else if (cmd === "start") { + await start() + } else if (cmd === "stop") { + await stop() + } else { + console.log("Usage: bun run deploy|start|stop") + process.exit(1) + } +} + +await main() \ No newline at end of file diff --git a/packages/iago/server.ts b/packages/iago/server.ts index 1cf2fd9..7e26bec 100644 --- a/packages/iago/server.ts +++ b/packages/iago/server.ts @@ -1,5 +1,4 @@ import { $ } from "bun" -import path from "path" import { Hono } from "hono" import { openai, createFile } from "./src/openai" import { serveStatic } from "hono/bun" @@ -43,7 +42,7 @@ app.get("/capture", async (c) => { // capture and analyze image app.get("/analyze", async (c) => { try { - // await runImagesnap() + await runImagesnap() const fileId = await createFile(IMAGE_PATH) @@ -66,6 +65,33 @@ app.get("/analyze", async (c) => { } }) + +// capture and analyze image, return HTML +app.get("/analyze.html", async (c) => { + try { + await runImagesnap() + + const fileId = await createFile(IMAGE_PATH) + + const result = await openai.responses.create({ + model: "gpt-4o", + input: [ + { + role: "user", + content: [ + { type: "input_text", text: "This image contains a corkboard with index cards on it. Please return the text content of each index card followed by a line break, and nothing else." }, + { type: "input_image", file_id: fileId, detail: "high" } + ] + } + ] + }) + + return c.html(`

corkboard

`) + } catch (err: any) { + return c.json({ error: err.message }, 500) + } +}) + app.get("/speak", async (c) => { const mp3 = await openai.audio.speech.create({ model: "gpt-4o-mini-tts", @@ -143,4 +169,5 @@ async function getDevices(): Promise { export default { port: 3000, fetch: app.fetch, + idleTimeout: 255 } \ No newline at end of file