> ## Documentation Index
> Fetch the complete documentation index at: https://growthx-changeset-release-main.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# v0.15.0 → v0.16.0

> Upgrading Output.ai projects from v0.15.0 to v0.16.0: @outputai/http is folded into @outputai/core, ky and undici become peer dependencies, sendHttpRequest() parses more response bodies as text, and the worker drops its workflow concurrency defaults.

This guide covers the move of `@outputai/http` into `@outputai/core`. The package is no longer published: its API now lives at `@outputai/core/http`, with the same exports and behavior.

Two smaller breaks come with it: `ky` and `undici` are now peer dependencies of `@outputai/core`, and `sendHttpRequest()` parses some response bodies differently.

Separately, the worker no longer sets defaults for two workflow concurrency variables, and one telemetry field is renamed. See [Worker defaults and telemetry](#worker-defaults-and-telemetry).

## What changed

* `@outputai/http` is replaced by the `@outputai/core/http` subpath. `outputFetch`, `createKyClient`, `addRequestCost`, and the `ky` and `undici` re-exports are unchanged.
* `@outputai/output` no longer depends on `@outputai/http`.
* `ky` (`>=2 <3`) and `undici` (`>=8 <9`) are peer dependencies of `@outputai/core`.
* `Tracing.Attribute.HTTPRequestCount` and `Tracing.Attribute.HTTPRequestCost` moved from `@outputai/core/sdk/runtime` to `@outputai/core/http` as `HTTPRequestCount` and `HTTPRequestCost`. The `http:request:count` and `http:request:cost` trace attributes are unchanged.
* `sendHttpRequest()` returns XML, form-urlencoded, and JavaScript response bodies as text instead of base64, and returns empty or invalid JSON bodies as raw text instead of throwing.
* With `OUTPUT_TRACE_HTTP_VERBOSE` on, HTTP request and response bodies in trace files are parsed the same way as `sendHttpRequest()`. Multipart bodies are stored as base64.

## Migration steps

### Update imports

Replace every import of `@outputai/http` with `@outputai/core/http`, including module mocks in tests:

```ts theme={null}
// Before
import { createKyClient, addRequestCost } from '@outputai/http';
vi.mock( '@outputai/http', () => ( { outputFetch: vi.fn() } ) );

// After
import { createKyClient, addRequestCost } from '@outputai/core/http';
vi.mock( '@outputai/core/http', () => ( { outputFetch: vi.fn() } ) );
```

### Remove the dependency

Delete `@outputai/http` from `dependencies`, `devDependencies`, and `peerDependencies` in `package.json`. If your project depends on `@outputai/core` directly rather than through `@outputai/output`, bump it to `0.16.0`.

### Install the peer dependencies

npm 7+ and pnpm install peer dependencies automatically. With other package managers, or if your install reports missing peers, add them yourself:

```bash theme={null}
npm install ky@2 undici@8
```

If your project already depends on `ky` or `undici`, make sure the versions fall in the supported ranges.

### Update trace attribute imports

Code that referenced `Tracing.Attribute.HTTPRequestCount` or `Tracing.Attribute.HTTPRequestCost` should import them from `@outputai/core/http`:

```ts theme={null}
// Before
import { Tracing } from '@outputai/core/sdk/runtime';
const isCost = attribute instanceof Tracing.Attribute.HTTPRequestCost;

// After
import { HTTPRequestCost } from '@outputai/core/http';
const isCost = attribute instanceof HTTPRequestCost;
```

To attach a cost to an HTTP request, keep using `addRequestCost()` from `@outputai/core/http`.

### Re-check `sendHttpRequest()` response bodies

This only affects calls with `responseOptions.includeBody: true`:

| Response | Before | After |
| - | - | - |
| `application/xml`, `*+xml` | base64 string | text |
| `application/x-www-form-urlencoded` | base64 string | text |
| `application/javascript` | base64 string | text |
| JSON content type with an empty body | throws | `''` |
| JSON content type with an invalid body | throws | raw text |

Remove any base64 decoding of those content types. If you relied on the error to detect a bad JSON response, check whether `body` is a string instead.

### Re-check trace file readers

If you parse trace files recorded with `OUTPUT_TRACE_HTTP_VERBOSE` on, request and response bodies now follow the table above, and multipart request bodies are base64 strings.

## Worker defaults and telemetry

No code changes are needed, but the worker behaves differently if you never set its concurrency variables, and one telemetry field is renamed.

### Workflow concurrency defaults

The worker no longer sets defaults for these two variables. When they are unset, `@temporalio/worker` applies its own:

| Variable | v0.15.0 | v0.16.0 |
| - | - | - |
| `TEMPORAL_MAX_CACHED_WORKFLOWS` | `1000` | Sized from the isolate's heap limit |
| `TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASK_EXECUTIONS` | `200` | `40` |

The cache size is `(heap limit in MiB - 200) * 600 / 1024`, with a minimum of 10. With `--max-old-space-size=4096` that is about 2,400 cached workflows. The formula assumes roughly 600 cached workflows per GB of heap, so if your workflows hold large inputs, outputs, or step results, set `TEMPORAL_MAX_CACHED_WORKFLOWS` explicitly.

If you relied on 200 concurrent workflow tasks, set `TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASK_EXECUTIONS=200`. Keep it at or below `TEMPORAL_MAX_CACHED_WORKFLOWS`.

The resolved values are logged at startup in the `Worker sizing` record, as `maxCachedWorkflows` and `workflowTaskSlots`.

### New startup warnings

After the `Worker sizing` record, the worker logs a warning in either or both of these cases, each with the values it compared:

| Warning | Cause | Fix |
| - | - | - |
| `Worker isolates may commit more heap than the host allows` | The heap limit times the isolate count exceeds the container's memory limit, or the machine's when there is no container. A `NODE_OPTIONS` heap cap applies to each isolate, and the worker runs one on its main thread plus one per workflow thread. | Lower the `NODE_OPTIONS` heap cap so the isolate count times the cap fits. |
| `Worker runs more workflow tasks than it can cache, forcing replays` | `TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASK_EXECUTIONS` resolves above `TEMPORAL_MAX_CACHED_WORKFLOWS`. | Lower the task executions or raise the cache. |

A project that only set `TEMPORAL_MAX_CACHED_WORKFLOWS` below `40` will now see the second warning, because task executions default to `40`. See [Memory and Isolates](/operations/worker-tuning#memory-and-isolates).

A Dockerfile copied from an earlier version of the [Railway](/operations/deployment/railway) or [Render](/operations/deployment/render) guide sets `--max-old-space-size-percentage=80`, which triggers the first warning because the worker runs two isolates by default. Those guides now use `40`.

### Telemetry field rename

If you enable `OUTPUT_WORKER_TELEMETRY_INTERVAL_MS` and parse the periodic `Worker` log, `memory.constrainedMemory` is now `memory.memoryLimit`.

The old field reported `process.constrainedMemory()` directly, which returns a sentinel near 2^64 when the process has no memory limit. `memoryLimit` reports the container's limit, or the machine's total memory when there is none.

Two fields were added to the same block: `memory.nonMainHeap` (`rss - heapUsed`) and `memory.heapSizeLimit`.

## Checklist

* Replace `@outputai/http` imports and mocks with `@outputai/core/http`, and remove the dependency.
* Install `ky@2` and `undici@8` if your package manager does not install peer dependencies.
* Import `HTTPRequestCount` and `HTTPRequestCost` from `@outputai/core/http`.
* Remove base64 decoding of XML, form-urlencoded, and JavaScript response bodies from `sendHttpRequest()`.
* Set `TEMPORAL_MAX_CACHED_WORKFLOWS` and `TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASK_EXECUTIONS` explicitly if you relied on the old defaults or your workflows hold large state.
* Lower `--max-old-space-size-percentage` to `40` if your Dockerfile uses the earlier Railway or Render value of `80`.
* Rename `memory.constrainedMemory` to `memory.memoryLimit` in anything that parses worker telemetry.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.