@cuylabs/agent-foundry-agentserver-responses 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,134 @@
1
+ import { AgentIsolationContext } from '@cuylabs/agent-foundry-agentserver-core';
2
+ import { p as ResponseProvider, b as ResponseObject, O as OutputItem, s as ResponseStreamProvider, r as ResponseStreamEvent } from '../types-Dvs2F85g.js';
3
+ import 'node:http';
4
+ import 'express';
5
+
6
+ declare class FoundryStorageError extends Error {
7
+ readonly status: number;
8
+ readonly code: string;
9
+ readonly responseBody?: unknown | undefined;
10
+ constructor(message: string, status: number, code?: string, responseBody?: unknown | undefined);
11
+ }
12
+ declare class FoundryStorageNotFoundError extends FoundryStorageError {
13
+ constructor(message: string, responseBody?: unknown);
14
+ }
15
+
16
+ interface FoundryStorageSettingsOptions {
17
+ projectEndpoint?: string;
18
+ storageBaseUrl?: string;
19
+ env?: NodeJS.ProcessEnv;
20
+ }
21
+ declare class FoundryStorageSettings {
22
+ readonly storageBaseUrl: string;
23
+ constructor(options: {
24
+ storageBaseUrl: string;
25
+ });
26
+ static fromEnv(env?: NodeJS.ProcessEnv): FoundryStorageSettings;
27
+ static fromEndpoint(endpoint: string): FoundryStorageSettings;
28
+ static resolve(options?: FoundryStorageSettingsOptions): FoundryStorageSettings;
29
+ buildUrl(path: string, query?: Record<string, string | undefined>): string;
30
+ }
31
+
32
+ interface AccessToken {
33
+ token: string;
34
+ expiresOnTimestamp?: number;
35
+ }
36
+ interface TokenCredential {
37
+ getToken(scopes: string | string[], options?: Record<string, unknown>): Promise<AccessToken | null>;
38
+ }
39
+ interface FoundryStorageProviderOptions extends FoundryStorageSettingsOptions {
40
+ credential: TokenCredential;
41
+ fetch?: typeof fetch;
42
+ getServerVersion?: () => string;
43
+ }
44
+ declare class FoundryStorageProvider implements ResponseProvider {
45
+ private readonly credential;
46
+ private readonly fetchImpl;
47
+ private readonly settings;
48
+ private readonly getServerVersion?;
49
+ constructor(options: FoundryStorageProviderOptions);
50
+ createResponse(response: ResponseObject, inputItems: OutputItem[], options?: {
51
+ historyItemIds?: readonly string[];
52
+ isolation?: AgentIsolationContext;
53
+ }): Promise<void>;
54
+ getResponse(responseId: string, options?: {
55
+ isolation?: AgentIsolationContext;
56
+ }): Promise<ResponseObject | undefined>;
57
+ updateResponse(response: ResponseObject, options?: {
58
+ isolation?: AgentIsolationContext;
59
+ }): Promise<void>;
60
+ deleteResponse(responseId: string, options?: {
61
+ isolation?: AgentIsolationContext;
62
+ }): Promise<boolean>;
63
+ getInputItems(responseId: string, options?: {
64
+ after?: string;
65
+ ascending?: boolean;
66
+ before?: string;
67
+ isolation?: AgentIsolationContext;
68
+ limit?: number;
69
+ }): Promise<OutputItem[] | undefined>;
70
+ getItems(itemIds: readonly string[], options?: {
71
+ isolation?: AgentIsolationContext;
72
+ }): Promise<Array<OutputItem | undefined>>;
73
+ getHistoryItemIds(previousResponseId: string | undefined, conversationId: string | undefined, limit: number, options?: {
74
+ isolation?: AgentIsolationContext;
75
+ }): Promise<string[]>;
76
+ private request;
77
+ private headers;
78
+ }
79
+
80
+ declare class InMemoryResponseProvider implements ResponseProvider, ResponseStreamProvider {
81
+ private readonly responses;
82
+ private readonly inputItems;
83
+ private readonly historyItemIds;
84
+ private readonly items;
85
+ private readonly streamEvents;
86
+ private readonly conversationResponses;
87
+ private readonly deleted;
88
+ createResponse(response: ResponseObject, inputItems: OutputItem[], options?: {
89
+ historyItemIds?: readonly string[];
90
+ isolation?: AgentIsolationContext;
91
+ }): Promise<void>;
92
+ getResponse(responseId: string, options?: {
93
+ isolation?: AgentIsolationContext;
94
+ }): Promise<ResponseObject | undefined>;
95
+ updateResponse(response: ResponseObject, options?: {
96
+ isolation?: AgentIsolationContext;
97
+ }): Promise<void>;
98
+ deleteResponse(responseId: string, options?: {
99
+ isolation?: AgentIsolationContext;
100
+ }): Promise<boolean>;
101
+ getItems(itemIds: readonly string[], options?: {
102
+ isolation?: AgentIsolationContext;
103
+ }): Promise<Array<OutputItem | undefined>>;
104
+ getInputItems(responseId: string, options?: {
105
+ after?: string;
106
+ ascending?: boolean;
107
+ before?: string;
108
+ isolation?: AgentIsolationContext;
109
+ limit?: number;
110
+ }): Promise<OutputItem[] | undefined>;
111
+ getHistoryItemIds(previousResponseId: string | undefined, conversationId: string | undefined, limit: number, options?: {
112
+ isolation?: AgentIsolationContext;
113
+ }): Promise<string[]>;
114
+ getHistoryItems(previousResponseId: string | undefined, conversationId: string | undefined, limit: number, options?: {
115
+ isolation?: AgentIsolationContext;
116
+ }): Promise<OutputItem[]>;
117
+ appendStreamEvent(responseId: string, event: ResponseStreamEvent, options?: {
118
+ isolation?: AgentIsolationContext;
119
+ }): Promise<void>;
120
+ getStreamEvents(responseId: string, options?: {
121
+ isolation?: AgentIsolationContext;
122
+ }): Promise<ResponseStreamEvent[] | undefined>;
123
+ saveStreamEvents(responseId: string, events: ResponseStreamEvent[], options?: {
124
+ isolation?: AgentIsolationContext;
125
+ }): Promise<void>;
126
+ deleteStreamEvents(responseId: string, options?: {
127
+ isolation?: AgentIsolationContext;
128
+ }): Promise<void>;
129
+ isDeleted(responseId: string, isolation?: AgentIsolationContext): boolean;
130
+ private collectPreviousResponseHistoryItemIds;
131
+ private collectResponseItemIds;
132
+ }
133
+
134
+ export { type AccessToken, FoundryStorageError, FoundryStorageNotFoundError, FoundryStorageProvider, type FoundryStorageProviderOptions, FoundryStorageSettings, type FoundryStorageSettingsOptions, InMemoryResponseProvider, type TokenCredential };
@@ -0,0 +1,14 @@
1
+ import {
2
+ FoundryStorageError,
3
+ FoundryStorageNotFoundError,
4
+ FoundryStorageProvider,
5
+ FoundryStorageSettings,
6
+ InMemoryResponseProvider
7
+ } from "../chunk-DGMWFFNQ.js";
8
+ export {
9
+ FoundryStorageError,
10
+ FoundryStorageNotFoundError,
11
+ FoundryStorageProvider,
12
+ FoundryStorageSettings,
13
+ InMemoryResponseProvider
14
+ };
@@ -0,0 +1,27 @@
1
+ import { Response } from 'express';
2
+ import { r as ResponseStreamEvent, j as ResponseContext, C as CreateResponse, b as ResponseObject } from '../types-Dvs2F85g.js';
3
+ import 'node:http';
4
+ import '@cuylabs/agent-foundry-agentserver-core';
5
+
6
+ interface SseEncoderState {
7
+ sequenceNumber: number;
8
+ }
9
+ declare function startResponsesSseResponse(res: Response): void;
10
+ declare function createSseEncoderState(): SseEncoderState;
11
+ declare function encodeSseEvent(event: ResponseStreamEvent, state?: SseEncoderState): string;
12
+ declare function encodeKeepAliveComment(comment?: string): string;
13
+
14
+ type TextSource = string | (() => string | Promise<string>) | AsyncIterable<string> | Iterable<string>;
15
+ declare class TextResponse implements AsyncIterable<ResponseStreamEvent> {
16
+ private readonly context;
17
+ private readonly request;
18
+ private readonly options;
19
+ constructor(context: ResponseContext, request: CreateResponse, options: {
20
+ text: TextSource;
21
+ configure?: (response: ResponseObject) => void;
22
+ });
23
+ [Symbol.asyncIterator](): AsyncIterator<ResponseStreamEvent>;
24
+ private generate;
25
+ }
26
+
27
+ export { type SseEncoderState, TextResponse, type TextSource, createSseEncoderState, encodeKeepAliveComment, encodeSseEvent, startResponsesSseResponse };
@@ -0,0 +1,14 @@
1
+ import {
2
+ TextResponse,
3
+ createSseEncoderState,
4
+ encodeKeepAliveComment,
5
+ encodeSseEvent,
6
+ startResponsesSseResponse
7
+ } from "../chunk-24VMS6GY.js";
8
+ export {
9
+ TextResponse,
10
+ createSseEncoderState,
11
+ encodeKeepAliveComment,
12
+ encodeSseEvent,
13
+ startResponsesSseResponse
14
+ };
@@ -0,0 +1,254 @@
1
+ import * as node_http from 'node:http';
2
+ import * as express from 'express';
3
+ import { Response, Request } from 'express';
4
+ import { AgentIsolationContext } from '@cuylabs/agent-foundry-agentserver-core';
5
+
6
+ declare class ResponseContext {
7
+ readonly responseId: string;
8
+ readonly request: CreateResponse;
9
+ readonly createdAt: number;
10
+ readonly modeFlags: ResponseModeFlags;
11
+ readonly sessionId: string;
12
+ readonly previousResponseId?: string;
13
+ readonly conversationId?: string;
14
+ readonly clientHeaders: Record<string, string>;
15
+ readonly queryParameters: Record<string, string>;
16
+ readonly isolation: AgentIsolationContext;
17
+ isShutdownRequested: boolean;
18
+ private readonly provider?;
19
+ private readonly historyLimit;
20
+ private readonly inputItems;
21
+ private resolvedInputCache?;
22
+ private historyCache?;
23
+ constructor(options: {
24
+ responseId: string;
25
+ request: CreateResponse;
26
+ modeFlags: ResponseModeFlags;
27
+ sessionId?: string;
28
+ provider?: ResponseProvider;
29
+ inputItems?: OutputItem[];
30
+ previousResponseId?: string;
31
+ conversationId?: string;
32
+ historyLimit?: number;
33
+ clientHeaders?: Record<string, string>;
34
+ queryParameters?: Record<string, string>;
35
+ isolation?: AgentIsolationContext;
36
+ createdAt?: number;
37
+ });
38
+ getInputItems(options?: {
39
+ resolveReferences?: boolean;
40
+ }): Promise<readonly OutputItem[]>;
41
+ getInputText(options?: {
42
+ resolveReferences?: boolean;
43
+ }): Promise<string>;
44
+ getHistory(): Promise<readonly OutputItem[]>;
45
+ getInputItemsForPersistence(): Promise<OutputItem[]>;
46
+ }
47
+
48
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
49
+ [key: string]: JsonValue;
50
+ };
51
+ interface AgentReference {
52
+ type: "agent_reference";
53
+ name: string;
54
+ version?: string;
55
+ id?: string;
56
+ }
57
+ interface ConversationReference {
58
+ id: string;
59
+ }
60
+ interface CreateResponse {
61
+ input?: ResponseInput;
62
+ model?: string;
63
+ stream?: boolean;
64
+ background?: boolean;
65
+ store?: boolean;
66
+ previous_response_id?: string | null;
67
+ conversation?: string | ConversationReference | null;
68
+ metadata?: Record<string, unknown> | null;
69
+ response_id?: string;
70
+ agent_session_id?: string;
71
+ agent_reference?: AgentReference;
72
+ [key: string]: unknown;
73
+ }
74
+ type ResponseInput = string | InputItem | InputItem[];
75
+ type InputItem = ItemMessage | ItemReference | FunctionCallOutputItem | Record<string, unknown>;
76
+ interface ItemMessage {
77
+ id?: string;
78
+ type: "message";
79
+ role: "user" | "assistant" | "system" | "developer";
80
+ content: string | MessageContent[];
81
+ }
82
+ interface ItemReference {
83
+ type: "item_reference";
84
+ id: string;
85
+ }
86
+ interface FunctionCallOutputItem {
87
+ id?: string;
88
+ type: "function_call_output";
89
+ call_id: string;
90
+ output: string;
91
+ }
92
+ type MessageContent = MessageContentInputText | MessageContentOutputText | MessageContentRefusal | Record<string, unknown>;
93
+ interface MessageContentInputText {
94
+ type: "input_text";
95
+ text: string;
96
+ }
97
+ interface MessageContentOutputText {
98
+ type: "output_text";
99
+ text: string;
100
+ annotations?: unknown[];
101
+ }
102
+ interface MessageContentRefusal {
103
+ type: "refusal";
104
+ refusal: string;
105
+ }
106
+ interface OutputItem {
107
+ id: string;
108
+ type: string;
109
+ status?: string;
110
+ role?: string;
111
+ content?: MessageContent[];
112
+ [key: string]: unknown;
113
+ }
114
+ type ResponseStatus = "queued" | "in_progress" | "completed" | "failed" | "cancelled" | "incomplete";
115
+ interface ResponseError {
116
+ code: string;
117
+ message: string;
118
+ type?: string;
119
+ }
120
+ interface ResponseUsage {
121
+ input_tokens?: number;
122
+ output_tokens?: number;
123
+ total_tokens?: number;
124
+ [key: string]: unknown;
125
+ }
126
+ interface ResponseObject {
127
+ id: string;
128
+ object: "response";
129
+ created_at: number;
130
+ status: ResponseStatus;
131
+ model?: string;
132
+ stream?: boolean;
133
+ background?: boolean;
134
+ store?: boolean;
135
+ output: OutputItem[];
136
+ error?: ResponseError | null;
137
+ previous_response_id?: string | null;
138
+ conversation?: ConversationReference;
139
+ metadata?: Record<string, unknown> | null;
140
+ usage?: ResponseUsage | null;
141
+ [key: string]: unknown;
142
+ }
143
+ interface ResponseStreamEvent {
144
+ type: string;
145
+ sequence_number?: number;
146
+ response?: ResponseObject;
147
+ item?: OutputItem;
148
+ item_id?: string;
149
+ output_index?: number;
150
+ content_index?: number;
151
+ part?: MessageContent;
152
+ delta?: string;
153
+ text?: string;
154
+ error?: ResponseError;
155
+ [key: string]: unknown;
156
+ }
157
+ interface ResponseModeFlags {
158
+ stream: boolean;
159
+ background: boolean;
160
+ store: boolean;
161
+ }
162
+ interface ResponseHandlerContext {
163
+ request: CreateResponse;
164
+ context: ResponseContext;
165
+ signal: AbortSignal;
166
+ }
167
+ type ResponseHandlerResult = AsyncIterable<ResponseStreamEvent | Record<string, unknown>> | Iterable<ResponseStreamEvent | Record<string, unknown>>;
168
+ type ResponseHandler = (request: CreateResponse, context: ResponseContext, signal: AbortSignal) => ResponseHandlerResult | Promise<ResponseHandlerResult>;
169
+ declare abstract class ResponsesHandler {
170
+ abstract handle(request: CreateResponse, context: ResponseContext, signal: AbortSignal): ResponseHandlerResult | Promise<ResponseHandlerResult>;
171
+ getOpenApi?(): unknown;
172
+ close?(): Promise<void> | void;
173
+ }
174
+ type ResponsesHandlerFactory = () => ResponsesHandler;
175
+ type ResponsesHandlerInput = ResponsesHandler | ResponsesHandlerFactory | ResponseHandler;
176
+ interface ResponseProvider {
177
+ createResponse(response: ResponseObject, inputItems: OutputItem[], options?: {
178
+ historyItemIds?: readonly string[];
179
+ isolation?: AgentIsolationContext;
180
+ }): Promise<void>;
181
+ getResponse(responseId: string, options?: {
182
+ isolation?: AgentIsolationContext;
183
+ }): Promise<ResponseObject | undefined>;
184
+ updateResponse(response: ResponseObject, options?: {
185
+ isolation?: AgentIsolationContext;
186
+ }): Promise<void>;
187
+ deleteResponse(responseId: string, options?: {
188
+ isolation?: AgentIsolationContext;
189
+ }): Promise<boolean>;
190
+ getItems(itemIds: readonly string[], options?: {
191
+ isolation?: AgentIsolationContext;
192
+ }): Promise<Array<OutputItem | undefined>>;
193
+ getInputItems(responseId: string, options?: {
194
+ after?: string;
195
+ ascending?: boolean;
196
+ before?: string;
197
+ isolation?: AgentIsolationContext;
198
+ limit?: number;
199
+ }): Promise<OutputItem[] | undefined>;
200
+ getHistoryItemIds(previousResponseId: string | undefined, conversationId: string | undefined, limit: number, options?: {
201
+ isolation?: AgentIsolationContext;
202
+ }): Promise<string[]>;
203
+ getHistoryItems?(previousResponseId: string | undefined, conversationId: string | undefined, limit: number, options?: {
204
+ isolation?: AgentIsolationContext;
205
+ }): Promise<OutputItem[]>;
206
+ }
207
+ interface ResponseStreamProvider {
208
+ appendStreamEvent(responseId: string, event: ResponseStreamEvent, options?: {
209
+ isolation?: AgentIsolationContext;
210
+ }): Promise<void>;
211
+ saveStreamEvents?(responseId: string, events: ResponseStreamEvent[], options?: {
212
+ isolation?: AgentIsolationContext;
213
+ }): Promise<void>;
214
+ getStreamEvents(responseId: string, options?: {
215
+ isolation?: AgentIsolationContext;
216
+ }): Promise<ResponseStreamEvent[] | undefined>;
217
+ deleteStreamEvents(responseId: string, options?: {
218
+ isolation?: AgentIsolationContext;
219
+ }): Promise<void>;
220
+ }
221
+ interface ResponsesServerLogger {
222
+ info(message: string, meta?: Record<string, unknown>): void;
223
+ warn(message: string, meta?: Record<string, unknown>): void;
224
+ error(message: string, meta?: Record<string, unknown>): void;
225
+ debug?(message: string, meta?: Record<string, unknown>): void;
226
+ }
227
+ interface ResponsesServer {
228
+ readonly app: express.Express;
229
+ readonly server: node_http.Server;
230
+ readonly port: number;
231
+ readonly host: string;
232
+ close(): Promise<void>;
233
+ }
234
+ interface ResponsesServerOptions {
235
+ handler: ResponsesHandlerInput;
236
+ port?: number;
237
+ host?: string;
238
+ appName?: string;
239
+ bodyLimit?: string;
240
+ requestLogging?: boolean;
241
+ trustProxy?: boolean | number | string;
242
+ gracefulShutdownTimeoutSeconds?: number;
243
+ configureObservability?: boolean;
244
+ logger?: ResponsesServerLogger;
245
+ store?: ResponseProvider & Partial<ResponseStreamProvider>;
246
+ defaultModel?: string;
247
+ defaultFetchHistoryCount?: number;
248
+ }
249
+ interface ResponsesRequest extends Request {
250
+ body: CreateResponse;
251
+ }
252
+ type ExpressResponse = Response;
253
+
254
+ export { type AgentReference as A, type CreateResponse as C, type ExpressResponse as E, type FunctionCallOutputItem as F, type InputItem as I, type JsonValue as J, type MessageContent as M, type OutputItem as O, type ResponsesServerOptions as R, type ResponsesServer as a, type ResponseObject as b, type ResponseInput as c, type ConversationReference as d, type ItemMessage as e, type ItemReference as f, type MessageContentInputText as g, type MessageContentOutputText as h, type MessageContentRefusal as i, ResponseContext as j, type ResponseError as k, type ResponseHandler as l, type ResponseHandlerContext as m, type ResponseHandlerResult as n, type ResponseModeFlags as o, type ResponseProvider as p, type ResponseStatus as q, type ResponseStreamEvent as r, type ResponseStreamProvider as s, type ResponseUsage as t, ResponsesHandler as u, type ResponsesHandlerFactory as v, type ResponsesHandlerInput as w, type ResponsesRequest as x, type ResponsesServerLogger as y };
package/docs/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Agent Server Responses Docs
2
+
3
+ This package is the TypeScript implementation of the Azure AI Foundry Hosted
4
+ Agents Responses protocol host. It mirrors the shape of Python
5
+ `azure-ai-agentserver-responses` while fitting the `agents-ts` package layout.
6
+
7
+ Use the package README for a quick start. Use these docs when working on the
8
+ host internals, storage providers, protocol behavior, or the bridge from
9
+ `@cuylabs/agent-core`.
10
+
11
+ ## Documents
12
+
13
+ | Document | Purpose |
14
+ | --- | --- |
15
+ | [hosting.md](./hosting.md) | Express host lifecycle, route layout, response execution, and tracing |
16
+ | [store.md](./store.md) | Durable storage options, Foundry storage, in-memory storage, and custom providers |
17
+ | [protocol.md](./protocol.md) | Responses endpoint behavior, IDs, validation, streaming, and replay |
18
+ | [agent-core-bridge.md](./agent-core-bridge.md) | How `@cuylabs/agent-foundry-hosting/responses` adapts `agent-core` turns |
19
+ | [python-parity.md](./python-parity.md) | Current parity against Python, TypeSpec, and production-readiness gaps |
20
+
21
+ ## Package Layers
22
+
23
+ ```text
24
+ @cuylabs/agent-foundry-agentserver-core
25
+ Express/Node equivalent of Python azure-ai-agentserver-core:
26
+ identity, headers, config, health, observability, request tracing
27
+
28
+ @cuylabs/agent-foundry-agentserver-responses
29
+ TypeScript equivalent of Python azure-ai-agentserver-responses:
30
+ Responses routes, SSE framing, IDs, models, storage provider contracts
31
+
32
+ @cuylabs/agent-foundry-hosting/responses
33
+ agents-ts bridge only: adapts agent-core / agent-server turns into Responses stream events
34
+ ```
35
+
36
+ The responses package is intentionally agent-agnostic. It knows how to host the
37
+ Responses protocol and persist protocol state. It does not know how a specific
38
+ agent reasons, calls tools, or stores its own runtime memory.
39
+
40
+ ## Comparison Targets
41
+
42
+ When checking parity against Python, compare packages by responsibility rather
43
+ than by framework or private file names:
44
+
45
+ | TypeScript package | Python package | Compare for |
46
+ | --- | --- | --- |
47
+ | `@cuylabs/agent-foundry-agentserver-core` | `azure-ai-agentserver-core` | Protocol-agnostic host behavior: config, health/readiness, protected headers, request IDs, request logging, tracing, graceful shutdown |
48
+ | `@cuylabs/agent-foundry-agentserver-responses` | `azure-ai-agentserver-responses` | Responses protocol behavior: create/get/delete/cancel/input-items, stream/replay, storage, response context, model validation, event lifecycle |
49
+ | `@cuylabs/agent-foundry-hosting/responses` | No direct Python peer | TypeScript-specific bridge from `agent-core`/`agent-server` events into the Responses protocol |
50
+
51
+ Python uses ASGI, Starlette, and Hypercorn. TypeScript uses Express and Node's
52
+ HTTP server. That framework difference is expected; the parity target is the
53
+ hosted-agent contract and observable protocol behavior.
54
+
55
+ ## Source Layout
56
+
57
+ The TypeScript source follows the same conceptual domains as the Python package
58
+ without copying Python private module names directly:
59
+
60
+ | TS path | Python peer | Responsibility |
61
+ | --- | --- | --- |
62
+ | `src/hosting/` | `responses/hosting/` | Express routes, request parsing, execution, tracing, validation |
63
+ | `src/store/` | `responses/store/` | In-memory and Foundry-backed response providers |
64
+ | `src/streaming/` | `responses/streaming/` | SSE encoding and text-response streaming helpers |
65
+ | `src/types.ts`, `src/model-helpers.ts`, `src/ids.ts` | `responses/models/` plus root helpers | Hand-written protocol types and model helpers until TypeSpec-generated models are added |
66
+
67
+ The `store` and `streaming` domains are also package subpath exports:
68
+
69
+ ```ts
70
+ import { FoundryStorageProvider } from "@cuylabs/agent-foundry-agentserver-responses/store";
71
+ import { TextResponse } from "@cuylabs/agent-foundry-agentserver-responses/streaming";
72
+ ```
@@ -0,0 +1,48 @@
1
+ # Agent-Core Bridge
2
+
3
+ This package is protocol-level and agent-agnostic. It exposes
4
+ `ResponsesHandler` and the HTTP host, but it does not depend on
5
+ `@cuylabs/agent-core`.
6
+
7
+ Use `@cuylabs/agent-foundry-hosting/responses` when an `agent-core` agent needs
8
+ to run behind the Responses protocol.
9
+
10
+ ```ts
11
+ import { runResponsesServer } from "@cuylabs/agent-foundry-agentserver-responses";
12
+ import { createResponsesHandlerForAgent } from "@cuylabs/agent-foundry-hosting/responses";
13
+ import {
14
+ createAgentServerAdapter,
15
+ InProcessAgentServer,
16
+ } from "@cuylabs/agent-server";
17
+
18
+ const server = new InProcessAgentServer(createAgentServerAdapter(myAgent));
19
+
20
+ await runResponsesServer({
21
+ handler: createResponsesHandlerForAgent(server),
22
+ port: 8088,
23
+ });
24
+ ```
25
+
26
+ ## Responsibilities
27
+
28
+ The bridge owns agent runtime translation:
29
+
30
+ - starts an `agent-server` turn for each create-response request
31
+ - sends the normalized user input into the turn
32
+ - maps `agent-core` events to Responses stream events
33
+ - forwards cancellation to `interruptTurn`
34
+ - closes the wrapped server when the handler closes
35
+
36
+ The responses package still owns protocol concerns:
37
+
38
+ - Express routing
39
+ - SSE framing
40
+ - response IDs and session IDs
41
+ - `ResponseContext`
42
+ - response snapshots
43
+ - storage and stream replay
44
+ - platform headers and tracing
45
+
46
+ Keep this split intact. New protocol behavior belongs in
47
+ `agent-foundry-agentserver-responses`. New agent-runtime mapping behavior
48
+ belongs in `agent-foundry-hosting/responses`.
@@ -0,0 +1,72 @@
1
+ # Hosting
2
+
3
+ The public host entry points are `createResponsesApp` and
4
+ `runResponsesServer` from `src/host.ts`.
5
+
6
+ `createResponsesApp` builds an Express app and wires the shared Agent Server
7
+ core middleware:
8
+
9
+ - request IDs and protected platform headers
10
+ - JSON body parsing
11
+ - observability initialization
12
+ - optional request logging
13
+ - Responses route registration
14
+ - not-found and error middleware
15
+
16
+ `runResponsesServer` wraps `createResponsesApp`, starts the HTTP server, logs
17
+ startup configuration, and handles graceful shutdown.
18
+
19
+ ## Internal Layout
20
+
21
+ The host is split so protocol behavior is not trapped in one large file:
22
+
23
+ | Path | Responsibility |
24
+ | --- | --- |
25
+ | `src/host.ts` | Public Express/server bootstrap |
26
+ | `src/hosting/routes.ts` | Route registration and method guards |
27
+ | `src/hosting/routes/*.ts` | Endpoint-specific request handlers |
28
+ | `src/hosting/execution.ts` | Handler execution loop and response event application |
29
+ | `src/hosting/tracing.ts` | Responses request span creation and response lifecycle binding |
30
+ | `src/hosting/http-utils.ts` | Query parsing, active key scoping, JSON parse errors |
31
+ | `src/hosting/validation.ts` | Server-boundary semantic validation |
32
+ | `src/streaming/` | SSE encoding and streaming response helpers used by route handlers |
33
+ | `src/store/` | Response persistence providers used by the host |
34
+
35
+ ## Response Execution
36
+
37
+ `POST /responses` normalizes the create request, resolves IDs and isolation,
38
+ creates a `ResponseContext`, starts a request span, and invokes the configured
39
+ `ResponsesHandler`.
40
+
41
+ The handler returns an iterable or async iterable of `ResponseStreamEvent`
42
+ objects. The execution loop applies each event to the in-flight
43
+ `ResponseObject`, persists the response and stream events when `store` is
44
+ enabled, and emits terminal events for completed, failed, or cancelled
45
+ responses.
46
+
47
+ For non-streaming requests, the HTTP response is sent after execution finishes.
48
+ For streaming requests, the host starts Server-Sent Events immediately and
49
+ writes each normalized response event as it arrives. For background requests,
50
+ the initial queued response can return before the handler finishes.
51
+
52
+ ## Handler Input
53
+
54
+ The host accepts any of these handler shapes:
55
+
56
+ ```ts
57
+ new MyResponsesHandler()
58
+ ```
59
+
60
+ ```ts
61
+ () => new MyResponsesHandler()
62
+ ```
63
+
64
+ ```ts
65
+ async function* handler(request, context, signal) {
66
+ yield /* ResponseStreamEvent */;
67
+ }
68
+ ```
69
+
70
+ The factory form is useful when each request needs an isolated handler
71
+ instance. A single handler instance is useful when it owns shared resources and
72
+ implements `close()`.