diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af17f338..bbabce78 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,10 +21,10 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/writer-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '22' @@ -43,10 +43,10 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '22' @@ -61,7 +61,7 @@ jobs: github.repository == 'stainless-sdks/writer-typescript' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -91,10 +91,10 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/writer-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '22' diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index e977e568..ed7e1cf5 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -20,10 +20,10 @@ jobs: contents: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v3 + uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1 with: node-version: '20' diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 897f1dab..b09d8cd1 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,11 +12,10 @@ jobs: if: github.repository == 'writer/writer-node' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check release environment run: | bash ./bin/check-release-environment env: NPM_TOKEN: ${{ secrets.WRITER_NPM_TOKEN || secrets.NPM_TOKEN }} - diff --git a/.prettierignore b/.prettierignore index 7cc13dd1..36afd3b3 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,6 +2,7 @@ CHANGELOG.md /ecosystem-tests/*/** /node_modules /deno +/packages/mcp-server/manifest.json # don't format tsc output, will break source maps dist diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e601dc3f..d4f6f299 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.0.0-rc.1" + ".": "3.0.0" } diff --git a/.stats.yml b/.stats.yml index 18b117f4..45b858e1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 30 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/writerai%2Fwriter-ea6b4de3976794a02ea8fc01669d901cd7b159ba0d598cc9653e01c987a2f806.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/writerai/writer-275de8f7afa2d37404ebebc082dda35e70ab94437de270b5bc6e2fdc94c9fdae.yml openapi_spec_hash: 4d4a9ba232d19a6180e6d4a7d5566103 config_hash: 8701b1a467238f1afdeceeb7feb1adc6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 66a60d48..b7570184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,311 @@ # Changelog +## 3.0.0 (2026-06-02) + +Full Changelog: [v3.0.0...v3.0.0](https://github.com/writer/writer-node/compare/v3.0.0...v3.0.0) + +### ⚠ BREAKING CHANGES + +* **mcp:** remove deprecated tool schemes +* **mcp:** **Migration:** To migrate, simply modify the command used to invoke the MCP server. Currently, the only supported tool scheme is code mode. Now, starting the server with just `node /path/to/mcp/server` or `npx package-name` will invoke code tools: changing your command to one of these is likely all you will need to do. + +### Features + +* **api:** add model graphs.Question ([#67](https://github.com/writer/writer-node/issues/67)) ([af195e9](https://github.com/writer/writer-node/commit/af195e9a6e4562dfb7a7e24cde19a20d45e8511f)) +* **api:** add new endpoints ([#94](https://github.com/writer/writer-node/issues/94)) ([b0dcac4](https://github.com/writer/writer-node/commit/b0dcac40bb742924828cc51fd2c8702ab509e9a1)) +* **api:** add streaming to application generation ([#122](https://github.com/writer/writer-node/issues/122)) ([c85d6c6](https://github.com/writer/writer-node/commit/c85d6c62e16d3b9f38b401d162ab144123413b55)) +* **api:** add streaming to kg question ([#101](https://github.com/writer/writer-node/issues/101)) ([0279ffc](https://github.com/writer/writer-node/commit/0279ffc13185a7cc4e34bcd5df0489b19bcd8b64)) +* **api:** add support for graphs and files endpoints ([#13](https://github.com/writer/writer-node/issues/13)) ([52f462c](https://github.com/writer/writer-node/commit/52f462c25a34a0876577bf7e02444e57b99bf7aa)) +* **api:** added method to generate applications content ([#43](https://github.com/writer/writer-node/issues/43)) ([09b2657](https://github.com/writer/writer-node/commit/09b26572e0b66f490cb5fef0ee3f0c0250ae9142)) +* **api:** api update ([#100](https://github.com/writer/writer-node/issues/100)) ([a7c6e10](https://github.com/writer/writer-node/commit/a7c6e10b93285a3c5a42ed468097bab2556d6be3)) +* **api:** api update ([#121](https://github.com/writer/writer-node/issues/121)) ([f4adda0](https://github.com/writer/writer-node/commit/f4adda020d78626ce8ddf24e87c866db24e4baaf)) +* **api:** api update ([#81](https://github.com/writer/writer-node/issues/81)) ([d61a1db](https://github.com/writer/writer-node/commit/d61a1db8343f7ca2d98de4ef66c16020b2d7144b)) +* **api:** api update ([#84](https://github.com/writer/writer-node/issues/84)) ([dfbb999](https://github.com/writer/writer-node/commit/dfbb9998ef58cf008ad4ec920fc387050ee37153)) +* **api:** api update ([#87](https://github.com/writer/writer-node/issues/87)) ([eabef89](https://github.com/writer/writer-node/commit/eabef89d3b32f0a46e546e004d16d91f3b91e63c)) +* **api:** default timeout increase to 3 min ([#111](https://github.com/writer/writer-node/issues/111)) ([e0d48dc](https://github.com/writer/writer-node/commit/e0d48dc70007e2ff26f7045ee5362d8954328805)) +* **api:** Deprecate AI Detection, Medical Comprehend, and Context-Aware Text Splitting ([91097e4](https://github.com/writer/writer-node/commit/91097e4d5d1165e5f8d422b475389b34e9371349)) +* **api:** manual updates ([0012f4c](https://github.com/writer/writer-node/commit/0012f4ccc4acda716ef0559edc28f14af57911fa)) +* **api:** manual updates ([d9dd552](https://github.com/writer/writer-node/commit/d9dd55266323cb77cb8d4b88b6cc3ff3c7a91a00)) +* **api:** manual updates ([#102](https://github.com/writer/writer-node/issues/102)) ([eea7dcc](https://github.com/writer/writer-node/commit/eea7dcc7d88ebe666cce615991b302dfec62d46b)) +* **api:** manual updates ([#105](https://github.com/writer/writer-node/issues/105)) ([9158a6d](https://github.com/writer/writer-node/commit/9158a6debe889e7cc7cf23df00d5f46671d352e7)) +* **api:** manual updates ([#119](https://github.com/writer/writer-node/issues/119)) ([37f2a16](https://github.com/writer/writer-node/commit/37f2a169c41b4b0a22d7bcff562f6881a66f3af9)) +* **api:** manual updates ([#62](https://github.com/writer/writer-node/issues/62)) ([d9dedc4](https://github.com/writer/writer-node/commit/d9dedc400a225420ef23bbd2bc0077a1cac59ba5)) +* **api:** manual updates ([#64](https://github.com/writer/writer-node/issues/64)) ([d072c4d](https://github.com/writer/writer-node/commit/d072c4d279ee25087b282404a097fa80a1f7d17c)) +* **api:** manual updates ([#95](https://github.com/writer/writer-node/issues/95)) ([26f13bd](https://github.com/writer/writer-node/commit/26f13bda1f456ff17cb8194cf5c2edeb6303652b)) +* **api:** OpenAPI spec update via Stainless API ([#11](https://github.com/writer/writer-node/issues/11)) ([e742ffe](https://github.com/writer/writer-node/commit/e742ffeb02c8cbee7abee98e70c7ca6673770b85)) +* **api:** OpenAPI spec update via Stainless API ([#19](https://github.com/writer/writer-node/issues/19)) ([00d9929](https://github.com/writer/writer-node/commit/00d9929fea595070b9e0e3e6042b40f0d6f898cf)) +* **api:** OpenAPI spec update via Stainless API ([#22](https://github.com/writer/writer-node/issues/22)) ([b3b9223](https://github.com/writer/writer-node/commit/b3b9223530de5b8c65bc3e0c58869a8a4a140d3b)) +* **api:** OpenAPI spec update via Stainless API ([#23](https://github.com/writer/writer-node/issues/23)) ([1e9c082](https://github.com/writer/writer-node/commit/1e9c08252bf0987fa7e0830bfaa5db6d306cc405)) +* **api:** OpenAPI spec update via Stainless API ([#25](https://github.com/writer/writer-node/issues/25)) ([cc8dca0](https://github.com/writer/writer-node/commit/cc8dca08fa4c6b0adcb8fb921a7741e0e78e3934)) +* **api:** rename kg question and add text-to-graph ([#103](https://github.com/writer/writer-node/issues/103)) ([5e651e2](https://github.com/writer/writer-node/commit/5e651e2383975474a8dea114527c4111e01f9b2d)) +* **api:** rename to chat_completion_chunk ([#73](https://github.com/writer/writer-node/issues/73)) ([e4d5ac4](https://github.com/writer/writer-node/commit/e4d5ac4a9cf5eb8fa8a068024628b4ae689e5468)) +* **api:** update models in readme ([#79](https://github.com/writer/writer-node/issues/79)) ([19b7851](https://github.com/writer/writer-node/commit/19b7851bc31035fb457063bd5ea92aa15f4bc4ee)) +* **api:** update tools api methods ([#99](https://github.com/writer/writer-node/issues/99)) ([991f955](https://github.com/writer/writer-node/commit/991f955a62816fbd25e92649f84383f264521755)) +* **api:** update via SDK Studio ([f0c7afd](https://github.com/writer/writer-node/commit/f0c7afd876cd809a1050bd6ca45ad23803c4475e)) +* **api:** update via SDK Studio ([a700263](https://github.com/writer/writer-node/commit/a700263a6a96e5b2fd42f4e177cc9a08393273d5)) +* **api:** update via SDK Studio ([4ea2214](https://github.com/writer/writer-node/commit/4ea2214221363c04a2fff5c4478d0e0e21c220dd)) +* **api:** update via SDK Studio ([b3c74ab](https://github.com/writer/writer-node/commit/b3c74ab04b2e8fadb6739969b8ceeee6d853fdaa)) +* **api:** update via SDK Studio ([f3018fc](https://github.com/writer/writer-node/commit/f3018fc9f6feb08d54b3a76f80681626c0083272)) +* **api:** update via SDK Studio ([b42882d](https://github.com/writer/writer-node/commit/b42882ddec15bab1f2c0897a8dc337fff5b96432)) +* **api:** update via SDK Studio ([27e23b1](https://github.com/writer/writer-node/commit/27e23b1d7856d7e172adf3879fdee397cf9c8048)) +* **api:** update via SDK Studio ([3504f6d](https://github.com/writer/writer-node/commit/3504f6dcf928563eaafd31ded2572d6c2e2f0530)) +* **api:** update via SDK Studio ([ad2a87f](https://github.com/writer/writer-node/commit/ad2a87f902a94a48ddfdfc8c6e1284dbf0ecdbe8)) +* **api:** update via SDK Studio ([#14](https://github.com/writer/writer-node/issues/14)) ([88e43b2](https://github.com/writer/writer-node/commit/88e43b271ffbf1130d6ed582bd8fb0c29bdbf4e1)) +* **api:** update via SDK Studio ([#15](https://github.com/writer/writer-node/issues/15)) ([11d170b](https://github.com/writer/writer-node/commit/11d170bf8649dca8beb99519ca0d12097bf28412)) +* **api:** update via SDK Studio ([#16](https://github.com/writer/writer-node/issues/16)) ([455b64a](https://github.com/writer/writer-node/commit/455b64ae3c138ae1befef9d20b317b686bf99133)) +* **api:** update via SDK Studio ([#17](https://github.com/writer/writer-node/issues/17)) ([fcd684d](https://github.com/writer/writer-node/commit/fcd684d35d9e66c8a7f85c515c22d50ce25c89ba)) +* **api:** update via SDK Studio ([#20](https://github.com/writer/writer-node/issues/20)) ([4f863a4](https://github.com/writer/writer-node/commit/4f863a424f73ec65d7075450de05f1fafbda22a6)) +* **api:** update via SDK Studio ([#21](https://github.com/writer/writer-node/issues/21)) ([19a6a2c](https://github.com/writer/writer-node/commit/19a6a2cc64b7f9900cead093521b5b6c3d17c29f)) +* **api:** update via SDK Studio ([#24](https://github.com/writer/writer-node/issues/24)) ([04c9642](https://github.com/writer/writer-node/commit/04c964230fb0a45b01bac545f1c3e4f5a0a1a7e9)) +* **api:** update via SDK Studio ([#3](https://github.com/writer/writer-node/issues/3)) ([514a183](https://github.com/writer/writer-node/commit/514a1831d625e4e536e5c1331f11f634dc78d977)) +* **api:** update via SDK Studio ([#37](https://github.com/writer/writer-node/issues/37)) ([978cf26](https://github.com/writer/writer-node/commit/978cf26ddca6e10cccbb36fb0a7e0eaa44ae367b)) +* **api:** update via SDK Studio ([#4](https://github.com/writer/writer-node/issues/4)) ([c57666a](https://github.com/writer/writer-node/commit/c57666a9bac97efdbc39fe3d4dc397ae4cfd83a3)) +* **api:** update via SDK Studio ([#41](https://github.com/writer/writer-node/issues/41)) ([6e08bc0](https://github.com/writer/writer-node/commit/6e08bc0d85946bda11b397bb647f32595992d322)) +* **api:** update via SDK Studio ([#42](https://github.com/writer/writer-node/issues/42)) ([2c54f4a](https://github.com/writer/writer-node/commit/2c54f4a8975a92d169beff5dbd9b096f7999e7b5)) +* **api:** update via SDK Studio ([#6](https://github.com/writer/writer-node/issues/6)) ([4e3a404](https://github.com/writer/writer-node/commit/4e3a404e9b208735519a190b21f987c1a0c258cc)) +* **api:** update via SDK Studio ([#7](https://github.com/writer/writer-node/issues/7)) ([8bacaeb](https://github.com/writer/writer-node/commit/8bacaebb0db6e46ad27f9d1e6b959d23708aa48b)) +* **client:** send retry count header ([#61](https://github.com/writer/writer-node/issues/61)) ([c0a3dde](https://github.com/writer/writer-node/commit/c0a3ddebb34f34567f01951f39bee1a144e2d05a)) +* feat: joint method `uploadAndAddFileToGraph` ([49ae4ba](https://github.com/writer/writer-node/commit/49ae4ba238ca5791e9df5ef42998fffe33e5c121)) +* fix: lint ([4a363dc](https://github.com/writer/writer-node/commit/4a363dc4869b1022e31367b6ddd42b4757ee479e)) +* fix(api/files): remove unintentional Content-Length header param ([00aa0e8](https://github.com/writer/writer-node/commit/00aa0e8d85f8c90d2923f506f650cb93dc8c1438)) +* **internal:** make git install file structure match npm ([#118](https://github.com/writer/writer-node/issues/118)) ([407d303](https://github.com/writer/writer-node/commit/407d303875b56668730be19459cf33441745c577)) +* joint method `uploadAndAddFileToGraph` ([d9e933a](https://github.com/writer/writer-node/commit/d9e933ad43c9808f175a84651333429a7d12272b)) +* **mcp:** add an option to disable code tool ([fa96ea5](https://github.com/writer/writer-node/commit/fa96ea5f1c6c863ee94918f58f532ecf7d4ec8c3)) +* **mcp:** add initial server instructions ([d52d098](https://github.com/writer/writer-node/commit/d52d098bfb5163f020f6bf7a0e45e1ea911ca962)) +* **mcp:** add typescript check to code execution tool ([7ecde82](https://github.com/writer/writer-node/commit/7ecde8204a6475dc8106c4c90d1e90030260e465)) +* **mcp:** handle code mode calls in the Stainless API ([a705a1b](https://github.com/writer/writer-node/commit/a705a1b8ed30c17464d0a3700c828796550ed8d6)) +* **mcp:** return logs on code tool errors ([76551d3](https://github.com/writer/writer-node/commit/76551d345f33dbe6f6ea1bc437b691bcf3690664)) +* support setting headers via env ([775860c](https://github.com/writer/writer-node/commit/775860c7b034ec2b29133441ca42ff1653559737)) + + +### Bug Fixes + +* add content type to file uploads param ([cb5531a](https://github.com/writer/writer-node/commit/cb5531ab082f648e26b41b109e56b84bd41b4c50)) +* **api/files:** remove unintentional Content-Length header param ([82e9f9b](https://github.com/writer/writer-node/commit/82e9f9ba2258b00b23b494336599792cc501ddb7)) +* change file content type to Core.Uploadable ([64c3ac9](https://github.com/writer/writer-node/commit/64c3ac9f330c55616511146bc4c2c228ebf05fc6)) +* **client:** avoid memory leak with abort signals ([325c9ca](https://github.com/writer/writer-node/commit/325c9ca844c64083fb0e09f83c291cc17ef2c61d)) +* **client:** avoid removing abort listener too early ([8a3f29d](https://github.com/writer/writer-node/commit/8a3f29dbe0af0d126d7227b500c551204c916773)) +* **client:** preserve URL params already embedded in path ([c650393](https://github.com/writer/writer-node/commit/c650393f8ea5e1ceebb4c903f69b78d85572279c)) +* **compat:** remove ReadableStream polyfill redundant since node v16 ([#33](https://github.com/writer/writer-node/issues/33)) ([2dac835](https://github.com/writer/writer-node/commit/2dac83558310169906d1057ad08f80ae9ec81272)) +* **docs/contributing:** correct pnpm link command ([edcceda](https://github.com/writer/writer-node/commit/edcceda07df649e2a6dfd80d1b220b8e17a1b3ea)) +* **docs:** fix mcp installation instructions for remote servers ([5248a83](https://github.com/writer/writer-node/commit/5248a83066782fedd9c97b4b6f78f476c2535d59)) +* Fix linting error ([dea914e](https://github.com/writer/writer-node/commit/dea914eeb246514c80ea2a1e69d79c4a8f0e7ef3)) +* Fix linting errors. ([adf5ccb](https://github.com/writer/writer-node/commit/adf5ccb8d52080f03a8704e41d304b3838250376)) +* Fix linting errors. ([#246](https://github.com/writer/writer-node/issues/246)) ([dea914e](https://github.com/writer/writer-node/commit/dea914eeb246514c80ea2a1e69d79c4a8f0e7ef3)) +* fix request delays for retrying to be more respectful of high requested delays ([b897aab](https://github.com/writer/writer-node/commit/b897aab23f199ac46e4fe6092fb3c1cbc0cbdb7d)) +* fix tool_choice schema ([d3ade29](https://github.com/writer/writer-node/commit/d3ade29281eaf5ffd94022e77313d8cfe96955e3)) +* lint ([18cf3c1](https://github.com/writer/writer-node/commit/18cf3c185780c9b7cf63137ae4dfb776f96b6723)) +* **lint:** format ([032bc59](https://github.com/writer/writer-node/commit/032bc59490e65b17137e26d965e481290fc2e526)) +* **mcp:** add client instantiation options to code tool ([761c3b1](https://github.com/writer/writer-node/commit/761c3b1ccc0eacc6b7ed7782fd1abddefc9020d7)) +* **mcp:** allow falling back for required env variables ([7e8d2fc](https://github.com/writer/writer-node/commit/7e8d2fc3c1012493584dab21e31c36e0f458b3fd)) +* **mcp:** correct code tool API endpoint ([6cd6857](https://github.com/writer/writer-node/commit/6cd6857db708dc98d8ee76b3b324c1a123de222c)) +* **mcp:** correct code tool api output types ([9b088bc](https://github.com/writer/writer-node/commit/9b088bc1c7705c55bfb6f448f85520171a0ae820)) +* **mcp:** fix env parsing ([a8328e7](https://github.com/writer/writer-node/commit/a8328e7d7dc8abae15fe7c8bb653e206a14c51cd)) +* **mcp:** fix options parsing ([6690d22](https://github.com/writer/writer-node/commit/6690d22af5aac3cdc2ffd883010b06989e6a4f92)) +* **mcp:** initialize SDK lazily to avoid failing the connection on init errors ([49df35f](https://github.com/writer/writer-node/commit/49df35fc62598b6ccc91e4e45cf5afa530c4f19d)) +* **mcp:** pass base url to code tool ([59063c0](https://github.com/writer/writer-node/commit/59063c0bea7c292d3bc080b32b8bfd92316446e5)) +* **mcp:** return correct lines on typescript errors ([c7e0c9b](https://github.com/writer/writer-node/commit/c7e0c9bffca2893dd36715811ba3b6001fa5544d)) +* **mcp:** return tool execution error on api error ([b62c6ba](https://github.com/writer/writer-node/commit/b62c6ba071ea931ae3af7b996b084403be6b0777)) +* **mcp:** update code tool prompt ([382ffb1](https://github.com/writer/writer-node/commit/382ffb1f2535c072fc1def53a0eb1e1456b609b9)) +* **mcp:** update prompt ([dddad93](https://github.com/writer/writer-node/commit/dddad93a9b1c3ab92f1d52a5bdbe31af46939d8e)) +* **mcp:** use `pure-lockfile` when building mcp server ([1e77ebc](https://github.com/writer/writer-node/commit/1e77ebcc14b5b7a82dcfe65fe0a1d7410d2e2288)) +* treat text/plan with format: binary as raw upload ([5f3799d](https://github.com/writer/writer-node/commit/5f3799dd90e31153b9e3c9f31e666e6f90c4ef5f)) +* **typescript:** upgrade tsc-multi so that it works with Node 26 ([c4f21ed](https://github.com/writer/writer-node/commit/c4f21edee4915b5e8d0c757dd6de75c2627d79bd)) +* **types:** remove leftover polyfill usage ([#60](https://github.com/writer/writer-node/issues/60)) ([043939d](https://github.com/writer/writer-node/commit/043939d96fdd8179fc56ff3b3ed48f37a91d724e)) +* **uploads:** avoid making redundant memory copies ([#55](https://github.com/writer/writer-node/issues/55)) ([f864fb3](https://github.com/writer/writer-node/commit/f864fb33da970311e3ef32cac083ba5543fe6a7c)) + + +### Chores + +* avoid formatting file that gets changed during releases ([6a45720](https://github.com/writer/writer-node/commit/6a457206747179f91a6bd085e19b26b68d5caf99)) +* break long lines in snippets into multiline ([58a37e3](https://github.com/writer/writer-node/commit/58a37e30f60599207bdc756ba723d25686770d4a)) +* **ci:** bump prism mock server version ([#47](https://github.com/writer/writer-node/issues/47)) ([3b881e9](https://github.com/writer/writer-node/commit/3b881e99f6d06d964f6b3d5c2321b2731ad8f0b3)) +* **ci:** escape input path in publish-npm workflow ([5a5bf6b](https://github.com/writer/writer-node/commit/5a5bf6b7c85abbc390ed796347b77855d8f5a461)) +* **ci:** minor changes ([#46](https://github.com/writer/writer-node/issues/46)) ([2cab651](https://github.com/writer/writer-node/commit/2cab65110b303808962dfa4f8378ca0d2e40aa0b)) +* **ci:** skip lint on metadata-only changes ([01c3e15](https://github.com/writer/writer-node/commit/01c3e15869a06fd6247270c6d6f2bc77ebbefd26)) +* **ci:** skip uploading artifacts on stainless-internal branches ([51bf9fc](https://github.com/writer/writer-node/commit/51bf9fc60afb36994efbac0e9bc04e39a2b5b163)) +* **ci:** upgrade `actions/github-script` ([c84c7b9](https://github.com/writer/writer-node/commit/c84c7b9ebc03fcee7411719aa5fd783cbdcdc38c)) +* **client:** do not parse responses with empty content-length ([6802838](https://github.com/writer/writer-node/commit/6802838d8eab0322f78ba8f2612aa282687715c9)) +* **client:** restructure abort controller binding ([3204f51](https://github.com/writer/writer-node/commit/3204f51e093c5f1390cef993d2a377b778edbe1d)) +* **docs:** fix incorrect client var names ([#34](https://github.com/writer/writer-node/issues/34)) ([186a9d9](https://github.com/writer/writer-node/commit/186a9d9816a8b1021203958aeaebc5954ce95c25)) +* fix example snippet imports ([4e80d76](https://github.com/writer/writer-node/commit/4e80d762dfb7537a347bcb7ea12a553f97d72f5b)) +* fix typo in descriptions ([2f6c30f](https://github.com/writer/writer-node/commit/2f6c30f7e0a9f56641eeb077fdda5abf79c9e11c)) +* **format:** run eslint and prettier separately ([be7d4a0](https://github.com/writer/writer-node/commit/be7d4a0d88334afce883d534ca85d735aa026bc4)) +* **formatter:** run prettier and eslint separately ([b671b3d](https://github.com/writer/writer-node/commit/b671b3d852b2943f44140f8ccd827100e9121149)) +* go live ([#1](https://github.com/writer/writer-node/issues/1)) ([97d56db](https://github.com/writer/writer-node/commit/97d56db208b49ffc17c8d54c52cdd8fc53699fa7)) +* **internal/client:** fix form-urlencoded requests ([69d4765](https://github.com/writer/writer-node/commit/69d476512384faa4ba6f068921c0aacb2fcd8c54)) +* **internal:** add constant for default timeout ([#36](https://github.com/writer/writer-node/issues/36)) ([b4220e2](https://github.com/writer/writer-node/commit/b4220e2d2ad266040c753b4c42f1f0da1a51a166)) +* **internal:** add health check to MCP server when running in HTTP mode ([cbb4461](https://github.com/writer/writer-node/commit/cbb44616abd6e800f622b8e2e1a406f5da72c85b)) +* **internal:** allow basic filtering of methods allowed for MCP code mode ([a07d4aa](https://github.com/writer/writer-node/commit/a07d4aaa8dcf25a61de3721f0203b26fac082ea0)) +* **internal:** allow setting x-stainless-api-key header on mcp server requests ([ec7acc0](https://github.com/writer/writer-node/commit/ec7acc08393eb40ab704817b28ac441a25747ff0)) +* **internal:** always generate MCP server dockerfiles and upgrade associated dependencies ([dc3398b](https://github.com/writer/writer-node/commit/dc3398b32e6139cb085ec0b1291e068d71cd35cf)) +* **internal:** avoid type checking errors with ts-reset ([d32477d](https://github.com/writer/writer-node/commit/d32477dbfdf57bcd09bc40722698fad93b31fbde)) +* **internal:** bump @modelcontextprotocol/sdk, @hono/node-server, and minimatch ([85c4851](https://github.com/writer/writer-node/commit/85c4851f99e0cf1c918e6ffaec248dddffcecb77)) +* **internal:** bump cross-spawn to v7.0.6 ([#124](https://github.com/writer/writer-node/issues/124)) ([b5ccd7c](https://github.com/writer/writer-node/commit/b5ccd7cfba653cd078769eef9900933fed84819f)) +* **internal:** cache fetch instruction calls in MCP server ([6745b11](https://github.com/writer/writer-node/commit/6745b119635f4fb1adc214136afb028beaf617e7)) +* **internal:** codegen related update ([88197ba](https://github.com/writer/writer-node/commit/88197ba9e896440696a46b21129b07862f90dc3c)) +* **internal:** codegen related update ([7f46854](https://github.com/writer/writer-node/commit/7f46854adff49ae46df71380fb8a40cd0879c4ae)) +* **internal:** codegen related update ([c959300](https://github.com/writer/writer-node/commit/c95930084716f047fd69d97c0d6314da95dc8ae4)) +* **internal:** codegen related update ([f120aae](https://github.com/writer/writer-node/commit/f120aaee36cb691f3be43210e34324982b51805d)) +* **internal:** codegen related update ([757eeae](https://github.com/writer/writer-node/commit/757eeae33e139f642cdb432b600c7c6887e65f25)) +* **internal:** codegen related update ([56fc7c7](https://github.com/writer/writer-node/commit/56fc7c7870a26529558d4ae70d238d201e2015a0)) +* **internal:** codegen related update ([e12403b](https://github.com/writer/writer-node/commit/e12403bc7c73a4ae453c9bfbab7a5423a91497e7)) +* **internal:** codegen related update ([1be7281](https://github.com/writer/writer-node/commit/1be72815af2ad70591cfc3a0c63bbf318d5dc405)) +* **internal:** codegen related update ([4807744](https://github.com/writer/writer-node/commit/4807744a4ec789fa0e283d33fa77b50a9f9880fc)) +* **internal:** codegen related update ([e56fb21](https://github.com/writer/writer-node/commit/e56fb21f84394e9f58fadcfaa86b1e52ab8f4673)) +* **internal:** codegen related update ([c549df2](https://github.com/writer/writer-node/commit/c549df28775dfec7ec1367b854068d9d845b851d)) +* **internal:** codegen related update ([220705b](https://github.com/writer/writer-node/commit/220705bccf50e9c1a2c0c087a697e274a64e090c)) +* **internal:** codegen related update ([cf8a0ac](https://github.com/writer/writer-node/commit/cf8a0ac27f7a4d3c2f09435d537a0e9b6d5f7a95)) +* **internal:** codegen related update ([5958ab9](https://github.com/writer/writer-node/commit/5958ab937e37a09fe325dfc509537080825573e0)) +* **internal:** codegen related update ([30d1025](https://github.com/writer/writer-node/commit/30d10259e89332dd11656dbefbee651eeb506706)) +* **internal:** codegen related update ([#116](https://github.com/writer/writer-node/issues/116)) ([d632f68](https://github.com/writer/writer-node/commit/d632f686120b920e06dfa7a2dc76ddf651da7357)) +* **internal:** codegen related update ([#31](https://github.com/writer/writer-node/issues/31)) ([c3ba095](https://github.com/writer/writer-node/commit/c3ba0959665d5604bc963b16c6ab71f738686504)) +* **internal:** codegen related update ([#45](https://github.com/writer/writer-node/issues/45)) ([5c54eb9](https://github.com/writer/writer-node/commit/5c54eb96d4bfcaa305990be63ef98839679ac56d)) +* **internal:** codegen related update ([#48](https://github.com/writer/writer-node/issues/48)) ([d908809](https://github.com/writer/writer-node/commit/d9088094ecd095db6f598384dbda4bd1f01ce460)) +* **internal:** codegen related update ([#49](https://github.com/writer/writer-node/issues/49)) ([d057479](https://github.com/writer/writer-node/commit/d05747974f065d73ffa6c19c792292fd626b87d8)) +* **internal:** codegen related update ([#51](https://github.com/writer/writer-node/issues/51)) ([fcebf50](https://github.com/writer/writer-node/commit/fcebf50518f24dd765d675b94afd3937ac66dd5b)) +* **internal:** codegen related update ([#58](https://github.com/writer/writer-node/issues/58)) ([0b0a85d](https://github.com/writer/writer-node/commit/0b0a85d7d4be783fbd9a674ed1d3bc961e313b94)) +* **internal:** codegen related update ([#69](https://github.com/writer/writer-node/issues/69)) ([4fdbf70](https://github.com/writer/writer-node/commit/4fdbf70757530bd9dfd045e60da042877aac82a4)) +* **internal:** codegen related update ([#72](https://github.com/writer/writer-node/issues/72)) ([611a33b](https://github.com/writer/writer-node/commit/611a33bda7ce33ec69fa3907a2b6ad7ae0fbe781)) +* **internal:** dependency updates ([#53](https://github.com/writer/writer-node/issues/53)) ([ab3c399](https://github.com/writer/writer-node/commit/ab3c399044f36aa74f21148770869c034c4185ab)) +* **internal:** fix MCP docker image builds in yarn projects ([4a40b93](https://github.com/writer/writer-node/commit/4a40b93b9a76b15213e3b890686f806e301e2328)) +* **internal:** fix MCP Dockerfiles so they can be built without buildkit ([2e39b4f](https://github.com/writer/writer-node/commit/2e39b4fa5f4ee2554f2185a0466933e7414eccec)) +* **internal:** fix MCP Dockerfiles so they can be built without buildkit ([2aa7960](https://github.com/writer/writer-node/commit/2aa7960f102438b8b9a312bd32a1ddb1cb67b790)) +* **internal:** fix MCP server import ordering ([1a45a48](https://github.com/writer/writer-node/commit/1a45a48cde1f9961ac2f79d6bc775b1a607f0436)) +* **internal:** fix MCP server TS errors that occur with required client options ([64520aa](https://github.com/writer/writer-node/commit/64520aa474771c608f1a575d0cd9ae36bdca033c)) +* **internal:** fix pagination internals not accepting option promises ([302c9ab](https://github.com/writer/writer-node/commit/302c9ab7a966a1cc9e3f46a376057ab0d479ee83)) +* **internal:** improve layout of generated MCP server files ([da6f525](https://github.com/writer/writer-node/commit/da6f525158745577a74376c352bb967515e0f902)) +* **internal:** improve local docs search for MCP servers ([bf2441f](https://github.com/writer/writer-node/commit/bf2441f89a2d2642dcfb5978938518a3dba7ad15)) +* **internal:** improve local docs search for MCP servers ([d1710b0](https://github.com/writer/writer-node/commit/d1710b03fc4b42bdc8cab7dc288bea9eb084af71)) +* **internal:** make generated MCP servers compatible with Cloudflare worker environments ([d8af505](https://github.com/writer/writer-node/commit/d8af505573509dfa5541cb49021e7279850cd457)) +* **internal:** make MCP code execution location configurable via a flag ([8b197f0](https://github.com/writer/writer-node/commit/8b197f0e9406fc38ac7b318836484982b6b895a7)) +* **internal:** more robust bootstrap script ([af77915](https://github.com/writer/writer-node/commit/af77915717a2749b0275b3fc9c1a09f4c69826ce)) +* **internal:** move LineDecoder to a separate file ([#76](https://github.com/writer/writer-node/issues/76)) ([f8c8855](https://github.com/writer/writer-node/commit/f8c885507286f008fb26a501d692d25f912b4798)) +* **internal:** move stringifyQuery implementation to internal function ([08e2c09](https://github.com/writer/writer-node/commit/08e2c09ebe73f6c62b9d9b531662ff7827c7aa64)) +* **internal:** pass props through internal parser ([#78](https://github.com/writer/writer-node/issues/78)) ([bb1aae5](https://github.com/writer/writer-node/commit/bb1aae50a38e375118b3ddaf35ceabb83b0ae44d)) +* **internal:** refactor flag parsing for MCP servers and add debug flag ([5291a9f](https://github.com/writer/writer-node/commit/5291a9f086f73589f86a3a6bd604e6686e961f13)) +* **internal:** remove unnecessary getRequestClient function ([#123](https://github.com/writer/writer-node/issues/123)) ([8e9e6f0](https://github.com/writer/writer-node/commit/8e9e6f02a09bf3c31bdeb0c616ab51800696d2ed)) +* **internal:** show error causes in MCP servers when running in local mode ([6faf2cc](https://github.com/writer/writer-node/commit/6faf2cc413f92b3b0ae150251ecc63cc731bf07a)) +* **internal:** support custom-instructions-path flag in MCP servers ([8d2f3d0](https://github.com/writer/writer-node/commit/8d2f3d0fae360c5d3ae00fe48376e570e1904731)) +* **internal:** support local docs search in MCP servers ([f479ec6](https://github.com/writer/writer-node/commit/f479ec6f4141d7c59cf0dd44dff9fdf38debd2f4)) +* **internal:** support oauth authorization code flow for MCP servers ([96ba350](https://github.com/writer/writer-node/commit/96ba350f38776d9622a9cc4124ebca788a5fa9e1)) +* **internal:** support type annotations when running MCP in local execution mode ([7282ea3](https://github.com/writer/writer-node/commit/7282ea3eb7f9c0579ed0d7c14ed3585612b8d381)) +* **internal:** support x-stainless-mcp-client-envs header in MCP servers ([29ec150](https://github.com/writer/writer-node/commit/29ec150c6869179932be3ac434fc3596a2883387)) +* **internal:** support x-stainless-mcp-client-permissions headers in MCP servers ([5cacf5f](https://github.com/writer/writer-node/commit/5cacf5ff4671398607b6dcb56414c43a20bd77b8)) +* **internal:** switch MCP servers to use pino for logging ([a2693a7](https://github.com/writer/writer-node/commit/a2693a734be31a23d6f3156fd93c33a0a272a55c)) +* **internal:** tweak CI branches ([700bb90](https://github.com/writer/writer-node/commit/700bb904c404df16bd4e6c7635c7ab4de1ced843)) +* **internal:** update `actions/checkout` version ([ac62b27](https://github.com/writer/writer-node/commit/ac62b278b1aa8635c85e4b7f80dfd461c76bbde9)) +* **internal:** update dependencies to address dependabot vulnerabilities ([96b9468](https://github.com/writer/writer-node/commit/96b9468dddad4693959b59bd4dfd0c64e6948def)) +* **internal:** update docs ordering ([dec3f3d](https://github.com/writer/writer-node/commit/dec3f3d0198f8caf0ed3c0851d823ea130731cc8)) +* **internal:** update gitignore ([a8a8b44](https://github.com/writer/writer-node/commit/a8a8b44016b44b27e31cd36b7d4c3d726c0994f5)) +* **internal:** update isAbsoluteURL ([#126](https://github.com/writer/writer-node/issues/126)) ([0a676eb](https://github.com/writer/writer-node/commit/0a676eba5b7a8330fe6b196e362c105d8f3049c6)) +* **internal:** update lock file ([8872b80](https://github.com/writer/writer-node/commit/8872b80dddc9edf1d45de5387acce00b13e6010c)) +* **internal:** update multipart form array serialization ([5be2c2b](https://github.com/writer/writer-node/commit/5be2c2beea67491dcf0fe54ec757a049daa5e05b)) +* **internal:** upgrade @modelcontextprotocol/sdk and hono ([e62fb6c](https://github.com/writer/writer-node/commit/e62fb6c36372a4ece5574a2075248213641f9a50)) +* **internal:** upgrade babel, qs, js-yaml ([5717a02](https://github.com/writer/writer-node/commit/5717a02433ce869ff16eddce1a30b892667b37d5)) +* **internal:** upgrade eslint ([4ae73b1](https://github.com/writer/writer-node/commit/4ae73b119027a678183ab79ddef25703584f63b7)) +* **internal:** use link instead of file in MCP server package.json files ([245c089](https://github.com/writer/writer-node/commit/245c089021989cd21c8d418c2b846e34780b00db)) +* **internal:** use x-stainless-mcp-client-envs header for MCP remote code tool calls ([368815e](https://github.com/writer/writer-node/commit/368815effa9872d7cfb68b6b59fc2a3c292d3642)) +* **internal:** version bump ([#113](https://github.com/writer/writer-node/issues/113)) ([37a3f70](https://github.com/writer/writer-node/commit/37a3f705d82f14269e925377dc09d9869a653dc8)) +* **internal:** version bump ([#115](https://github.com/writer/writer-node/issues/115)) ([9309158](https://github.com/writer/writer-node/commit/930915807369000620132d52c5f45df6bd3462fb)) +* **internal:** version bump ([#28](https://github.com/writer/writer-node/issues/28)) ([254dd3c](https://github.com/writer/writer-node/commit/254dd3cc6595271fc239b42e2a8d2ebb683f7a9a)) +* **internal:** version bump ([#9](https://github.com/writer/writer-node/issues/9)) ([e8cc802](https://github.com/writer/writer-node/commit/e8cc8027b3ae9a9c7e25e932bb5815758b923017)) +* **mcp-server:** add support for session id, forward client info ([9fa5781](https://github.com/writer/writer-node/commit/9fa5781db92bbc1d576f0a6e2224368e9c526137)) +* **mcp-server:** improve instructions ([50343c5](https://github.com/writer/writer-node/commit/50343c59ca40bf64eb6d0fc315af953bced30f97)) +* **mcp-server:** increase local docs search result count from 5 to 10 ([f87e6b9](https://github.com/writer/writer-node/commit/f87e6b98513143c4570ab640361262109f507966)) +* **mcp-server:** log client info ([a946922](https://github.com/writer/writer-node/commit/a9469221dba5e55d923db1d7e5f11cf1bb1cbf6e)) +* **mcp-server:** return access instructions for 404 without API key ([30ceb2d](https://github.com/writer/writer-node/commit/30ceb2d5135fd4d2a17ba9ab6041d32573405b60)) +* **mcp:** add intent param to execute tool ([c988c65](https://github.com/writer/writer-node/commit/c988c65c5ac29240540265630b0b2c9a565caa94)) +* **mcp:** correctly update version in sync with sdk ([b93d491](https://github.com/writer/writer-node/commit/b93d491022f90f2f6b92bab112676e5df18bf4c2)) +* **mcp:** forward STAINLESS_API_KEY to docs search endpoint ([dde1184](https://github.com/writer/writer-node/commit/dde11849b78e009db7128c811b0f511f442801ae)) +* **mcp:** pass intent param to execute handler ([58fa431](https://github.com/writer/writer-node/commit/58fa4314badfa5ba2cd2cf148ffb46227d965389)) +* **mcp:** remove deprecated tool schemes ([e376d65](https://github.com/writer/writer-node/commit/e376d65638ff29ccef3339c53b61c6207a3c08d2)) +* **mcp:** up tsconfig lib version to es2022 ([cb421df](https://github.com/writer/writer-node/commit/cb421dfbb23c198f7bd3b39d6555c6e22ec0a200)) +* **mcp:** update lockfile ([8d1106e](https://github.com/writer/writer-node/commit/8d1106e94062b4610f8e0333761f82749c0bbc9f)) +* **mcp:** upgrade dependencies ([5766d6c](https://github.com/writer/writer-node/commit/5766d6c58f52a74fcfc718fa92e46a4a0e0103d7)) +* rebuild project due to codegen change ([#104](https://github.com/writer/writer-node/issues/104)) ([e1c82c3](https://github.com/writer/writer-node/commit/e1c82c3fcaa679478ed321bf97cf8935ed98e7d6)) +* rebuild project due to codegen change ([#107](https://github.com/writer/writer-node/issues/107)) ([f053183](https://github.com/writer/writer-node/commit/f0531839142b957f8e6574a654eceb82c9f7a4e0)) +* rebuild project due to codegen change ([#109](https://github.com/writer/writer-node/issues/109)) ([7f35e1b](https://github.com/writer/writer-node/commit/7f35e1b0c9574e02273130e99d56f99829ff7062)) +* rebuild project due to codegen change ([#110](https://github.com/writer/writer-node/issues/110)) ([fc9e0e0](https://github.com/writer/writer-node/commit/fc9e0e088f76f18055213deaf259381b7713b415)) +* rebuild project due to codegen change ([#90](https://github.com/writer/writer-node/issues/90)) ([89fa5b3](https://github.com/writer/writer-node/commit/89fa5b3b669fc430ab3578a126cffd4b536bcbd2)) +* rebuild project due to codegen change ([#91](https://github.com/writer/writer-node/issues/91)) ([3657edb](https://github.com/writer/writer-node/commit/3657edb012dac0612aef8d09944a0283718988e2)) +* rebuild project due to codegen change ([#92](https://github.com/writer/writer-node/issues/92)) ([a60408e](https://github.com/writer/writer-node/commit/a60408e45c1eae74b653e3f4b7120e461f9e29a0)) +* rebuild project due to codegen change ([#93](https://github.com/writer/writer-node/issues/93)) ([0f9276c](https://github.com/writer/writer-node/commit/0f9276cfecc4d48ded3536dfb6075636f298fc4f)) +* rebuild project due to codegen change ([#96](https://github.com/writer/writer-node/issues/96)) ([25327f5](https://github.com/writer/writer-node/commit/25327f5a7c98774387f100155428a291acd82f46)) +* rebuild project due to codegen change ([#97](https://github.com/writer/writer-node/issues/97)) ([6df076b](https://github.com/writer/writer-node/commit/6df076b5af13422cb960d602b6aeb174e6bbdbc9)) +* rebuild project due to codegen change ([#98](https://github.com/writer/writer-node/issues/98)) ([890c742](https://github.com/writer/writer-node/commit/890c74292aadb14d39ccec510f115b5740badf31)) +* redact api-key headers in debug logs ([7b2b3a9](https://github.com/writer/writer-node/commit/7b2b3a92068d07ca8d292adfe1059870cbe5265d)) +* restructure docs search code ([6eeaf25](https://github.com/writer/writer-node/commit/6eeaf254b4afdffe9244423b9528dae85392db45)) +* **test:** do not count install time for mock server timeout ([a345373](https://github.com/writer/writer-node/commit/a3453738634b2bcccde87fd0e9736eb1356ee45f)) +* **tests:** bump steady to v0.19.4 ([dad22a4](https://github.com/writer/writer-node/commit/dad22a4cd08a9aaedc076023093519f9b4813d87)) +* **tests:** bump steady to v0.19.5 ([b51c69d](https://github.com/writer/writer-node/commit/b51c69df9ec75a75a86560ddfa23ecb908dd5ff7)) +* **tests:** bump steady to v0.19.6 ([241c42d](https://github.com/writer/writer-node/commit/241c42d876331b92dee01b704d1eae1c0587f8f4)) +* **tests:** bump steady to v0.19.7 ([518baf9](https://github.com/writer/writer-node/commit/518baf98c314c1fe39c2d44e95863212f881f8b2)) +* **tests:** bump steady to v0.20.1 ([32f3fb9](https://github.com/writer/writer-node/commit/32f3fb9a4eebc6658ac077164f2eee9e21ddad00)) +* **tests:** bump steady to v0.20.2 ([b54c180](https://github.com/writer/writer-node/commit/b54c18011c29d415e55f7ccad2bfb0be46e3ba87)) +* **tests:** bump steady to v0.22.1 ([3a42ea2](https://github.com/writer/writer-node/commit/3a42ea27a588abc1ecf5ed6464ab83316eedfdc4)) +* **tests:** remove redundant File import ([c4c7f9e](https://github.com/writer/writer-node/commit/c4c7f9e09ddff73a285f9860ae19c1a2f0a9e59a)) +* **tests:** update prism version ([#32](https://github.com/writer/writer-node/issues/32)) ([6ea2f59](https://github.com/writer/writer-node/commit/6ea2f5920f53502b6ba5e0b7530aa22b0a1a620a)) +* **types:** nicer error class types + jsdocs ([#125](https://github.com/writer/writer-node/issues/125)) ([a94669a](https://github.com/writer/writer-node/commit/a94669a86363b394efc1d045144eff4c4e0ac257)) +* Update completions-streaming.ts ([303a7b4](https://github.com/writer/writer-node/commit/303a7b434686bed3e8b2ac4ddc68daa329ecf804)) +* update mock server docs ([b21d0a5](https://github.com/writer/writer-node/commit/b21d0a594a1ce7a8bf9db8f67af853f1dbefc16f)) +* update placeholder string ([95ae007](https://github.com/writer/writer-node/commit/95ae007e055d87d31ae11cbb2163ab5e882c20d5)) +* use latest @modelcontextprotocol/sdk ([08d8625](https://github.com/writer/writer-node/commit/08d8625b8b8a46b8b0f8bb92c6ee57be5b90a780)) + + +### Documentation + +* add pagination example ([#74](https://github.com/writer/writer-node/issues/74)) ([09b3ee2](https://github.com/writer/writer-node/commit/09b3ee23124d02bf223c1ec1e8458217af47b570)) +* **api:** updates to API spec ([535ef81](https://github.com/writer/writer-node/commit/535ef81a129dd3fb6c372079ff3a4af07e5861d2)) +* **api:** updates to API spec ([#44](https://github.com/writer/writer-node/issues/44)) ([5b3f183](https://github.com/writer/writer-node/commit/5b3f183754a6422212fba2175831ffcbb8470e8b)) +* **api:** updates to API spec ([#57](https://github.com/writer/writer-node/issues/57)) ([73dddc8](https://github.com/writer/writer-node/commit/73dddc829bc31141415005a762b0a3c16d1a852a)) +* **api:** updates to API spec ([#63](https://github.com/writer/writer-node/issues/63)) ([50a86f4](https://github.com/writer/writer-node/commit/50a86f4593fbcff313397279b32bb5ceb24fd471)) +* **api:** updates to API spec ([#70](https://github.com/writer/writer-node/issues/70)) ([7c0721d](https://github.com/writer/writer-node/commit/7c0721da2901bd6e4ee7aba97b32ec8b6d8bec52)) +* **api:** updates to API spec ([#75](https://github.com/writer/writer-node/issues/75)) ([3fad6c7](https://github.com/writer/writer-node/commit/3fad6c7738c5abf3e795f3b7d8c35d9a76eaf98b)) +* **api:** updates to API spec ([#77](https://github.com/writer/writer-node/issues/77)) ([8749431](https://github.com/writer/writer-node/commit/87494313a99d6c8be5f768ce7654bf7f52f7042a)) +* prominently feature MCP server setup in root SDK readmes ([723e616](https://github.com/writer/writer-node/commit/723e616cc53d9a26740f5de5b72a1ec9e0313949)) +* update http mcp docs ([34a1c2e](https://github.com/writer/writer-node/commit/34a1c2e84ada77d9b1d6aa3b94edcc9ebebc9244)) + + +### Refactors + +* **tests:** switch from prism to steady ([5d62789](https://github.com/writer/writer-node/commit/5d6278939d566e78b574a04a11fc53659b29f5e1)) + +## 3.0.0 (2026-06-02) + +Full Changelog: [v3.0.0-rc.1...v3.0.0](https://github.com/writer/writer-node/compare/v3.0.0-rc.1...v3.0.0) + +### Features + +* support setting headers via env ([775860c](https://github.com/writer/writer-node/commit/775860c7b034ec2b29133441ca42ff1653559737)) + + +### Bug Fixes + +* **mcp:** use `pure-lockfile` when building mcp server ([1e77ebc](https://github.com/writer/writer-node/commit/1e77ebcc14b5b7a82dcfe65fe0a1d7410d2e2288)) +* treat text/plan with format: binary as raw upload ([5f3799d](https://github.com/writer/writer-node/commit/5f3799dd90e31153b9e3c9f31e666e6f90c4ef5f)) +* **typescript:** upgrade tsc-multi so that it works with Node 26 ([c4f21ed](https://github.com/writer/writer-node/commit/c4f21edee4915b5e8d0c757dd6de75c2627d79bd)) + + +### Chores + +* avoid formatting file that gets changed during releases ([6a45720](https://github.com/writer/writer-node/commit/6a457206747179f91a6bd085e19b26b68d5caf99)) +* **format:** run eslint and prettier separately ([be7d4a0](https://github.com/writer/writer-node/commit/be7d4a0d88334afce883d534ca85d735aa026bc4)) +* **formatter:** run prettier and eslint separately ([b671b3d](https://github.com/writer/writer-node/commit/b671b3d852b2943f44140f8ccd827100e9121149)) +* **internal:** codegen related update ([88197ba](https://github.com/writer/writer-node/commit/88197ba9e896440696a46b21129b07862f90dc3c)) +* **internal:** codegen related update ([7f46854](https://github.com/writer/writer-node/commit/7f46854adff49ae46df71380fb8a40cd0879c4ae)) +* **internal:** more robust bootstrap script ([af77915](https://github.com/writer/writer-node/commit/af77915717a2749b0275b3fc9c1a09f4c69826ce)) +* **internal:** update docs ordering ([dec3f3d](https://github.com/writer/writer-node/commit/dec3f3d0198f8caf0ed3c0851d823ea130731cc8)) +* redact api-key headers in debug logs ([7b2b3a9](https://github.com/writer/writer-node/commit/7b2b3a92068d07ca8d292adfe1059870cbe5265d)) +* restructure docs search code ([6eeaf25](https://github.com/writer/writer-node/commit/6eeaf254b4afdffe9244423b9528dae85392db45)) +* **tests:** bump steady to v0.22.1 ([3a42ea2](https://github.com/writer/writer-node/commit/3a42ea27a588abc1ecf5ed6464ab83316eedfdc4)) +* **tests:** remove redundant File import ([c4c7f9e](https://github.com/writer/writer-node/commit/c4c7f9e09ddff73a285f9860ae19c1a2f0a9e59a)) + + +### Documentation + +* update http mcp docs ([34a1c2e](https://github.com/writer/writer-node/commit/34a1c2e84ada77d9b1d6aa3b94edcc9ebebc9244)) + ## 3.0.0-rc.1 (2026-04-13) Full Changelog: [v2.3.3-rc.1...v3.0.0-rc.1](https://github.com/writer/writer-node/compare/v2.3.3-rc.1...v3.0.0-rc.1) diff --git a/README.md b/README.md index a4d28040..c642d075 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ const client = new Writer({ ``` > Never hard-code your API keys in source code or commit them to version control systems like GitHub. -> We recommend adding `WRITER_API_KEY="My API Key"` to your `.env` file so that your API Key is not stored in source control. +> We recommend adding `WRITER_API_KEY="My API Key"` to your `.env` file so that your API Key is not stored in source control. ## Usage @@ -125,13 +125,13 @@ const stream = await client.chat.chat({ model: 'palmyra-x5', stream: true, }); -let outputText = ""; +let outputText = ''; for await (const chunk of stream) { - if (chunk.choices[0]?.delta?.content) { - outputText += chunk.choices[0].delta.content; - } else { - continue; - } + if (chunk.choices[0]?.delta?.content) { + outputText += chunk.choices[0].delta.content; + } else { + continue; + } } console.log(outputText); ``` diff --git a/api.md b/api.md index 97acf2cd..30c4d049 100644 --- a/api.md +++ b/api.md @@ -133,7 +133,7 @@ Methods: - client.files.delete(fileID) -> FileDeleteResponse - client.files.download(fileID) -> Response - client.files.retry({ ...params }) -> FileRetryResponse -- client.files.upload({ ...params }) -> File +- client.files.upload(content, { ...params }) -> File # Tools diff --git a/bin/cli b/bin/cli index 87d8f71a..69403d48 100755 --- a/bin/cli +++ b/bin/cli @@ -8,15 +8,21 @@ const commands = { fn: () => { const result = spawnSync( 'npx', - ['-y', 'https://github.com/stainless-api/migrate-ts/releases/download/0.0.2/stainless-api-migrate-0.0.2-6.tgz', '--migrationConfig', require.resolve('./migration-config.json'), ...process.argv.slice(3)], + [ + '-y', + 'https://github.com/stainless-api/migrate-ts/releases/download/0.0.2/stainless-api-migrate-0.0.2-6.tgz', + '--migrationConfig', + require.resolve('./migration-config.json'), + ...process.argv.slice(3), + ], { stdio: 'inherit' }, ); if (result.status !== 0) { process.exit(result.status); } - } - } -} + }, + }, +}; function exitWithHelp() { console.log(`Usage: writer-sdk `); diff --git a/eslint.config.mjs b/eslint.config.mjs index 3954b642..edd23b90 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,7 +1,6 @@ // @ts-check import tseslint from 'typescript-eslint'; import unusedImports from 'eslint-plugin-unused-imports'; -import prettier from 'eslint-plugin-prettier'; export default tseslint.config( { @@ -14,11 +13,9 @@ export default tseslint.config( plugins: { '@typescript-eslint': tseslint.plugin, 'unused-imports': unusedImports, - prettier, }, rules: { 'no-unused-vars': 'off', - 'prettier/prettier': 'error', 'unused-imports/no-unused-imports': 'error', 'no-restricted-imports': [ 'error', diff --git a/examples/upload-and-attach-file-to-graph.ts b/examples/upload-and-attach-file-to-graph.ts index 45c47b91..5cfb1219 100755 --- a/examples/upload-and-attach-file-to-graph.ts +++ b/examples/upload-and-attach-file-to-graph.ts @@ -11,10 +11,9 @@ async function main() { description: 'This is a graph created from the SDK', }); - let file = await client.files.upload({ + let file = await client.files.upload(fs.createReadStream('examples/example.txt'), { 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="example.txt"', - content: fs.createReadStream('examples/example.txt'), }); console.log(file.id); diff --git a/package.json b/package.json index b824c951..4577ad04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "writer-sdk", - "version": "3.0.0-rc.1", + "version": "3.0.0", "description": "The official TypeScript library for the Writer API", "author": "Writer ", "types": "dist/index.d.ts", @@ -35,7 +35,6 @@ "@typescript-eslint/eslint-plugin": "8.31.1", "@typescript-eslint/parser": "8.31.1", "eslint": "^9.39.1", - "eslint-plugin-prettier": "^5.4.1", "eslint-plugin-unused-imports": "^4.1.4", "fast-check": "^3.23.1", "iconv-lite": "^0.6.3", @@ -44,7 +43,7 @@ "publint": "^0.2.12", "ts-jest": "^29.1.0", "ts-node": "^10.5.0", - "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz", "tsconfig-paths": "^4.0.0", "tslib": "^2.8.1", "typescript": "5.8.3", diff --git a/packages/mcp-server/manifest.json b/packages/mcp-server/manifest.json index 423d6234..a870fd12 100644 --- a/packages/mcp-server/manifest.json +++ b/packages/mcp-server/manifest.json @@ -1,7 +1,7 @@ { "dxt_version": "0.2", "name": "writer-sdk-mcp", - "version": "3.0.0-rc.1", + "version": "3.0.0", "description": "The official MCP Server for the Writer API", "author": { "name": "Writer", diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 7faa371d..7b32ac90 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "writer-sdk-mcp", - "version": "3.0.0-rc.1", + "version": "3.0.0", "description": "The official MCP Server for the Writer API", "author": "Writer ", "types": "dist/index.d.ts", @@ -74,7 +74,7 @@ "ts-jest": "^29.1.0", "ts-morph": "^19.0.0", "ts-node": "^10.5.0", - "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz", "tsconfig-paths": "^4.0.0" }, "imports": { diff --git a/packages/mcp-server/src/local-docs-search.ts b/packages/mcp-server/src/local-docs-search.ts index a5b686e6..8cc33329 100644 --- a/packages/mcp-server/src/local-docs-search.ts +++ b/packages/mcp-server/src/local-docs-search.ts @@ -64,24 +64,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## generate_content\n\n`client.applications.generateContent(application_id: string, inputs: { id: string; value: string[]; }[], stream?: boolean): { suggestion: string; title?: string; }`\n\n**post** `/v1/applications/{application_id}`\n\nGenerate content from an existing no-code agent (formerly called no-code applications) with inputs.\n\n### Parameters\n\n- `application_id: string`\n\n- `inputs: { id: string; value: string[]; }[]`\n\n- `stream?: boolean`\n Indicates whether the response should be streamed. Currently only supported for research assistant applications.\n\n### Returns\n\n- `{ suggestion: string; title?: string; }`\n\n - `suggestion: string`\n - `title?: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst stream = await client.applications.generateContent('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', { inputs: [{ id: 'id', value: ['string'] }] });\nfor await (const applicationGenerateContentChunk of stream) {\n console.log(applicationGenerateContentChunk);\n}\n```", perLanguage: { - go: { - method: 'client.Applications.GenerateContent', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGenerateContentResponse, err := client.Applications.GenerateContent(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\twritersdk.ApplicationGenerateContentParams{\n\t\t\tInputs: writersdk.F([]writersdk.ApplicationGenerateContentParamsInput{{\n\t\t\t\tID: writersdk.F("id"),\n\t\t\t\tValue: writersdk.F([]string{"string"}),\n\t\t\t}}),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGenerateContentResponse.Suggestion)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.generateContent', example: - 'curl https://api.writer.com/v1/applications/$APPLICATION_ID \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "inputs": [\n {\n "id": "id",\n "value": [\n "string"\n ]\n }\n ]\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGenerateContentResponse = await client.applications.generateContent(\n '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n { inputs: [{ id: 'id', value: ['string'] }] },\n);\n\nconsole.log(applicationGenerateContentResponse.suggestion);", }, python: { method: 'applications.generate_content', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfor application in client.applications.generate_content(\n application_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n inputs=[{\n "id": "id",\n "value": ["string"],\n }],\n):\n print(application)', }, - typescript: { - method: 'client.applications.generateContent', + go: { + method: 'client.Applications.GenerateContent', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGenerateContentResponse = await client.applications.generateContent(\n '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n { inputs: [{ id: 'id', value: ['string'] }] },\n);\n\nconsole.log(applicationGenerateContentResponse.suggestion);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGenerateContentResponse, err := client.Applications.GenerateContent(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\twritersdk.ApplicationGenerateContentParams{\n\t\t\tInputs: writersdk.F([]writersdk.ApplicationGenerateContentParamsInput{{\n\t\t\t\tID: writersdk.F("id"),\n\t\t\t\tValue: writersdk.F([]string{"string"}),\n\t\t\t}}),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGenerateContentResponse.Suggestion)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/$APPLICATION_ID \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "inputs": [\n {\n "id": "id",\n "value": [\n "string"\n ]\n }\n ]\n }\'', }, }, }, @@ -106,24 +106,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## list\n\n`client.applications.list(after?: string, before?: string, limit?: number, order?: 'asc' | 'desc', type?: 'generation'): { id: string; created_at: string; inputs: object[]; name: string; status: 'deployed' | 'draft'; type: 'generation'; updated_at: string; last_deployed_at?: string; }`\n\n**get** `/v1/applications`\n\nRetrieves a paginated list of no-code agents (formerly called no-code applications) with optional filtering and sorting capabilities.\n\n### Parameters\n\n- `after?: string`\n Return results after this application ID for pagination.\n\n- `before?: string`\n Return results before this application ID for pagination.\n\n- `limit?: number`\n Maximum number of applications to return in the response.\n\n- `order?: 'asc' | 'desc'`\n Sort order for the results based on creation time.\n\n- `type?: 'generation'`\n Filter applications by their type.\n\n### Returns\n\n- `{ id: string; created_at: string; inputs: { input_type: 'text' | 'dropdown' | 'file' | 'media'; name: string; required: boolean; description?: string; options?: { list: string[]; } | { file_types: string[]; max_file_size_mb: number; max_files: number; max_word_count: number; upload_types: 'url' | 'file_id'[]; } | { file_types: string[]; max_image_size_mb: number; } | { max_fields: number; min_fields: number; }; }[]; name: string; status: 'deployed' | 'draft'; type: 'generation'; updated_at: string; last_deployed_at?: string; }`\n Detailed application object including its input configuration.\n\n - `id: string`\n - `created_at: string`\n - `inputs: { input_type: 'text' | 'dropdown' | 'file' | 'media'; name: string; required: boolean; description?: string; options?: { list: string[]; } | { file_types: string[]; max_file_size_mb: number; max_files: number; max_word_count: number; upload_types: 'url' | 'file_id'[]; } | { file_types: string[]; max_image_size_mb: number; } | { max_fields: number; min_fields: number; }; }[]`\n - `name: string`\n - `status: 'deployed' | 'draft'`\n - `type: 'generation'`\n - `updated_at: string`\n - `last_deployed_at?: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\n// Automatically fetches more pages as needed.\nfor await (const applicationListResponse of client.applications.list()) {\n console.log(applicationListResponse);\n}\n```", perLanguage: { - go: { - method: 'client.Applications.List', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Applications.List(context.TODO(), writersdk.ApplicationListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.list', example: - 'curl https://api.writer.com/v1/applications \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const applicationListResponse of client.applications.list()) {\n console.log(applicationListResponse.id);\n}", }, python: { method: 'applications.list', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\npage = client.applications.list()\npage = page.data[0]\nprint(page.id)', }, - typescript: { - method: 'client.applications.list', + go: { + method: 'client.Applications.List', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const applicationListResponse of client.applications.list()) {\n console.log(applicationListResponse.id);\n}", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Applications.List(context.TODO(), writersdk.ApplicationListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -142,24 +142,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## retrieve\n\n`client.applications.retrieve(application_id: string): { id: string; created_at: string; inputs: object[]; name: string; status: 'deployed' | 'draft'; type: 'generation'; updated_at: string; last_deployed_at?: string; }`\n\n**get** `/v1/applications/{application_id}`\n\nRetrieves detailed information for a specific no-code agent (formerly called no-code applications), including its configuration and current status.\n\n### Parameters\n\n- `application_id: string`\n\n### Returns\n\n- `{ id: string; created_at: string; inputs: { input_type: 'text' | 'dropdown' | 'file' | 'media'; name: string; required: boolean; description?: string; options?: { list: string[]; } | { file_types: string[]; max_file_size_mb: number; max_files: number; max_word_count: number; upload_types: 'url' | 'file_id'[]; } | { file_types: string[]; max_image_size_mb: number; } | { max_fields: number; min_fields: number; }; }[]; name: string; status: 'deployed' | 'draft'; type: 'generation'; updated_at: string; last_deployed_at?: string; }`\n Detailed application object including its input configuration.\n\n - `id: string`\n - `created_at: string`\n - `inputs: { input_type: 'text' | 'dropdown' | 'file' | 'media'; name: string; required: boolean; description?: string; options?: { list: string[]; } | { file_types: string[]; max_file_size_mb: number; max_files: number; max_word_count: number; upload_types: 'url' | 'file_id'[]; } | { file_types: string[]; max_image_size_mb: number; } | { max_fields: number; min_fields: number; }; }[]`\n - `name: string`\n - `status: 'deployed' | 'draft'`\n - `type: 'generation'`\n - `updated_at: string`\n - `last_deployed_at?: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst application = await client.applications.retrieve('application_id');\n\nconsole.log(application);\n```", perLanguage: { - go: { - method: 'client.Applications.Get', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplication, err := client.Applications.Get(context.TODO(), "application_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", application.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.retrieve', example: - 'curl https://api.writer.com/v1/applications/$APPLICATION_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst application = await client.applications.retrieve('application_id');\n\nconsole.log(application.id);", }, python: { method: 'applications.retrieve', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\napplication = client.applications.retrieve(\n "application_id",\n)\nprint(application.id)', }, - typescript: { - method: 'client.applications.retrieve', + go: { + method: 'client.Applications.Get', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst application = await client.applications.retrieve('application_id');\n\nconsole.log(application.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplication, err := client.Applications.Get(context.TODO(), "application_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", application.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/$APPLICATION_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -183,24 +183,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## list\n\n`client.applications.jobs.list(application_id: string, limit?: number, offset?: number, status?: 'in_progress' | 'failed' | 'completed'): { id: string; application_id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; completed_at?: string; data?: application_generate_content_response; error?: string; updated_at?: string; }`\n\n**get** `/v1/applications/{application_id}/jobs`\n\nRetrieve all jobs created via the async API, linked to the provided application ID (or alias).\n\n### Parameters\n\n- `application_id: string`\n\n- `limit?: number`\n The pagination limit for retrieving the jobs.\n\n- `offset?: number`\n The pagination offset for retrieving the jobs.\n\n- `status?: 'in_progress' | 'failed' | 'completed'`\n The status of the job.\n\n### Returns\n\n- `{ id: string; application_id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; completed_at?: string; data?: { suggestion: string; title?: string; }; error?: string; updated_at?: string; }`\n\n - `id: string`\n - `application_id: string`\n - `created_at: string`\n - `status: 'in_progress' | 'failed' | 'completed'`\n - `completed_at?: string`\n - `data?: { suggestion: string; title?: string; }`\n - `error?: string`\n - `updated_at?: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\n// Automatically fetches more pages as needed.\nfor await (const applicationGenerateAsyncResponse of client.applications.jobs.list('application_id')) {\n console.log(applicationGenerateAsyncResponse);\n}\n```", perLanguage: { - go: { - method: 'client.Applications.Jobs.List', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Applications.Jobs.List(\n\t\tcontext.TODO(),\n\t\t"application_id",\n\t\twritersdk.ApplicationJobListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.jobs.list', example: - 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/jobs \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const applicationGenerateAsyncResponse of client.applications.jobs.list(\n 'application_id',\n)) {\n console.log(applicationGenerateAsyncResponse.id);\n}", }, python: { method: 'applications.jobs.list', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\npage = client.applications.jobs.list(\n application_id="application_id",\n)\npage = page.result[0]\nprint(page.id)', }, - typescript: { - method: 'client.applications.jobs.list', + go: { + method: 'client.Applications.Jobs.List', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const applicationGenerateAsyncResponse of client.applications.jobs.list(\n 'application_id',\n)) {\n console.log(applicationGenerateAsyncResponse.id);\n}", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Applications.Jobs.List(\n\t\tcontext.TODO(),\n\t\t"application_id",\n\t\twritersdk.ApplicationJobListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/jobs \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -218,24 +218,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## create\n\n`client.applications.jobs.create(application_id: string, inputs: { id: string; value: string[]; }[]): { id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; }`\n\n**post** `/v1/applications/{application_id}/jobs`\n\nGenerate content asynchronously from an existing no-code agent (formerly called no-code applications) with inputs.\n\n### Parameters\n\n- `application_id: string`\n\n- `inputs: { id: string; value: string[]; }[]`\n A list of input objects to generate content for.\n\n### Returns\n\n- `{ id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; }`\n\n - `id: string`\n - `created_at: string`\n - `status: 'in_progress' | 'failed' | 'completed'`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst job = await client.applications.jobs.create('application_id', { inputs: [{ id: 'id', value: ['string'] }] });\n\nconsole.log(job);\n```", perLanguage: { - go: { - method: 'client.Applications.Jobs.New', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tjob, err := client.Applications.Jobs.New(\n\t\tcontext.TODO(),\n\t\t"application_id",\n\t\twritersdk.ApplicationJobNewParams{\n\t\t\tInputs: writersdk.F([]writersdk.ApplicationJobNewParamsInput{{\n\t\t\t\tID: writersdk.F("id"),\n\t\t\t\tValue: writersdk.F([]string{"string"}),\n\t\t\t}}),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", job.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.jobs.create', example: - 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/jobs \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "inputs": [\n {\n "id": "id",\n "value": [\n "string"\n ]\n }\n ]\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst job = await client.applications.jobs.create('application_id', {\n inputs: [{ id: 'id', value: ['string'] }],\n});\n\nconsole.log(job.id);", }, python: { method: 'applications.jobs.create', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\njob = client.applications.jobs.create(\n application_id="application_id",\n inputs=[{\n "id": "id",\n "value": ["string"],\n }],\n)\nprint(job.id)', }, - typescript: { - method: 'client.applications.jobs.create', + go: { + method: 'client.Applications.Jobs.New', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst job = await client.applications.jobs.create('application_id', {\n inputs: [{ id: 'id', value: ['string'] }],\n});\n\nconsole.log(job.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tjob, err := client.Applications.Jobs.New(\n\t\tcontext.TODO(),\n\t\t"application_id",\n\t\twritersdk.ApplicationJobNewParams{\n\t\t\tInputs: writersdk.F([]writersdk.ApplicationJobNewParamsInput{{\n\t\t\t\tID: writersdk.F("id"),\n\t\t\t\tValue: writersdk.F([]string{"string"}),\n\t\t\t}}),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", job.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/jobs \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "inputs": [\n {\n "id": "id",\n "value": [\n "string"\n ]\n }\n ]\n }\'', }, }, }, @@ -253,24 +253,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## retry\n\n`client.applications.jobs.retry(job_id: string): { id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; }`\n\n**post** `/v1/applications/jobs/{job_id}/retry`\n\nRe-triggers the async execution of a single job previously created via the Async api and terminated in error.\n\n### Parameters\n\n- `job_id: string`\n\n### Returns\n\n- `{ id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; }`\n\n - `id: string`\n - `created_at: string`\n - `status: 'in_progress' | 'failed' | 'completed'`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst response = await client.applications.jobs.retry('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response);\n```", perLanguage: { - go: { - method: 'client.Applications.Jobs.Retry', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Applications.Jobs.Retry(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.jobs.retry', example: - 'curl https://api.writer.com/v1/applications/jobs/$JOB_ID/retry \\\n -X POST \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.applications.jobs.retry('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response.id);", }, python: { method: 'applications.jobs.retry', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.applications.jobs.retry(\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n)\nprint(response.id)', }, - typescript: { - method: 'client.applications.jobs.retry', + go: { + method: 'client.Applications.Jobs.Retry', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.applications.jobs.retry('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Applications.Jobs.Retry(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/jobs/$JOB_ID/retry \\\n -X POST \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -288,24 +288,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## retrieve\n\n`client.applications.jobs.retrieve(job_id: string): { id: string; application_id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; completed_at?: string; data?: application_generate_content_response; error?: string; updated_at?: string; }`\n\n**get** `/v1/applications/jobs/{job_id}`\n\nRetrieves a single job created via the Async API.\n\n### Parameters\n\n- `job_id: string`\n\n### Returns\n\n- `{ id: string; application_id: string; created_at: string; status: 'in_progress' | 'failed' | 'completed'; completed_at?: string; data?: { suggestion: string; title?: string; }; error?: string; updated_at?: string; }`\n\n - `id: string`\n - `application_id: string`\n - `created_at: string`\n - `status: 'in_progress' | 'failed' | 'completed'`\n - `completed_at?: string`\n - `data?: { suggestion: string; title?: string; }`\n - `error?: string`\n - `updated_at?: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst applicationGenerateAsyncResponse = await client.applications.jobs.retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(applicationGenerateAsyncResponse);\n```", perLanguage: { - go: { - method: 'client.Applications.Jobs.Get', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGenerateAsyncResponse, err := client.Applications.Jobs.Get(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGenerateAsyncResponse.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.jobs.retrieve', example: - 'curl https://api.writer.com/v1/applications/jobs/$JOB_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGenerateAsyncResponse = await client.applications.jobs.retrieve(\n '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n);\n\nconsole.log(applicationGenerateAsyncResponse.id);", }, python: { method: 'applications.jobs.retrieve', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\napplication_generate_async_response = client.applications.jobs.retrieve(\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n)\nprint(application_generate_async_response.id)', }, - typescript: { - method: 'client.applications.jobs.retrieve', + go: { + method: 'client.Applications.Jobs.Get', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGenerateAsyncResponse = await client.applications.jobs.retrieve(\n '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n);\n\nconsole.log(applicationGenerateAsyncResponse.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGenerateAsyncResponse, err := client.Applications.Jobs.Get(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGenerateAsyncResponse.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/jobs/$JOB_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -322,24 +322,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## list\n\n`client.applications.graphs.list(application_id: string): { graph_ids: string[]; }`\n\n**get** `/v1/applications/{application_id}/graphs`\n\nRetrieve Knowledge Graphs associated with a no-code agent that has chat capabilities.\n\n### Parameters\n\n- `application_id: string`\n\n### Returns\n\n- `{ graph_ids: string[]; }`\n\n - `graph_ids: string[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst applicationGraphsResponse = await client.applications.graphs.list('application_id');\n\nconsole.log(applicationGraphsResponse);\n```", perLanguage: { - go: { - method: 'client.Applications.Graphs.List', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGraphsResponse, err := client.Applications.Graphs.List(context.TODO(), "application_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGraphsResponse.GraphIDs)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.graphs.list', example: - 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/graphs \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGraphsResponse = await client.applications.graphs.list('application_id');\n\nconsole.log(applicationGraphsResponse.graph_ids);", }, python: { method: 'applications.graphs.list', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\napplication_graphs_response = client.applications.graphs.list(\n "application_id",\n)\nprint(application_graphs_response.graph_ids)', }, - typescript: { - method: 'client.applications.graphs.list', + go: { + method: 'client.Applications.Graphs.List', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGraphsResponse = await client.applications.graphs.list('application_id');\n\nconsole.log(applicationGraphsResponse.graph_ids);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGraphsResponse, err := client.Applications.Graphs.List(context.TODO(), "application_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGraphsResponse.GraphIDs)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/graphs \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -356,24 +356,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## update\n\n`client.applications.graphs.update(application_id: string, graph_ids: string[]): { graph_ids: string[]; }`\n\n**put** `/v1/applications/{application_id}/graphs`\n\nUpdates the list of Knowledge Graphs associated with a no-code chat agent.\n\n### Parameters\n\n- `application_id: string`\n\n- `graph_ids: string[]`\n A list of Knowledge Graph IDs to associate with the application. Note that this will replace the existing list of Knowledge Graphs associated with the application, not add to it.\n\n### Returns\n\n- `{ graph_ids: string[]; }`\n\n - `graph_ids: string[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst applicationGraphsResponse = await client.applications.graphs.update('application_id', { graph_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'] });\n\nconsole.log(applicationGraphsResponse);\n```", perLanguage: { - go: { - method: 'client.Applications.Graphs.Update', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGraphsResponse, err := client.Applications.Graphs.Update(\n\t\tcontext.TODO(),\n\t\t"application_id",\n\t\twritersdk.ApplicationGraphUpdateParams{\n\t\t\tGraphIDs: writersdk.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGraphsResponse.GraphIDs)\n}\n', - }, - http: { + typescript: { + method: 'client.applications.graphs.update', example: - 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/graphs \\\n -X PUT \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "graph_ids": [\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n ]\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGraphsResponse = await client.applications.graphs.update('application_id', {\n graph_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'],\n});\n\nconsole.log(applicationGraphsResponse.graph_ids);", }, python: { method: 'applications.graphs.update', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\napplication_graphs_response = client.applications.graphs.update(\n application_id="application_id",\n graph_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],\n)\nprint(application_graphs_response.graph_ids)', }, - typescript: { - method: 'client.applications.graphs.update', + go: { + method: 'client.Applications.Graphs.Update', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst applicationGraphsResponse = await client.applications.graphs.update('application_id', {\n graph_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'],\n});\n\nconsole.log(applicationGraphsResponse.graph_ids);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tapplicationGraphsResponse, err := client.Applications.Graphs.Update(\n\t\tcontext.TODO(),\n\t\t"application_id",\n\t\twritersdk.ApplicationGraphUpdateParams{\n\t\t\tGraphIDs: writersdk.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", applicationGraphsResponse.GraphIDs)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/applications/$APPLICATION_ID/graphs \\\n -X PUT \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "graph_ids": [\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n ]\n }\'', }, }, }, @@ -406,24 +406,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## chat\n\n`client.chat.chat(messages: { role: 'user' | 'assistant' | 'system' | 'tool'; content?: string | { text: string; type: 'text'; } | { image_url: object; type: 'image_url'; }[]; graph_data?: object; name?: string; refusal?: string; tool_call_id?: string; tool_calls?: object[]; }[], model: string, logprobs?: boolean, max_tokens?: number, n?: number, response_format?: { type: 'text' | 'json_schema'; json_schema?: object; }, stop?: string[] | string, stream?: boolean, stream_options?: { include_usage: boolean; }, temperature?: number, tool_choice?: { value: 'none' | 'auto' | 'required'; } | { value: object; }, tools?: { function: function_definition; type: 'function'; } | { function: object; type: 'graph'; } | { function: object; type: 'llm'; } | { function: object; type: 'translation'; } | { function: object; type: 'vision'; } | { function: object; type: 'web_search'; }[], top_p?: number): { id: string; choices: chat_completion_choice[]; created: number; model: string; object: 'chat.completion'; service_tier?: string; system_fingerprint?: string; usage?: chat_completion_usage; }`\n\n**post** `/v1/chat`\n\nGenerate a chat completion based on the provided messages. The response shown below is for non-streaming. To learn about streaming responses, see the [chat completion guide](https://dev.writer.com/home/chat-completion).\n\n### Parameters\n\n- `messages: { role: 'user' | 'assistant' | 'system' | 'tool'; content?: string | { text: string; type: 'text'; } | { image_url: { url: string; }; type: 'image_url'; }[]; graph_data?: { references?: { files?: object[]; web?: object[]; }; sources?: object[]; status?: 'processing' | 'finished'; subqueries?: { answer: string; query: string; sources: source[]; }[]; }; name?: string; refusal?: string; tool_call_id?: string; tool_calls?: { id: string; function: { arguments: string; name?: string; }; type: 'function'; index?: number; }[]; }[]`\n An array of message objects that form the conversation history or context for the model to respond to. The array must contain at least one message.\n\n- `model: string`\n The [ID of the model](https://dev.writer.com/home/models) to use for creating the chat completion. Supports `palmyra-x5`, `palmyra-x4`, `palmyra-fin`, `palmyra-med`, `palmyra-creative`, and `palmyra-x-003-instruct`.\n\n- `logprobs?: boolean`\n Specifies whether to return log probabilities of the output tokens.\n\n- `max_tokens?: number`\n Defines the maximum number of tokens (words and characters) that the model can generate in the response. This can be adjusted to allow for longer or shorter responses as needed. The maximum value varies by model. See the [models overview](/home/models) for more information about the maximum number of tokens for each model.\n\n- `n?: number`\n Specifies the number of completions (responses) to generate from the model in a single request. This parameter allows for generating multiple responses, offering a variety of potential replies from which to choose.\n\n- `response_format?: { type: 'text' | 'json_schema'; json_schema?: object; }`\n The response format to use for the chat completion, available with `palmyra-x4` and `palmyra-x5`.\n\n`text` is the default response format. [JSON Schema](https://json-schema.org/) is supported for structured responses. If you specify `json_schema`, you must also provide a `json_schema` object.\n - `type: 'text' | 'json_schema'`\n The type of response format to use.\n - `json_schema?: object`\n The JSON schema to use for the response format.\n\n- `stop?: string[] | string`\n A token or sequence of tokens that, when generated, will cause the model to stop producing further content. This can be a single token or an array of tokens, acting as a signal to end the output.\n\n- `stream?: boolean`\n Indicates whether the response should be streamed incrementally as it is generated or only returned once fully complete. Streaming can be useful for providing real-time feedback in interactive applications.\n\n- `stream_options?: { include_usage: boolean; }`\n Additional options for streaming.\n - `include_usage: boolean`\n Indicate whether to include usage information.\n\n- `temperature?: number`\n Controls the randomness or creativity of the model's responses. A higher temperature results in more varied and less predictable text, while a lower temperature produces more deterministic and conservative outputs.\n\n- `tool_choice?: { value: 'none' | 'auto' | 'required'; } | { value: object; }`\n Configure how the model will call functions:\n- `auto`: allows the model to automatically choose the tool to use, or not call a tool\n- `none`: disables tool calling; the model will instead generate a message\n- `required`: requires the model to call one or more tools\n\nYou can also use a JSON object to force the model to call a specific tool. For example, `{\"type\": \"function\", \"function\": {\"name\": \"get_current_weather\"}}` requires the model to call the `get_current_weather` function, regardless of the prompt.\n\n- `tools?: { function: { name: string; description?: string; parameters?: function_params; }; type: 'function'; } | { function: { graph_ids: string[]; subqueries: boolean; description?: string; query_config?: { grounding_level?: number; inline_citations?: boolean; keyword_threshold?: number; max_snippets?: number; max_subquestions?: number; max_tokens?: number; search_weight?: number; semantic_threshold?: number; }; }; type: 'graph'; } | { function: { description: string; model: string; }; type: 'llm'; } | { function: { formality: boolean; length_control: boolean; mask_profanity: boolean; model: 'palmyra-translate'; source_language_code?: string; target_language_code?: string; }; type: 'translation'; } | { function: { model: 'palmyra-vision'; variables: { file_id: string; name: string; }[]; }; type: 'vision'; } | { function: { exclude_domains: string[]; include_domains: string[]; }; type: 'web_search'; }[]`\n An array containing tool definitions for tools that the model can use to generate responses. The tool definitions use JSON schema. You can define your own functions or use one of the built-in `graph`, `llm`, `translation`, or `vision` tools. Note that you can only use one built-in tool type in the array (only one of `graph`, `llm`, `translation`, or `vision`). You can pass multiple [custom tools](https://dev.writer.com/home/tool-calling) of type `function` in the same request.\n\n- `top_p?: number`\n Sets the threshold for \"nucleus sampling,\" a technique to focus the model's token generation on the most likely subset of tokens. Only tokens with cumulative probability above this threshold are considered, controlling the trade-off between creativity and coherence.\n\n### Returns\n\n- `{ id: string; choices: { finish_reason: 'stop' | 'length' | 'content_filter' | 'tool_calls'; index: number; message: chat_completion_message; logprobs?: logprobs; }[]; created: number; model: string; object: 'chat.completion'; service_tier?: string; system_fingerprint?: string; usage?: { completion_tokens: number; prompt_tokens: number; total_tokens: number; completion_tokens_details?: object; prompt_token_details?: object; }; }`\n\n - `id: string`\n - `choices: { finish_reason: 'stop' | 'length' | 'content_filter' | 'tool_calls'; index: number; message: { content: string; refusal: string; role: 'assistant'; graph_data?: graph_data; llm_data?: object; tool_calls?: tool_call[]; translation_data?: object; web_search_data?: object; }; logprobs?: { content: logprobs_token[]; refusal: logprobs_token[]; }; }[]`\n - `created: number`\n - `model: string`\n - `object: 'chat.completion'`\n - `service_tier?: string`\n - `system_fingerprint?: string`\n - `usage?: { completion_tokens: number; prompt_tokens: number; total_tokens: number; completion_tokens_details?: { reasoning_tokens: number; }; prompt_token_details?: { cached_tokens: number; }; }`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst stream = await client.chat.chat({ messages: [{ role: 'user' }], model: 'model' });\nfor await (const chatCompletionChunk of stream) {\n console.log(chatCompletionChunk);\n}\n```", perLanguage: { - go: { - method: 'client.Chat.Chat', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tchatCompletion, err := client.Chat.Chat(context.TODO(), writersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("model"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", chatCompletion.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.chat.chat', example: - 'curl https://api.writer.com/v1/chat \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "messages": [\n {\n "role": "user"\n }\n ],\n "model": "model"\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst chatCompletion = await client.chat.chat({ messages: [{ role: 'user' }], model: 'model' });\n\nconsole.log(chatCompletion.id);", }, python: { method: 'chat.chat', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfor chat in client.chat.chat(\n messages=[{\n "role": "user"\n }],\n model="model",\n):\n print(chat)', }, - typescript: { - method: 'client.chat.chat', + go: { + method: 'client.Chat.Chat', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst chatCompletion = await client.chat.chat({ messages: [{ role: 'user' }], model: 'model' });\n\nconsole.log(chatCompletion.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tchatCompletion, err := client.Chat.Chat(context.TODO(), writersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("model"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", chatCompletion.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/chat \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "messages": [\n {\n "role": "user"\n }\n ],\n "model": "model"\n }\'', }, }, }, @@ -451,24 +451,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## create\n\n`client.completions.create(model: string, prompt: string, best_of?: number, max_tokens?: number, random_seed?: number, stop?: string[] | string, stream?: boolean, temperature?: number, top_p?: number): { choices: object[]; model?: string; }`\n\n**post** `/v1/completions`\n\nGenerate text completions using the specified model and prompt. This endpoint is useful for text generation tasks that don't require conversational context.\n\n### Parameters\n\n- `model: string`\n The [ID of the model](https://dev.writer.com/home/models) to use for generating text. Supports `palmyra-x5`, `palmyra-x4`, `palmyra-fin`, `palmyra-med`, `palmyra-creative`, and `palmyra-x-003-instruct`.\n\n- `prompt: string`\n The input text that the model will process to generate a response.\n\n- `best_of?: number`\n Specifies the number of completions to generate and return the best one. Useful for generating multiple outputs and choosing the best based on some criteria.\n\n- `max_tokens?: number`\n The maximum number of tokens that the model can generate in the response.\n\n- `random_seed?: number`\n A seed used to initialize the random number generator for the model, ensuring reproducibility of the output when the same inputs are provided.\n\n- `stop?: string[] | string`\n Specifies stopping conditions for the model's output generation. This can be an array of strings or a single string that the model will look for as a signal to stop generating further tokens.\n\n- `stream?: boolean`\n Determines whether the model's output should be streamed. If true, the output is generated and sent incrementally, which can be useful for real-time applications.\n\n- `temperature?: number`\n Controls the randomness of the model's outputs. Higher values lead to more random outputs, while lower values make the model more deterministic.\n\n- `top_p?: number`\n Used to control the nucleus sampling, where only the most probable tokens with a cumulative probability of top_p are considered for sampling, providing a way to fine-tune the randomness of predictions.\n\n### Returns\n\n- `{ choices: { text: string; log_probs?: object; }[]; model?: string; }`\n\n - `choices: { text: string; log_probs?: { content: object[]; refusal: object[]; }; }[]`\n - `model?: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst stream = await client.completions.create({ model: 'palmyra-x-003-instruct', prompt: 'Write me an SEO article about...' });\nfor await (const completionChunk of stream) {\n console.log(completionChunk);\n}\n```", perLanguage: { - go: { - method: 'client.Completions.New', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tcompletion, err := client.Completions.New(context.TODO(), writersdk.CompletionNewParams{\n\t\tModel: writersdk.F("palmyra-x-003-instruct"),\n\t\tPrompt: writersdk.F("Write me an SEO article about..."),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", completion.Choices)\n}\n', - }, - http: { + typescript: { + method: 'client.completions.create', example: - 'curl https://api.writer.com/v1/completions \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "model": "palmyra-x-003-instruct",\n "prompt": "Write me an SEO article about..."\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst completion = await client.completions.create({\n model: 'palmyra-x-003-instruct',\n prompt: 'Write me an SEO article about...',\n});\n\nconsole.log(completion.choices);", }, python: { method: 'completions.create', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfor completion in client.completions.create(\n model="palmyra-x-003-instruct",\n prompt="Write me an SEO article about...",\n):\n print(completion)', }, - typescript: { - method: 'client.completions.create', + go: { + method: 'client.Completions.New', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst completion = await client.completions.create({\n model: 'palmyra-x-003-instruct',\n prompt: 'Write me an SEO article about...',\n});\n\nconsole.log(completion.choices);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tcompletion, err := client.Completions.New(context.TODO(), writersdk.CompletionNewParams{\n\t\tModel: writersdk.F("palmyra-x-003-instruct"),\n\t\tPrompt: writersdk.F("Write me an SEO article about..."),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", completion.Choices)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/completions \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "model": "palmyra-x-003-instruct",\n "prompt": "Write me an SEO article about...",\n "best_of": 1,\n "max_tokens": 150,\n "random_seed": 42,\n "stop": [\n "."\n ],\n "stream": false,\n "temperature": 0.7,\n "top_p": 0.9\n }\'', }, }, }, @@ -485,23 +485,23 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## list\n\n`client.models.list(): { models: object[]; }`\n\n**get** `/v1/models`\n\nRetrieve a list of available models that can be used for text generation, chat completions, and other AI tasks.\n\n### Returns\n\n- `{ models: { id: string; name: string; }[]; }`\n\n - `models: { id: string; name: string; }[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst models = await client.models.list();\n\nconsole.log(models);\n```", perLanguage: { - go: { - method: 'client.Models.List', + typescript: { + method: 'client.models.list', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tmodels, err := client.Models.List(context.TODO())\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", models.Models)\n}\n', - }, - http: { - example: 'curl https://api.writer.com/v1/models \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst models = await client.models.list();\n\nconsole.log(models.models);", }, python: { method: 'models.list', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nmodels = client.models.list()\nprint(models.models)', }, - typescript: { - method: 'client.models.list', + go: { + method: 'client.Models.List', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst models = await client.models.list();\n\nconsole.log(models.models);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tmodels, err := client.Models.List(context.TODO())\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", models.Models)\n}\n', + }, + http: { + example: 'curl https://api.writer.com/v1/models \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -519,23 +519,23 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## list\n\n`client.graphs.list(after?: string, before?: string, limit?: number, order?: 'asc' | 'desc'): { id: string; created_at: string; file_status: object; name: string; type: 'manual' | 'connector' | 'web'; description?: string; urls?: object[]; }`\n\n**get** `/v1/graphs`\n\nRetrieve a list of Knowledge Graphs.\n\n### Parameters\n\n- `after?: string`\n The ID of the last object in the previous page. This parameter instructs the API to return the next page of results.\n\n- `before?: string`\n The ID of the first object in the previous page. This parameter instructs the API to return the previous page of results.\n\n- `limit?: number`\n Specifies the maximum number of objects returned in a page. The default value is 50. The minimum value is 1, and the maximum value is 100.\n\n- `order?: 'asc' | 'desc'`\n Specifies the order of the results. Valid values are asc for ascending and desc for descending.\n\n### Returns\n\n- `{ id: string; created_at: string; file_status: { completed: number; failed: number; in_progress: number; total: number; }; name: string; type: 'manual' | 'connector' | 'web'; description?: string; urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]; }`\n\n - `id: string`\n - `created_at: string`\n - `file_status: { completed: number; failed: number; in_progress: number; total: number; }`\n - `name: string`\n - `type: 'manual' | 'connector' | 'web'`\n - `description?: string`\n - `urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\n// Automatically fetches more pages as needed.\nfor await (const graph of client.graphs.list()) {\n console.log(graph);\n}\n```", perLanguage: { - go: { - method: 'client.Graphs.List', + typescript: { + method: 'client.graphs.list', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Graphs.List(context.TODO(), writersdk.GraphListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', - }, - http: { - example: 'curl https://api.writer.com/v1/graphs \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const graph of client.graphs.list()) {\n console.log(graph.id);\n}", }, python: { method: 'graphs.list', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\npage = client.graphs.list()\npage = page.data[0]\nprint(page.id)', }, - typescript: { - method: 'client.graphs.list', + go: { + method: 'client.Graphs.List', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const graph of client.graphs.list()) {\n console.log(graph.id);\n}", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Graphs.List(context.TODO(), writersdk.GraphListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', + }, + http: { + example: 'curl https://api.writer.com/v1/graphs \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -553,24 +553,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## create\n\n`client.graphs.create(description?: string, name?: string): { id: string; created_at: string; name: string; description?: string; urls?: object[]; }`\n\n**post** `/v1/graphs`\n\nCreate a new Knowledge Graph.\n\n### Parameters\n\n- `description?: string`\n A description of the Knowledge Graph (max 255 characters). Omitting this field leaves the description unchanged.\n\n- `name?: string`\n The name of the Knowledge Graph (max 255 characters). Omitting this field leaves the name unchanged.\n\n### Returns\n\n- `{ id: string; created_at: string; name: string; description?: string; urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]; }`\n\n - `id: string`\n - `created_at: string`\n - `name: string`\n - `description?: string`\n - `urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst graph = await client.graphs.create();\n\nconsole.log(graph);\n```", perLanguage: { - go: { - method: 'client.Graphs.New', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.New(context.TODO(), writersdk.GraphNewParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.graphs.create', example: - "curl https://api.writer.com/v1/graphs \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $WRITER_API_KEY\" \\\n -d '{}'", + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.create();\n\nconsole.log(graph.id);", }, python: { method: 'graphs.create', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\ngraph = client.graphs.create()\nprint(graph.id)', }, - typescript: { - method: 'client.graphs.create', + go: { + method: 'client.Graphs.New', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.create();\n\nconsole.log(graph.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.New(context.TODO(), writersdk.GraphNewParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', + }, + http: { + example: + "curl https://api.writer.com/v1/graphs \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $WRITER_API_KEY\" \\\n -d '{}'", }, }, }, @@ -588,24 +588,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## retrieve\n\n`client.graphs.retrieve(graph_id: string): { id: string; created_at: string; file_status: object; name: string; type: 'manual' | 'connector' | 'web'; description?: string; urls?: object[]; }`\n\n**get** `/v1/graphs/{graph_id}`\n\nRetrieve a Knowledge Graph.\n\n### Parameters\n\n- `graph_id: string`\n\n### Returns\n\n- `{ id: string; created_at: string; file_status: { completed: number; failed: number; in_progress: number; total: number; }; name: string; type: 'manual' | 'connector' | 'web'; description?: string; urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]; }`\n\n - `id: string`\n - `created_at: string`\n - `file_status: { completed: number; failed: number; in_progress: number; total: number; }`\n - `name: string`\n - `type: 'manual' | 'connector' | 'web'`\n - `description?: string`\n - `urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst graph = await client.graphs.retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph);\n```", perLanguage: { - go: { - method: 'client.Graphs.Get', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.Get(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.graphs.retrieve', example: - 'curl https://api.writer.com/v1/graphs/$GRAPH_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph.id);", }, python: { method: 'graphs.retrieve', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\ngraph = client.graphs.retrieve(\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n)\nprint(graph.id)', }, - typescript: { - method: 'client.graphs.retrieve', + go: { + method: 'client.Graphs.Get', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.Get(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/graphs/$GRAPH_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -628,24 +628,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## update\n\n`client.graphs.update(graph_id: string, description?: string, name?: string, urls?: { type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]): { id: string; created_at: string; name: string; description?: string; urls?: object[]; }`\n\n**put** `/v1/graphs/{graph_id}`\n\nUpdate the name and description of a Knowledge Graph.\n\n### Parameters\n\n- `graph_id: string`\n\n- `description?: string`\n A description of the Knowledge Graph (max 255 characters). Omitting this field leaves the description unchanged.\n\n- `name?: string`\n The name of the Knowledge Graph (max 255 characters). Omitting this field leaves the name unchanged.\n\n- `urls?: { type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]`\n An array of web connector URLs to update for this Knowledge Graph. You can only connect URLs to Knowledge Graphs with the type `web`. To clear the list of URLs, set this field to an empty array.\n\n### Returns\n\n- `{ id: string; created_at: string; name: string; description?: string; urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]; }`\n\n - `id: string`\n - `created_at: string`\n - `name: string`\n - `description?: string`\n - `urls?: { status: { status: 'validating' | 'success' | 'error'; error_type?: 'invalid_url' | 'not_searchable' | 'not_found' | 'paywall_or_login_page' | 'unexpected_error'; }; type: 'single_page' | 'sub_pages'; url: string; exclude_urls?: string[]; }[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst graph = await client.graphs.update('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph);\n```", perLanguage: { - go: { - method: 'client.Graphs.Update', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.Update(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\twritersdk.GraphUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.graphs.update', example: - "curl https://api.writer.com/v1/graphs/$GRAPH_ID \\\n -X PUT \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $WRITER_API_KEY\" \\\n -d '{}'", + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.update('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph.id);", }, python: { method: 'graphs.update', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\ngraph = client.graphs.update(\n graph_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n)\nprint(graph.id)', }, - typescript: { - method: 'client.graphs.update', + go: { + method: 'client.Graphs.Update', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.update('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.Update(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\twritersdk.GraphUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', + }, + http: { + example: + "curl https://api.writer.com/v1/graphs/$GRAPH_ID \\\n -X PUT \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $WRITER_API_KEY\" \\\n -d '{}'", }, }, }, @@ -662,24 +662,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## delete\n\n`client.graphs.delete(graph_id: string): { id: string; deleted: boolean; }`\n\n**delete** `/v1/graphs/{graph_id}`\n\nDelete a Knowledge Graph.\n\n### Parameters\n\n- `graph_id: string`\n\n### Returns\n\n- `{ id: string; deleted: boolean; }`\n\n - `id: string`\n - `deleted: boolean`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst graph = await client.graphs.delete('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph);\n```", perLanguage: { - go: { - method: 'client.Graphs.Delete', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.Delete(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.graphs.delete', example: - 'curl https://api.writer.com/v1/graphs/$GRAPH_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.delete('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph.id);", }, python: { method: 'graphs.delete', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\ngraph = client.graphs.delete(\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n)\nprint(graph.id)', }, - typescript: { - method: 'client.graphs.delete', + go: { + method: 'client.Graphs.Delete', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst graph = await client.graphs.delete('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(graph.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tgraph, err := client.Graphs.Delete(context.TODO(), "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", graph.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/graphs/$GRAPH_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -696,24 +696,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## add_file_to_graph\n\n`client.graphs.addFileToGraph(graph_id: string, file_id: string): { id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n**post** `/v1/graphs/{graph_id}/file`\n\nAdd a file to a Knowledge Graph.\n\n### Parameters\n\n- `graph_id: string`\n\n- `file_id: string`\n The unique identifier of the file.\n\n### Returns\n\n- `{ id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n - `id: string`\n - `created_at: string`\n - `graph_ids: string[]`\n - `name: string`\n - `status: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst file = await client.graphs.addFileToGraph('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', { file_id: 'file_id' });\n\nconsole.log(file);\n```", perLanguage: { - go: { - method: 'client.Graphs.AddFileToGraph', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Graphs.AddFileToGraph(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\twritersdk.GraphAddFileToGraphParams{\n\t\t\tFileID: writersdk.F("file_id"),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.graphs.addFileToGraph', example: - 'curl https://api.writer.com/v1/graphs/$GRAPH_ID/file \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "file_id": "file_id"\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.graphs.addFileToGraph('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {\n file_id: 'file_id',\n});\n\nconsole.log(file.id);", }, python: { method: 'graphs.add_file_to_graph', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfile = client.graphs.add_file_to_graph(\n graph_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n file_id="file_id",\n)\nprint(file.id)', }, - typescript: { - method: 'client.graphs.addFileToGraph', + go: { + method: 'client.Graphs.AddFileToGraph', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.graphs.addFileToGraph('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {\n file_id: 'file_id',\n});\n\nconsole.log(file.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Graphs.AddFileToGraph(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\twritersdk.GraphAddFileToGraphParams{\n\t\t\tFileID: writersdk.F("file_id"),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/graphs/$GRAPH_ID/file \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "file_id": "file_id"\n }\'', }, }, }, @@ -730,24 +730,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## remove_file_from_graph\n\n`client.graphs.removeFileFromGraph(graph_id: string, file_id: string): { id: string; deleted: boolean; }`\n\n**delete** `/v1/graphs/{graph_id}/file/{file_id}`\n\nRemove a file from a Knowledge Graph.\n\n### Parameters\n\n- `graph_id: string`\n\n- `file_id: string`\n\n### Returns\n\n- `{ id: string; deleted: boolean; }`\n\n - `id: string`\n - `deleted: boolean`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst response = await client.graphs.removeFileFromGraph('file_id', { graph_id: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' });\n\nconsole.log(response);\n```", perLanguage: { - go: { - method: 'client.Graphs.RemoveFileFromGraph', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Graphs.RemoveFileFromGraph(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\t"file_id",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.graphs.removeFileFromGraph', example: - 'curl https://api.writer.com/v1/graphs/$GRAPH_ID/file/$FILE_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.graphs.removeFileFromGraph('file_id', {\n graph_id: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n});\n\nconsole.log(response.id);", }, python: { method: 'graphs.remove_file_from_graph', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.graphs.remove_file_from_graph(\n file_id="file_id",\n graph_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n)\nprint(response.id)', }, - typescript: { - method: 'client.graphs.removeFileFromGraph', + go: { + method: 'client.Graphs.RemoveFileFromGraph', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.graphs.removeFileFromGraph('file_id', {\n graph_id: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n});\n\nconsole.log(response.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Graphs.RemoveFileFromGraph(\n\t\tcontext.TODO(),\n\t\t"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n\t\t"file_id",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/graphs/$GRAPH_ID/file/$FILE_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -771,24 +771,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## question\n\n`client.graphs.question(graph_ids: string[], question: string, query_config?: { grounding_level?: number; inline_citations?: boolean; keyword_threshold?: number; max_snippets?: number; max_subquestions?: number; max_tokens?: number; search_weight?: number; semantic_threshold?: number; }, stream?: boolean, subqueries?: boolean): { answer: string; question: string; sources: source[]; references?: object; subqueries?: object[]; }`\n\n**post** `/v1/graphs/question`\n\nAsk a question to specified Knowledge Graphs.\n\n### Parameters\n\n- `graph_ids: string[]`\n The unique identifiers of the Knowledge Graphs to query.\n\n- `question: string`\n The question to answer using the Knowledge Graph.\n\n- `query_config?: { grounding_level?: number; inline_citations?: boolean; keyword_threshold?: number; max_snippets?: number; max_subquestions?: number; max_tokens?: number; search_weight?: number; semantic_threshold?: number; }`\n Configuration options for Knowledge Graph queries, including search parameters and citation settings.\n - `grounding_level?: number`\n Level of grounding required for responses, controlling how closely answers must be tied to source material. Set lower for grounded outputs, higher for creativity. Higher values (closer to 1.0) allow more creative interpretation, while lower values (closer to 0.0) stick more closely to source material. Range: 0.0-1.0, Default: 0.0.\n - `inline_citations?: boolean`\n Whether to include inline citations in the response, showing which Knowledge Graph sources were used. Default: false.\n - `keyword_threshold?: number`\n Threshold for keyword-based matching when searching Knowledge Graph content. Set higher for stricter relevance, lower for broader range. Higher values (closer to 1.0) require stronger keyword matches, while lower values (closer to 0.0) allow more lenient matching. Range: 0.0-1.0, Default: 0.7.\n - `max_snippets?: number`\n Maximum number of text snippets to retrieve from the Knowledge Graph for context. Works in concert with `search_weight` to control best matches vs broader coverage. While technically supports 1-60, values below 5 may return no results due to RAG implementation. Recommended range: 5-25. Due to RAG system behavior, you may see more snippets than requested. Range: 1-60, Default: 30.\n - `max_subquestions?: number`\n Maximum number of subquestions to generate when processing complex queries. Set higher to improve detail, set lower to reduce response time. Range: 1-10, Default: 6.\n - `max_tokens?: number`\n Maximum number of tokens the model can generate in the response. This controls the length of the AI's answer. Set higher for longer answers, set lower for shorter, faster answers. Range: 100-8000, Default: 4000.\n - `search_weight?: number`\n Weight given to search results when ranking and selecting relevant information. Higher values (closer to 100) prioritize keyword-based matching, while lower values (closer to 0) prioritize semantic similarity matching. Use higher values for exact keyword searches, lower values for conceptual similarity searches. Range: 0-100, Default: 50.\n - `semantic_threshold?: number`\n Threshold for semantic similarity matching when searching Knowledge Graph content. Set higher for stricter relevance, lower for broader range. Higher values (closer to 1.0) require stronger semantic similarity, while lower values (closer to 0.0) allow more lenient semantic matching. Range: 0.0-1.0, Default: 0.7.\n\n- `stream?: boolean`\n Determines whether the model's output should be streamed. If true, the output is generated and sent incrementally, which can be useful for real-time applications.\n\n- `subqueries?: boolean`\n Specify whether to include subqueries.\n\n### Returns\n\n- `{ answer: string; question: string; sources: { file_id: string; snippet: string; }[]; references?: { files?: { fileId: string; score: number; text: string; cite?: string; page?: number; }[]; web?: { score: number; text: string; title: string; url: string; }[]; }; subqueries?: { answer: string; query: string; sources: object[]; }[]; }`\n\n - `answer: string`\n - `question: string`\n - `sources: { file_id: string; snippet: string; }[]`\n - `references?: { files?: { fileId: string; score: number; text: string; cite?: string; page?: number; }[]; web?: { score: number; text: string; title: string; url: string; }[]; }`\n - `subqueries?: { answer: string; query: string; sources: { file_id: string; snippet: string; }[]; }[]`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst stream = await client.graphs.question({ graph_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'], question: 'question' });\nfor await (const questionResponseChunk of stream) {\n console.log(questionResponseChunk);\n}\n```", perLanguage: { - go: { - method: 'client.Graphs.Question', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tquestion, err := client.Graphs.Question(context.TODO(), writersdk.GraphQuestionParams{\n\t\tGraphIDs: writersdk.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),\n\t\tQuestion: writersdk.F("question"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", question.Answer)\n}\n', - }, - http: { + typescript: { + method: 'client.graphs.question', example: - 'curl https://api.writer.com/v1/graphs/question \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "graph_ids": [\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n ],\n "question": "question"\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst question = await client.graphs.question({\n graph_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'],\n question: 'question',\n});\n\nconsole.log(question.answer);", }, python: { method: 'graphs.question', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfor graph in client.graphs.question(\n graph_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],\n question="question",\n):\n print(graph)', }, - typescript: { - method: 'client.graphs.question', + go: { + method: 'client.Graphs.Question', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst question = await client.graphs.question({\n graph_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'],\n question: 'question',\n});\n\nconsole.log(question.answer);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tquestion, err := client.Graphs.Question(context.TODO(), writersdk.GraphQuestionParams{\n\t\tGraphIDs: writersdk.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),\n\t\tQuestion: writersdk.F("question"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", question.Answer)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/graphs/question \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "graph_ids": [\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n ],\n "question": "question"\n }\'', }, }, }, @@ -806,24 +806,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## retrieve\n\n`client.files.retrieve(file_id: string): { id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n**get** `/v1/files/{file_id}`\n\nRetrieve detailed information about a specific file, including its metadata, status, and associated graphs.\n\n### Parameters\n\n- `file_id: string`\n\n### Returns\n\n- `{ id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n - `id: string`\n - `created_at: string`\n - `graph_ids: string[]`\n - `name: string`\n - `status: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst file = await client.files.retrieve('file_id');\n\nconsole.log(file);\n```", perLanguage: { - go: { - method: 'client.Files.Get', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Files.Get(context.TODO(), "file_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.files.retrieve', example: - 'curl https://api.writer.com/v1/files/$FILE_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.files.retrieve('file_id');\n\nconsole.log(file.id);", }, python: { method: 'files.retrieve', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfile = client.files.retrieve(\n "file_id",\n)\nprint(file.id)', }, - typescript: { - method: 'client.files.retrieve', + go: { + method: 'client.Files.Get', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.files.retrieve('file_id');\n\nconsole.log(file.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Files.Get(context.TODO(), "file_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/files/$FILE_ID \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -840,24 +840,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## delete\n\n`client.files.delete(file_id: string): { id: string; deleted: boolean; }`\n\n**delete** `/v1/files/{file_id}`\n\nPermanently delete a file from the system. This action cannot be undone.\n\n### Parameters\n\n- `file_id: string`\n\n### Returns\n\n- `{ id: string; deleted: boolean; }`\n\n - `id: string`\n - `deleted: boolean`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst file = await client.files.delete('file_id');\n\nconsole.log(file);\n```", perLanguage: { - go: { - method: 'client.Files.Delete', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Files.Delete(context.TODO(), "file_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.files.delete', example: - 'curl https://api.writer.com/v1/files/$FILE_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.files.delete('file_id');\n\nconsole.log(file.id);", }, python: { method: 'files.delete', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfile = client.files.delete(\n "file_id",\n)\nprint(file.id)', }, - typescript: { - method: 'client.files.delete', + go: { + method: 'client.Files.Delete', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.files.delete('file_id');\n\nconsole.log(file.id);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Files.Delete(context.TODO(), "file_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/files/$FILE_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -883,23 +883,23 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## list\n\n`client.files.list(after?: string, before?: string, file_types?: string, graph_id?: string, limit?: number, order?: 'asc' | 'desc', status?: 'in_progress' | 'completed' | 'failed'): { id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n**get** `/v1/files`\n\nRetrieve a paginated list of files with optional filtering by status, graph association, and file type.\n\n### Parameters\n\n- `after?: string`\n The ID of the last object in the previous page. This parameter instructs the API to return the next page of results.\n\n- `before?: string`\n The ID of the first object in the previous page. This parameter instructs the API to return the previous page of results.\n\n- `file_types?: string`\n The extensions of the files to retrieve. Separate multiple extensions with a comma. For example: `pdf,jpg,docx`.\n\n- `graph_id?: string`\n The unique identifier of the graph to which the files belong.\n\n- `limit?: number`\n Specifies the maximum number of objects returned in a page. The default value is 50. The minimum value is 1, and the maximum value is 100.\n\n- `order?: 'asc' | 'desc'`\n Specifies the order of the results. Valid values are asc for ascending and desc for descending.\n\n- `status?: 'in_progress' | 'completed' | 'failed'`\n Specifies the status of the files to retrieve. Valid values are in_progress, completed or failed.\n\n### Returns\n\n- `{ id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n - `id: string`\n - `created_at: string`\n - `graph_ids: string[]`\n - `name: string`\n - `status: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\n// Automatically fetches more pages as needed.\nfor await (const file of client.files.list()) {\n console.log(file);\n}\n```", perLanguage: { - go: { - method: 'client.Files.List', + typescript: { + method: 'client.files.list', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Files.List(context.TODO(), writersdk.FileListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', - }, - http: { - example: 'curl https://api.writer.com/v1/files \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const file of client.files.list()) {\n console.log(file.id);\n}", }, python: { method: 'files.list', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\npage = client.files.list()\npage = page.data[0]\nprint(page.id)', }, - typescript: { - method: 'client.files.list', + go: { + method: 'client.Files.List', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const file of client.files.list()) {\n console.log(file.id);\n}", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tpage, err := client.Files.List(context.TODO(), writersdk.FileListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", page)\n}\n', + }, + http: { + example: 'curl https://api.writer.com/v1/files \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -915,26 +915,26 @@ const EMBEDDED_METHODS: MethodEntry[] = [ params: ['content: string;', 'Content-Disposition: string;', 'graphId?: string;'], response: '{ id: string; created_at: string; graph_ids: string[]; name: string; status: string; }', markdown: - "## upload\n\n`client.files.upload(content: string, Content-Disposition: string, graphId?: string): { id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n**post** `/v1/files`\n\nUpload a new file to the system. Supports various file formats including PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, and XLSX.\n\n### Parameters\n\n- `content: string`\n\n- `Content-Disposition: string`\n\n- `graphId?: string`\n The unique identifier of the Knowledge Graph to associate the uploaded file with.\n\nNote: The response from the upload endpoint does not include the `graphId` field, but the association will be visible when you retrieve the file using the file retrieval endpoint.\n\n### Returns\n\n- `{ id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n - `id: string`\n - `created_at: string`\n - `graph_ids: string[]`\n - `name: string`\n - `status: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst file = await client.files.upload({ content: fs.createReadStream('path/to/file'), 'Content-Disposition': 'Content-Disposition' });\n\nconsole.log(file);\n```", + "## upload\n\n`client.files.upload(content: string, Content-Disposition: string, graphId?: string): { id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n**post** `/v1/files`\n\nUpload a new file to the system. Supports various file formats including PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, and XLSX.\n\n### Parameters\n\n- `content: string`\n\n- `Content-Disposition: string`\n\n- `graphId?: string`\n The unique identifier of the Knowledge Graph to associate the uploaded file with.\n\nNote: The response from the upload endpoint does not include the `graphId` field, but the association will be visible when you retrieve the file using the file retrieval endpoint.\n\n### Returns\n\n- `{ id: string; created_at: string; graph_ids: string[]; name: string; status: string; }`\n\n - `id: string`\n - `created_at: string`\n - `graph_ids: string[]`\n - `name: string`\n - `status: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst file = await client.files.upload(fs.createReadStream('path/to/file'), { 'Content-Disposition': 'Content-Disposition' });\n\nconsole.log(file);\n```", perLanguage: { - go: { - method: 'client.Files.Upload', - example: - 'package main\n\nimport (\n\t"bytes"\n\t"context"\n\t"fmt"\n\t"io"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Files.Upload(context.TODO(), writersdk.FileUploadParams{\n\t\tContent: io.Reader(bytes.NewBuffer([]byte("Example data"))),\n\t\tContentDisposition: writersdk.F("Content-Disposition"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', - }, - http: { + typescript: { + method: 'client.files.upload', example: - "curl https://api.writer.com/v1/files \\\n -H 'Content-Type: text/plain' \\\n -H \"Authorization: Bearer $WRITER_API_KEY\" \\\n -F 'content=@/path/to/content'", + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.files.upload(fs.createReadStream('path/to/file'), {\n 'Content-Disposition': 'Content-Disposition',\n});\n\nconsole.log(file.id);", }, python: { method: 'files.upload', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nfile = client.files.upload(\n content=b"Example data",\n content_disposition="Content-Disposition",\n)\nprint(file.id)', }, - typescript: { - method: 'client.files.upload', + go: { + method: 'client.Files.Upload', example: - "import fs from 'fs';\nimport Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst file = await client.files.upload({\n content: fs.createReadStream('path/to/file'),\n 'Content-Disposition': 'Content-Disposition',\n});\n\nconsole.log(file.id);", + 'package main\n\nimport (\n\t"bytes"\n\t"context"\n\t"fmt"\n\t"io"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tfile, err := client.Files.Upload(\n\t\tcontext.TODO(),\n\t\tio.Reader(bytes.NewBuffer([]byte("Example data"))),\n\t\twritersdk.FileUploadParams{\n\t\t\tContentDisposition: writersdk.F("Content-Disposition"),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", file.ID)\n}\n', + }, + http: { + example: + "curl https://api.writer.com/v1/files \\\n -H 'Content-Type: text/plain' \\\n -H \"Authorization: Bearer $WRITER_API_KEY\" \\\n -F 'content=@/path/to/content'", }, }, }, @@ -952,24 +952,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## download\n\n`client.files.download(file_id: string): string`\n\n**get** `/v1/files/{file_id}/download`\n\nDownload the binary content of a file. The response will contain the file data in the appropriate MIME type.\n\n### Parameters\n\n- `file_id: string`\n\n### Returns\n\n- `string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst response = await client.files.download('file_id');\n\nconsole.log(response);\n\nconst content = await response.blob()\nconsole.log(content)\n```", perLanguage: { - go: { - method: 'client.Files.Download', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Files.Download(context.TODO(), "file_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response)\n}\n', - }, - http: { + typescript: { + method: 'client.files.download', example: - 'curl https://api.writer.com/v1/files/$FILE_ID/download \\\n -H "Authorization: Bearer $WRITER_API_KEY"', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.files.download('file_id');\n\nconsole.log(response);\n\nconst content = await response.blob();\nconsole.log(content);", }, python: { method: 'files.download', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.files.download(\n "file_id",\n)\nprint(response)\ncontent = response.read()\nprint(content)', }, - typescript: { - method: 'client.files.download', + go: { + method: 'client.Files.Download', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.files.download('file_id');\n\nconsole.log(response);\n\nconst content = await response.blob();\nconsole.log(content);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Files.Download(context.TODO(), "file_id")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/files/$FILE_ID/download \\\n -H "Authorization: Bearer $WRITER_API_KEY"', }, }, }, @@ -987,24 +987,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## retry\n\n`client.files.retry(file_ids: string[]): { success?: boolean; }`\n\n**post** `/v1/files/retry`\n\nRetry processing of files that previously failed to process. This will re-attempt the processing of the specified files.\n\n### Parameters\n\n- `file_ids: string[]`\n The unique identifier of the files to retry.\n\n### Returns\n\n- `{ success?: boolean; }`\n\n - `success?: boolean`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst response = await client.files.retry({ file_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'] });\n\nconsole.log(response);\n```", perLanguage: { - go: { - method: 'client.Files.Retry', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Files.Retry(context.TODO(), writersdk.FileRetryParams{\n\t\tFileIDs: writersdk.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Success)\n}\n', - }, - http: { + typescript: { + method: 'client.files.retry', example: - 'curl https://api.writer.com/v1/files/retry \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "file_ids": [\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n ]\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.files.retry({ file_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'] });\n\nconsole.log(response.success);", }, python: { method: 'files.retry', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.files.retry(\n file_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],\n)\nprint(response.success)', }, - typescript: { - method: 'client.files.retry', + go: { + method: 'client.Files.Retry', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.files.retry({ file_ids: ['182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e'] });\n\nconsole.log(response.success);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Files.Retry(context.TODO(), writersdk.FileRetryParams{\n\t\tFileIDs: writersdk.F([]string{"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Success)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/files/retry \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "file_ids": [\n "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n ]\n }\'', }, }, }, @@ -1021,24 +1021,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## parse_pdf\n\n`client.tools.parsePdf(file_id: string, format: 'text' | 'markdown'): { content: string; }`\n\n**post** `/v1/tools/pdf-parser/{file_id}`\n\nParse PDF to other formats.\n\n### Parameters\n\n- `file_id: string`\n\n- `format: 'text' | 'markdown'`\n The format into which the PDF content should be converted.\n\n### Returns\n\n- `{ content: string; }`\n\n - `content: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst response = await client.tools.parsePdf('file_id', { format: 'text' });\n\nconsole.log(response);\n```", perLanguage: { - go: { - method: 'client.Tools.ParsePdf', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Tools.ParsePdf(\n\t\tcontext.TODO(),\n\t\t"file_id",\n\t\twritersdk.ToolParsePdfParams{\n\t\t\tFormat: writersdk.F(writersdk.ToolParsePdfParamsFormatText),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Content)\n}\n', - }, - http: { + typescript: { + method: 'client.tools.parsePdf', example: - 'curl https://api.writer.com/v1/tools/pdf-parser/$FILE_ID \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "format": "text"\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.tools.parsePdf('file_id', { format: 'text' });\n\nconsole.log(response.content);", }, python: { method: 'tools.parse_pdf', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.tools.parse_pdf(\n file_id="file_id",\n format="text",\n)\nprint(response.content)', }, - typescript: { - method: 'client.tools.parsePdf', + go: { + method: 'client.Tools.ParsePdf', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.tools.parsePdf('file_id', { format: 'text' });\n\nconsole.log(response.content);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Tools.ParsePdf(\n\t\tcontext.TODO(),\n\t\t"file_id",\n\t\twritersdk.ToolParsePdfParams{\n\t\t\tFormat: writersdk.F(writersdk.ToolParsePdfParamsFormatText),\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Content)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/tools/pdf-parser/$FILE_ID \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "format": "text"\n }\'', }, }, }, @@ -1070,24 +1070,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## web_search\n\n`client.tools.webSearch(chunks_per_source?: number, country?: string, days?: number, exclude_domains?: string[], include_answer?: boolean, include_domains?: string[], include_raw_content?: 'text' | 'markdown' | boolean, max_results?: number, query?: string, search_depth?: 'basic' | 'advanced', stream?: boolean, time_range?: 'day' | 'week' | 'month' | 'year' | 'd' | 'w' | 'm' | 'y', topic?: 'general' | 'news'): { query: string; sources: object[]; answer?: string; }`\n\n**post** `/v1/tools/web-search`\n\nSearch the web for information about a given query and return relevant results with source URLs.\n\n### Parameters\n\n- `chunks_per_source?: number`\n Only applies when `search_depth` is `advanced`. Specifies how many text segments to extract from each source. Limited to 3 chunks maximum.\n\n- `country?: string`\n Localizes search results to a specific country. Only applies to general topic searches.\n\n- `days?: number`\n For news topic searches, specifies how many days of news coverage to include.\n\n- `exclude_domains?: string[]`\n Domains to exclude from the search. If unset, the search includes all domains.\n\n- `include_answer?: boolean`\n Whether to include a generated answer to the query in the response. If `false`, only search results are returned.\n\n- `include_domains?: string[]`\n Domains to include in the search. If unset, the search includes all domains.\n\n- `include_raw_content?: 'text' | 'markdown' | boolean`\n Controls how raw content is included in search results:\n\n- `text`: Returns plain text without formatting markup\n- `markdown`: Returns structured content with markdown formatting (headers, links, bold text)\n- `true`: Same as `markdown`\n- `false`: Raw content is not included (default if unset)\n\n- `max_results?: number`\n Limits the number of search results returned. Cannot exceed 20 sources.\n\n- `query?: string`\n The search query.\n\n- `search_depth?: 'basic' | 'advanced'`\n Controls search comprehensiveness:\n\n- `basic`: Returns fewer but highly relevant results\n- `advanced`: Performs a deeper search with more results\n\n- `stream?: boolean`\n Enables streaming of search results as they become available.\n\n- `time_range?: 'day' | 'week' | 'month' | 'year' | 'd' | 'w' | 'm' | 'y'`\n Filters results to content published within the specified time range back from the current date. For example, `week` or `w` returns results from the past 7 days.\n\n- `topic?: 'general' | 'news'`\n The search topic category. Use `news` for current events and news articles, or `general` for broader web search.\n\n### Returns\n\n- `{ query: string; sources: { raw_content?: string; url?: string; }[]; answer?: string; }`\n\n - `query: string`\n - `sources: { raw_content?: string; url?: string; }[]`\n - `answer?: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst response = await client.tools.webSearch();\n\nconsole.log(response);\n```", perLanguage: { - go: { - method: 'client.Tools.WebSearch', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Tools.WebSearch(context.TODO(), writersdk.ToolWebSearchParams{\n\t\tIncludeDomains: writersdk.F([]string{"dev.writer.com"}),\n\t\tQuery: writersdk.F("How do I get an API key for the Writer API?"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Query)\n}\n', - }, - http: { + typescript: { + method: 'client.tools.webSearch', example: - "curl https://api.writer.com/v1/tools/web-search \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $WRITER_API_KEY\" \\\n -d '{}'", + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.tools.webSearch({\n include_domains: ['dev.writer.com'],\n query: 'How do I get an API key for the Writer API?',\n});\n\nconsole.log(response.query);", }, python: { method: 'tools.web_search', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.tools.web_search(\n include_domains=["dev.writer.com"],\n query="How do I get an API key for the Writer API?",\n)\nprint(response.query)', }, - typescript: { - method: 'client.tools.webSearch', + go: { + method: 'client.Tools.WebSearch', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.tools.webSearch({\n include_domains: ['dev.writer.com'],\n query: 'How do I get an API key for the Writer API?',\n});\n\nconsole.log(response.query);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Tools.WebSearch(context.TODO(), writersdk.ToolWebSearchParams{\n\t\tIncludeDomains: writersdk.F([]string{"dev.writer.com"}),\n\t\tQuery: writersdk.F("How do I get an API key for the Writer API?"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Query)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/tools/web-search \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "include_domains": [\n "dev.writer.com"\n ],\n "query": "How do I get an API key for the Writer API?"\n }\'', }, }, }, @@ -1112,24 +1112,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## translate\n\n`client.translation.translate(formality: boolean, length_control: boolean, mask_profanity: boolean, model: 'palmyra-translate', source_language_code: string, target_language_code: string, text: string): { data: string; }`\n\n**post** `/v1/translation`\n\nTranslate text from one language to another.\n\n### Parameters\n\n- `formality: boolean`\n Whether to use formal or informal language in the translation. See the [list of languages that support formality](https://dev.writer.com/api-reference/translation-api/language-support#formality). If the language does not support formality, this parameter is ignored.\n\n- `length_control: boolean`\n Whether to control the length of the translated text. See the [list of languages that support length control](https://dev.writer.com/api-reference/translation-api/language-support#length-control). If the language does not support length control, this parameter is ignored.\n\n- `mask_profanity: boolean`\n Whether to mask profane words in the translated text. See the [list of languages that do not support profanity masking](https://dev.writer.com/api-reference/translation-api/language-support#profanity-masking). If the language does not support profanity masking, this parameter is ignored.\n\n- `model: 'palmyra-translate'`\n The model to use for translation.\n\n- `source_language_code: string`\n The [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) language code of the original text to translate. For example, `en` for English, `zh` for Chinese, `fr` for French, `es` for Spanish. If the language has a variant, the code appends the two-digit [ISO-3166 country code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes). For example, Mexican Spanish is `es-MX`. See the [list of supported languages and language codes](https://dev.writer.com/api-reference/translation-api/language-support).\n\n- `target_language_code: string`\n The [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) language code of the target language for the translation. For example, `en` for English, `zh` for Chinese, `fr` for French, `es` for Spanish. If the language has a variant, the code appends the two-digit [ISO-3166 country code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes). For example, Mexican Spanish is `es-MX`. See the [list of supported languages and language codes](https://dev.writer.com/api-reference/translation-api/language-support).\n\n- `text: string`\n The text to translate. Maximum of 100,000 words.\n\n### Returns\n\n- `{ data: string; }`\n\n - `data: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst translationResponse = await client.translation.translate({\n formality: true,\n length_control: true,\n mask_profanity: true,\n model: 'palmyra-translate',\n source_language_code: 'en',\n target_language_code: 'es',\n text: 'Hello, world!',\n});\n\nconsole.log(translationResponse);\n```", perLanguage: { - go: { - method: 'client.Translation.Translate', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\ttranslationResponse, err := client.Translation.Translate(context.TODO(), writersdk.TranslationTranslateParams{\n\t\tTranslationRequest: writersdk.TranslationRequestParam{\n\t\t\tFormality: writersdk.F(true),\n\t\t\tLengthControl: writersdk.F(true),\n\t\t\tMaskProfanity: writersdk.F(true),\n\t\t\tModel: writersdk.F(writersdk.TranslationRequestModelPalmyraTranslate),\n\t\t\tSourceLanguageCode: writersdk.F("en"),\n\t\t\tTargetLanguageCode: writersdk.F("es"),\n\t\t\tText: writersdk.F("Hello, world!"),\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", translationResponse.Data)\n}\n', - }, - http: { + typescript: { + method: 'client.translation.translate', example: - 'curl https://api.writer.com/v1/translation \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "formality": true,\n "length_control": true,\n "mask_profanity": true,\n "model": "palmyra-translate",\n "source_language_code": "en",\n "target_language_code": "es",\n "text": "Hello, world!"\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst translationResponse = await client.translation.translate({\n formality: true,\n length_control: true,\n mask_profanity: true,\n model: 'palmyra-translate',\n source_language_code: 'en',\n target_language_code: 'es',\n text: 'Hello, world!',\n});\n\nconsole.log(translationResponse.data);", }, python: { method: 'translation.translate', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\ntranslation_response = client.translation.translate(\n formality=True,\n length_control=True,\n mask_profanity=True,\n model="palmyra-translate",\n source_language_code="en",\n target_language_code="es",\n text="Hello, world!",\n)\nprint(translation_response.data)', }, - typescript: { - method: 'client.translation.translate', + go: { + method: 'client.Translation.Translate', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst translationResponse = await client.translation.translate({\n formality: true,\n length_control: true,\n mask_profanity: true,\n model: 'palmyra-translate',\n source_language_code: 'en',\n target_language_code: 'es',\n text: 'Hello, world!',\n});\n\nconsole.log(translationResponse.data);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\ttranslationResponse, err := client.Translation.Translate(context.TODO(), writersdk.TranslationTranslateParams{\n\t\tTranslationRequest: writersdk.TranslationRequestParam{\n\t\t\tFormality: writersdk.F(true),\n\t\t\tLengthControl: writersdk.F(true),\n\t\t\tMaskProfanity: writersdk.F(true),\n\t\t\tModel: writersdk.F(writersdk.TranslationRequestModelPalmyraTranslate),\n\t\t\tSourceLanguageCode: writersdk.F("en"),\n\t\t\tTargetLanguageCode: writersdk.F("es"),\n\t\t\tText: writersdk.F("Hello, world!"),\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", translationResponse.Data)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/translation \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "formality": true,\n "length_control": true,\n "mask_profanity": true,\n "model": "palmyra-translate",\n "source_language_code": "en",\n "target_language_code": "es",\n "text": "Hello, world!"\n }\'', }, }, }, @@ -1151,24 +1151,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ markdown: "## analyze\n\n`client.vision.analyze(model: 'palmyra-vision', prompt: string, variables: { file_id: string; name: string; }[]): { data: string; }`\n\n**post** `/v1/vision`\n\nSubmit images and documents with a prompt to generate an analysis. Supports JPG, PNG, PDF, and TXT files up to 7MB each.\n\n### Parameters\n\n- `model: 'palmyra-vision'`\n The model to use for image analysis.\n\n- `prompt: string`\n The prompt to use for the image analysis. The prompt must include the name of each image variable, surrounded by double curly braces (`{{}}`). For example, `Describe the difference between the image {{image_1}} and the image {{image_2}}`.\n\n- `variables: { file_id: string; name: string; }[]`\n\n### Returns\n\n- `{ data: string; }`\n\n - `data: string`\n\n### Example\n\n```typescript\nimport Writer from 'writer-sdk';\n\nconst client = new Writer();\n\nconst visionResponse = await client.vision.analyze({\n model: 'palmyra-vision',\n prompt: 'Describe the difference between the image {{image_1}} and the image {{image_2}}.',\n variables: [{ file_id: 'f1234', name: 'image_1' }, { file_id: 'f9876', name: 'image_2' }],\n});\n\nconsole.log(visionResponse);\n```", perLanguage: { - go: { - method: 'client.Vision.Analyze', - example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tvisionResponse, err := client.Vision.Analyze(context.TODO(), writersdk.VisionAnalyzeParams{\n\t\tVisionRequest: writersdk.VisionRequestParam{\n\t\t\tModel: writersdk.F(writersdk.VisionRequestModelPalmyraVision),\n\t\t\tPrompt: writersdk.F("Describe the difference between the image {{image_1}} and the image {{image_2}}."),\n\t\t\tVariables: writersdk.F([]writersdk.VisionRequestVariableParam{{\n\t\t\t\tFileID: writersdk.F("f1234"),\n\t\t\t\tName: writersdk.F("image_1"),\n\t\t\t}, {\n\t\t\t\tFileID: writersdk.F("f9876"),\n\t\t\t\tName: writersdk.F("image_2"),\n\t\t\t}}),\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", visionResponse.Data)\n}\n', - }, - http: { + typescript: { + method: 'client.vision.analyze', example: - 'curl https://api.writer.com/v1/vision \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "model": "palmyra-vision",\n "prompt": "Describe the difference between the image {{image_1}} and the image {{image_2}}.",\n "variables": [\n {\n "file_id": "f1234",\n "name": "image_1"\n },\n {\n "file_id": "f9876",\n "name": "image_2"\n }\n ]\n }\'', + "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst visionResponse = await client.vision.analyze({\n model: 'palmyra-vision',\n prompt: 'Describe the difference between the image {{image_1}} and the image {{image_2}}.',\n variables: [\n { name: 'image_1', file_id: 'f1234' },\n { name: 'image_2', file_id: 'f9876' },\n ],\n});\n\nconsole.log(visionResponse.data);", }, python: { method: 'vision.analyze', example: 'import os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\nvision_response = client.vision.analyze(\n model="palmyra-vision",\n prompt="Describe the difference between the image {{image_1}} and the image {{image_2}}.",\n variables=[{\n "name": "image_1",\n "file_id": "f1234",\n }, {\n "name": "image_2",\n "file_id": "f9876",\n }],\n)\nprint(vision_response.data)', }, - typescript: { - method: 'client.vision.analyze', + go: { + method: 'client.Vision.Analyze', example: - "import Writer from 'writer-sdk';\n\nconst client = new Writer({\n apiKey: process.env['WRITER_API_KEY'], // This is the default and can be omitted\n});\n\nconst visionResponse = await client.vision.analyze({\n model: 'palmyra-vision',\n prompt: 'Describe the difference between the image {{image_1}} and the image {{image_2}}.',\n variables: [\n { name: 'image_1', file_id: 'f1234' },\n { name: 'image_2', file_id: 'f9876' },\n ],\n});\n\nconsole.log(visionResponse.data);", + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tvisionResponse, err := client.Vision.Analyze(context.TODO(), writersdk.VisionAnalyzeParams{\n\t\tVisionRequest: writersdk.VisionRequestParam{\n\t\t\tModel: writersdk.F(writersdk.VisionRequestModelPalmyraVision),\n\t\t\tPrompt: writersdk.F("Describe the difference between the image {{image_1}} and the image {{image_2}}."),\n\t\t\tVariables: writersdk.F([]writersdk.VisionRequestVariableParam{{\n\t\t\t\tFileID: writersdk.F("f1234"),\n\t\t\t\tName: writersdk.F("image_1"),\n\t\t\t}, {\n\t\t\t\tFileID: writersdk.F("f9876"),\n\t\t\t\tName: writersdk.F("image_2"),\n\t\t\t}}),\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", visionResponse.Data)\n}\n', + }, + http: { + example: + 'curl https://api.writer.com/v1/vision \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $WRITER_API_KEY" \\\n -d \'{\n "model": "palmyra-vision",\n "prompt": "Describe the difference between the image {{image_1}} and the image {{image_2}}.",\n "variables": [\n {\n "file_id": "f1234",\n "name": "image_1"\n },\n {\n "file_id": "f9876",\n "name": "image_2"\n }\n ]\n }\'', }, }, }, @@ -1176,14 +1176,14 @@ const EMBEDDED_METHODS: MethodEntry[] = [ const EMBEDDED_READMES: { language: string; content: string }[] = [ { - language: 'python', + language: 'go', content: - '# Writer Python API library\n\n\n[![PyPI version](https://img.shields.io/pypi/v/writer-sdk.svg?label=pypi%20(stable))](https://pypi.org/project/writer-sdk/)\n\nThe Writer Python library provides convenient access to the Writer REST API from any Python 3.9+\napplication. The library includes type definitions for all request params and response fields,\nand offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).\n\n\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\n## MCP Server\n\nUse the Writer MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6Ik15IEFQSSBLZXkifX0)\n[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22writer-sdk-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22writer-sdk-mcp%22%5D%2C%22env%22%3A%7B%22WRITER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)\n\n> Note: You may need to set environment variables in your MCP client.\n\n## Documentation\n\nThe REST API documentation can be found on [dev.writer.com](https://dev.writer.com/api-guides/introduction). The full API of this library can be found in [api.md](api.md).\n\n## Installation\n\n```sh\n# install from PyPI\npip install writer-sdk\n```\n\n## Usage\n\nThe full API of this library can be found in [api.md](api.md).\n\n```python\nimport os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\n\nchat_completion = client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\nprint(chat_completion.id)\n```\n\nWhile you can provide an `api_key` keyword argument,\nwe recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)\nto add `WRITER_API_KEY="My API Key"` to your `.env` file\nso that your API Key is not stored in source control.\n\n## Async usage\n\nSimply import `AsyncWriter` instead of `Writer` and use `await` with each API call:\n\n```python\nimport os\nimport asyncio\nfrom writerai import AsyncWriter\n\nclient = AsyncWriter(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\n\nasync def main() -> None:\n chat_completion = await client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n )\n print(chat_completion.id)\n\nasyncio.run(main())\n```\n\nFunctionality between the synchronous and asynchronous clients is otherwise identical.\n\n### With aiohttp\n\nBy default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.\n\nYou can enable this by installing `aiohttp`:\n\n```sh\n# install from PyPI\npip install writer-sdk[aiohttp]\n```\n\nThen you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:\n\n```python\nimport os\nimport asyncio\nfrom writerai import DefaultAioHttpClient\nfrom writerai import AsyncWriter\n\nasync def main() -> None:\n async with AsyncWriter(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n http_client=DefaultAioHttpClient(),\n) as client:\n chat_completion = await client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n )\n print(chat_completion.id)\n\nasyncio.run(main())\n```\n\n## Streaming responses\n\nWe provide support for streaming responses using Server Side Events (SSE).\n\n```python\nfrom writerai import Writer\n\nclient = Writer()\n\nstream = client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n stream=True,\n)\nfor chat_completion in stream:\n print(chat_completion.id)\n```\n\nThe async client uses the exact same interface.\n\n```python\nfrom writerai import AsyncWriter\n\nclient = AsyncWriter()\n\nstream = await client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n stream=True,\n)\nasync for chat_completion in stream:\n print(chat_completion.id)\n```\n\n## Using types\n\nNested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:\n\n- Serializing back into JSON, `model.to_json()`\n- Converting to a dictionary, `model.to_dict()`\n\nTyped requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`.\n\n## Pagination\n\nList methods in the Writer API are paginated.\n\nThis library provides auto-paginating iterators with each list response, so you do not have to request successive pages manually:\n\n```python\nfrom writerai import Writer\n\nclient = Writer()\n\nall_graphs = []\n# Automatically fetches more pages as needed.\nfor graph in client.graphs.list():\n # Do something with graph here\n all_graphs.append(graph)\nprint(all_graphs)\n```\n\nOr, asynchronously:\n\n```python\nimport asyncio\nfrom writerai import AsyncWriter\n\nclient = AsyncWriter()\n\nasync def main() -> None:\n all_graphs = []\n # Iterate through items across all pages, issuing requests as needed.\n async for graph in client.graphs.list():\n all_graphs.append(graph)\n print(all_graphs)\n\nasyncio.run(main())\n```\n\nAlternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages:\n\n```python\nfirst_page = await client.graphs.list()\nif first_page.has_next_page():\n print(f"will fetch next page using these details: {first_page.next_page_info()}")\n next_page = await first_page.get_next_page()\n print(f"number of items we just fetched: {len(next_page.data)}")\n\n# Remove `await` for non-async usage.\n```\n\nOr just work directly with the returned data:\n\n```python\nfirst_page = await client.graphs.list()\n\nprint(f"next page cursor: {first_page.after}") # => "next page cursor: ..."\nfor graph in first_page.data:\n print(graph.id)\n\n# Remove `await` for non-async usage.\n```\n\n## Nested params\n\nNested parameters are dictionaries, typed using `TypedDict`, for example:\n\n```python\nfrom writerai import Writer\n\nclient = Writer()\n\nchat_completion = client.chat.chat(\n messages=[{\n "role": "user"\n }],\n model="model",\n response_format={\n "type": "text"\n },\n)\nprint(chat_completion.response_format)\n```\n\n\n\n## Handling errors\n\nWhen the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `writerai.APIConnectionError` is raised.\n\nWhen the API returns a non-success status code (that is, 4xx or 5xx\nresponse), a subclass of `writerai.APIStatusError` is raised, containing `status_code` and `response` properties.\n\nAll errors inherit from `writerai.APIError`.\n\n```python\nimport writerai\nfrom writerai import Writer\n\nclient = Writer()\n\ntry:\n client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n )\nexcept writerai.APIConnectionError as e:\n print("The server could not be reached")\n print(e.__cause__) # an underlying Exception, likely raised within httpx.\nexcept writerai.RateLimitError as e:\n print("A 429 status code was received; we should back off a bit.")\nexcept writerai.APIStatusError as e:\n print("Another non-200-range status code was received")\n print(e.status_code)\n print(e.response)\n```\n\nError codes are as follows:\n\n| Status Code | Error Type |\n| ----------- | -------------------------- |\n| 400 | `BadRequestError` |\n| 401 | `AuthenticationError` |\n| 403 | `PermissionDeniedError` |\n| 404 | `NotFoundError` |\n| 422 | `UnprocessableEntityError` |\n| 429 | `RateLimitError` |\n| >=500 | `InternalServerError` |\n| N/A | `APIConnectionError` |\n\n### Retries\n\nCertain errors are automatically retried 7 times by default, with a short exponential backoff.\nConnection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,\n429 Rate Limit, and >=500 Internal errors are all retried by default.\n\nYou can use the `max_retries` option to configure or disable retry settings:\n\n```python\nfrom writerai import Writer\n\n# Configure the default for all requests:\nclient = Writer(\n # default is 2\n max_retries=0,\n)\n\n# Or, configure per-request:\nclient.with_options(max_retries = 5).chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\n```\n\n### Timeouts\n\nBy default requests time out after 3 minutes. You can configure this with a `timeout` option,\nwhich accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:\n\n```python\nfrom writerai import Writer\n\n# Configure the default for all requests:\nclient = Writer(\n # 20 seconds (default is 3 minutes)\n timeout=20.0,\n)\n\n# More granular control:\nclient = Writer(\n timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),\n)\n\n# Override per-request:\nclient.with_options(timeout = 5.0).chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\n```\n\nOn timeout, an `APITimeoutError` is thrown.\n\nNote that requests that time out are [retried twice by default](#retries).\n\n\n\n## Advanced\n\n### Logging\n\nWe use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module.\n\nYou can enable logging by setting the environment variable `WRITER_LOG` to `info`.\n\n```shell\n$ export WRITER_LOG=info\n```\n\nOr to `debug` for more verbose logging.\n\n### How to tell whether `None` means `null` or missing\n\nIn an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`:\n\n```py\nif response.my_field is None:\n if \'my_field\' not in response.model_fields_set:\n print(\'Got json like {}, without a "my_field" key present at all.\')\n else:\n print(\'Got json like {"my_field": null}.\')\n```\n\n### Accessing raw response data (e.g. headers)\n\nThe "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,\n\n```py\nfrom writerai import Writer\n\nclient = Writer()\nresponse = client.chat.with_raw_response.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\nprint(response.headers.get(\'X-My-Header\'))\n\nchat = response.parse() # get the object that `chat.chat()` would have returned\nprint(chat.id)\n```\n\nThese methods return an [`APIResponse`](https://github.com/writer/writer-python/tree/main/src/writerai/_response.py) object.\n\nThe async client returns an [`AsyncAPIResponse`](https://github.com/writer/writer-python/tree/main/src/writerai/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.\n\n#### `.with_streaming_response`\n\nThe above interface eagerly reads the full response body when you make the request, which may not always be what you want.\n\nTo stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.\n\n```python\nwith client.chat.with_streaming_response.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n) as response :\n print(response.headers.get(\'X-My-Header\'))\n\n for line in response.iter_lines():\n print(line)\n```\n\nThe context manager is required so that the response will reliably be closed.\n\n### Making custom/undocumented requests\n\nThis library is typed for convenient access to the documented API.\n\nIf you need to access undocumented endpoints, params, or response properties, the library can still be used.\n\n#### Undocumented endpoints\n\nTo make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other\nhttp verbs. Options on the client will be respected (such as retries) when making this request.\n\n```py\nimport httpx\n\nresponse = client.post(\n "/foo",\n cast_to=httpx.Response,\n body={"my_param": True},\n)\n\nprint(response.headers.get("x-foo"))\n```\n\n#### Undocumented request params\n\nIf you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` request\noptions.\n\n#### Undocumented response properties\n\nTo access undocumented response properties, you can access the extra fields like `response.unknown_prop`. You\ncan also get all the extra fields on the Pydantic model as a dict with\n[`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra).\n\n### Configuring the HTTP client\n\nYou can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including:\n\n- Support for [proxies](https://www.python-httpx.org/advanced/proxies/)\n- Custom [transports](https://www.python-httpx.org/advanced/transports/)\n- Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality\n\n```python\nimport httpx\nfrom writerai import Writer, DefaultHttpxClient\n\nclient = Writer(\n # Or use the `WRITER_BASE_URL` env var\n base_url="http://my.test.server.example.com:8083",\n http_client=DefaultHttpxClient(proxy="http://my.test.proxy.example.com", transport=httpx.HTTPTransport(local_address="0.0.0.0")),\n)\n```\n\nYou can also customize the client on a per-request basis by using `with_options()`:\n\n```python\nclient.with_options(http_client=DefaultHttpxClient(...))\n```\n\n### Managing HTTP resources\n\nBy default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.\n\n```py\nfrom writerai import Writer\n\nwith Writer() as client:\n # make requests here\n ...\n\n# HTTP client is now closed\n```\n\n## Versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes that only affect static types, without breaking runtime behavior.\n2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n3. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/writer/writer-python/issues) with questions, bugs, or suggestions.\n\n### Determining the installed version\n\nIf you\'ve upgraded to the latest version but aren\'t seeing any new features you were expecting then your python environment is likely still using an older version.\n\nYou can determine the version that is being used at runtime with:\n\n```py\nimport writerai\nprint(writerai.__version__)\n```\n\n## Requirements\n\nPython 3.9 or higher.\n\n## Contributing\n\nSee [the contributing documentation](./CONTRIBUTING.md).\n', + '# Writer Go API Library\n\nGo Reference\n\nThe Writer Go library provides convenient access to the [Writer REST API](https://dev.writer.com/api-guides/introduction)\nfrom applications written in Go.\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\n## MCP Server\n\nUse the Writer MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6Ik15IEFQSSBLZXkifX0)\n[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22writer-sdk-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22writer-sdk-mcp%22%5D%2C%22env%22%3A%7B%22WRITER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)\n\n> Note: You may need to set environment variables in your MCP client.\n\n## Installation\n\n\n\n```go\nimport (\n\t"github.com/stainless-sdks/writer-go" // imported as SDK_PackageName\n)\n```\n\n\n\nOr to pin the version:\n\n\n\n```sh\ngo get -u \'github.com/stainless-sdks/writer-go@v0.0.1\'\n```\n\n\n\n## Requirements\n\nThis library requires Go 1.22+.\n\n## Usage\n\nThe full API of this library can be found in [api.md](api.md).\n\n```go\npackage main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n\t"github.com/stainless-sdks/writer-go/shared"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"), // defaults to os.LookupEnv("WRITER_API_KEY")\n\t)\n\tchatCompletion, err := client.Chat.Chat(context.TODO(), writersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", chatCompletion.ID)\n}\n\n```\n\n### Request fields\n\nAll request parameters are wrapped in a generic `Field` type,\nwhich we use to distinguish zero values from null or omitted fields.\n\nThis prevents accidentally sending a zero value if you forget a required parameter,\nand enables explicitly sending `null`, `false`, `\'\'`, or `0` on optional parameters.\nAny field not specified is not sent.\n\nTo construct fields with values, use the helpers `String()`, `Int()`, `Float()`, or most commonly, the generic `F[T]()`.\nTo send a null, use `Null[T]()`, and to send a nonconforming value, use `Raw[T](any)`. For example:\n\n```go\nparams := FooParams{\n\tName: SDK_PackageName.F("hello"),\n\n\t// Explicitly send `"description": null`\n\tDescription: SDK_PackageName.Null[string](),\n\n\tPoint: SDK_PackageName.F(SDK_PackageName.Point{\n\t\tX: SDK_PackageName.Int(0),\n\t\tY: SDK_PackageName.Int(1),\n\n\t\t// In cases where the API specifies a given type,\n\t\t// but you want to send something else, use `Raw`:\n\t\tZ: SDK_PackageName.Raw[int64](0.01), // sends a float\n\t}),\n}\n```\n\n### Response objects\n\nAll fields in response structs are value types (not pointers or wrappers).\n\nIf a given field is `null`, not present, or invalid, the corresponding field\nwill simply be its zero value.\n\nAll response structs also include a special `JSON` field, containing more detailed\ninformation about each property, which you can use like so:\n\n```go\nif res.Name == "" {\n\t// true if `"name"` is either not present or explicitly null\n\tres.JSON.Name.IsNull()\n\n\t// true if the `"name"` key was not present in the response JSON at all\n\tres.JSON.Name.IsMissing()\n\n\t// When the API returns data that cannot be coerced to the expected type:\n\tif res.JSON.Name.IsInvalid() {\n\t\traw := res.JSON.Name.Raw()\n\n\t\tlegacyName := struct{\n\t\t\tFirst string `json:"first"`\n\t\t\tLast string `json:"last"`\n\t\t}{}\n\t\tjson.Unmarshal([]byte(raw), &legacyName)\n\t\tname = legacyName.First + " " + legacyName.Last\n\t}\n}\n```\n\nThese `.JSON` structs also include an `Extras` map containing\nany properties in the json response that were not specified\nin the struct. This can be useful for API features not yet\npresent in the SDK.\n\n```go\nbody := res.JSON.ExtraFields["my_unexpected_field"].Raw()\n```\n\n### RequestOptions\n\nThis library uses the functional options pattern. Functions defined in the\n`SDK_PackageOptionName` package return a `RequestOption`, which is a closure that mutates a\n`RequestConfig`. These options can be supplied to the client or at individual\nrequests. For example:\n\n```go\nclient := SDK_PackageName.SDK_ClientInitializerName(\n\t// Adds a header to every request made by the client\n\tSDK_PackageOptionName.WithHeader("X-Some-Header", "custom_header_info"),\n)\n\nclient.Chat.Chat(context.TODO(), ...,\n\t// Override the header\n\tSDK_PackageOptionName.WithHeader("X-Some-Header", "some_other_custom_header_info"),\n\t// Add an undocumented field to the request body, using sjson syntax\n\tSDK_PackageOptionName.WithJSONSet("some.json.path", map[string]string{"my": "object"}),\n)\n```\n\nSee the [full list of request options](https://pkg.go.dev/github.com/stainless-sdks/writer-go/SDK_PackageOptionName).\n\n### Pagination\n\nThis library provides some conveniences for working with paginated list endpoints.\n\nYou can use `.ListAutoPaging()` methods to iterate through items across all pages:\n\n```go\niter := client.Graphs.ListAutoPaging(context.TODO(), writersdk.GraphListParams{})\n// Automatically fetches more pages as needed.\nfor iter.Next() {\n\tgraph := iter.Current()\n\tfmt.Printf("%+v\\n", graph)\n}\nif err := iter.Err(); err != nil {\n\tpanic(err.Error())\n}\n```\n\nOr you can use simple `.List()` methods to fetch a single page and receive a standard response object\nwith additional helper methods like `.GetNextPage()`, e.g.:\n\n```go\npage, err := client.Graphs.List(context.TODO(), writersdk.GraphListParams{})\nfor page != nil {\n\tfor _, graph := range page.Data {\n\t\tfmt.Printf("%+v\\n", graph)\n\t}\n\tpage, err = page.GetNextPage()\n}\nif err != nil {\n\tpanic(err.Error())\n}\n```\n\n### Errors\n\nWhen the API returns a non-success status code, we return an error with type\n`*SDK_PackageName.Error`. This contains the `StatusCode`, `*http.Request`, and\n`*http.Response` values of the request, as well as the JSON of the error body\n(much like other response objects in the SDK).\n\nTo handle errors, we recommend that you use the `errors.As` pattern:\n\n```go\n_, err := client.Chat.Chat(context.TODO(), writersdk.ChatChatParams{\n\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t}}),\n\tModel: writersdk.F("palmyra-x5"),\n})\nif err != nil {\n\tvar apierr *writersdk.Error\n\tif errors.As(err, &apierr) {\n\t\tprintln(string(apierr.DumpRequest(true))) // Prints the serialized HTTP request\n\t\tprintln(string(apierr.DumpResponse(true))) // Prints the serialized HTTP response\n\t}\n\tpanic(err.Error()) // GET "/v1/chat": 400 Bad Request { ... }\n}\n```\n\nWhen other errors occur, they are returned unwrapped; for example,\nif HTTP transport fails, you might receive `*url.Error` wrapping `*net.OpError`.\n\n### Timeouts\n\nRequests do not time out by default; use context to configure a timeout for a request lifecycle.\n\nNote that if a request is [retried](#retries), the context timeout does not start over.\nTo set a per-retry timeout, use `SDK_PackageOptionName.WithRequestTimeout()`.\n\n```go\n// This sets the timeout for the request, including all the retries.\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)\ndefer cancel()\nclient.Chat.Chat(\n\tctx,\n\twritersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t},\n\t// This sets the per-retry timeout\n\toption.WithRequestTimeout(20*time.Second),\n)\n```\n\n### File uploads\n\nRequest parameters that correspond to file uploads in multipart requests are typed as\n`param.Field[io.Reader]`. The contents of the `io.Reader` will by default be sent as a multipart form\npart with the file name of "anonymous_file" and content-type of "application/octet-stream".\n\nThe file name and content-type can be customized by implementing `Name() string` or `ContentType()\nstring` on the run-time type of `io.Reader`. Note that `os.File` implements `Name() string`, so a\nfile returned by `os.Open` will be sent with the file name on disk.\n\nWe also provide a helper `SDK_PackageName.FileParam(reader io.Reader, filename string, contentType string)`\nwhich can be used to wrap any `io.Reader` with the appropriate file name and content type.\n\n\n\n### Retries\n\nCertain errors will be automatically retried 7 times by default, with a short exponential backoff.\nWe retry by default all connection errors, 408 Request Timeout, 409 Conflict, 429 Rate Limit,\nand >=500 Internal errors.\n\nYou can use the `WithMaxRetries` option to configure or disable this:\n\n```go\n// Configure the default for all requests:\nclient := writersdk.NewClient(\n\toption.WithMaxRetries(0), // default is 2\n)\n\n// Override per-request:\nclient.Chat.Chat(\n\tcontext.TODO(),\n\twritersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t},\n\toption.WithMaxRetries(5),\n)\n```\n\n\n### Accessing raw response data (e.g. response headers)\n\nYou can access the raw HTTP response data by using the `option.WithResponseInto()` request option. This is useful when\nyou need to examine response headers, status codes, or other details.\n\n```go\n// Create a variable to store the HTTP response\nvar response *http.Response\nchatCompletion, err := client.Chat.Chat(\n\tcontext.TODO(),\n\twritersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t},\n\toption.WithResponseInto(&response),\n)\nif err != nil {\n\t// handle error\n}\nfmt.Printf("%+v\\n", chatCompletion)\n\nfmt.Printf("Status Code: %d\\n", response.StatusCode)\nfmt.Printf("Headers: %+#v\\n", response.Header)\n```\n\n### Making custom/undocumented requests\n\nThis library is typed for convenient access to the documented API. If you need to access undocumented\nendpoints, params, or response properties, the library can still be used.\n\n#### Undocumented endpoints\n\nTo make requests to undocumented endpoints, you can use `client.Get`, `client.Post`, and other HTTP verbs.\n`RequestOptions` on the client, such as retries, will be respected when making these requests.\n\n```go\nvar (\n // params can be an io.Reader, a []byte, an encoding/json serializable object,\n // or a "…Params" struct defined in this library.\n params map[string]interface{}\n\n // result can be an []byte, *http.Response, a encoding/json deserializable object,\n // or a model defined in this library.\n result *http.Response\n)\nerr := client.Post(context.Background(), "/unspecified", params, &result)\nif err != nil {\n …\n}\n```\n\n#### Undocumented request params\n\nTo make requests using undocumented parameters, you may use either the `SDK_PackageOptionName.WithQuerySet()`\nor the `SDK_PackageOptionName.WithJSONSet()` methods.\n\n```go\nparams := FooNewParams{\n ID: SDK_PackageName.F("id_xxxx"),\n Data: SDK_PackageName.F(FooNewParamsData{\n FirstName: SDK_PackageName.F("John"),\n }),\n}\nclient.Foo.New(context.Background(), params, SDK_PackageOptionName.WithJSONSet("data.last_name", "Doe"))\n```\n\n#### Undocumented response properties\n\nTo access undocumented response properties, you may either access the raw JSON of the response as a string\nwith `result.JSON.RawJSON()`, or get the raw JSON of a particular field on the result with\n`result.JSON.Foo.Raw()`.\n\nAny fields that are not present on the response struct will be saved and can be accessed by `result.JSON.ExtraFields()` which returns the extra fields as a `map[string]Field`.\n\n### Middleware\n\nWe provide `SDK_PackageOptionName.WithMiddleware` which applies the given\nmiddleware to requests.\n\n```go\nfunc Logger(req *http.Request, next SDK_PackageOptionName.MiddlewareNext) (res *http.Response, err error) {\n\t// Before the request\n\tstart := time.Now()\n\tLogReq(req)\n\n\t// Forward the request to the next handler\n\tres, err = next(req)\n\n\t// Handle stuff after the request\n\tend := time.Now()\n\tLogRes(res, err, start - end)\n\n return res, err\n}\n\nclient := SDK_PackageName.SDK_ClientInitializerName(\n\tSDK_PackageOptionName.WithMiddleware(Logger),\n)\n```\n\nWhen multiple middlewares are provided as variadic arguments, the middlewares\nare applied left to right. If `SDK_PackageOptionName.WithMiddleware` is given\nmultiple times, for example first in the client then the method, the\nmiddleware in the client will run first and the middleware given in the method\nwill run next.\n\nYou may also replace the default `http.Client` with\n`SDK_PackageOptionName.WithHTTPClient(client)`. Only one http client is\naccepted (this overwrites any previous client) and receives requests after any\nmiddleware has been applied.\n\n## Semantic versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n2. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/writer-go/issues) with questions, bugs, or suggestions.\n\n## Contributing\n\nSee [the contributing documentation](./CONTRIBUTING.md).\n', }, { - language: 'go', + language: 'python', content: - '# Writer Go API Library\n\nGo Reference\n\nThe Writer Go library provides convenient access to the [Writer REST API](https://dev.writer.com/api-guides/introduction)\nfrom applications written in Go.\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\n## MCP Server\n\nUse the Writer MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6Ik15IEFQSSBLZXkifX0)\n[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22writer-sdk-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22writer-sdk-mcp%22%5D%2C%22env%22%3A%7B%22WRITER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)\n\n> Note: You may need to set environment variables in your MCP client.\n\n## Installation\n\n\n\n```go\nimport (\n\t"github.com/stainless-sdks/writer-go" // imported as SDK_PackageName\n)\n```\n\n\n\nOr to pin the version:\n\n\n\n```sh\ngo get -u \'github.com/stainless-sdks/writer-go@v0.0.1\'\n```\n\n\n\n## Requirements\n\nThis library requires Go 1.22+.\n\n## Usage\n\nThe full API of this library can be found in [api.md](api.md).\n\n```go\npackage main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/stainless-sdks/writer-go"\n\t"github.com/stainless-sdks/writer-go/option"\n\t"github.com/stainless-sdks/writer-go/shared"\n)\n\nfunc main() {\n\tclient := writersdk.NewClient(\n\t\toption.WithAPIKey("My API Key"), // defaults to os.LookupEnv("WRITER_API_KEY")\n\t)\n\tchatCompletion, err := client.Chat.Chat(context.TODO(), writersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", chatCompletion.ID)\n}\n\n```\n\n### Request fields\n\nAll request parameters are wrapped in a generic `Field` type,\nwhich we use to distinguish zero values from null or omitted fields.\n\nThis prevents accidentally sending a zero value if you forget a required parameter,\nand enables explicitly sending `null`, `false`, `\'\'`, or `0` on optional parameters.\nAny field not specified is not sent.\n\nTo construct fields with values, use the helpers `String()`, `Int()`, `Float()`, or most commonly, the generic `F[T]()`.\nTo send a null, use `Null[T]()`, and to send a nonconforming value, use `Raw[T](any)`. For example:\n\n```go\nparams := FooParams{\n\tName: SDK_PackageName.F("hello"),\n\n\t// Explicitly send `"description": null`\n\tDescription: SDK_PackageName.Null[string](),\n\n\tPoint: SDK_PackageName.F(SDK_PackageName.Point{\n\t\tX: SDK_PackageName.Int(0),\n\t\tY: SDK_PackageName.Int(1),\n\n\t\t// In cases where the API specifies a given type,\n\t\t// but you want to send something else, use `Raw`:\n\t\tZ: SDK_PackageName.Raw[int64](0.01), // sends a float\n\t}),\n}\n```\n\n### Response objects\n\nAll fields in response structs are value types (not pointers or wrappers).\n\nIf a given field is `null`, not present, or invalid, the corresponding field\nwill simply be its zero value.\n\nAll response structs also include a special `JSON` field, containing more detailed\ninformation about each property, which you can use like so:\n\n```go\nif res.Name == "" {\n\t// true if `"name"` is either not present or explicitly null\n\tres.JSON.Name.IsNull()\n\n\t// true if the `"name"` key was not present in the response JSON at all\n\tres.JSON.Name.IsMissing()\n\n\t// When the API returns data that cannot be coerced to the expected type:\n\tif res.JSON.Name.IsInvalid() {\n\t\traw := res.JSON.Name.Raw()\n\n\t\tlegacyName := struct{\n\t\t\tFirst string `json:"first"`\n\t\t\tLast string `json:"last"`\n\t\t}{}\n\t\tjson.Unmarshal([]byte(raw), &legacyName)\n\t\tname = legacyName.First + " " + legacyName.Last\n\t}\n}\n```\n\nThese `.JSON` structs also include an `Extras` map containing\nany properties in the json response that were not specified\nin the struct. This can be useful for API features not yet\npresent in the SDK.\n\n```go\nbody := res.JSON.ExtraFields["my_unexpected_field"].Raw()\n```\n\n### RequestOptions\n\nThis library uses the functional options pattern. Functions defined in the\n`SDK_PackageOptionName` package return a `RequestOption`, which is a closure that mutates a\n`RequestConfig`. These options can be supplied to the client or at individual\nrequests. For example:\n\n```go\nclient := SDK_PackageName.SDK_ClientInitializerName(\n\t// Adds a header to every request made by the client\n\tSDK_PackageOptionName.WithHeader("X-Some-Header", "custom_header_info"),\n)\n\nclient.Chat.Chat(context.TODO(), ...,\n\t// Override the header\n\tSDK_PackageOptionName.WithHeader("X-Some-Header", "some_other_custom_header_info"),\n\t// Add an undocumented field to the request body, using sjson syntax\n\tSDK_PackageOptionName.WithJSONSet("some.json.path", map[string]string{"my": "object"}),\n)\n```\n\nSee the [full list of request options](https://pkg.go.dev/github.com/stainless-sdks/writer-go/SDK_PackageOptionName).\n\n### Pagination\n\nThis library provides some conveniences for working with paginated list endpoints.\n\nYou can use `.ListAutoPaging()` methods to iterate through items across all pages:\n\n```go\niter := client.Graphs.ListAutoPaging(context.TODO(), writersdk.GraphListParams{})\n// Automatically fetches more pages as needed.\nfor iter.Next() {\n\tgraph := iter.Current()\n\tfmt.Printf("%+v\\n", graph)\n}\nif err := iter.Err(); err != nil {\n\tpanic(err.Error())\n}\n```\n\nOr you can use simple `.List()` methods to fetch a single page and receive a standard response object\nwith additional helper methods like `.GetNextPage()`, e.g.:\n\n```go\npage, err := client.Graphs.List(context.TODO(), writersdk.GraphListParams{})\nfor page != nil {\n\tfor _, graph := range page.Data {\n\t\tfmt.Printf("%+v\\n", graph)\n\t}\n\tpage, err = page.GetNextPage()\n}\nif err != nil {\n\tpanic(err.Error())\n}\n```\n\n### Errors\n\nWhen the API returns a non-success status code, we return an error with type\n`*SDK_PackageName.Error`. This contains the `StatusCode`, `*http.Request`, and\n`*http.Response` values of the request, as well as the JSON of the error body\n(much like other response objects in the SDK).\n\nTo handle errors, we recommend that you use the `errors.As` pattern:\n\n```go\n_, err := client.Chat.Chat(context.TODO(), writersdk.ChatChatParams{\n\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t}}),\n\tModel: writersdk.F("palmyra-x5"),\n})\nif err != nil {\n\tvar apierr *writersdk.Error\n\tif errors.As(err, &apierr) {\n\t\tprintln(string(apierr.DumpRequest(true))) // Prints the serialized HTTP request\n\t\tprintln(string(apierr.DumpResponse(true))) // Prints the serialized HTTP response\n\t}\n\tpanic(err.Error()) // GET "/v1/chat": 400 Bad Request { ... }\n}\n```\n\nWhen other errors occur, they are returned unwrapped; for example,\nif HTTP transport fails, you might receive `*url.Error` wrapping `*net.OpError`.\n\n### Timeouts\n\nRequests do not time out by default; use context to configure a timeout for a request lifecycle.\n\nNote that if a request is [retried](#retries), the context timeout does not start over.\nTo set a per-retry timeout, use `SDK_PackageOptionName.WithRequestTimeout()`.\n\n```go\n// This sets the timeout for the request, including all the retries.\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)\ndefer cancel()\nclient.Chat.Chat(\n\tctx,\n\twritersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t},\n\t// This sets the per-retry timeout\n\toption.WithRequestTimeout(20*time.Second),\n)\n```\n\n### File uploads\n\nRequest parameters that correspond to file uploads in multipart requests are typed as\n`param.Field[io.Reader]`. The contents of the `io.Reader` will by default be sent as a multipart form\npart with the file name of "anonymous_file" and content-type of "application/octet-stream".\n\nThe file name and content-type can be customized by implementing `Name() string` or `ContentType()\nstring` on the run-time type of `io.Reader`. Note that `os.File` implements `Name() string`, so a\nfile returned by `os.Open` will be sent with the file name on disk.\n\nWe also provide a helper `SDK_PackageName.FileParam(reader io.Reader, filename string, contentType string)`\nwhich can be used to wrap any `io.Reader` with the appropriate file name and content type.\n\n\n\n### Retries\n\nCertain errors will be automatically retried 7 times by default, with a short exponential backoff.\nWe retry by default all connection errors, 408 Request Timeout, 409 Conflict, 429 Rate Limit,\nand >=500 Internal errors.\n\nYou can use the `WithMaxRetries` option to configure or disable this:\n\n```go\n// Configure the default for all requests:\nclient := writersdk.NewClient(\n\toption.WithMaxRetries(0), // default is 2\n)\n\n// Override per-request:\nclient.Chat.Chat(\n\tcontext.TODO(),\n\twritersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t},\n\toption.WithMaxRetries(5),\n)\n```\n\n\n### Accessing raw response data (e.g. response headers)\n\nYou can access the raw HTTP response data by using the `option.WithResponseInto()` request option. This is useful when\nyou need to examine response headers, status codes, or other details.\n\n```go\n// Create a variable to store the HTTP response\nvar response *http.Response\nchatCompletion, err := client.Chat.Chat(\n\tcontext.TODO(),\n\twritersdk.ChatChatParams{\n\t\tMessages: writersdk.F([]writersdk.ChatChatParamsMessage{{\n\t\t\tContent: writersdk.F[writersdk.ChatChatParamsMessagesContentUnion](shared.UnionString("Write a haiku about programming")),\n\t\t\tRole: writersdk.F(writersdk.ChatChatParamsMessagesRoleUser),\n\t\t}}),\n\t\tModel: writersdk.F("palmyra-x5"),\n\t},\n\toption.WithResponseInto(&response),\n)\nif err != nil {\n\t// handle error\n}\nfmt.Printf("%+v\\n", chatCompletion)\n\nfmt.Printf("Status Code: %d\\n", response.StatusCode)\nfmt.Printf("Headers: %+#v\\n", response.Header)\n```\n\n### Making custom/undocumented requests\n\nThis library is typed for convenient access to the documented API. If you need to access undocumented\nendpoints, params, or response properties, the library can still be used.\n\n#### Undocumented endpoints\n\nTo make requests to undocumented endpoints, you can use `client.Get`, `client.Post`, and other HTTP verbs.\n`RequestOptions` on the client, such as retries, will be respected when making these requests.\n\n```go\nvar (\n // params can be an io.Reader, a []byte, an encoding/json serializable object,\n // or a "…Params" struct defined in this library.\n params map[string]interface{}\n\n // result can be an []byte, *http.Response, a encoding/json deserializable object,\n // or a model defined in this library.\n result *http.Response\n)\nerr := client.Post(context.Background(), "/unspecified", params, &result)\nif err != nil {\n …\n}\n```\n\n#### Undocumented request params\n\nTo make requests using undocumented parameters, you may use either the `SDK_PackageOptionName.WithQuerySet()`\nor the `SDK_PackageOptionName.WithJSONSet()` methods.\n\n```go\nparams := FooNewParams{\n ID: SDK_PackageName.F("id_xxxx"),\n Data: SDK_PackageName.F(FooNewParamsData{\n FirstName: SDK_PackageName.F("John"),\n }),\n}\nclient.Foo.New(context.Background(), params, SDK_PackageOptionName.WithJSONSet("data.last_name", "Doe"))\n```\n\n#### Undocumented response properties\n\nTo access undocumented response properties, you may either access the raw JSON of the response as a string\nwith `result.JSON.RawJSON()`, or get the raw JSON of a particular field on the result with\n`result.JSON.Foo.Raw()`.\n\nAny fields that are not present on the response struct will be saved and can be accessed by `result.JSON.ExtraFields()` which returns the extra fields as a `map[string]Field`.\n\n### Middleware\n\nWe provide `SDK_PackageOptionName.WithMiddleware` which applies the given\nmiddleware to requests.\n\n```go\nfunc Logger(req *http.Request, next SDK_PackageOptionName.MiddlewareNext) (res *http.Response, err error) {\n\t// Before the request\n\tstart := time.Now()\n\tLogReq(req)\n\n\t// Forward the request to the next handler\n\tres, err = next(req)\n\n\t// Handle stuff after the request\n\tend := time.Now()\n\tLogRes(res, err, start - end)\n\n return res, err\n}\n\nclient := SDK_PackageName.SDK_ClientInitializerName(\n\tSDK_PackageOptionName.WithMiddleware(Logger),\n)\n```\n\nWhen multiple middlewares are provided as variadic arguments, the middlewares\nare applied left to right. If `SDK_PackageOptionName.WithMiddleware` is given\nmultiple times, for example first in the client then the method, the\nmiddleware in the client will run first and the middleware given in the method\nwill run next.\n\nYou may also replace the default `http.Client` with\n`SDK_PackageOptionName.WithHTTPClient(client)`. Only one http client is\naccepted (this overwrites any previous client) and receives requests after any\nmiddleware has been applied.\n\n## Semantic versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n2. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/writer-go/issues) with questions, bugs, or suggestions.\n\n## Contributing\n\nSee [the contributing documentation](./CONTRIBUTING.md).\n', + '# Writer Python API library\n\n\n[![PyPI version](https://img.shields.io/pypi/v/writer-sdk.svg?label=pypi%20(stable))](https://pypi.org/project/writer-sdk/)\n\nThe Writer Python library provides convenient access to the Writer REST API from any Python 3.9+\napplication. The library includes type definitions for all request params and response fields,\nand offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).\n\n\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\n## MCP Server\n\nUse the Writer MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6Ik15IEFQSSBLZXkifX0)\n[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22writer-sdk-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22writer-sdk-mcp%22%5D%2C%22env%22%3A%7B%22WRITER_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)\n\n> Note: You may need to set environment variables in your MCP client.\n\n## Documentation\n\nThe REST API documentation can be found on [dev.writer.com](https://dev.writer.com/api-guides/introduction). The full API of this library can be found in [api.md](api.md).\n\n## Installation\n\n```sh\n# install from PyPI\npip install writer-sdk\n```\n\n## Usage\n\nThe full API of this library can be found in [api.md](api.md).\n\n```python\nimport os\nfrom writerai import Writer\n\nclient = Writer(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\n\nchat_completion = client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\nprint(chat_completion.id)\n```\n\nWhile you can provide an `api_key` keyword argument,\nwe recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)\nto add `WRITER_API_KEY="My API Key"` to your `.env` file\nso that your API Key is not stored in source control.\n\n## Async usage\n\nSimply import `AsyncWriter` instead of `Writer` and use `await` with each API call:\n\n```python\nimport os\nimport asyncio\nfrom writerai import AsyncWriter\n\nclient = AsyncWriter(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n)\n\nasync def main() -> None:\n chat_completion = await client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n )\n print(chat_completion.id)\n\nasyncio.run(main())\n```\n\nFunctionality between the synchronous and asynchronous clients is otherwise identical.\n\n### With aiohttp\n\nBy default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.\n\nYou can enable this by installing `aiohttp`:\n\n```sh\n# install from PyPI\npip install writer-sdk[aiohttp]\n```\n\nThen you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:\n\n```python\nimport os\nimport asyncio\nfrom writerai import DefaultAioHttpClient\nfrom writerai import AsyncWriter\n\nasync def main() -> None:\n async with AsyncWriter(\n api_key=os.environ.get("WRITER_API_KEY"), # This is the default and can be omitted\n http_client=DefaultAioHttpClient(),\n) as client:\n chat_completion = await client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n )\n print(chat_completion.id)\n\nasyncio.run(main())\n```\n\n## Streaming responses\n\nWe provide support for streaming responses using Server Side Events (SSE).\n\n```python\nfrom writerai import Writer\n\nclient = Writer()\n\nstream = client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n stream=True,\n)\nfor chat_completion in stream:\n print(chat_completion.id)\n```\n\nThe async client uses the exact same interface.\n\n```python\nfrom writerai import AsyncWriter\n\nclient = AsyncWriter()\n\nstream = await client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n stream=True,\n)\nasync for chat_completion in stream:\n print(chat_completion.id)\n```\n\n## Using types\n\nNested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:\n\n- Serializing back into JSON, `model.to_json()`\n- Converting to a dictionary, `model.to_dict()`\n\nTyped requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`.\n\n## Pagination\n\nList methods in the Writer API are paginated.\n\nThis library provides auto-paginating iterators with each list response, so you do not have to request successive pages manually:\n\n```python\nfrom writerai import Writer\n\nclient = Writer()\n\nall_graphs = []\n# Automatically fetches more pages as needed.\nfor graph in client.graphs.list():\n # Do something with graph here\n all_graphs.append(graph)\nprint(all_graphs)\n```\n\nOr, asynchronously:\n\n```python\nimport asyncio\nfrom writerai import AsyncWriter\n\nclient = AsyncWriter()\n\nasync def main() -> None:\n all_graphs = []\n # Iterate through items across all pages, issuing requests as needed.\n async for graph in client.graphs.list():\n all_graphs.append(graph)\n print(all_graphs)\n\nasyncio.run(main())\n```\n\nAlternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages:\n\n```python\nfirst_page = await client.graphs.list()\nif first_page.has_next_page():\n print(f"will fetch next page using these details: {first_page.next_page_info()}")\n next_page = await first_page.get_next_page()\n print(f"number of items we just fetched: {len(next_page.data)}")\n\n# Remove `await` for non-async usage.\n```\n\nOr just work directly with the returned data:\n\n```python\nfirst_page = await client.graphs.list()\n\nprint(f"next page cursor: {first_page.after}") # => "next page cursor: ..."\nfor graph in first_page.data:\n print(graph.id)\n\n# Remove `await` for non-async usage.\n```\n\n## Nested params\n\nNested parameters are dictionaries, typed using `TypedDict`, for example:\n\n```python\nfrom writerai import Writer\n\nclient = Writer()\n\nchat_completion = client.chat.chat(\n messages=[{\n "role": "user"\n }],\n model="model",\n response_format={\n "type": "text"\n },\n)\nprint(chat_completion.response_format)\n```\n\n\n\n## Handling errors\n\nWhen the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `writerai.APIConnectionError` is raised.\n\nWhen the API returns a non-success status code (that is, 4xx or 5xx\nresponse), a subclass of `writerai.APIStatusError` is raised, containing `status_code` and `response` properties.\n\nAll errors inherit from `writerai.APIError`.\n\n```python\nimport writerai\nfrom writerai import Writer\n\nclient = Writer()\n\ntry:\n client.chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n )\nexcept writerai.APIConnectionError as e:\n print("The server could not be reached")\n print(e.__cause__) # an underlying Exception, likely raised within httpx.\nexcept writerai.RateLimitError as e:\n print("A 429 status code was received; we should back off a bit.")\nexcept writerai.APIStatusError as e:\n print("Another non-200-range status code was received")\n print(e.status_code)\n print(e.response)\n```\n\nError codes are as follows:\n\n| Status Code | Error Type |\n| ----------- | -------------------------- |\n| 400 | `BadRequestError` |\n| 401 | `AuthenticationError` |\n| 403 | `PermissionDeniedError` |\n| 404 | `NotFoundError` |\n| 422 | `UnprocessableEntityError` |\n| 429 | `RateLimitError` |\n| >=500 | `InternalServerError` |\n| N/A | `APIConnectionError` |\n\n### Retries\n\nCertain errors are automatically retried 7 times by default, with a short exponential backoff.\nConnection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,\n429 Rate Limit, and >=500 Internal errors are all retried by default.\n\nYou can use the `max_retries` option to configure or disable retry settings:\n\n```python\nfrom writerai import Writer\n\n# Configure the default for all requests:\nclient = Writer(\n # default is 2\n max_retries=0,\n)\n\n# Or, configure per-request:\nclient.with_options(max_retries = 5).chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\n```\n\n### Timeouts\n\nBy default requests time out after 3 minutes. You can configure this with a `timeout` option,\nwhich accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:\n\n```python\nfrom writerai import Writer\n\n# Configure the default for all requests:\nclient = Writer(\n # 20 seconds (default is 3 minutes)\n timeout=20.0,\n)\n\n# More granular control:\nclient = Writer(\n timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),\n)\n\n# Override per-request:\nclient.with_options(timeout = 5.0).chat.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\n```\n\nOn timeout, an `APITimeoutError` is thrown.\n\nNote that requests that time out are [retried twice by default](#retries).\n\n\n\n## Advanced\n\n### Logging\n\nWe use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module.\n\nYou can enable logging by setting the environment variable `WRITER_LOG` to `info`.\n\n```shell\n$ export WRITER_LOG=info\n```\n\nOr to `debug` for more verbose logging.\n\n### How to tell whether `None` means `null` or missing\n\nIn an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`:\n\n```py\nif response.my_field is None:\n if \'my_field\' not in response.model_fields_set:\n print(\'Got json like {}, without a "my_field" key present at all.\')\n else:\n print(\'Got json like {"my_field": null}.\')\n```\n\n### Accessing raw response data (e.g. headers)\n\nThe "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,\n\n```py\nfrom writerai import Writer\n\nclient = Writer()\nresponse = client.chat.with_raw_response.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n)\nprint(response.headers.get(\'X-My-Header\'))\n\nchat = response.parse() # get the object that `chat.chat()` would have returned\nprint(chat.id)\n```\n\nThese methods return an [`APIResponse`](https://github.com/writer/writer-python/tree/main/src/writerai/_response.py) object.\n\nThe async client returns an [`AsyncAPIResponse`](https://github.com/writer/writer-python/tree/main/src/writerai/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.\n\n#### `.with_streaming_response`\n\nThe above interface eagerly reads the full response body when you make the request, which may not always be what you want.\n\nTo stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.\n\n```python\nwith client.chat.with_streaming_response.chat(\n messages=[{\n "content": "Write a haiku about programming",\n "role": "user",\n }],\n model="palmyra-x5",\n) as response :\n print(response.headers.get(\'X-My-Header\'))\n\n for line in response.iter_lines():\n print(line)\n```\n\nThe context manager is required so that the response will reliably be closed.\n\n### Making custom/undocumented requests\n\nThis library is typed for convenient access to the documented API.\n\nIf you need to access undocumented endpoints, params, or response properties, the library can still be used.\n\n#### Undocumented endpoints\n\nTo make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other\nhttp verbs. Options on the client will be respected (such as retries) when making this request.\n\n```py\nimport httpx\n\nresponse = client.post(\n "/foo",\n cast_to=httpx.Response,\n body={"my_param": True},\n)\n\nprint(response.headers.get("x-foo"))\n```\n\n#### Undocumented request params\n\nIf you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` request\noptions.\n\n#### Undocumented response properties\n\nTo access undocumented response properties, you can access the extra fields like `response.unknown_prop`. You\ncan also get all the extra fields on the Pydantic model as a dict with\n[`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra).\n\n### Configuring the HTTP client\n\nYou can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including:\n\n- Support for [proxies](https://www.python-httpx.org/advanced/proxies/)\n- Custom [transports](https://www.python-httpx.org/advanced/transports/)\n- Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality\n\n```python\nimport httpx\nfrom writerai import Writer, DefaultHttpxClient\n\nclient = Writer(\n # Or use the `WRITER_BASE_URL` env var\n base_url="http://my.test.server.example.com:8083",\n http_client=DefaultHttpxClient(proxy="http://my.test.proxy.example.com", transport=httpx.HTTPTransport(local_address="0.0.0.0")),\n)\n```\n\nYou can also customize the client on a per-request basis by using `with_options()`:\n\n```python\nclient.with_options(http_client=DefaultHttpxClient(...))\n```\n\n### Managing HTTP resources\n\nBy default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.\n\n```py\nfrom writerai import Writer\n\nwith Writer() as client:\n # make requests here\n ...\n\n# HTTP client is now closed\n```\n\n## Versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes that only affect static types, without breaking runtime behavior.\n2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n3. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/writer/writer-python/issues) with questions, bugs, or suggestions.\n\n### Determining the installed version\n\nIf you\'ve upgraded to the latest version but aren\'t seeing any new features you were expecting then your python environment is likely still using an older version.\n\nYou can determine the version that is being used at runtime with:\n\n```py\nimport writerai\nprint(writerai.__version__)\n```\n\n## Requirements\n\nPython 3.9 or higher.\n\n## Contributing\n\nSee [the contributing documentation](./CONTRIBUTING.md).\n', }, { language: 'typescript', diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index f6b107b8..c57801b0 100644 --- a/packages/mcp-server/src/server.ts +++ b/packages/mcp-server/src/server.ts @@ -28,7 +28,7 @@ export const newMcpServer = async ({ new McpServer( { name: 'writer_sdk_api', - version: '3.0.0-rc.1', + version: '3.0.0', }, { instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }), diff --git a/packages/mcp-server/yarn.lock b/packages/mcp-server/yarn.lock index c7e37692..05aa4e17 100644 --- a/packages/mcp-server/yarn.lock +++ b/packages/mcp-server/yarn.lock @@ -3085,6 +3085,11 @@ minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minisearch@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-7.2.0.tgz#3dc30e41e9464b3836553b6d969b656614f8f359" + integrity sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg== + mkdirp@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" @@ -3921,9 +3926,9 @@ ts-node@^10.5.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz": - version "1.1.9" - resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz#777f6f5d9e26bf0e94e5170990dd3a841d6707cd" +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz": + version "1.1.11" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz#010247051be13b55abdc98f787c017285149f4f2" dependencies: debug "^4.3.7" fast-glob "^3.3.2" @@ -4105,6 +4110,10 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" +"writer-sdk@link:../../dist": + version "0.0.0" + uid "" + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" diff --git a/scripts/bootstrap b/scripts/bootstrap index a8b69ff3..2e315f53 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then brew bundle check >/dev/null 2>&1 || { echo -n "==> Install Homebrew dependencies? (y/N): " read -r response diff --git a/scripts/build b/scripts/build index 30e0f598..8a4cfd0e 100755 --- a/scripts/build +++ b/scripts/build @@ -52,6 +52,6 @@ fi # build all sub-packages for dir in packages/*; do if [ -d "$dir" ]; then - (cd "$dir" && yarn install && yarn build) + (cd "$dir" && yarn install --pure-lockfile && yarn build) fi done diff --git a/scripts/fast-format b/scripts/fast-format index 53721ac0..0cd6b02d 100755 --- a/scripts/fast-format +++ b/scripts/fast-format @@ -31,10 +31,7 @@ if ! [ -z "$ESLINT_FILES" ]; then fi echo "==> Running prettier --write" -# format things eslint didn't -PRETTIER_FILES="$(grep '\.\(js\|json\)$' "$FILE_LIST" || true)" -if ! [ -z "$PRETTIER_FILES" ]; then - echo "$PRETTIER_FILES" | xargs ./node_modules/.bin/prettier \ - --write --cache --cache-strategy metadata --no-error-on-unmatched-pattern \ - '!**/dist' '!**/*.ts' '!**/*.mts' '!**/*.cts' '!**/*.js' '!**/*.mjs' '!**/*.cjs' +if ! [ -z "$FILE_LIST" ]; then + cat "$FILE_LIST" | xargs ./node_modules/prettier/bin/prettier.cjs \ + --write --cache --cache-strategy metadata --no-error-on-unmatched-pattern --ignore-unknown fi diff --git a/scripts/format b/scripts/format index 7a756401..e14103f9 100755 --- a/scripts/format +++ b/scripts/format @@ -8,5 +8,4 @@ echo "==> Running eslint --fix" ./node_modules/.bin/eslint --fix . echo "==> Running prettier --write" -# format things eslint didn't -./node_modules/.bin/prettier --write --cache --cache-strategy metadata . '!**/dist' '!**/*.ts' '!**/*.mts' '!**/*.cts' '!**/*.js' '!**/*.mjs' '!**/*.cjs' +./node_modules/prettier/bin/prettier.cjs --write --cache --cache-strategy metadata . diff --git a/scripts/lint b/scripts/lint index 3ffb78a6..45aeb536 100755 --- a/scripts/lint +++ b/scripts/lint @@ -4,6 +4,9 @@ set -e cd "$(dirname "$0")/.." +echo "==> Running prettier --check" +./node_modules/prettier/bin/prettier.cjs --check . + echo "==> Running eslint" ./node_modules/.bin/eslint . diff --git a/scripts/mock b/scripts/mock index 5cd7c157..feebe5ed 100755 --- a/scripts/mock +++ b/scripts/mock @@ -22,9 +22,9 @@ echo "==> Starting mock server with URL ${URL}" # Run steady mock on the given spec if [ "$1" == "--daemon" ]; then # Pre-install the package so the download doesn't eat into the startup timeout - npm exec --package=@stdy/cli@0.20.2 -- steady --version + npm exec --package=@stdy/cli@0.22.1 -- steady --version - npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & # Wait for server to come online via health endpoint (max 30s) echo -n "Waiting for server" @@ -48,5 +48,5 @@ if [ "$1" == "--daemon" ]; then echo else - npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" fi diff --git a/scripts/test b/scripts/test index a9d718cf..19b8d0c7 100755 --- a/scripts/test +++ b/scripts/test @@ -43,7 +43,7 @@ elif ! steady_is_running ; then echo -e "To run the server, pass in the path or url of your OpenAPI" echo -e "spec to the steady command:" echo - echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.20.2 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" + echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" echo exit 1 diff --git a/scripts/utils/postprocess-files.cjs b/scripts/utils/postprocess-files.cjs index deae575e..a8cdeb7c 100644 --- a/scripts/utils/postprocess-files.cjs +++ b/scripts/utils/postprocess-files.cjs @@ -23,12 +23,19 @@ async function postprocess() { // strip out lib="dom", types="node", and types="react" references; these // are needed at build time, but would pollute the user's TS environment - const transformed = code.replace( + let transformed = code.replace( /^ *\/\/\/ * ' '.repeat(match.length - 1) + '\n', ); + // TypeScript's declaration emitter collapses /** @ts-ignore */ onto the same + // line as the type declaration, which doesn't work. So we convert to // @ts-ignore + // on its own line to properly suppresses errors. + if (file.endsWith('.d.ts') || file.endsWith('.d.mts') || file.endsWith('.d.cts')) { + transformed = transformed.replace(/\/\*\* @ts-ignore\b[^*]*\*\/ /gm, '// @ts-ignore\n'); + } + if (transformed !== code) { console.error(`wrote ${path.relative(process.cwd(), file)}`); await fs.promises.writeFile(file, transformed, 'utf8'); diff --git a/src/client.ts b/src/client.ts index d43b78e2..eb4689c9 100644 --- a/src/client.ts +++ b/src/client.ts @@ -252,6 +252,18 @@ export class Writer { this.fetch = options.fetch ?? Shims.getDefaultFetch(); this.#encoder = Opts.FallbackEncoder; + const customHeadersEnv = readEnv('WRITER_CUSTOM_HEADERS'); + if (customHeadersEnv) { + const parsed: Record = {}; + for (const line of customHeadersEnv.split('\n')) { + const colon = line.indexOf(':'); + if (colon >= 0) { + parsed[line.substring(0, colon).trim()] = line.substring(colon + 1).trim(); + } + } + options.defaultHeaders = { ...parsed, ...options.defaultHeaders }; + } + this._options = options; this.apiKey = apiKey; diff --git a/src/internal/types.ts b/src/internal/types.ts index b668dfc0..a050513a 100644 --- a/src/internal/types.ts +++ b/src/internal/types.ts @@ -40,7 +40,6 @@ type OverloadedParameters = : T extends (...args: infer A) => unknown ? A : never; -/* eslint-disable */ /** * These imports attempt to get types from a parent package's dependencies. * Unresolved bare specifiers can trigger [automatic type acquisition][1] in some projects, which @@ -63,19 +62,18 @@ type OverloadedParameters = * * [1]: https://www.typescriptlang.org/tsconfig/#typeAcquisition */ -/** @ts-ignore For users with \@types/node */ +/** @ts-ignore For users with \@types/node */ /* prettier-ignore */ type UndiciTypesRequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users with undici */ +/** @ts-ignore For users with undici */ /* prettier-ignore */ type UndiciRequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users with \@types/bun */ +/** @ts-ignore For users with \@types/bun */ /* prettier-ignore */ type BunRequestInit = globalThis.FetchRequestInit; -/** @ts-ignore For users with node-fetch@2 */ +/** @ts-ignore For users with node-fetch@2 */ /* prettier-ignore */ type NodeFetch2RequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users with node-fetch@3, doesn't need file extension because types are at ./@types/index.d.ts */ +/** @ts-ignore For users with node-fetch@3, doesn't need file extension because types are at ./@types/index.d.ts */ /* prettier-ignore */ type NodeFetch3RequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users who use Deno */ +/** @ts-ignore For users who use Deno */ /* prettier-ignore */ type FetchRequestInit = NonNullable[1]>; -/* eslint-enable */ type RequestInits = | NotAny diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts index b6662952..e611b194 100644 --- a/src/internal/utils/log.ts +++ b/src/internal/utils/log.ts @@ -107,6 +107,8 @@ export const formatRequestDetails = (details: { name, ( name.toLowerCase() === 'authorization' || + name.toLowerCase() === 'api-key' || + name.toLowerCase() === 'x-api-key' || name.toLowerCase() === 'cookie' || name.toLowerCase() === 'set-cookie' ) ? diff --git a/src/resources/files.ts b/src/resources/files.ts index 4c2a2690..2fc92196 100644 --- a/src/resources/files.ts +++ b/src/resources/files.ts @@ -4,6 +4,7 @@ import { APIResource } from '../core/resource'; import { APIPromise } from '../core/api-promise'; import { CursorPage, type CursorPageParams, PagePromise } from '../core/pagination'; import { type Uploadable } from '../core/uploads'; +import type { Response } from '../internal/builtin-types'; import { buildHeaders } from '../internal/headers'; import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; @@ -59,22 +60,16 @@ export class Files extends APIResource { * Upload a new file to the system. Supports various file formats including PDF, * DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, and XLSX. */ - upload(params: FileUploadParams, options?: RequestOptions): APIPromise { - const { - content, - 'Content-Disposition': contentDisposition, - 'Content-Type': contentType, - graphId, - } = params; + upload(content: Uploadable, params: FileUploadParams, options?: RequestOptions): APIPromise { + const { 'Content-Disposition': contentDisposition, 'Content-Type': contentType, graphId } = params; return this._client.post('/v1/files', { - query: { graphId }, body: content, + query: { graphId }, ...options, - headers: { - 'Content-Type': contentType, - 'Content-Disposition': contentDisposition, - ...options?.headers, - }, + headers: buildHeaders([ + { 'Content-Type': contentType, 'Content-Disposition': contentDisposition }, + options?.headers, + ]), }); } } @@ -171,11 +166,6 @@ export interface FileRetryParams { } export interface FileUploadParams { - /** - * Body param - */ - content: Uploadable; - /** * Header param: The disposition type of the file, typically used to indicate the * form-data name. Use `attachment` with the filename parameter to specify the name diff --git a/src/version.ts b/src/version.ts index 1e17ebcc..bccd5c23 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '3.0.0-rc.1'; // x-release-please-version +export const VERSION = '3.0.0'; // x-release-please-version diff --git a/tests/api-resources/files.test.ts b/tests/api-resources/files.test.ts index 895c0ee6..899bd855 100644 --- a/tests/api-resources/files.test.ts +++ b/tests/api-resources/files.test.ts @@ -76,8 +76,7 @@ describe('resource files', () => { // requests with binary data not yet supported in test environment test.skip('upload: only required params', async () => { - const responsePromise = client.files.upload({ - content: await toFile(Buffer.from('Example data'), 'README.md'), + const responsePromise = client.files.upload(await toFile(Buffer.from('Example data'), 'README.md'), { 'Content-Disposition': 'Content-Disposition', 'Content-Type': 'Content-Type', }); @@ -92,8 +91,7 @@ describe('resource files', () => { // requests with binary data not yet supported in test environment test.skip('upload: required and optional params', async () => { - const response = await client.files.upload({ - content: await toFile(Buffer.from('Example data'), 'README.md'), + const response = await client.files.upload(await toFile(Buffer.from('Example data'), 'README.md'), { 'Content-Disposition': 'Content-Disposition', 'Content-Type': 'Content-Type', graphId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 33cd87e2..cab4aaef 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,7 +1,6 @@ import fs from 'fs'; import type { ResponseLike } from 'writer-sdk/internal/to-file'; import { toFile } from 'writer-sdk/core/uploads'; -import { File } from 'node:buffer'; class MyClass { name: string = 'foo'; diff --git a/yarn.lock b/yarn.lock index 894a1b79..64b3a996 100644 --- a/yarn.lock +++ b/yarn.lock @@ -709,11 +709,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@pkgr/core@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.4.tgz#d897170a2b0ba51f78a099edccd968f7b103387c" - integrity sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw== - "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" @@ -1220,9 +1215,9 @@ baseline-browser-mapping@^2.9.0: integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== brace-expansion@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.0.tgz#4f41a41190216ee36067ec381526fe9539c4f0ae" - integrity sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w== + version "2.1.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.1.tgz#c68b1c4111c76aae3a6fba55d496cee10c39dad8" + integrity sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA== dependencies: balanced-match "^1.0.0" @@ -1515,14 +1510,6 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-plugin-prettier@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.1.tgz#99b55d7dd70047886b2222fdd853665f180b36af" - integrity sha512-9dF+KuU/Ilkq27A8idRP7N2DH8iUR6qXcjF3FR2wETY21PZdBrIjwCau8oboyGj9b7etWmTGEeM8e7oOed6ZWg== - dependencies: - prettier-linter-helpers "^1.0.0" - synckit "^0.11.7" - eslint-plugin-unused-imports@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz#62ddc7446ccbf9aa7b6f1f0b00a980423cda2738" @@ -1681,11 +1668,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" @@ -2853,13 +2835,6 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - prettier@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.1.tgz#6ba9f23165d690b6cbdaa88cb0807278f7019848" @@ -3161,13 +3136,6 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -synckit@^0.11.7: - version "0.11.8" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.8.tgz#b2aaae998a4ef47ded60773ad06e7cb821f55457" - integrity sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A== - dependencies: - "@pkgr/core" "^0.2.4" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -3241,9 +3209,9 @@ ts-node@^10.5.0: v8-compile-cache-lib "^3.0.0" yn "3.1.1" -"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz": - version "1.1.9" - resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz#777f6f5d9e26bf0e94e5170990dd3a841d6707cd" +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz": + version "1.1.11" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz#010247051be13b55abdc98f787c017285149f4f2" dependencies: debug "^4.3.7" fast-glob "^3.3.2" @@ -3311,10 +3279,10 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici-types@~6.21.0: - version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" - integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== unicode-emoji-modifier-base@^1.0.0: version "1.0.0"