diff --git a/.github/workflows/package-smoke-test.yaml b/.github/workflows/package-smoke-test.yaml index 5bfa92368..d1265d3ed 100644 --- a/.github/workflows/package-smoke-test.yaml +++ b/.github/workflows/package-smoke-test.yaml @@ -66,82 +66,10 @@ jobs: - name: Run installation type detection tests run: bash packages/cli/scripts/test-installation-type.sh - standalone-agent-test: - runs-on: blacksmith-2vcpu-ubuntu-2404 - timeout-minutes: 5 - name: Standalone Agent Test - steps: - - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install - - - name: Build packages - run: bun run build - - - name: Run standalone agent test - run: bun run test:standalone - - integration-test: + testing-apps-test: runs-on: blacksmith-2vcpu-ubuntu-2404 timeout-minutes: 10 - name: SDK Integration Test Suite - env: - AGENTUITY_API_URL: https://api.agentuity.com - AGENTUITY_USER_ID: ${{ vars.AGENTUITY_USER_ID }} - AGENTUITY_CLOUD_ORG_ID: ${{ vars.AGENTUITY_CLOUD_ORG_ID }} - AGENTUITY_REGION: usc - steps: - - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install - - - name: Prepare SDK for testing - run: bash scripts/prepare-sdk-for-testing.sh - - - name: Install SDK in integration-suite - run: bash scripts/install-sdk-tarballs.sh apps/testing/integration-suite - - - name: Setup test credentials - run: | - # Generate CLI API key for authentication - APIKEY=$(curl $AGENTUITY_API_URL/cli/auth/short-token -H 'Content-Type: application/json' --data "{\"secret\":\"${{ secrets.AGENTUITY_APITOKEN_SHARED_SECRET }}\",\"userId\":\"${{ env.AGENTUITY_USER_ID }}\"}" | jq -r '.data.apiKey') - echo "::add-mask::${APIKEY}" - echo "AGENTUITY_CLI_API_KEY=${APIKEY}" >> $GITHUB_ENV - - # Set SDK key for integration-suite tests - echo "AGENTUITY_SDK_KEY=${{ secrets.INTEGRATION_SUITE_AGENTUITY_SDK_KEY }}" >> $GITHUB_ENV - - # Set OpenAI API key for embedding operations - echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> $GITHUB_ENV - - - name: Run integration test suite - run: bash apps/testing/integration-suite/scripts/ci-test.sh - - cloud-deployment-test: - runs-on: blacksmith-2vcpu-ubuntu-2404 - timeout-minutes: 15 - name: Cloud Deployment Tests - env: - AGENTUITY_API_URL: https://api.agentuity.com - AGENTUITY_APP_URL: https://app.agentuity.com - AGENTUITY_TRANSPORT_URL: https://catalyst-usc.agentuity.cloud - AGENTUITY_CATALYST_URL: https://catalyst-usc.agentuity.cloud - AGENTUITY_STREAM_URL: https://streams-usc.agentuity.cloud - AGENTUITY_KEYVALUE_URL: https://catalyst-usc.agentuity.cloud - AGENTUITY_SANDBOX_URL: https://catalyst-usc.agentuity.cloud - AGENTUITY_OBJECTSTORE_URL: https://catalyst-usc.agentuity.cloud - AGENTUITY_VECTOR_URL: https://catalyst-usc.agentuity.cloud - AGENTUITY_LOG_LEVEL: error - AGENTUITY_REGION: usc - AGENTUITY_USER_ID: ${{ vars.AGENTUITY_USER_ID }} + name: Testing Apps (local tests) steps: - uses: actions/checkout@v4 @@ -151,79 +79,17 @@ jobs: - name: Install dependencies run: bun install - - name: Prepare SDK for testing - run: bash scripts/prepare-sdk-for-testing.sh - - - name: Install SDK in cloud-deployment - run: bash scripts/install-sdk-tarballs.sh apps/testing/cloud-deployment - - - name: Setup test credentials - run: | - # Generate CLI API key for cloud operations - APIKEY=$(curl $AGENTUITY_API_URL/cli/auth/short-token -H 'Content-Type: application/json' --data "{\"secret\":\"${{ secrets.AGENTUITY_APITOKEN_SHARED_SECRET }}\",\"userId\":\"${{ env.AGENTUITY_USER_ID }}\"}" | jq -r '.data.apiKey') - echo "::add-mask::${APIKEY}" - echo "AGENTUITY_CLI_API_KEY=${APIKEY}" >> $GITHUB_ENV - - # Set SDK key for runtime operations - echo "AGENTUITY_SDK_KEY=${{ secrets.CLOUD_DEPLOYMENT_AGENTUITY_SDK_KEY }}" >> $GITHUB_ENV - - # Set OpenAI API key for embedding operations - echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> $GITHUB_ENV - - - name: Create .env file for app runtime - run: | - cd apps/testing/cloud-deployment - cat > .env << EOF - AGENTUITY_SDK_KEY=${{ secrets.CLOUD_DEPLOYMENT_AGENTUITY_SDK_KEY }} - OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }} - AGENTUITY_API_URL=$AGENTUITY_API_URL - AGENTUITY_APP_URL=$AGENTUITY_APP_URL - AGENTUITY_TRANSPORT_URL=$AGENTUITY_TRANSPORT_URL - AGENTUITY_CATALYST_URL=$AGENTUITY_CATALYST_URL - AGENTUITY_STREAM_URL=$AGENTUITY_STREAM_URL - AGENTUITY_KEYVALUE_URL=$AGENTUITY_KEYVALUE_URL - AGENTUITY_SANDBOX_URL=$AGENTUITY_SANDBOX_URL - AGENTUITY_OBJECTSTORE_URL=$AGENTUITY_OBJECTSTORE_URL - AGENTUITY_VECTOR_URL=$AGENTUITY_VECTOR_URL - AGENTUITY_LOG_LEVEL=$AGENTUITY_LOG_LEVEL - AGENTUITY_REGION=$AGENTUITY_REGION - EOF - - - name: Run cloud deployment tests - run: bash scripts/test-cloud-deployment.sh - - # TODO: Re-enable after artifact storage quota resets (disabled 2026-02-01) - # - name: Upload deployment logs - # if: failure() - # uses: actions/upload-artifact@v4 - # with: - # name: deployment-logs - # path: ~/.config/agentuity/logs/ - # if-no-files-found: ignore - # retention-days: 1 - - - name: Cleanup - if: always() - run: rm -rf apps/testing/cloud-deployment/.env - - template-integration-test: - runs-on: blacksmith-2vcpu-ubuntu-2404 - timeout-minutes: 30 - name: Template Integration Tests - steps: - - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 + - name: Run standalone-backend tests + run: cd apps/testing/standalone-backend && bun test - - name: Install dependencies - run: bun install + - name: Run oauth tests + run: cd apps/testing/oauth && bun test - - name: Build packages - run: bun run build + - name: Run e2e-web tests + run: cd apps/testing/e2e-web && bun test - - name: Run template integration tests - run: bun scripts/test-templates.ts --skip-outdated + - name: Run integration-suite tests + run: cd apps/testing/integration-suite && bun test sandbox-cli-test: runs-on: blacksmith-2vcpu-ubuntu-2404 @@ -256,36 +122,6 @@ jobs: - name: Run sandbox CLI tests run: bash scripts/test-sandbox.sh - storage-cli-test: - runs-on: blacksmith-2vcpu-ubuntu-2404 - timeout-minutes: 10 - name: Storage CLI Tests - env: - AGENTUITY_API_URL: https://api.agentuity.com - AGENTUITY_USER_ID: ${{ vars.AGENTUITY_USER_ID }} - AGENTUITY_CLOUD_ORG_ID: ${{ vars.AGENTUITY_CLOUD_ORG_ID }} - AGENTUITY_REGION: usc - steps: - - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install - - - name: Build packages - run: bun run build - - - name: Setup test credentials - run: | - # Generate CLI API key for authentication - APIKEY=$(curl $AGENTUITY_API_URL/cli/auth/short-token -H 'Content-Type: application/json' --data "{\"secret\":\"${{ secrets.AGENTUITY_APITOKEN_SHARED_SECRET }}\",\"userId\":\"${{ env.AGENTUITY_USER_ID }}\"}" | jq -r '.data.apiKey') - echo "::add-mask::${APIKEY}" - echo "AGENTUITY_CLI_API_KEY=${APIKEY}" >> $GITHUB_ENV - - - name: Run storage CLI tests - run: bun scripts/test-storage.ts queue-sdk-test: runs-on: blacksmith-2vcpu-ubuntu-2404 @@ -347,48 +183,10 @@ jobs: - name: Run queue CLI tests run: bash scripts/test-queue.sh - playwright-e2e-test: - runs-on: blacksmith-4vcpu-ubuntu-2204 - timeout-minutes: 15 - name: Playwright E2E Smoke Test - steps: - - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install - - - name: Install Playwright browsers - run: bunx playwright install --with-deps chromium - - - name: Prepare SDK for testing - timeout-minutes: 5 - run: bash scripts/prepare-sdk-for-testing.sh --packages-only - - - name: Install SDK in e2e-web - run: bash scripts/install-sdk-tarballs.sh apps/testing/e2e-web - - # No explicit build step needed: playwright.config.ts webServer starts - # "bun run dev" which compiles on-the-fly via Vite. A production build - # would be redundant since e2e tests run against the dev server. - - name: Run Playwright E2E tests - run: bun run test:e2e - - # TODO: Re-enable after artifact storage quota resets (disabled 2026-02-01) - # - name: Upload Playwright report - # uses: actions/upload-artifact@v4 - # if: always() - # with: - # name: playwright-report - # path: playwright-report/ - # retention-days: 1 - framework-demo-test: - runs-on: blacksmith-4vcpu-ubuntu-2204 - timeout-minutes: 15 - name: Framework Integration Tests (TanStack & Next.js) + runs-on: blacksmith-2vcpu-ubuntu-2404 + timeout-minutes: 30 + name: Framework Demo Tests steps: - uses: actions/checkout@v4 @@ -398,30 +196,11 @@ jobs: - name: Install dependencies run: bun install - - name: Install Playwright browsers - run: bunx playwright install --with-deps chromium + - name: Build packages + run: bun run build - - name: Prepare SDK for testing - run: bash scripts/prepare-sdk-for-testing.sh + - name: Install Playwright + run: bunx playwright install --with-deps chromium - - name: Install SDK in framework demo apps - run: | - # Install in main app (frontend packages) - bash scripts/install-sdk-tarballs.sh apps/testing/tanstack-start - bash scripts/install-sdk-tarballs.sh apps/testing/nextjs-app - # Install in agentuity subfolders (runtime packages) - bash scripts/install-sdk-tarballs.sh apps/testing/tanstack-start/agentuity - bash scripts/install-sdk-tarballs.sh apps/testing/nextjs-app/agentuity - - - name: Run Framework Demo tests - timeout-minutes: 8 - run: bash scripts/test-framework-demos.sh --skip-build - - # TODO: Re-enable after artifact storage quota resets (disabled 2026-02-01) - # - name: Upload Playwright report - # uses: actions/upload-artifact@v4 - # if: always() - # with: - # name: framework-demo-playwright-report - # path: playwright-report/ - # retention-days: 1 + - name: Run framework demo tests + run: bash scripts/test-framework-demos.sh diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index ac09822f8..000000000 --- a/.prettierignore +++ /dev/null @@ -1,5 +0,0 @@ -bun.lock -**/.agentuity/* -packages/cli/test-interop/go-common -*.sh -**/generated/*.ts \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index edcfaba14..000000000 --- a/.prettierrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "trailingComma": "es5", - "useTabs": true, - "tabWidth": 3, - "printWidth": 100, - "semi": true, - "singleQuote": true -} diff --git a/apps/docs/src/generated/env.d.ts b/apps/docs/src/generated/env.d.ts deleted file mode 100644 index 53b894fe0..000000000 --- a/apps/docs/src/generated/env.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -// @generated -// AUTO-GENERATED from local .env files -// This file is auto-generated by the build tool - do not edit manually - -declare global { - namespace NodeJS { - interface ProcessEnv { - readonly AGENTUITY_ORG_ID: string; - readonly AGENTUITY_SDK_KEY: string; - readonly AGENT_BEARER_TOKEN: string; - readonly DATABASE_URL: string; - readonly S3_ACCESS_KEY_ID: string; - readonly S3_BUCKET: string; - readonly S3_ENDPOINT: string; - readonly S3_SECRET_ACCESS_KEY: string; - readonly SANDBOX_SNAPSHOT_ID: string; - } - } -} - -// Vite-compatible environment types -// Only includes variables with VITE_, AGENTUITY_PUBLIC_, or PUBLIC_ prefix -interface ImportMetaEnv { - // No VITE_*, AGENTUITY_PUBLIC_*, or PUBLIC_* prefixed variables found -} - -interface ImportMeta { - readonly env: ImportMetaEnv; -} - -export {}; - -// FOUND AN ERROR IN THIS FILE? -// Please file an issue at https://github.com/agentuity/sdk/issues -// or if you know the fix please submit a PR! diff --git a/apps/testing/auth-package-app/.agents/agentuity/sdk/agent/AGENTS.md b/apps/testing/auth-package-app/.agents/agentuity/sdk/agent/AGENTS.md deleted file mode 100644 index 3c5330d3c..000000000 --- a/apps/testing/auth-package-app/.agents/agentuity/sdk/agent/AGENTS.md +++ /dev/null @@ -1,308 +0,0 @@ -# Agents Folder Guide - -This folder contains AI agents for your Agentuity application. Each agent is organized in its own subdirectory. - -## Generated Types - -The `src/generated/` folder contains auto-generated TypeScript files: - -- `registry.ts` - Agent registry with strongly-typed agent definitions and schema types -- `routes.ts` - Route registry for API, WebSocket, and SSE endpoints -- `app.ts` - Application entry point (regenerated on every build) - -**Important:** Never edit files in `src/generated/` - they are overwritten on every build. - -Import generated types in your agents: - -```typescript -import type { HelloInput, HelloOutput } from '../generated/registry'; -``` - -## Directory Structure - -Each agent folder must contain: - -- **agent.ts** (required) - Agent definition with schema and handler - -Example structure: - -``` -src/agent/ -├── hello/ -│ └── agent.ts -├── process-data/ -│ └── agent.ts -└── (generated files in src/generated/) -``` - -**Note:** HTTP routes are defined separately in `src/api/` - see the API folder guide for details. - -## Creating an Agent - -### Basic Agent (agent.ts) - -```typescript -import { createAgent } from '@agentuity/runtime'; -import { s } from '@agentuity/schema'; - -const agent = createAgent('my-agent', { - description: 'What this agent does', - schema: { - input: s.object({ - name: s.string(), - age: s.number(), - }), - output: s.string(), - }, - handler: async (ctx, input) => { - // Access context: ctx.app, ctx.config, ctx.logger, ctx.kv, ctx.vector, ctx.stream - return `Hello, ${input.name}! You are ${input.age} years old.`; - }, -}); - -export default agent; -``` - -### Agent with Lifecycle (setup/shutdown) - -```typescript -import { createAgent } from '@agentuity/runtime'; -import { s } from '@agentuity/schema'; - -const agent = createAgent('lifecycle-agent', { - description: 'Agent with setup and shutdown', - schema: { - input: s.object({ message: s.string() }), - output: s.object({ result: s.string() }), - }, - setup: async (app) => { - // Initialize resources (runs once on startup) - // app contains: appName, version, startedAt, config - return { - agentId: `agent-${Math.random().toString(36).substr(2, 9)}`, - connectionPool: ['conn-1', 'conn-2'], - }; - }, - handler: async (ctx, input) => { - // Access setup config via ctx.config (fully typed) - ctx.logger.info('Agent ID:', ctx.config.agentId); - ctx.logger.info('Connections:', ctx.config.connectionPool); - return { result: `Processed: ${input.message}` }; - }, - shutdown: async (app, config) => { - // Cleanup resources (runs on shutdown) - console.log('Shutting down agent:', config.agentId); - }, -}); - -export default agent; -``` - -### Agent with Event Listeners - -```typescript -import { createAgent } from '@agentuity/runtime'; -import { s } from '@agentuity/schema'; - -const agent = createAgent('event-agent', { - schema: { - input: s.object({ data: s.string() }), - output: s.string(), - }, - handler: async (ctx, input) => { - return `Processed: ${input.data}`; - }, -}); - -agent.addEventListener('started', (eventName, agent, ctx) => { - ctx.logger.info('Agent started'); -}); - -agent.addEventListener('completed', (eventName, agent, ctx) => { - ctx.logger.info('Agent completed'); -}); - -agent.addEventListener('errored', (eventName, agent, ctx, error) => { - ctx.logger.error('Agent errored:', error); -}); - -export default agent; -``` - -## Agent Context (ctx) - -The handler receives a context object with: - -- **ctx.app** - Application state (appName, version, startedAt, config from createApp) -- **ctx.config** - Agent-specific config (from setup return value, fully typed) -- **ctx.logger** - Structured logger (info, warn, error, debug, trace) -- **ctx.tracer** - OpenTelemetry tracer for custom spans -- **ctx.sessionId** - Unique session identifier -- **ctx.kv** - Key-value storage -- **ctx.vector** - Vector storage for embeddings -- **ctx.stream** - Stream storage for real-time data -- **ctx.state** - In-memory request-scoped state (Map) -- **ctx.thread** - Thread information for multi-turn conversations -- **ctx.session** - Session information -- **ctx.waitUntil** - Schedule background tasks - -## Examples - -### Using Key-Value Storage - -```typescript -handler: async (ctx, input) => { - await ctx.kv.set('user:123', { name: 'Alice', age: 30 }); - const user = await ctx.kv.get('user:123'); - await ctx.kv.delete('user:123'); - const keys = await ctx.kv.list('user:*'); - return user; -}; -``` - -### Using Vector Storage - -```typescript -handler: async (ctx, input) => { - await ctx.vector.upsert('docs', [ - { id: '1', values: [0.1, 0.2, 0.3], metadata: { text: 'Hello' } }, - ]); - const results = await ctx.vector.query('docs', [0.1, 0.2, 0.3], { topK: 5 }); - return results; -}; -``` - -### Using Streams - -```typescript -handler: async (ctx, input) => { - const stream = await ctx.stream.create('agent-logs'); - await ctx.stream.write(stream.id, 'Processing step 1'); - await ctx.stream.write(stream.id, 'Processing step 2'); - return { streamId: stream.id }; -}; -``` - -### Background Tasks with waitUntil - -```typescript -handler: async (ctx, input) => { - // Schedule background work that continues after response - ctx.waitUntil(async () => { - await ctx.kv.set('processed', Date.now()); - ctx.logger.info('Background task complete'); - }); - - return { status: 'processing' }; -}; -``` - -### Calling Another Agent - -```typescript -// Import the agent directly -import otherAgent from '../other-agent/agent'; - -handler: async (ctx, input) => { - const result = await otherAgent.run({ data: input.value }); - return `Other agent returned: ${result}`; -}; -``` - -## Subagents (Nested Agents) - -Agents can have subagents organized one level deep. This is useful for grouping related functionality. - -### Directory Structure for Subagents - -``` -src/agent/ -└── team/ # Parent agent - ├── agent.ts # Parent agent - ├── members/ # Subagent - │ └── agent.ts - └── tasks/ # Subagent - └── agent.ts -``` - -### Parent Agent - -```typescript -import { createAgent } from '@agentuity/runtime'; -import { s } from '@agentuity/schema'; - -const agent = createAgent('team', { - description: 'Team Manager', - schema: { - input: s.object({ action: s.union([s.literal('info'), s.literal('count')]) }), - output: s.object({ - message: s.string(), - timestamp: s.string(), - }), - }, - handler: async (ctx, { action }) => { - return { - message: 'Team parent agent - manages members and tasks', - timestamp: new Date().toISOString(), - }; - }, -}); - -export default agent; -``` - -### Subagent (Accessing Parent) - -```typescript -import { createAgent } from '@agentuity/runtime'; -import { s } from '@agentuity/schema'; -import parentAgent from '../agent'; - -const agent = createAgent('team.members', { - description: 'Members Subagent', - schema: { - input: s.object({ - action: s.union([s.literal('list'), s.literal('add'), s.literal('remove')]), - name: s.optional(s.string()), - }), - output: s.object({ - members: s.array(s.string()), - parentInfo: s.optional(s.string()), - }), - }, - handler: async (ctx, { action, name }) => { - // Call parent agent directly - const parentResult = await parentAgent.run({ action: 'info' }); - const parentInfo = `Parent says: ${parentResult.message}`; - - let members = ['Alice', 'Bob']; - if (action === 'add' && name) { - members.push(name); - } - - return { members, parentInfo }; - }, -}); - -export default agent; -``` - -### Key Points About Subagents - -- **One level deep**: Only one level of nesting is supported (no nested subagents) -- **Access parent**: Import and call parent agents directly -- **Agent names**: Subagents have dotted names like `"team.members"` -- **Shared context**: Subagents share the same app context (kv, logger, etc.) - -## Rules - -- Each agent folder name becomes the agent's route name (e.g., `hello/` → `/agent/hello`) -- **agent.ts** must export default the agent instance -- The first argument to `createAgent()` is the agent name (must match folder structure) -- Input/output schemas are enforced with @agentuity/schema validation -- Setup return value type automatically flows to ctx.config (fully typed) -- Use ctx.logger for logging, not console.log -- Import agents directly to call them (recommended approach) -- Subagents are one level deep only (team/members/, not team/members/subagent/) - - diff --git a/apps/testing/auth-package-app/.agents/agentuity/sdk/api/AGENTS.md b/apps/testing/auth-package-app/.agents/agentuity/sdk/api/AGENTS.md deleted file mode 100644 index e6c32b3fb..000000000 --- a/apps/testing/auth-package-app/.agents/agentuity/sdk/api/AGENTS.md +++ /dev/null @@ -1,367 +0,0 @@ -# APIs Folder Guide - -This folder contains REST API routes for your Agentuity application. Each API is organized in its own subdirectory. - -## Generated Types - -The `src/generated/` folder contains auto-generated TypeScript files: - -- `routes.ts` - Route registry with strongly-typed route definitions and schema types -- `registry.ts` - Agent registry (for calling agents from routes) -- `app.ts` - Application entry point (regenerated on every build) - -**Important:** Never edit files in `src/generated/` - they are overwritten on every build. - -Import generated types in your routes: - -```typescript -import type { POST_Api_UsersInput, POST_Api_UsersOutput } from '../generated/routes'; -``` - -## Directory Structure - -Each API folder must contain: - -- **route.ts** (required) - HTTP route definitions using Hono router - -Example structure: - -``` -src/api/ -├── index.ts (optional, mounted at /api) -├── status/ -│ └── route.ts (mounted at /api/status) -├── users/ -│ └── route.ts (mounted at /api/users) -├── agent-call/ - └── route.ts (mounted at /api/agent-call) -``` - -## Creating an API - -### Basic API (route.ts) - -```typescript -import { createRouter } from '@agentuity/runtime'; - -const router = createRouter(); - -// GET /api/status -router.get('/', (c) => { - return c.json({ - status: 'ok', - timestamp: new Date().toISOString(), - version: '1.0.0', - }); -}); - -// POST /api/status -router.post('/', async (c) => { - const body = await c.req.json(); - return c.json({ received: body }); -}); - -export default router; -``` - -### API with Request Validation - -```typescript -import { createRouter } from '@agentuity/runtime'; -import { s } from '@agentuity/schema'; -import { validator } from 'hono/validator'; - -const router = createRouter(); - -const createUserSchema = s.object({ - name: s.string(), - email: s.string(), - age: s.number(), -}); - -router.post( - '/', - validator('json', (value, c) => { - const result = createUserSchema['~standard'].validate(value); - if (result.issues) { - return c.json({ error: 'Validation failed', issues: result.issues }, 400); - } - return result.value; - }), - async (c) => { - const data = c.req.valid('json'); - // data is fully typed: { name: string, email: string, age: number } - return c.json({ - success: true, - user: data, - }); - } -); - -export default router; -``` - -### API Calling Agents - -APIs can call agents directly by importing them: - -```typescript -import { createRouter } from '@agentuity/runtime'; -import helloAgent from '@agent/hello'; - -const router = createRouter(); - -router.get('/', async (c) => { - // Call an agent directly - const result = await helloAgent.run({ name: 'API Caller', age: 42 }); - - return c.json({ - success: true, - agentResult: result, - }); -}); - -router.post('/with-input', async (c) => { - const body = await c.req.json(); - const { name, age } = body; - - // Call agent with dynamic input - const result = await helloAgent.run({ name, age }); - - return c.json({ - success: true, - agentResult: result, - }); -}); - -export default router; -``` - -### API with Agent Validation - -Use `agent.validator()` for automatic input validation from agent schemas: - -```typescript -import { createRouter } from '@agentuity/runtime'; -import myAgent from '@agent/my-agent'; - -const router = createRouter(); - -// POST with automatic validation using agent's input schema -router.post('/', myAgent.validator(), async (c) => { - const data = c.req.valid('json'); // Fully typed from agent schema! - const result = await myAgent.run(data); - return c.json({ success: true, result }); -}); - -export default router; -``` - -### API with Logging - -```typescript -import { createRouter } from '@agentuity/runtime'; - -const router = createRouter(); - -router.get('/log-test', (c) => { - c.var.logger.info('Info message'); - c.var.logger.error('Error message'); - c.var.logger.warn('Warning message'); - c.var.logger.debug('Debug message'); - c.var.logger.trace('Trace message'); - - return c.text('Check logs'); -}); - -export default router; -``` - -## Route Context (c) - -The route handler receives a Hono context object with: - -- **c.req** - Request object (c.req.json(), c.req.param(), c.req.query(), etc.) -- **c.json()** - Return JSON response -- **c.text()** - Return text response -- **c.html()** - Return HTML response -- **c.redirect()** - Redirect to URL -- **c.var.logger** - Structured logger (info, warn, error, debug, trace) -- **c.var.kv** - Key-value storage -- **c.var.vector** - Vector storage -- **c.var.stream** - Stream management -- **Import agents directly** - Import and call agents directly (recommended) - -## HTTP Methods - -```typescript -const router = createRouter(); - -router.get('/path', (c) => { - /* ... */ -}); -router.post('/path', (c) => { - /* ... */ -}); -router.put('/path', (c) => { - /* ... */ -}); -router.patch('/path', (c) => { - /* ... */ -}); -router.delete('/path', (c) => { - /* ... */ -}); -router.options('/path', (c) => { - /* ... */ -}); -``` - -## Path Parameters - -```typescript -// GET /api/users/:id -router.get('/:id', (c) => { - const id = c.req.param('id'); - return c.json({ userId: id }); -}); - -// GET /api/posts/:postId/comments/:commentId -router.get('/:postId/comments/:commentId', (c) => { - const postId = c.req.param('postId'); - const commentId = c.req.param('commentId'); - return c.json({ postId, commentId }); -}); -``` - -## Query Parameters - -```typescript -// GET /api/search?q=hello&limit=10 -router.get('/search', (c) => { - const query = c.req.query('q'); - const limit = c.req.query('limit') || '20'; - return c.json({ query, limit: parseInt(limit) }); -}); -``` - -## Request Body - -```typescript -// JSON body -router.post('/', async (c) => { - const body = await c.req.json(); - return c.json({ received: body }); -}); - -// Form data -router.post('/upload', async (c) => { - const formData = await c.req.formData(); - const file = formData.get('file'); - return c.json({ fileName: file?.name }); -}); -``` - -## Error Handling - -```typescript -import myAgent from '@agent/my-agent'; - -router.get('/', async (c) => { - try { - const result = await myAgent.run({ data: 'test' }); - return c.json({ success: true, result }); - } catch (error) { - c.var.logger.error('Agent call failed:', error); - return c.json( - { - success: false, - error: error instanceof Error ? error.message : String(error), - }, - 500 - ); - } -}); -``` - -## Response Types - -```typescript -// JSON response -return c.json({ data: 'value' }); - -// Text response -return c.text('Hello World'); - -// HTML response -return c.html('
Created: {result.name}
} -Status: {isConnected ? 'Connected' : 'Disconnected'}
- -{JSON.stringify(msg)}
- ))} -Connected: {isConnected ? 'Yes' : 'No'}
- {error &&Error: {error.message}
} -Latest: {JSON.stringify(data)}
- -API Base: {baseUrl}
; -} -``` - -### useAuth - Authentication State - -Access and manage authentication state. - -```typescript -import { useAuth } from '@agentuity/react'; - -function AuthStatus() { - const { isAuthenticated, authHeader, setAuthHeader, authLoading } = useAuth(); - - const handleLogin = async (token: string) => { - setAuthHeader?.(`Bearer ${token}`); - }; - - const handleLogout = () => { - setAuthHeader?.(null); - }; - - if (authLoading) returnLoading...
; - - return ( -Count: {count}
- -{JSON.stringify(agentResult)}
-