From 86afc05ae714f5a52a5f9a0a7492120b0321aa57 Mon Sep 17 00:00:00 2001 From: Jacob Valdez Date: Mon, 16 Feb 2026 12:26:32 -0800 Subject: [PATCH 1/4] docs: add demo app section to README and quickstart notebook - Added demo app links and descriptions to README - Added examples/quickstart.ipynb demonstrating remote browser agent usage with tslab kernel: create session, send task with streaming, screenshots, session control, and high-level API Co-Authored-By: Claude Opus 4.6 --- README.md | 14 +++ examples/quickstart.ipynb | 201 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 examples/quickstart.ipynb diff --git a/README.md b/README.md index 0977469..1c8f3dc 100644 --- a/README.md +++ b/README.md @@ -514,6 +514,20 @@ npx tsx examples/research/competitor-analysis.ts \ --- +## Demo App + +An interactive Electron desktop GUI that showcases all SDK capabilities — sessions, SSE streaming, screenshots, pause/resume/cancel, and quick action cards. + +**[agi-inc/demo-node-electron](https://github.com/agi-inc/demo-node-electron)** + +```bash +git clone https://github.com/agi-inc/demo-node-electron.git && cd demo-node-electron +npm install +AGI_API_KEY=your-key npx electron --require ts-node/register main.ts +``` + +--- + ## Documentation & Resources **Learn More** diff --git a/examples/quickstart.ipynb b/examples/quickstart.ipynb new file mode 100644 index 0000000..e3abbc4 --- /dev/null +++ b/examples/quickstart.ipynb @@ -0,0 +1,201 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# AGI Node.js SDK - Quickstart\n", + "This notebook demonstrates how to use the AGI Node.js SDK to create and control remote browser agents." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "Import the SDK and create a client." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import { AGIClient } from 'agi';\n", + "\n", + "const client = new AGIClient({ apiKey: process.env.AGI_API_KEY });\n", + "console.log('Connected to AGI API');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a Session\n", + "Create a remote browser session using the `agi-0` agent." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "const session = await client.sessions.create('agi-0');\n", + "console.log(`Session ID: ${session.sessionId}`);\n", + "console.log(`Status: ${session.status}`);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Send a Task\n", + "Send a task to the agent and stream the results in real-time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "await client.sessions.sendMessage(session.sessionId, 'What is the current time? Search Google to find out.');\n", + "\n", + "for await (const event of client.sessions.streamEvents(session.sessionId)) {\n", + " const eventType = event.event;\n", + " let content = '';\n", + " \n", + " if (event.data) {\n", + " const data = event.data;\n", + " if (typeof data === 'object') {\n", + " content = data.content || data.message || data.text || JSON.stringify(data);\n", + " } else {\n", + " content = String(data);\n", + " }\n", + " }\n", + " \n", + " switch (eventType) {\n", + " case 'thought':\n", + " console.log(`Thought: ${content.slice(0, 100)}`);\n", + " break;\n", + " case 'step':\n", + " console.log(`Step: ${content.slice(0, 100)}`);\n", + " break;\n", + " case 'done':\n", + " console.log(`Done: ${content.slice(0, 200)}`);\n", + " break;\n", + " case 'error':\n", + " console.log(`Error: ${content}`);\n", + " break;\n", + " case 'question':\n", + " console.log(`Agent asks: ${content}`);\n", + " break;\n", + " }\n", + " \n", + " if (eventType === 'done' || eventType === 'error') break;\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Take a Screenshot\n", + "Capture the current state of the remote browser." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "const screenshot = await client.sessions.screenshot(session.sessionId);\n", + "let imgData = screenshot.screenshot;\n", + "if (imgData.includes(',')) {\n", + " imgData = imgData.split(',')[1];\n", + "}\n", + "// Display as base64 image\n", + "const buffer = Buffer.from(imgData, 'base64');\n", + "console.log(`Screenshot captured (${buffer.length} bytes)`);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Session Control\n", + "Pause, resume, or cancel the agent." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "await client.sessions.pause(session.sessionId);\n", + "console.log('Session paused');\n", + "\n", + "await client.sessions.resume(session.sessionId);\n", + "console.log('Session resumed');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cleanup\n", + "Delete the session when done." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "await client.sessions.delete(session.sessionId);\n", + "console.log('Session deleted');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using the High-Level API\n", + "The recommended way - handles cleanup automatically." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "{\n", + " await using const session = client.session('agi-0');\n", + " const result = await session.runTask('Search for the latest Node.js LTS version');\n", + " console.log(`Result: ${result.data}`);\n", + " console.log(`Duration: ${result.metadata.duration}s`);\n", + " console.log(`Steps: ${result.metadata.steps}`);\n", + "}" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "TypeScript", + "language": "typescript", + "name": "tslab" + }, + "language_info": { + "name": "typescript", + "version": "5.0.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file From 4989ee82e85bbd3e67147c47a99843be3e75b905 Mon Sep 17 00:00:00 2001 From: Jacob Valdez Date: Mon, 16 Feb 2026 14:05:36 -0800 Subject: [PATCH 2/4] fix(docs): remove invalid `const` from `await using` declaration `await using const` is not valid syntax per TC39 Explicit Resource Management proposal. Changed to `await using session = ...`. Co-Authored-By: Claude Opus 4.6 --- examples/quickstart.ipynb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/examples/quickstart.ipynb b/examples/quickstart.ipynb index e3abbc4..e23ea88 100644 --- a/examples/quickstart.ipynb +++ b/examples/quickstart.ipynb @@ -174,15 +174,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "{\n", - " await using const session = client.session('agi-0');\n", - " const result = await session.runTask('Search for the latest Node.js LTS version');\n", - " console.log(`Result: ${result.data}`);\n", - " console.log(`Duration: ${result.metadata.duration}s`);\n", - " console.log(`Steps: ${result.metadata.steps}`);\n", - "}" - ] + "source": "{\n await using session = client.session('agi-0');\n const result = await session.runTask('Search for the latest Node.js LTS version');\n console.log(`Result: ${result.data}`);\n console.log(`Duration: ${result.metadata.duration}s`);\n console.log(`Steps: ${result.metadata.steps}`);\n}" } ], "metadata": { From 8425b84f17067e39b6784546c139fc32d1114444 Mon Sep 17 00:00:00 2001 From: Jacob Valdez Date: Mon, 16 Feb 2026 16:52:41 -0800 Subject: [PATCH 3/4] refactor(docs): replace Jupyter notebook with quickstart-remote.ts script Removed examples/quickstart.ipynb and added examples/basic/quickstart-remote.ts to match existing example conventions. Covers the same content: session creation, task streaming, screenshots, pause/resume, cleanup, and high-level API. Co-Authored-By: Claude Opus 4.6 --- examples/basic/quickstart-remote.ts | 98 ++++++++++++++ examples/quickstart.ipynb | 193 ---------------------------- 2 files changed, 98 insertions(+), 193 deletions(-) create mode 100644 examples/basic/quickstart-remote.ts delete mode 100644 examples/quickstart.ipynb diff --git a/examples/basic/quickstart-remote.ts b/examples/basic/quickstart-remote.ts new file mode 100644 index 0000000..06f5fb1 --- /dev/null +++ b/examples/basic/quickstart-remote.ts @@ -0,0 +1,98 @@ +/** + * Remote browser agent quickstart + * + * Demonstrates the full SDK workflow: create a session, send a task + * with real-time event streaming, take a screenshot, pause/resume, + * and clean up. + * + * Usage: + * AGI_API_KEY=sk-... npx ts-node examples/basic/quickstart-remote.ts + */ + +import { AGIClient } from '../../src'; + +const client = new AGIClient({ apiKey: process.env.AGI_API_KEY || 'your-api-key' }); + +async function main() { + // --- Low-level API (explicit lifecycle) --- + + // 1. Create a remote browser session + const session = await client.sessions.create('agi-0'); + console.log(`Session ID: ${session.sessionId}`); + console.log(`Status: ${session.status}\n`); + + // 2. Send a task and stream events + await client.sessions.sendMessage( + session.sessionId, + 'What is the current time? Search Google to find out.' + ); + + for await (const event of client.sessions.streamEvents(session.sessionId)) { + const eventType = event.event; + let content = ''; + + if (event.data) { + const data = event.data as Record; + if (typeof data === 'object') { + content = String(data.content || data.message || data.text || JSON.stringify(data)); + } else { + content = String(data); + } + } + + switch (eventType) { + case 'thought': + console.log(` Thought: ${content.slice(0, 100)}`); + break; + case 'step': + console.log(` Step: ${content.slice(0, 100)}`); + break; + case 'done': + console.log(`\n Done: ${content.slice(0, 200)}`); + break; + case 'error': + console.log(`\n Error: ${content}`); + break; + case 'question': + console.log(` Agent asks: ${content}`); + break; + } + + if (eventType === 'done' || eventType === 'error') break; + } + + // 3. Take a screenshot + const screenshot = await client.sessions.screenshot(session.sessionId); + const imgData = screenshot.screenshot.includes(',') + ? screenshot.screenshot.split(',')[1] + : screenshot.screenshot; + const buffer = Buffer.from(imgData, 'base64'); + console.log(`\nScreenshot captured (${buffer.length} bytes)`); + + // 4. Session control + await client.sessions.pause(session.sessionId); + console.log('Session paused'); + + await client.sessions.resume(session.sessionId); + console.log('Session resumed'); + + // 5. Cleanup + await client.sessions.delete(session.sessionId); + console.log('Session deleted\n'); + + // --- High-level API (recommended) --- + + console.log('--- High-level API ---'); + { + await using session = client.session('agi-0'); + const result = await session.runTask( + 'Search for the latest Node.js LTS version' + ); + console.log(`Result: ${result.data}`); + console.log(`Duration: ${result.metadata.duration}s`); + console.log(`Steps: ${result.metadata.steps}`); + } + // Session automatically deleted when scope exits +} + +main().catch(console.error); diff --git a/examples/quickstart.ipynb b/examples/quickstart.ipynb deleted file mode 100644 index e23ea88..0000000 --- a/examples/quickstart.ipynb +++ /dev/null @@ -1,193 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# AGI Node.js SDK - Quickstart\n", - "This notebook demonstrates how to use the AGI Node.js SDK to create and control remote browser agents." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Setup\n", - "Import the SDK and create a client." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import { AGIClient } from 'agi';\n", - "\n", - "const client = new AGIClient({ apiKey: process.env.AGI_API_KEY });\n", - "console.log('Connected to AGI API');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a Session\n", - "Create a remote browser session using the `agi-0` agent." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "const session = await client.sessions.create('agi-0');\n", - "console.log(`Session ID: ${session.sessionId}`);\n", - "console.log(`Status: ${session.status}`);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Send a Task\n", - "Send a task to the agent and stream the results in real-time." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "await client.sessions.sendMessage(session.sessionId, 'What is the current time? Search Google to find out.');\n", - "\n", - "for await (const event of client.sessions.streamEvents(session.sessionId)) {\n", - " const eventType = event.event;\n", - " let content = '';\n", - " \n", - " if (event.data) {\n", - " const data = event.data;\n", - " if (typeof data === 'object') {\n", - " content = data.content || data.message || data.text || JSON.stringify(data);\n", - " } else {\n", - " content = String(data);\n", - " }\n", - " }\n", - " \n", - " switch (eventType) {\n", - " case 'thought':\n", - " console.log(`Thought: ${content.slice(0, 100)}`);\n", - " break;\n", - " case 'step':\n", - " console.log(`Step: ${content.slice(0, 100)}`);\n", - " break;\n", - " case 'done':\n", - " console.log(`Done: ${content.slice(0, 200)}`);\n", - " break;\n", - " case 'error':\n", - " console.log(`Error: ${content}`);\n", - " break;\n", - " case 'question':\n", - " console.log(`Agent asks: ${content}`);\n", - " break;\n", - " }\n", - " \n", - " if (eventType === 'done' || eventType === 'error') break;\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Take a Screenshot\n", - "Capture the current state of the remote browser." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "const screenshot = await client.sessions.screenshot(session.sessionId);\n", - "let imgData = screenshot.screenshot;\n", - "if (imgData.includes(',')) {\n", - " imgData = imgData.split(',')[1];\n", - "}\n", - "// Display as base64 image\n", - "const buffer = Buffer.from(imgData, 'base64');\n", - "console.log(`Screenshot captured (${buffer.length} bytes)`);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Session Control\n", - "Pause, resume, or cancel the agent." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "await client.sessions.pause(session.sessionId);\n", - "console.log('Session paused');\n", - "\n", - "await client.sessions.resume(session.sessionId);\n", - "console.log('Session resumed');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Cleanup\n", - "Delete the session when done." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "await client.sessions.delete(session.sessionId);\n", - "console.log('Session deleted');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Using the High-Level API\n", - "The recommended way - handles cleanup automatically." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": "{\n await using session = client.session('agi-0');\n const result = await session.runTask('Search for the latest Node.js LTS version');\n console.log(`Result: ${result.data}`);\n console.log(`Duration: ${result.metadata.duration}s`);\n console.log(`Steps: ${result.metadata.steps}`);\n}" - } - ], - "metadata": { - "kernelspec": { - "display_name": "TypeScript", - "language": "typescript", - "name": "tslab" - }, - "language_info": { - "name": "typescript", - "version": "5.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file From 710a764ce756d08fc4c984a601cf1172a1539445 Mon Sep 17 00:00:00 2001 From: Jacob Valdez Date: Mon, 16 Feb 2026 18:22:03 -0800 Subject: [PATCH 4/4] style: fix prettier formatting in quickstart-remote example Co-Authored-By: Claude Opus 4.6 --- examples/basic/quickstart-remote.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/basic/quickstart-remote.ts b/examples/basic/quickstart-remote.ts index 06f5fb1..5e18834 100644 --- a/examples/basic/quickstart-remote.ts +++ b/examples/basic/quickstart-remote.ts @@ -85,9 +85,7 @@ async function main() { console.log('--- High-level API ---'); { await using session = client.session('agi-0'); - const result = await session.runTask( - 'Search for the latest Node.js LTS version' - ); + const result = await session.runTask('Search for the latest Node.js LTS version'); console.log(`Result: ${result.data}`); console.log(`Duration: ${result.metadata.duration}s`); console.log(`Steps: ${result.metadata.steps}`);