diff --git a/README.md b/README.md index 2d149d5..5d8dbd5 100644 --- a/README.md +++ b/README.md @@ -352,6 +352,17 @@ var options = new SessionCreateOptions }; ``` +## Demo App + +An interactive Avalonia desktop GUI that showcases all SDK capabilities — sessions, SSE streaming, screenshots, pause/resume/cancel, and quick action cards. + +**[agi-inc/demo-csharp-avalonia](https://github.com/agi-inc/demo-csharp-avalonia)** + +```bash +git clone https://github.com/agi-inc/demo-csharp-avalonia.git && cd demo-csharp-avalonia +AGI_API_KEY=your-key dotnet run +``` + ## License MIT diff --git a/examples/quickstart.ipynb b/examples/quickstart.ipynb new file mode 100644 index 0000000..be77d7c --- /dev/null +++ b/examples/quickstart.ipynb @@ -0,0 +1,286 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# AGI C# SDK - Quickstart\n", + "This notebook demonstrates how to use the AGI C# SDK to create and control remote browser agents." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "Install the NuGet package and import the SDK." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": [ + "#r \"nuget: Agi, 0.5.0\"\n", + "\n", + "using Agi;\n", + "using Agi.Types;\n", + "\n", + "Console.WriteLine(\"AGI SDK loaded\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a Client\n", + "Initialize the client with your API key." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": [ + "// Uses AGI_API_KEY environment variable by default\n", + "var client = new AgiClient();\n", + "Console.WriteLine(\"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": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": [ + "var session = await client.Sessions.CreateAsync(\"agi-0\");\n", + "Console.WriteLine($\"Session ID: {session.SessionId}\");\n", + "Console.WriteLine($\"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": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": [ + "await client.Sessions.SendMessageAsync(session.SessionId, \"What is the current time? Search Google to find out.\");\n", + "\n", + "await foreach (var evt in client.Sessions.StreamEventsAsync(session.SessionId))\n", + "{\n", + " var eventType = evt.Event.ToString().ToLowerInvariant();\n", + " var content = \"\";\n", + " \n", + " try\n", + " {\n", + " var data = evt.Data;\n", + " if (data.ValueKind == System.Text.Json.JsonValueKind.Object)\n", + " {\n", + " if (data.TryGetProperty(\"content\", out var c)) content = c.ToString();\n", + " else if (data.TryGetProperty(\"message\", out var m)) content = m.ToString();\n", + " else if (data.TryGetProperty(\"text\", out var t)) content = t.ToString();\n", + " else content = data.ToString();\n", + " }\n", + " else content = data.ToString();\n", + " }\n", + " catch { content = evt.Data.ToString(); }\n", + "\n", + " switch (eventType)\n", + " {\n", + " case \"thought\":\n", + " Console.WriteLine($\"\\U0001f4ad {(content.Length > 100 ? content[..100] : content)}\");\n", + " break;\n", + " case \"step\":\n", + " Console.WriteLine($\"\\u25b6\\ufe0f {(content.Length > 100 ? content[..100] : content)}\");\n", + " break;\n", + " case \"done\":\n", + " Console.WriteLine($\"\\u2705 Done: {(content.Length > 200 ? content[..200] : content)}\");\n", + " break;\n", + " case \"error\":\n", + " Console.WriteLine($\"\\u274c Error: {content}\");\n", + " break;\n", + " case \"question\":\n", + " Console.WriteLine($\"\\u2753 Agent asks: {content}\");\n", + " break;\n", + " }\n", + " \n", + " if (eventType is \"done\" or \"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": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": "var screenshot = await client.Sessions.ScreenshotAsync(session.SessionId);\nvar imgData = screenshot.Data;\nif (imgData.Contains(\",\"))\n imgData = imgData.Split(\",\")[1];\n\nvar bytes = Convert.FromBase64String(imgData);\nConsole.WriteLine($\"Screenshot captured ({bytes.Length} bytes)\");" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Session Control\n", + "Pause, resume, or cancel the agent." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": [ + "await client.Sessions.PauseAsync(session.SessionId);\n", + "Console.WriteLine(\"Session paused\");\n", + "\n", + "await client.Sessions.ResumeAsync(session.SessionId);\n", + "Console.WriteLine(\"Session resumed\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cleanup\n", + "Delete the session when done." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": [ + "await client.Sessions.DeleteAsync(session.SessionId);\n", + "Console.WriteLine(\"Session deleted\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using the High-Level API\n", + "The recommended way - handles cleanup automatically with IAsyncDisposable." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [], + "source": [ + "await using var managedSession = await client.SessionAsync(\"agi-0\");\n", + "var result = await managedSession.RunTaskAsync(\n", + " \"Search for the latest .NET release version on dotnet.microsoft.com\");\n", + "Console.WriteLine($\"Result: {result.Data}\");\n", + "Console.WriteLine($\"Duration: {result.Metadata.Duration}s\");\n", + "Console.WriteLine($\"Steps: {result.Metadata.Steps}\");" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".NET (C#)", + "language": "C#", + "name": ".net-csharp" + }, + "language_info": { + "name": "csharp" + }, + "polyglot_notebook": { + "kernelInfo": { + "defaultKernelName": "csharp", + "items": [ + { + "aliases": [], + "languageName": "csharp", + "name": "csharp" + } + ] + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file