{"id":27888639,"url":"https://github.com/oneirocom/nitro-agent","last_synced_at":"2025-07-27T11:33:17.248Z","repository":{"id":254331047,"uuid":"837294982","full_name":"Oneirocom/nitro-agent","owner":"Oneirocom","description":null,"archived":false,"fork":false,"pushed_at":"2024-11-28T00:22:44.000Z","size":1839,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-28T01:25:06.782Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Oneirocom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-02T16:24:42.000Z","updated_at":"2024-11-28T00:22:48.000Z","dependencies_parsed_at":"2024-08-31T14:45:09.861Z","dependency_job_id":null,"html_url":"https://github.com/Oneirocom/nitro-agent","commit_stats":null,"previous_names":["oneirocom/nitro-test"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oneirocom%2Fnitro-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oneirocom%2Fnitro-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oneirocom%2Fnitro-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oneirocom%2Fnitro-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Oneirocom","download_url":"https://codeload.github.com/Oneirocom/nitro-agent/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252470763,"owners_count":21753047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-05T09:10:16.595Z","updated_at":"2025-05-05T09:10:17.158Z","avatar_url":"https://github.com/Oneirocom.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Magick Agent Nitro Template\n\nThis repository serves as a template for deploying Agents created with Magick via the Nitro framework.\n\nNitro is is a framework for rapidly building serverless applications. It has a robust set of features, all of which are documented in the [Nitro documentation](https://nitro.unjs.io/).\n\n## Introduction\n\nThe Magick Agent Nitro Template is a template for deploying Agents created with Magick via the Nitro framework. Its purpose is to produce a standalone runtime bundle which includes your agent and which can be deployed to a variety of platforms.\n\nWe utilize the new nitro module system to extend the functionality of the nitro runtime to include the Magick agent class, and a set of structured folders to modify the behavior of the agent at runtime. This allows us to take advantage of the nitro runtime's robust set of features, such as websockets, routes, and more.\n\n## Requirements\n\nA Magick Agent has a number of requirements.\n\n- Postgres\n- Redis\n- Keywords\n- Embedder service\n\nThe purpose of these is:\n\n- **PostgreSQL database**: The agent stores its requests, state, eventsd, and more in a PostgreSQL database.\n- **Redis database**: Redis is used for caching the agents graph state for faster access and read/write operations. For advanced use cases, there are a number of events which the agent will emit, and you can listen for these events in your own code.\n- **Keywords service**: Keywords is our current LLM proxy provider. They provide a simple API for interacting with a variety of LLMs. They have observability, cost management, and more.\n- **Embedder URL and API key**: Currently our embedder service is the only hard dependency that the Agent has on our infrastructure. This is because, currently, knowledge is uploaded via the IDE UI, which means it winds up on our embedder service. This will change in the future. Our intention is to provide a folder for knowledge files in your repository, and have the agent pull that knowledge in during runtime.\n\n## Getting Started\n\n1. Fill in all required environment variables in `.env` file (see [Environment Variables](#environment-variables))\n2. Run `npm install` (this will also run `npm init` as a postinstall script)\n\nThe postinstall script runs migrations against the configured database and generates your Prisma client for your system. This will set up your database and create the necessary tables.\n\n## Running Locally\n\n`npm run dev`\n\n## Building for Production\n\n`npm run build`\n\n## Configuring Your Agent\n\nPlace your spell files from the Magick IDE into the `agent/spells` folder. These spells are loaded into the runtime to become active.\n\nWe will also be working to add some support for public variables, and multiple agents.\n\n## Interacting with Your Agent\n\nThe Agent is available in the Nitro runtime, allowing interaction through various Nitro library abstractions like routes and websockets. The agent uses a channel-based system for handling conversations, where each channel represents a unique conversation context.\n\nHere's an example of how to interact with your agent using channels:\n\n```typescript\nexport default defineEventHandler(async (event) =\u003e {\n  const body = await readBody(event);\n  const { prompt, userid } = body;\n  const nitro = useNitroApp();\n\n  // Function to communicate with agent through a channel\n  const sendMessageToAgent = async (content, channelId) =\u003e {\n    return new Promise((resolve, reject) =\u003e {\n      // Create a channel for this conversation\n      const channel = nitro.agent.channel(channelId);\n\n      // Set up message handler\n      channel.on(\"messageReceived\", (response) =\u003e {\n        channel.removeAllListeners();\n        resolve({\n          status: \"success\",\n          data: response.data,\n          event: response.event,\n        });\n      });\n\n      // Handle errors\n      channel.on(\"error\", (error) =\u003e {\n        channel.removeAllListeners();\n        reject(error);\n      });\n\n      // Send message through channel\n      channel.emitToAgent(\n        \"message\",\n        nitro.agent.formatEvent({\n          content: content,\n          sender: channelId,\n          channel: channelId,\n          eventName: \"message\",\n          skipPersist: true,\n          rawData: content,\n          metadata: {\n            sessionId: channelId,\n            timestamp: new Date().toISOString(),\n          },\n        })\n      );\n    });\n  };\n\n  try {\n    const result = await sendMessageToAgent(prompt, userid);\n    return {\n      message: \"Data received successfully\",\n      prompt: prompt,\n      generated: result,\n    };\n  } catch (error) {\n    return {\n      status: \"error\",\n      error: error,\n    };\n  }\n});\n```\n\n### Channel-Based Communication\n\nThe agent now uses a channel system for managing conversations:\n\n- Each conversation gets its own channel, typically identified by a user ID\n- Channels provide isolated communication contexts\n- Messages and responses are scoped to their specific channels\n- Channels automatically clean up listeners after message handling\n\nKey concepts:\n\n- `nitro.agent.channel(channelId)`: Creates/gets a channel for a specific conversation\n- `channel.emitToAgent()`: Sends a message through the channel\n- `channel.on(\"messageReceived\")`: Listens for responses on the channel\n- Each channel should handle its own cleanup by removing listeners after use\n\n### Message Format\n\nWhen sending messages to the agent, use the following format:\n\n```typescript\nnitro.agent.formatEvent({\n  content: \"Your message here\",\n  sender: \"user_id\",\n  channel: \"channel_id\",\n  eventName: \"message\",\n  skipPersist: true, // Set to false if you want to persist messages\n  rawData: \"Your message here\",\n  metadata: {\n    sessionId: \"channel_id\",\n    timestamp: new Date().toISOString(),\n  },\n});\n```\n\n## Agent Class\n\nThe Agent class acts as an event engine. You can send events (e.g., `message`) to the agent and listen for responses on the `messageReceived` event.\n\nExample usage:\n\n```typescript\nnitro.agent.emit(\n  \"message\",\n  nitro.agent.formatEvent({\n    content: \"Hello, Agent!\",\n    sender: \"user123\",\n    channel: \"session456\",\n    eventName: \"message\",\n    skipPersist: false,\n    rawData: \"Hello, Agent!\",\n  })\n);\n\nnitro.agent.on(\"messageReceived\", (response) =\u003e {\n  console.log(response.data.content);\n});\n```\n\nKey properties in `formatEvent`:\n\n- `sender`: Unique user ID\n- `channel`: Unique namespace for the interaction (e.g., user ID or game session)\n\n## Authentication\n\nWe do not handle authetication directly. Nitro has many authentication solutions which can be used, and users are expected to implement their own authentication solution.\n\nOnce you have a user, you can use the user's ID as the `sender` and the user's ID as the `channel` in the `formatEvent` function.\n\n## Environment Variables\n\nYou will need to fill in the following environment variables. Duplicate the `.env.example` file and rename it to `.env`. Fill in your values.\n\n```bash\nKEYWORDS_API_KEY=your_keywords_api_key\nKEYWORDS_API_URL=http://localhost:3000\nREDIS_URL=redis://localhost:6379\nDATABASE_URL=postgresql://user:password@localhost:5432/mydb\nAGENT_EMBEDDER_API_KEY=your_agent_embedder_api_key\nNEXT_PUBLIC_EMBEDDER_SERVER_URL=https://embedder-prod-production.up.railway.app/api\n```\n\n- `KEYWORDS_API_KEY`: API key for the keywords service\n- `KEYWORDS_API_URL`: URL for the keywords service\n- `REDIS_URL`: Redis connection string\n- `DATABASE_URL`: PostgreSQL connection string\n- `AGENT_EMBEDDER_API_KEY`: API key for accessing your agent's knowledge\n- `NEXT_PUBLIC_EMBEDDER_SERVER_URL`: URL for the embedder service\n\nTo obtain your `AGENT_EMBEDDER_API_KEY`:\n\n1. Go to the Knowledge tab in the Magick IDE\n2. Click the 'Generate Token' button\n3. Use the generated token as your `AGENT_EMBEDDER_API_KEY`\n\nThis key allows your agent to access its knowledge base.\n\n## Deployment\n\nAs with any Nitro application, you can deploy your application to a variety of platforms. You can find more information in the [Nitro deployment documentation](https://nitro.unjs.io/deploy).\n\n## Nitro.js Documentation\n\nFor more information on Nitro.js, visit the [official documentation](https://nitro.unjs.io/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foneirocom%2Fnitro-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foneirocom%2Fnitro-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foneirocom%2Fnitro-agent/lists"}