diff --git a/README.md b/README.md index 2ac9286..1f4c43b 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,10 @@ # axme-sdk-typescript -**Official TypeScript SDK for the AXME platform.** Send and manage intents, observe lifecycle events, handle approvals, and access the enterprise admin surface — fully typed, Promise-based, works in Node.js and edge runtimes. +**TypeScript SDK for AXME** - send intents, listen for deliveries, resume workflows. Fully typed, Promise-based, works in Node.js and edge runtimes. -> **Alpha** · API surface is stabilizing. Not recommended for production workloads yet. -> **Alpha** — install CLI, log in, run your first example in under 5 minutes. [Quick Start](https://cloud.axme.ai/alpha/cli) · [hello@axme.ai](mailto:hello@axme.ai) +[![Alpha](https://img.shields.io/badge/status-alpha-orange)](https://cloud.axme.ai/alpha/cli) [![npm](https://img.shields.io/npm/v/@axme/axme)](https://www.npmjs.com/package/@axme/axme) [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE) ---- - -## What Is AXME? - -AXME is a coordination infrastructure for durable execution of long-running intents across distributed systems. - -It provides a model for executing **intents** — requests that may take minutes, hours, or longer to complete — across services, agents, and human participants. - -## AXP — the Intent Protocol - -At the core of AXME is **AXP (Intent Protocol)** — an open protocol that defines contracts and lifecycle rules for intent processing. - -AXP can be implemented independently. -The open part of the platform includes: - -- the protocol specification and schemas -- SDKs and CLI for integration -- conformance tests -- implementation and integration documentation - -## AXME Cloud - -**AXME Cloud** is the managed service that runs AXP in production together with **The Registry** (identity and routing). - -It removes operational complexity by providing: - -- reliable intent delivery and retries -- lifecycle management for long-running operations -- handling of timeouts, waits, reminders, and escalation -- observability of intent status and execution history - -State and events can be accessed through: - -- API and SDKs -- event streams and webhooks -- the cloud console - ---- - -## What You Can Do With This SDK - -- **Send intents** — create typed, durable actions with delivery guarantees -- **Observe lifecycle** — subscribe to real-time state events via SSE -- **Approve or reject** — handle human-in-the-loop steps from your application -- **Control workflows** — pause, resume, cancel, update retry policies and reminders -- **Administer** — manage organizations, workspaces, service accounts, and grants +**[Quick Start](https://cloud.axme.ai/alpha/cli)** · **[Docs](https://github.com/AxmeAI/axme-docs)** · **[Examples](https://github.com/AxmeAI/axme-examples)** --- @@ -60,295 +14,107 @@ State and events can be accessed through: npm install @axme/axme ``` +Requires Node.js 20+. + --- -## Quickstart +## Quick Start ```typescript import { AxmeClient } from "@axme/axme"; -const client = new AxmeClient({ - apiKey: "AXME_API_KEY", // sent as x-api-key - actorToken: "OPTIONAL_USER_OR_SESSION_TOKEN", // sent as Authorization: Bearer - // Optional override (defaults to https://api.cloud.axme.ai): - // baseUrl: "https://staging-api.cloud.axme.ai", -}); - -// Check connectivity -console.log(await client.health()); +const client = new AxmeClient({ apiKey: "axme_sa_..." }); -// Send an intent to a registered agent address +// Send an intent - survives crashes, retries, timeouts const intent = await client.createIntent( { intent_type: "order.fulfillment.v1", - to_agent: "agent://acme-corp/production/fulfillment-service", - payload: { order_id: "ord_123", priority: "high" }, + to_agent: "agent://myorg/production/fulfillment-service", + payload: { order_id: "ord_123" }, }, - { correlationId: "corr-ord-123-001", idempotencyKey: "fulfill-ord-123-001" } + { idempotencyKey: "fulfill-ord-123-001" } ); -console.log(intent.intent_id, intent.status); - -// List registered agent addresses in your workspace -const agents = await client.listAgents({ orgId: "acme-corp-uuid", workspaceId: "prod-ws-uuid" }); -for (const agent of agents.agents as Array>) { - console.log(agent.address, agent.status); -} -``` - ---- - -## Minimal Language-Native Example - -Short basic submit/get example: - -- [`examples/basic-submit.ts`](examples/basic-submit.ts) - -Run: - -```bash -export AXME_API_KEY="axme_sa_..." -npx tsx examples/basic-submit.ts -``` - -Full runnable scenario set lives in: - -- Cloud: -- Protocol-only: - ---- - -## API Method Families - -The SDK covers the full public API surface organized into families: - -![API Method Family Map](https://raw.githubusercontent.com/AxmeAI/axme-docs/main/docs/diagrams/api/01-api-method-family-map.svg) - -*D1 families (intents, inbox, approvals) are the core integration path. D2 adds schemas, webhooks, and media. D3 covers enterprise admin. The SDK implements all three tiers.* - ---- - -## Protocol Envelope - -Every request from this SDK is wrapped in the AXP protocol envelope, handled transparently: - -![AXP Protocol Envelope](https://raw.githubusercontent.com/AxmeAI/axme-docs/main/docs/diagrams/protocol/01-protocol-envelope.svg) - -*The SDK sets `x-api-key` on every request, and sets `Authorization: Bearer ` when `actorToken` is configured. It also handles `Idempotency-Key` and `X-Trace-Id` headers for reliability and tracing.* - ---- - -## Idempotency - -Every mutating method accepts an optional `idempotencyKey`. Pass it for any operation you might retry: -![Idempotency and Replay Protection](https://raw.githubusercontent.com/AxmeAI/axme-docs/main/docs/diagrams/protocol/03-idempotency-and-replay-protection.svg) - -```typescript -// Safe to call multiple times — only executes once -const intent = await client.createIntent(payload, { - idempotencyKey: "my-unique-key-001", -}); +// Wait for resolution +const result = await client.waitFor(intent.intent_id); +console.log(result.status); ``` --- -## Observing Events +## Connect an Agent ```typescript -// Stream lifecycle events until resolution -for await (const event of client.observe(intent.intent_id)) { - console.log(event.event_type, event.status); - if (["RESOLVED", "CANCELLED", "EXPIRED"].includes(event.status)) break; +for await (const delivery of client.listen("agent://myorg/production/my-agent")) { + const intent = await client.getIntent(delivery.intent_id); + const result = await process(intent.payload); + await client.resumeIntent(delivery.intent_id, result); } ``` --- -## Human-in-the-Loop (8 Task Types) - -AXME supports 8 human task types. Each pauses the workflow and notifies a human via email with a link to a web task page. - -| Task type | Use case | Default outcomes | -|-----------|----------|-----------------| -| `approval` | Approve or reject a request | approved, rejected | -| `confirmation` | Confirm a real-world action completed | confirmed, denied | -| `review` | Review content with multiple outcomes | approved, changes_requested, rejected | -| `assignment` | Assign work to a person or team | assigned, declined | -| `form` | Collect structured data via form fields | submitted | -| `clarification` | Request clarification (comment required) | provided, declined | -| `manual_action` | Physical task completion (evidence required) | completed, failed | -| `override` | Override a policy gate (comment required) | override_approved, rejected | +## Human Approvals ```typescript -// Create an intent with a human task step -const result = await client.createIntent({ - intentType: "intent.budget.approval.v1", - toAgent: "agent://agent_core", - payload: { amount: 32000, department: "engineering" }, - humanTask: { - title: "Approve Q3 budget", - description: "Review and approve the Q3 infrastructure budget.", - taskType: "approval", - notifyEmail: "approver@example.com", - allowedOutcomes: ["approved", "rejected"], +const intent = await client.createIntent({ + intent_type: "intent.budget.approval.v1", + to_agent: "agent://myorg/prod/agent_core", + payload: { amount: 32000 }, + human_task: { + task_type: "approval", + notify_email: "approver@example.com", + allowed_outcomes: ["approved", "rejected"], }, }); +const result = await client.waitFor(intent.intent_id); // waits until human acts ``` -Task types with forms use `form_schema` to define required fields: - -```typescript -humanTask: { - title: "Assign incident commander", - taskType: "assignment", - notifyEmail: "oncall@example.com", - formSchema: { - type: "object", - required: ["assignee"], - properties: { - assignee: { type: "string", title: "Commander name" }, - priority: { type: "string", enum: ["P1", "P2", "P3"] }, - }, - }, -}, -``` - -### Programmatic approvals (inbox API) - -```typescript -// Fetch and approve pending items -const inbox = await client.listInbox({ ownerAgent: "agent://manager" }); - -for (const item of (Array.isArray(inbox.items) ? inbox.items : [])) { - const threadId = typeof item?.thread_id === "string" ? item.thread_id : undefined; - if (!threadId) continue; - await client.approveInboxThread( - threadId, - { note: "Reviewed and approved" }, - { ownerAgent: "agent://manager" } - ); -} -``` +8 task types: `approval`, `confirmation`, `review`, `assignment`, `form`, `clarification`, `manual_action`, `override`. Full reference: [axme-docs](https://github.com/AxmeAI/axme-docs). --- -## Workflow Controls - -```typescript -// Update retry policy and add a reminder on a live intent -await client.updateIntentControls(intentId, { - controls: { - max_retries: 5, - retry_delay_seconds: 30, - reminders: [{ offset_seconds: 3600, note: "1h reminder" }], - }, - policy_generation: intent.policy_generation, -}); -``` - ---- - -## Cross-Org Delivery Control - -Organizations can control which external orgs may send intents to their agents: - -1. **Org receive policy** — org-wide default (`open`, `allowlist`, `closed`) -2. **Agent receive override** — per-agent exceptions to the org policy +## Observe Lifecycle Events ```typescript -// Get org receive policy -const policy = await client.get(`/v1/organizations/${orgId}/receive-policy`); - -// Set to allowlist mode -await client.put(`/v1/organizations/${orgId}/receive-policy`, { - mode: "allowlist", - allowlist: ["org_id_of_trusted_partner"], -}); - -// Per-agent override -await client.put(`/v1/agents/${address}/receive-override`, { - override_type: "allow", - source_org_id: "org_id_of_partner", -}); -``` - -See [`cross-org-receive-policy.md`](https://github.com/AxmeAI/axme-docs/blob/main/docs/cross-org-receive-policy.md) for the full decision flow. - ---- - -## Repository Structure - -``` -axme-sdk-typescript/ -├── src/ -│ ├── client.ts # AxmeClient — all API methods -│ ├── config.ts # AxmeClientConfig type -│ └── errors.ts # AxmeAPIError and subclasses -├── test/ # Unit and integration tests -├── examples/ -│ └── basic-submit.ts # Minimal language-native quickstart -├── docs/ -└── tsconfig.json +for await (const event of client.observe(intent.intent_id)) { + console.log(event.event_type, event.status); + if (["RESOLVED", "CANCELLED", "EXPIRED"].includes(event.status)) break; +} ``` --- -## MCP (Model Context Protocol) - -The TypeScript SDK includes a built-in MCP endpoint client for gateway-hosted MCP sessions: +## Examples -```typescript -// Initialize an MCP session -const init = await client.mcpInitialize(); -console.log(init.serverInfo); - -// List available tools -const tools = await client.mcpListTools(); -for (const tool of (Array.isArray(tools.tools) ? tools.tools : [])) { - console.log((tool as Record).name); -} - -// Call a tool -const result = await client.mcpCallTool("create_intent", { - arguments: { - intent_type: "order.fulfillment.v1", - payload: { order_id: "ord_123" }, - owner_agent: "agent://fulfillment-service", - }, -}); -console.log(result); +```bash +export AXME_API_KEY="axme_sa_..." +npx tsx examples/basic-submit.ts ``` -MCP calls go to `/mcp` by default. Override with `mcpEndpointPath` in the client config. +More: [axme-examples](https://github.com/AxmeAI/axme-examples) --- -## Tests +## Development ```bash +npm install npm test ``` --- -## Related Repositories +## Related -| Repository | Role | +| | | |---|---| -| [axme-docs](https://github.com/AxmeAI/axme-docs) | Full API reference and integration guides | -| [axme-spec](https://github.com/AxmeAI/axme-spec) | Schema contracts this SDK implements | -| [axme-conformance](https://github.com/AxmeAI/axme-conformance) | Conformance suite that validates this SDK | -| [axme-examples](https://github.com/AxmeAI/axme-examples) | Runnable examples using this SDK | -| [axme-sdk-python](https://github.com/AxmeAI/axme-sdk-python) | Python equivalent | -| [axme-sdk-go](https://github.com/AxmeAI/axme-sdk-go) | Go equivalent | -| [axme-sdk-java](https://github.com/AxmeAI/axme-sdk-java) | Java equivalent | -| [axme-sdk-dotnet](https://github.com/AxmeAI/axme-sdk-dotnet) | .NET equivalent | +| [axme-docs](https://github.com/AxmeAI/axme-docs) | API reference and integration guides | +| [axme-examples](https://github.com/AxmeAI/axme-examples) | Runnable examples | +| [axp-spec](https://github.com/AxmeAI/axp-spec) | Protocol specification | +| [axme-cli](https://github.com/AxmeAI/axme-cli) | CLI tool | +| [axme-conformance](https://github.com/AxmeAI/axme-conformance) | Conformance suite | --- -## Contributing & Contact - -- Bug reports and feature requests: open an issue in this repository -- Quick Start: https://cloud.axme.ai/alpha/cli · Contact: [hello@axme.ai](mailto:hello@axme.ai) -- Security disclosures: see [SECURITY.md](SECURITY.md) -- Contribution guidelines: [CONTRIBUTING.md](CONTRIBUTING.md) +[hello@axme.ai](mailto:hello@axme.ai) · [Security](SECURITY.md) · [License](LICENSE)