{"_id":"@typesafe-ai/sdk","_rev":"4-600205a07ac5cd4a1802a07015dfc0ca","name":"@typesafe-ai/sdk","dist-tags":{"bootstrap":"0.0.0-bootstrap.0","latest":"0.7.0"},"versions":{"0.0.0-bootstrap.0":{"name":"@typesafe-ai/sdk","version":"0.0.0-bootstrap.0","license":"MIT","_id":"@typesafe-ai/sdk@0.0.0-bootstrap.0","maintainers":[{"name":"alliesafe","email":"allie@typesafe.ai"},{"name":"diogo149","email":"diogo@typesafe.ai"}],"homepage":"https://docs.typesafe.ai","bugs":{"url":"https://github.com/typesafe-ai/typesafe-sdk-js/issues"},"dist":{"shasum":"43900134b4e5778a64aa981838ed9ee466229457","tarball":"https://registry.npmjs.org/@typesafe-ai/sdk/-/sdk-0.0.0-bootstrap.0.tgz","fileCount":3,"integrity":"sha512-NyW0Q5dnHAVpLMhdxQ6tsBJSpqK9wth6WvKZ5Dt33pnXgyK7ghguUWLkwPprnlp+BRfdq/ebOdyqBO6UeJ3stg==","signatures":[{"sig":"MEUCIAaSa4Kpl5JtZA2QNmB5y7cy87yIECmkFLAJB5IyKTzXAiEAzcYw+vKwp8os2cjQRx+xZ7x6VWH+6nvyF9iX+tr3gQE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@typesafe-ai%2fsdk@0.0.0-bootstrap.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1987},"_from":"file:typesafe-ai-sdk-0.0.0-bootstrap.0.tgz","_npmUser":{"name":"alliesafe","email":"allie@typesafe.ai"},"_resolved":"/home/runner/work/typesafe-sdk-js/typesafe-sdk-js/typesafe-ai-sdk-0.0.0-bootstrap.0.tgz","_integrity":"sha512-NyW0Q5dnHAVpLMhdxQ6tsBJSpqK9wth6WvKZ5Dt33pnXgyK7ghguUWLkwPprnlp+BRfdq/ebOdyqBO6UeJ3stg==","repository":{"url":"git+https://github.com/typesafe-ai/typesafe-sdk-js.git","type":"git"},"_npmVersion":"11.19.0","description":"Placeholder for the TypeSafe JavaScript and TypeScript SDK; not a functional SDK.","directories":{},"_nodeVersion":"24.20.0","publishConfig":{"tag":"bootstrap","access":"public","provenance":true},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sdk_0.0.0-bootstrap.0_1789181778891_0.9533027403588827","host":"s3://npm-registry-packages-npm-production"}},"0.5.7":{"name":"@typesafe-ai/sdk","version":"0.5.7","author":{"name":"evinism"},"license":"MIT","_id":"@typesafe-ai/sdk@0.5.7","maintainers":[{"name":"alliesafe","email":"allie@typesafe.ai"},{"name":"diogo149","email":"diogo@typesafe.ai"}],"homepage":"https://docs.typesafe.ai/sdk/javascript","bugs":{"url":"https://github.com/typesafe-ai/typesafe-sdk-js/issues"},"dist":{"shasum":"50f56e8a27cab8cb402652a506697654ff57cfd3","tarball":"https://registry.npmjs.org/@typesafe-ai/sdk/-/sdk-0.5.7.tgz","fileCount":9,"integrity":"sha512-OrbhDXyxDoX9l45/Mcts+TsNuvubCuZQzINQv0BMbi32ztcapzgrCnMmaW9gK5+JkgQAZcnJH1f47lAur+i1hw==","signatures":[{"sig":"MEYCIQDSihwgXlCHBSJF7y3YUXd0aBkFoK/dHakieLPYzogjvgIhAJemk3sg8Fjf/oMl36NdbaxX0ftcdNiepj/0YCN0ZDOA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@typesafe-ai%2fsdk@0.5.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":214551},"main":"./dist/index.cjs","type":"module","_from":"file:release/typesafe-ai-sdk-0.5.7.tgz","types":"./dist/index.d.cts","module":"./dist/index.mjs","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"scripts":{"demo":"tsx examples/demo.ts","docs":"npm ci --prefix docs --ignore-scripts --no-audit --no-fund && npm run --prefix docs build","lint":"biome check .","test":"vitest run","build":"tsdown","check":"npm run lint && npm run typecheck && npm run check:version && npm run test:coverage && npm run build && npm run test:dist && npm run check:package","lint:fix":"biome check --write .","push:jsr":"npm run check && jsr publish","push:npm":"npm publish","test:dist":"vitest run --config vitest.dist.config.ts","typecheck":"tsc","test:watch":"vitest","push:jsr:dry":"npm run check && jsr publish --dry-run --allow-dirty","push:npm:dry":"npm publish --dry-run","check:package":"node scripts/check-package.mjs","check:version":"node scripts/check-version.mjs","test:coverage":"vitest run --coverage","prepublishOnly":"npm run check","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c64f1c0-094c-4ddd-87bd-604d64fedbb2"}},"_resolved":"/home/runner/work/typesafe-sdk-js/typesafe-sdk-js/release/typesafe-ai-sdk-0.5.7.tgz","_integrity":"sha512-OrbhDXyxDoX9l45/Mcts+TsNuvubCuZQzINQv0BMbi32ztcapzgrCnMmaW9gK5+JkgQAZcnJH1f47lAur+i1hw==","repository":{"url":"git+https://github.com/typesafe-ai/typesafe-sdk-js.git","type":"git"},"_npmVersion":"11.19.0","description":"TypeScript SDK for the TypeSafe API","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"npm@11.19.0","devDependencies":{"jsr":"^0.14.3","tsx":"^4.23.13","tsdown":"^0.22.14","vitest":"^4.1.11","publint":"^0.3.24","git-cliff":"2.13.1","typescript":"^7.0.2","@types/node":"^26.4.1","@biomejs/biome":"^2.5.11","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.5.7_1789186400959_0.2792102019670122","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@typesafe-ai/sdk","version":"0.6.0","author":{"name":"evinism"},"license":"MIT","_id":"@typesafe-ai/sdk@0.6.0","maintainers":[{"name":"alliesafe","email":"allie@typesafe.ai"},{"name":"diogo149","email":"diogo@typesafe.ai"}],"homepage":"https://docs.typesafe.ai/sdk/javascript","bugs":{"url":"https://github.com/typesafe-ai/typesafe-sdk-js/issues"},"dist":{"shasum":"dbba30689e77c317e7619fbee006caa18f37a76a","tarball":"https://registry.npmjs.org/@typesafe-ai/sdk/-/sdk-0.6.0.tgz","fileCount":9,"integrity":"sha512-IddX+Q0XM+VagOUZFeP7wZjaO4SHMdvnh2zEBdrZZnXedWI3BNK1lKhMx3ayrkFWvVLbVcUHJy6AVZlY+e6Jaw==","signatures":[{"sig":"MEUCIQCiuSLyeKu5VTIUGJKI3nc4HpE0YG6wy5jFJJcBpYK9dQIgNs/BsaAra+zCQvH/Bm6iE35f2rjtVNGkO/wkSSeIRrw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@typesafe-ai%2fsdk@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":209203},"main":"./dist/index.cjs","type":"module","_from":"file:release/typesafe-ai-sdk-0.6.0.tgz","types":"./dist/index.d.cts","module":"./dist/index.mjs","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"scripts":{"demo":"tsx examples/demo.ts","docs":"npm ci --prefix docs --ignore-scripts --no-audit --no-fund && npm run --prefix docs build","lint":"biome check .","test":"vitest run","build":"tsdown","check":"npm run lint && npm run typecheck && npm run check:version && npm run test:coverage && npm run build && npm run test:dist && npm run check:package","lint:fix":"biome check --write .","push:jsr":"npm run check && jsr publish","push:npm":"npm publish","test:dist":"vitest run --config vitest.dist.config.ts","typecheck":"tsc","test:watch":"vitest","push:jsr:dry":"npm run check && jsr publish --dry-run --allow-dirty","push:npm:dry":"npm publish --dry-run","check:package":"node scripts/check-package.mjs","check:version":"node scripts/check-version.mjs","test:coverage":"vitest run --coverage","prepublishOnly":"npm run check","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c64f1c0-094c-4ddd-87bd-604d64fedbb2"}},"_resolved":"/home/runner/work/typesafe-sdk-js/typesafe-sdk-js/release/typesafe-ai-sdk-0.6.0.tgz","_integrity":"sha512-IddX+Q0XM+VagOUZFeP7wZjaO4SHMdvnh2zEBdrZZnXedWI3BNK1lKhMx3ayrkFWvVLbVcUHJy6AVZlY+e6Jaw==","repository":{"url":"git+https://github.com/typesafe-ai/typesafe-sdk-js.git","type":"git"},"_npmVersion":"11.19.0","description":"TypeScript SDK for the TypeSafe API","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"npm@11.19.0","devDependencies":{"jsr":"^0.14.3","tsx":"^4.23.13","tsdown":"^0.22.14","vitest":"^4.1.11","publint":"^0.3.24","git-cliff":"2.13.1","typescript":"^7.0.2","@types/node":"^26.4.1","@biomejs/biome":"^2.5.11","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.6.0_1789496239115_0.11329610694343417","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"_id":"@typesafe-ai/sdk@0.7.0","bugs":{"url":"https://github.com/typesafe-ai/typesafe-sdk-js/issues"},"dist":{"shasum":"f3d06cd9913f0861b05cf45e1bd27e9d867dd3ec","tarball":"https://registry.npmjs.org/@typesafe-ai/sdk/-/sdk-0.7.0.tgz","fileCount":9,"integrity":"sha512-Yg3OZArCQMJx98ut8QVkhx3rFo9ON7pz8Hjzv8c3FGz69Sk8jYftLOlz+Wf6kq6jol/1m08aBnjRAzJr2x3GoQ==","signatures":[{"sig":"MEQCICZQXrDqAUf/H1eeg0myOWUCKe5CwYj/Q/TFfid6bp5QAiAcmtDxXtVCa4O/ZhUv5uxKoynNu7C6SPIX1CxdGVSDLQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCFbDcgwIrtJmSMTNEvVSeh5sP1dX8p12LEQK29r/SBEQIhANg6O+YPoqIoUXGdUjOqX4yekQEkOPFhmBwrnKRSjTwp"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@typesafe-ai%2fsdk@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":338733},"main":"./dist/index.cjs","name":"@typesafe-ai/sdk","type":"module","_from":"file:release/typesafe-ai-sdk-0.7.0.tgz","types":"./dist/index.d.cts","author":{"name":"evinism"},"module":"./dist/index.mjs","engines":{"node":">=22"},"exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"license":"MIT","scripts":{"demo":"tsx examples/demo.ts","docs":"npm ci --prefix docs --ignore-scripts --no-audit --no-fund && npm run --prefix docs build","lint":"biome check .","test":"vitest run","build":"tsdown","check":"npm run lint && npm run typecheck && npm run check:version && npm run test:coverage && npm run build && npm run test:dist && npm run check:package","lint:fix":"biome check --write .","push:jsr":"npm run check && jsr publish","push:npm":"npm publish","test:dist":"vitest run --config vitest.dist.config.ts","typecheck":"tsc","test:watch":"vitest","push:jsr:dry":"npm run check && jsr publish --dry-run --allow-dirty","push:npm:dry":"npm publish --dry-run","check:package":"node scripts/check-package.mjs","check:version":"node scripts/check-version.mjs","test:coverage":"vitest run --coverage","prepublishOnly":"npm run check","test:integration":"vitest run --config vitest.integration.config.ts"},"version":"0.7.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"4c64f1c0-094c-4ddd-87bd-604d64fedbb2"}},"homepage":"https://docs.typesafe.ai/go/js-sdk","_resolved":"/home/runner/work/typesafe-sdk-js/typesafe-sdk-js/release/typesafe-ai-sdk-0.7.0.tgz","_integrity":"sha512-Yg3OZArCQMJx98ut8QVkhx3rFo9ON7pz8Hjzv8c3FGz69Sk8jYftLOlz+Wf6kq6jol/1m08aBnjRAzJr2x3GoQ==","repository":{"url":"git+https://github.com/typesafe-ai/typesafe-sdk-js.git","type":"git"},"_npmVersion":"11.19.0","description":"TypeScript SDK for the TypeSafe API","directories":{},"maintainers":[{"name":"alliesafe","email":"allie@typesafe.ai"},{"name":"diogo149","email":"diogo@typesafe.ai"}],"sideEffects":false,"_nodeVersion":"24.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"npm@11.19.0","devDependencies":{"jsr":"^0.14.3","tsx":"^4.23.13","tsdown":"^0.22.14","vitest":"^4.1.11","publint":"^0.3.24","git-cliff":"2.13.1","typescript":"^7.0.2","@types/node":"^26.4.1","@biomejs/biome":"^2.5.11","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.7.0_1792013139323_0.8281586027586214"}}},"time":{"created":"2026-09-12T02:56:18.693Z","modified":"2026-10-14T21:25:39.841Z","0.0.0-bootstrap.0":"2026-09-12T02:56:19.015Z","0.5.7":"2026-09-12T04:13:21.117Z","0.6.0":"2026-09-15T18:17:19.263Z","0.7.0":"2026-10-14T21:25:39.441Z"},"bugs":{"url":"https://github.com/typesafe-ai/typesafe-sdk-js/issues"},"author":{"name":"evinism"},"license":"MIT","homepage":"https://docs.typesafe.ai/go/js-sdk","repository":{"url":"git+https://github.com/typesafe-ai/typesafe-sdk-js.git","type":"git"},"description":"TypeScript SDK for the TypeSafe API","maintainers":[{"name":"alliesafe","email":"allie@typesafe.ai"},{"name":"diogo149","email":"diogo@typesafe.ai"}],"readme":"# TypeSafe AI JavaScript SDK\n\nJavaScript and TypeScript SDK for [TypeSafe AI](https://typesafe.ai).\n\n## Quickstart\n\nInstall the SDK (Node.js 22 or newer):\n\n```sh\nnpm install @typesafe-ai/sdk\n```\n\nSet `TYPESAFE_API_KEY` in your environment, then create and use the client:\n\n```ts\nimport { choice, TypeSafeClient } from \"@typesafe-ai/sdk\";\n\nconst client = new TypeSafeClient();\nconst response = await client.systemOne({\n  state: { document: \"I was charged twice. Please fix this ASAP.\" },\n  questions: {\n    category: choice(\"What is this ticket about?\", {\n      billing: null,\n      technical: null,\n      other: null,\n    }),\n  },\n});\n\nconsole.log(response.answers.category.choice);\n```\n\nAnswer types are inferred from your questions. The package includes ESM, CommonJS, and TypeScript declarations.\n\n## Images\n\nCreate an image with `image()` from file bytes or a `Blob` such as a `File`, or with\n`Image.fromBase64()` from base64 text. Images must be PNG or JPEG; the API detects the format\nfrom the file bytes and rejects other formats, such as WebP and GIF, with a `BadRequestError`.\nThere are three ways to use an image in a request, and they can be combined.\n\nImage support is experimental. Opt in by sending the `TypeSafe-Danger-Zone-Images: true`\nheader:\n\n```ts\nconst client = new TypeSafeClient({\n  defaultHeaders: { \"TypeSafe-Danger-Zone-Images\": \"true\" },\n});\n```\n\nTo send it with a single request instead, pass it in the call's `headers` option.\n\n### Place the image in the content\n\nPut the image anywhere in `state`, question instructions, or criteria:\n\n```ts\nimport { openAsBlob } from \"node:fs\";\nimport { image, noul, score, TypeSafeClient } from \"@typesafe-ai/sdk\";\n\nconst client = new TypeSafeClient();\nconst photo = image(await openAsBlob(\"returns/RMA-1042.jpg\"));\n\nconst { answers } = await client.systemOne({\n  state: { claim: \"The mug arrived with a chipped rim.\", photo },\n  questions: {\n    damaged: noul(\"Is the product in the photo damaged?\"),\n    severity: score(\"How severe is the damage?\", [\"none\", \"cosmetic\", \"unusable\"]),\n  },\n});\nconsole.log(answers.damaged.noul, answers.severity.score);\n```\n\n### Write the image into text with `withAssets`\n\nTag a template literal with `withAssets` to reference images inside text. This route\nhandler checks a seller's upload against the catalog photo:\n\n```ts\nimport { choice, image, noul, TypeSafeClient, withAssets } from \"@typesafe-ai/sdk\";\nimport { catalogPhotoUrl } from \"./catalog\";\n\nconst client = new TypeSafeClient();\n\nexport async function POST(request: Request): Promise<Response> {\n  const form = await request.formData();\n  const upload = image(form.get(\"photo\") as File);\n  const catalog = image(await (await fetch(catalogPhotoUrl(String(form.get(\"sku\"))))).blob());\n\n  const { answers } = await client.systemOne({\n    state: withAssets`A seller uploaded ${upload} for a listing whose catalog photo is ${catalog}.`,\n    questions: {\n      sameProduct: noul(withAssets`Does ${upload} show the same product as ${catalog}?`),\n      quality: choice(withAssets`Is ${upload} usable as a listing photo?`, {\n        usable: null,\n        blurry: null,\n        cropped: null,\n        notAProduct: null,\n      }),\n    },\n  });\n  return Response.json({ sameProduct: answers.sameProduct.noul, quality: answers.quality.choice });\n}\n```\n\nEach image is sent once, however many times it is used. An image in an untagged template\nliteral, such as `` `Compare ${upload}` ``, rejects the call with a `TypeSafeError` before the\nrequest is sent.\n\nTo write a list of images, join it with `withAssets.join`, which works like `Array.prototype.join`:\n\n```ts\nconst uploads = (form.getAll(\"photos\") as File[]).map((file) => image(file));\nconst state = withAssets`The seller uploaded ${withAssets.join(uploads, \", \")}.`;\n```\n\n### Choose your own references with `assets`\n\nPass images in `assets`, keyed by a reference of your choice, to reference them from plain\nstrings, such as prompts stored in configuration:\n\n```ts\nimport { readFile } from \"node:fs/promises\";\nimport { image, noul, TypeSafeClient } from \"@typesafe-ai/sdk\";\n\nconst client = new TypeSafeClient();\n\nconst { answers } = await client.systemOne({\n  state: \"A customer returned <delivered>. The catalog photo is <catalog>.\",\n  questions: { matches: noul(\"Is <delivered> the product shown in <catalog>?\") },\n  assets: {\n    \"<delivered>\": image(await readFile(\"returns/RMA-1042.jpg\")),\n    \"<catalog>\": image(await readFile(\"catalog/mug.png\")),\n  },\n});\nconsole.log(answers.matches.noul);\n```\n\nUse distinct delimiters, such as `<delivered>`, so references don't match ordinary text.\nAn image in `assets` that is also placed in content or in `withAssets` text is written there as\nits name. Every name in `assets` must appear in the request; otherwise the call rejects with a\n`TypeSafeError` before sending.\n\n### Locate something with `box`\n\nAsk a `box` question to locate what its instructions describe. The answer's `box` holds the\nedges as fractions of the image's height (`top`, `bottom`) and width (`left`, `right`), and its\n`confidence` is `null` when the API doesn't report one. Use the `jev-preview` model for `box`\nquestions:\n\n```ts\nimport { openAsBlob } from \"node:fs\";\nimport { box, image, TypeSafeClient } from \"@typesafe-ai/sdk\";\n\nconst client = new TypeSafeClient();\n\nconst { answers } = await client.systemOne({\n  state: image(await openAsBlob(\"returns/RMA-1042.jpg\")),\n  questions: { damage: box(\"The damaged area of the product\") },\n  model: \"jev-preview\",\n});\nconst { top, bottom, left, right } = answers.damage.box;\n```\n\nRequests with images are sent as `multipart/form-data`, with each image's file bytes in its\nown part.\n\n## Request compression\n\nThe client compresses request bodies of 1 KiB or more with zstd, which reduces upload size and\ntime, especially for large states. Smaller bodies fit in a single TCP segment, so they are sent\nuncompressed. zstd requires Node.js 22.15 or newer; on other runtimes, all bodies are sent\nuncompressed. Pass `compression: false` to send all bodies uncompressed, for example to an API\nthat doesn't accept compressed requests:\n\n```ts\nconst client = new TypeSafeClient({ compression: false });\n```\n\n## Documentation\n\nLearn what TypeSafe can do in the [TypeSafe docs](https://docs.typesafe.ai/).\nSee the SDK's [client](src/client.ts) and [types](src/types.ts) for API options and defaults.\n","readmeFilename":"README.md"}