{"_id":"@caqophony/sdk","name":"@caqophony/sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@caqophony/sdk","version":"0.1.0","description":"Official SDK for Caqophony Swarm external products","private":false,"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","clean":"rm -rf dist .turbo","test":"jest","prepublishOnly":"npm run build"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/mikegamaroff/caqophony.git","directory":"packages/sdk"},"homepage":"https://github.com/mikegamaroff/caqophony/tree/main/packages/sdk#readme","devDependencies":{"@caqophony/typescript-config":"workspace:*","typescript":"^5.6.3","jest":"^29.7.0","@jest/globals":"^29.7.0","ts-jest":"^29.2.5","@types/node":"^20"},"engines":{"node":">=18.0.0"},"keywords":["caqophony","swarm","sdk","oauth2","ai","tokens"],"license":"MIT","_id":"@caqophony/sdk@0.1.0","gitHead":"9c56d6425029476ac7b96a942f7fa60640749609","bugs":{"url":"https://github.com/mikegamaroff/caqophony/issues"},"_nodeVersion":"20.19.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-9M1RRzakYgr9l4Vx3roCrYk3HOLK4Qvod8RweXUsTGNofvY6OJctegDjJzGGogS8oV7N0tomc1TyMB/brQTJqw==","shasum":"b0c601f70ce0690021480d921d05812cd45de743","tarball":"https://registry.npmjs.org/@caqophony/sdk/-/sdk-0.1.0.tgz","fileCount":18,"unpackedSize":36750,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCNihV/s5x2n5bXYCQ1oj1GwYy8w+IAnsR6iP8zf1dnQAIgO0lXdCMydNwKdNa1+dgFklWCbOciEFT9qzXTnWpdOPY="}]},"_npmUser":{"name":"mikegamaroff","email":"mike@caqophony.com"},"directories":{},"maintainers":[{"name":"mikegamaroff","email":"mike@caqophony.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.1.0_1771259401422_0.45263908080308357"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-16T16:30:01.320Z","0.1.0":"2026-02-16T16:30:01.596Z","modified":"2026-02-16T16:30:01.804Z"},"maintainers":[{"name":"mikegamaroff","email":"mike@caqophony.com"}],"description":"Official SDK for Caqophony Swarm external products","homepage":"https://github.com/mikegamaroff/caqophony/tree/main/packages/sdk#readme","keywords":["caqophony","swarm","sdk","oauth2","ai","tokens"],"repository":{"type":"git","url":"git+https://github.com/mikegamaroff/caqophony.git","directory":"packages/sdk"},"bugs":{"url":"https://github.com/mikegamaroff/caqophony/issues"},"license":"MIT","readme":"# @caqophony/sdk\n\nOfficial SDK for building external products on the Caqophony Swarm platform. Provides OAuth2 authentication, token management, and AI generation.\n\n## Install\n\n```bash\nnpm install @caqophony/sdk\n# or\nyarn add @caqophony/sdk\n# or\npnpm add @caqophony/sdk\n```\n\n## Quick Start\n\n### 1. Register Your App\n\nGo to the [Swarm Developer Portal](https://swarm.caqophony.com/developer) and register your app to get a `client_id` and `client_secret`.\n\n### 2. Set Up Authentication\n\n```typescript\nimport { SwarmAuth } from '@caqophony/sdk';\n\nconst auth = new SwarmAuth({\n  clientId: process.env.SWARM_CLIENT_ID!,\n  clientSecret: process.env.SWARM_CLIENT_SECRET!,\n  redirectUri: 'http://localhost:3000/api/auth/callback',\n  scopes: ['user:profile', 'tokens:read', 'tokens:deduct', 'ai:generate'],\n  baseUrl: process.env.SWARM_BASE_URL, // optional, defaults to production\n});\n\n// Step 1: Redirect user to Swarm login\nconst authorizeUrl = auth.getAuthorizeUrl();\n// → redirect user to authorizeUrl\n\n// Step 2: Handle the callback (in your callback route)\nconst session = await auth.handleCallback(code);\n// session.accessToken, session.refreshToken, session.expiresIn, session.scopes\n\n// Step 3: Get user info\nconst user = await auth.getUserInfo(session.accessToken);\n// user.sub, user.email, user.name, user.tenant_id\n\n// Refresh an expired token\nconst newSession = await auth.refreshSession(session.refreshToken);\n\n// Revoke a token (logout)\nawait auth.revokeToken(session.accessToken);\n```\n\n### 3. Check Token Balance\n\n```typescript\nimport { SwarmTokens } from '@caqophony/sdk';\n\nconst tokens = new SwarmTokens({\n  accessToken: session.accessToken,\n  baseUrl: process.env.SWARM_BASE_URL,\n});\n\nconst balance = await tokens.getBalance();\n// balance.current, balance.allocated, balance.percent_used, balance.account_status\n\nconst usage = await tokens.getUsage('2025-01');\n// usage.period, usage.usage[], usage.total_tokens, usage.total_cost\n\nconst history = await tokens.getUsageHistory(6);\n// history.months[]\n```\n\n### 4. Generate AI Content\n\n```typescript\nimport { SwarmAI } from '@caqophony/sdk';\n\nconst ai = new SwarmAI({\n  accessToken: session.accessToken,\n  baseUrl: process.env.SWARM_BASE_URL,\n});\n\n// Non-streaming\nconst result = await ai.generate({\n  messages: [\n    { role: 'user', content: 'Write an intro for a podcast about AI' },\n  ],\n  system: 'You are a podcast scriptwriter.',\n  max_tokens: 1024,\n  feature: 'script_generation',\n});\n// result.content, result.usage, result.tokens_deducted\n\n// Streaming (SSE)\nfor await (const event of ai.generateStream({\n  messages: [{ role: 'user', content: 'Write a podcast intro' }],\n  feature: 'script_generation',\n})) {\n  switch (event.event) {\n    case 'content_delta':\n      process.stdout.write(event.data.text);\n      break;\n    case 'message_complete':\n      console.log(`\\nTokens used: ${event.data.tokens_deducted}`);\n      break;\n    case 'error':\n      console.error(event.data.error_description);\n      break;\n  }\n}\n```\n\n## OAuth Scopes\n\n| Scope               | Description                             |\n| ------------------- | --------------------------------------- |\n| `user:profile`      | Read user profile (email, name, tenant) |\n| `tokens:read`       | Read token balance and usage history    |\n| `tokens:deduct`     | Deduct tokens for feature usage         |\n| `subscription:read` | Read subscription status                |\n| `ai:generate`       | Generate AI content via the Swarm proxy |\n\n## API Reference\n\n### `SwarmAuth`\n\n| Method                         | Description                            |\n| ------------------------------ | -------------------------------------- |\n| `getAuthorizeUrl(state?)`      | Build the OAuth authorization URL      |\n| `handleCallback(code)`         | Exchange authorization code for tokens |\n| `refreshSession(refreshToken)` | Refresh an expired access token        |\n| `getUserInfo(accessToken)`     | Fetch the authenticated user's profile |\n| `revokeToken(token, hint?)`    | Revoke an access or refresh token      |\n\n### `SwarmTokens`\n\n| Method                     | Description                           |\n| -------------------------- | ------------------------------------- |\n| `getBalance()`             | Get current token balance             |\n| `deduct(input)`            | Deduct tokens for feature usage       |\n| `getUsage(period?)`        | Get usage breakdown for a month       |\n| `getUsageHistory(months?)` | Get historical usage across months    |\n| `setAccessToken(token)`    | Update the access token after refresh |\n\n### `SwarmAI`\n\n| Method                   | Description                            |\n| ------------------------ | -------------------------------------- |\n| `generate(params)`       | Generate AI content (non-streaming)    |\n| `generateStream(params)` | Generate AI content with SSE streaming |\n| `setAccessToken(token)`  | Update the access token after refresh  |\n\n### `SwarmError`\n\nAll API errors throw `SwarmError` with `code`, `message`, and `status` properties.\n\n```typescript\nimport { SwarmError } from '@caqophony/sdk';\n\ntry {\n  await tokens.getBalance();\n} catch (err) {\n  if (err instanceof SwarmError) {\n    console.error(`${err.code}: ${err.message} (HTTP ${err.status})`);\n  }\n}\n```\n\n## Requirements\n\n- Node.js >= 18.0.0\n- A registered app on the Swarm Developer Portal\n","readmeFilename":"README.md","_rev":"1-54b8b6d84462800f568007bc8f78f892"}