# @cuylabs/agent-foundry-agentserver-responses

TypeScript host for the Foundry Hosted Agents Responses protocol.

This package mirrors Python `azure-ai-agentserver-responses`: it plugs into
`@cuylabs/agent-foundry-agentserver-core` and adds the Responses protocol HTTP
surface: create, stream with SSE, cancel, delete, replay, and input-item
listing.

## Docs

The quick start stays in this README. Deeper package docs live in
[`docs/`](./docs/README.md):

| Document | Purpose |
| --- | --- |
| [`docs/hosting.md`](./docs/hosting.md) | Express lifecycle, route layout, execution, and tracing |
| [`docs/store.md`](./docs/store.md) | Foundry storage, in-memory storage, stream replay, and custom providers |
| [`docs/protocol.md`](./docs/protocol.md) | Endpoint behavior, modes, IDs, validation, and OpenAPI |
| [`docs/agent-core-bridge.md`](./docs/agent-core-bridge.md) | How `agent-foundry-hosting/responses` adapts `agent-core` turns |
| [`docs/python-parity.md`](./docs/python-parity.md) | Current parity against Python, TypeSpec, and production-readiness gaps |

Example samples live in [`samples/`](./samples/README.md).

Public subpath exports are available for the same conceptual areas as the
Python package:

```ts
import { FoundryStorageProvider } from "@cuylabs/agent-foundry-agentserver-responses/store";
import { TextResponse } from "@cuylabs/agent-foundry-agentserver-responses/streaming";
```

```ts
import {
  ResponseContext,
  TextResponse,
  runResponsesServer,
  type CreateResponse,
} from "@cuylabs/agent-foundry-agentserver-responses";

await runResponsesServer({
  port: 8088,
  async handler(request: CreateResponse, context: ResponseContext) {
    const text = await context.getInputText();
    return new TextResponse(context, request, {
      text: `Echo: ${text}`,
    });
  },
});
```

## Durable Storage

Durable storage is the persistence layer behind the Responses protocol. The
host process can always keep response state in memory, but that state is lost
when the container restarts and it cannot be shared across replicas. A durable
provider stores the response snapshot, the resolved input items, history item
IDs, and item lookup records in Foundry storage so `GET /responses/{id}`,
`GET /responses/{id}/input_items`, and future turns using
`previous_response_id` keep working outside the current Node.js process.

For local development, `InMemoryResponseProvider` is still the default. In a
hosted Foundry environment, pass `FoundryStorageProvider` explicitly:

```ts
import { DefaultAzureCredential } from "@azure/identity";
import { runResponsesServer } from "@cuylabs/agent-foundry-agentserver-responses";
import {
  FoundryStorageProvider,
} from "@cuylabs/agent-foundry-agentserver-responses/store";

await runResponsesServer({
  handler,
  store: new FoundryStorageProvider({
    credential: new DefaultAzureCredential(),
  }),
});
```

The storage provider follows the Python SDK storage API shape:
`POST /storage/responses`, `GET/POST/DELETE /storage/responses/{id}`,
`GET /storage/responses/{id}/input_items`,
`POST /storage/items/batch/retrieve`, and `GET /storage/history/item_ids`.
Stream replay is a separate provider capability; when a durable provider does
not implement stream replay, the host uses in-process replay storage.

## Schema Models

The Python package has generated model classes from the Responses OpenAPI
schema. This TypeScript package now exposes the protocol-level model surface as
strong structural types (`CreateResponse`, `ResponseObject`, `OutputItem`,
`ResponseStreamEvent`) plus runtime validation for the hosted-agent semantics
that matter at the server boundary, such as `background=true` requiring
`store=true`, `stream_options` requiring `stream=true`, metadata limits, ID
format validation, and cursor pagination. The long-term direction should be to
replace or augment these structural types with generated TypeScript models from
the same OpenAPI source, while preserving the handler/provider interfaces in
this package.

## Endpoints

| Method | Route | Description |
| --- | --- | --- |
| `POST` | `/responses` | Create a response |
| `GET` | `/responses/{response_id}` | Retrieve a response snapshot, or SSE replay with `?stream=true` |
| `POST` | `/responses/{response_id}/cancel` | Cancel a background response |
| `DELETE` | `/responses/{response_id}` | Delete a stored response |
| `GET` | `/responses/{response_id}/input_items` | List input items |

## Layering

This package is protocol-level and agent-agnostic. Use
`@cuylabs/agent-foundry-hosting/responses` to bridge `@cuylabs/agent-core` or
`@cuylabs/agent-server` into this protocol package, matching the existing
Invocations split.
