{"_id":"@aiand/sdk","_rev":"3-980e62b878919f58a28511145ac6adc5","name":"@aiand/sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@aiand/sdk","version":"0.1.0","keywords":["aiand","ai&","openai-compatible","openapi","sdk","typescript"],"author":{"name":"ai&"},"license":"Apache-2.0","_id":"@aiand/sdk@0.1.0","maintainers":[{"name":"aiand","email":"dev@aiand.com"}],"homepage":"https://docs.aiand.com","bugs":{"url":"https://github.com/aiandlabs/aiand-typescript/issues"},"dist":{"shasum":"93cb344ba8d7d637340a83b45ef70236d4375c0c","tarball":"https://registry.npmjs.org/@aiand/sdk/-/sdk-0.1.0.tgz","fileCount":8,"integrity":"sha512-zOQakKF/vIswf/wdQM8FMsG9Vr7uAUMjyx8tq4zsyUbm6mGGufCRGLhseqeuSwaQbB4dOGbFVoANZ9gxZ0/2Zg==","signatures":[{"sig":"MEUCIQCrYMc0b2WM4ZgxR0TL0k+cbMj1ThLf8KZUFmufr3nJggIgZdjjkP73lCZR6jeeQEeXYb3UjJOGy+DkI9rns5kXQ6Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":990638},"main":"./dist/index.cjs","type":"module","_from":"file:aiand-sdk-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsup src/index.ts --format cjs,esm --dts --clean","prepack":"npm run build","test:vcr":"vitest run tests/openai-api-vcr.test.ts","update-sdk":"./scripts/update-sdk"},"_npmUser":{"name":"aiand","email":"dev@aiand.com"},"_resolved":"/Users/atul/projects/aiand-typescript/aiand-sdk-0.1.0.tgz","_integrity":"sha512-zOQakKF/vIswf/wdQM8FMsG9Vr7uAUMjyx8tq4zsyUbm6mGGufCRGLhseqeuSwaQbB4dOGbFVoANZ9gxZ0/2Zg==","repository":{"url":"git+https://github.com/aiandlabs/aiand-typescript.git","type":"git"},"_npmVersion":"11.12.1","description":"TypeScript SDK for the ai& API, generated from the public OpenAPI spec.","directories":{},"sideEffects":false,"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^4.1.8","typescript":"^5.9.0","@types/node":"^20.19.0","@pollyjs/core":"^6.0.6","@pollyjs/persister-fs":"^6.0.6","@pollyjs/adapter-fetch":"^6.0.7"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.0_1780545789450_0.1001198906578713","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-06-04T04:03:09.266Z","modified":"2026-09-28T08:45:41.786Z","0.1.0":"2026-06-04T04:03:09.603Z"},"bugs":{"url":"https://github.com/aiandlabs/aiand-typescript/issues"},"author":{"name":"ai&"},"license":"Apache-2.0","homepage":"https://docs.aiand.com","keywords":["aiand","ai&","openai-compatible","openapi","sdk","typescript"],"repository":{"url":"git+https://github.com/aiandlabs/aiand-typescript.git","type":"git"},"description":"TypeScript SDK for the ai& API, generated from the public OpenAPI spec.","maintainers":[{"email":"dev@aiand.com","name":"aiand-admin"},{"email":"islomjon@aiand.com","name":"islomjon_toji"}],"readme":"# aiand-typescript\n\nUse the ai& API with TypeScript.\n\nThis package is generated from the public ai& OpenAPI spec with\n[OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator). It covers the\nOpenAI-compatible endpoints currently present in the spec: models, chat completions,\nlegacy completions, responses, files, and chunked uploads.\n\nThe npm package name is `@aiand/sdk`.\n\n## Installation\n\nFrom this checkout:\n\n```sh\ncd aiand-typescript\nnpm install\nnpm run build\n```\n\nOnce this package is published, install it as:\n\n```sh\nnpm install @aiand/sdk\n```\n\nThe current SDK version is `0.1.0`. See [CHANGELOG.md](CHANGELOG.md) for release notes.\n\n## Usage\n\nSet your API key in the environment:\n\n```sh\nexport AIAND_API_KEY=\"your-aiand-api-key\"\n```\n\nCreate a client:\n\n```ts\nimport { Configuration, OpenaiApi } from \"@aiand/sdk\";\n\nconst configuration = new Configuration({\n  accessToken: process.env.AIAND_API_KEY,\n});\n\nconst client = new OpenaiApi(configuration);\nconst models = await client.listModels();\n\nconsole.log(models.data[0].id);\n```\n\nThe generated base URL is `https://api.aiand.com`. The OpenAPI paths include `/v1`, so SDK\ncalls resolve to URLs like `https://api.aiand.com/v1/models`.\n\n`OpenaiApi` is generated from the source spec's `openai` tag.\n\n## Chat\n\n```ts\nimport { Configuration, OpenaiApi } from \"@aiand/sdk\";\n\nconst client = new OpenaiApi(\n  new Configuration({ accessToken: process.env.AIAND_API_KEY }),\n);\n\nconst response = await client.createChatCompletion({\n  createChatCompletionRequest: {\n    model: \"openai/gpt-oss-120b\",\n    messages: [\n      { role: \"system\", content: \"You are concise and practical.\" },\n      { role: \"user\", content: \"Give me one sentence about ai&.\" },\n    ],\n    temperature: 0.2,\n  },\n});\n\nconsole.log(response.choices[0].message.content);\n```\n\n## Completions\n\n```ts\nimport { Configuration, OpenaiApi } from \"@aiand/sdk\";\n\nconst client = new OpenaiApi(\n  new Configuration({ accessToken: process.env.AIAND_API_KEY }),\n);\n\nconst response = await client.createCompletion({\n  createCompletionRequest: {\n    model: \"openai/gpt-oss-120b\",\n    prompt: \"Write a short product tagline for ai&:\",\n    max_tokens: 32,\n  },\n});\n\nconsole.log(response.choices[0].text);\n```\n\n## Responses\n\n```ts\nimport { Configuration, OpenaiApi } from \"@aiand/sdk\";\n\nconst client = new OpenaiApi(\n  new Configuration({ accessToken: process.env.AIAND_API_KEY }),\n);\n\nconst response = await client.createResponse({\n  createResponseRequest: {\n    model: \"openai/gpt-oss-120b\",\n    input: \"Give me one practical sentence about ai&.\",\n    temperature: 0.2,\n    max_output_tokens: 64,\n    parallel_tool_calls: false,\n    truncation: \"disabled\",\n  },\n});\n\nconsole.log(response.output);\n```\n\n## Models And Pricing\n\n```ts\nimport { Configuration, OpenaiApi } from \"@aiand/sdk\";\n\nconst client = new OpenaiApi(\n  new Configuration({ accessToken: process.env.AIAND_API_KEY }),\n);\n\nconst models = await client.listModels();\n\nfor (const model of models.data) {\n  console.log(\n    model.id,\n    model.provider,\n    model.context_window,\n    model.capabilities,\n    model.input_per_1m,\n    model.output_per_1m,\n  );\n}\n```\n\nThe docs describe model pricing as precise string fields. This SDK keeps\n`input_per_1m` and `output_per_1m` as strings instead of numbers.\n\n## Files\n\nUpload a file once, then reference the returned `file_id` from chat completion requests.\n\n```ts\nimport { readFile } from \"node:fs/promises\";\n\nimport { Configuration, FilesApi } from \"@aiand/sdk\";\n\nconst files = new FilesApi(\n  new Configuration({ accessToken: process.env.AIAND_API_KEY }),\n);\n\nconst bytes = await readFile(\"diagram.png\");\nconst file = new Blob([bytes], { type: \"image/png\" });\n\nconst uploaded = await files.uploadFile({\n  file,\n  purpose: \"vision\",\n});\n\nconsole.log(uploaded.id);\n```\n\nThe file purpose values are `vision`, `video`, `audio`, and `document`.\n\n## Chunked Uploads\n\nFor larger assets, create an upload, add parts in order, then complete it.\n\n```ts\nimport { readFile } from \"node:fs/promises\";\n\nimport { Configuration, UploadsApi } from \"@aiand/sdk\";\n\nconst uploads = new UploadsApi(\n  new Configuration({ accessToken: process.env.AIAND_API_KEY }),\n);\n\nconst bytes = await readFile(\"clip.mp4\");\n\nconst upload = await uploads.createUpload({\n  createUploadRequest: {\n    filename: \"clip.mp4\",\n    purpose: \"video\",\n    bytes: bytes.byteLength,\n    mime_type: \"video/mp4\",\n  },\n});\n\nconst part = await uploads.addUploadPart({\n  id: upload.id,\n  data: new Blob([bytes], { type: \"video/mp4\" }),\n});\n\nconst completed = await uploads.completeUpload({\n  id: upload.id,\n  completeUploadRequest: { part_ids: [part.id] },\n});\n\nconsole.log(completed.file?.id);\n```\n\n## Timeouts And Headers\n\nEvery generated operation accepts the standard `fetch` override argument:\n\n```ts\nconst response = await client.listModels({\n  signal: AbortSignal.timeout(30_000),\n  headers: { \"X-Request-Source\": \"aiand-typescript\" },\n});\n```\n\nUse `Configuration({ accessToken: ... })` for API-key auth. The docs note that browser/JWT\nauth can require `X-Org-ID`; for server-side API keys, the organization is resolved from\nthe key.\n\n## Errors\n\nThe generated client throws `ResponseError` for non-2xx responses.\n\n```ts\nimport { ResponseError } from \"@aiand/sdk\";\n\ntry {\n  await client.listModels();\n} catch (error) {\n  if (error instanceof ResponseError) {\n    console.log(error.response.status);\n    console.log(await error.response.text());\n  }\n}\n```\n\n## Testing\n\nRun the unit tests without making network calls:\n\n```sh\nnpm test\n```\n\nRun the focused type check:\n\n```sh\nnpm run lint\n```\n\nBuild the package:\n\n```sh\nnpm run build\n```\n\nGenerated code under `src/` is recreated by OpenAPI Generator and should be reviewed for\nbehavior, not reformatted by hand.\n\n## Recording HTTP Cassettes\n\nTests use [PollyJS](https://netflix.github.io/pollyjs/) for VCR-style live API coverage.\nPolly records HAR fixtures under its default `recordings` directory.\n\nCommitted recordings are replayed by default when you run:\n\n```sh\nnpm test\n```\n\nTo refresh or add recordings, export an API key and run the focused VCR suite:\n\n```sh\nexport AIAND_API_KEY=your-aiand-api-key\nnpm run test:vcr\n```\n\nThe cassette config filters the request `Authorization` header and the same response\nheaders as the Python SDK before HAR fixtures are written. Only commit sanitized cassette\nfiles.\n\nThe VCR suite records one Polly HAR cassette per public endpoint group:\n\n- `list-models`\n- `chat-completion`\n- `completion`\n- `response`\n- `files-lifecycle`\n- `uploads-complete`\n- `uploads-cancel`\n\nTogether those cassettes hit every endpoint currently generated from the OpenAPI spec:\n`GET /v1/models`, `POST /v1/chat/completions`, `POST /v1/completions`,\n`POST /v1/responses`, `GET /v1/files`, `POST /v1/files`, `GET /v1/files/{id}`,\n`GET /v1/files/{id}/content`, `DELETE /v1/files/{id}`, `POST /v1/uploads`,\n`POST /v1/uploads/{id}/parts`, `POST /v1/uploads/{id}/complete`, and\n`POST /v1/uploads/{id}/cancel`.\n\n## Updating The SDK\n\nPrerequisites:\n\n- Java, required by OpenAPI Generator.\n- Node/npm with `npx`, used to run `@openapitools/openapi-generator-cli@2.34.0`.\n- Node 18 or newer.\n\nRegenerate from the latest published spec:\n\n```sh\n./scripts/update-sdk\n```\n\nThat script:\n\n1. Downloads `https://api.aiand.com/openapi.json` to `openapi/openapi.json`.\n2. Runs OpenAPI Generator with `openapi-generator-config.yaml`.\n3. Applies `scripts/patch-generated-client.mjs` for generator-specific TypeScript\n   compatibility.\n\nAfter regenerating:\n\n```sh\nnpm test\nnpm run lint\nnpm run build\n```\n\nReview the generated diff in `src/`, `docs/`, and `openapi/openapi.json`.\n\nThe npm wrapper is pinned in `scripts/update-sdk`, and the OpenAPI Generator version is\npinned in `openapitools.json`. To upgrade either one, edit the pinned version, regenerate,\nand review the generated diff carefully.\n\n## Development Notes\n\nMost SDK files are generated. The main hand-maintained files are:\n\n- `README.md`\n- `CHANGELOG.md`\n- `LICENSE`\n- `package.json`\n- `tsconfig.json`\n- `vitest.config.ts`\n- `scripts/update-sdk`\n- `scripts/patch-generated-client.mjs`\n- `tests/`\n\n`scripts/patch-generated-client.mjs` patches the generated `ChatCompletionMessage` type.\nThe current spec models chat message variants with anonymous `anyOf` schemas, and the\nTypeScript generator collapses the aggregate type into the `tool` message shape. The patch\nkeeps normal `system`, `user`, `assistant`, `developer`, and `tool` messages type-safe\nuntil the source spec names or discriminates those variants.\n\nBug reports and pull requests are welcome.\n\n## License\n\nThis project is licensed under the [Apache License 2.0](LICENSE).\n","readmeFilename":"README.md"}