@independo/inderun-web 0.1.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.
package/dist/errors.js ADDED
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Standardized framework exception thrown when route selection or provider execution fails.
3
+ * Extends the native JavaScript Error class and exposes normalized error schema fields.
4
+ */
5
+ export class IndeRunException extends Error {
6
+ /** The schema version matching the API contracts. */
7
+ schemaVersion = "1.0";
8
+ /** The categorized class of error. */
9
+ errorClass;
10
+ /** The unique execution run ID. */
11
+ runId;
12
+ /** The provider ID responsible for the error. */
13
+ providerId;
14
+ /** Whether the error is transient and retryable. */
15
+ retryable;
16
+ /** Suggested cooling-down time in milliseconds before retry. */
17
+ retryAfterMs;
18
+ /** Custom details and metadata context. */
19
+ details;
20
+ constructor(params) {
21
+ super(params.message);
22
+ this.name = "IndeRunException";
23
+ this.errorClass = params.errorClass;
24
+ if (params.runId !== undefined)
25
+ this.runId = params.runId;
26
+ if (params.providerId !== undefined)
27
+ this.providerId = params.providerId;
28
+ if (params.retryable !== undefined)
29
+ this.retryable = params.retryable;
30
+ if (params.retryAfterMs !== undefined)
31
+ this.retryAfterMs = params.retryAfterMs;
32
+ if (params.details !== undefined)
33
+ this.details = params.details;
34
+ Object.setPrototypeOf(this, IndeRunException.prototype);
35
+ }
36
+ /**
37
+ * Converts the exception into a JSON-compatible contract-compliant IndeRunError.
38
+ */
39
+ toContractError() {
40
+ const err = {
41
+ schemaVersion: this.schemaVersion,
42
+ errorClass: this.errorClass,
43
+ message: this.message
44
+ };
45
+ if (this.runId !== undefined)
46
+ err.runId = this.runId;
47
+ if (this.providerId !== undefined)
48
+ err.providerId = this.providerId;
49
+ if (this.retryable !== undefined)
50
+ err.retryable = this.retryable;
51
+ if (this.retryAfterMs !== undefined)
52
+ err.retryAfterMs = this.retryAfterMs;
53
+ if (this.details !== undefined)
54
+ err.details = this.details;
55
+ return err;
56
+ }
57
+ }
58
+ /**
59
+ * Factory helper for CapabilityMismatch error class.
60
+ */
61
+ export function createCapabilityMismatch(message, extra) {
62
+ return new IndeRunException({ errorClass: "CapabilityMismatch", message, ...extra });
63
+ }
64
+ /**
65
+ * Factory helper for Offline error class.
66
+ */
67
+ export function createOffline(message, extra) {
68
+ return new IndeRunException({ errorClass: "Offline", message, ...extra });
69
+ }
70
+ /**
71
+ * Factory helper for AuthError error class.
72
+ */
73
+ export function createAuthError(message, extra) {
74
+ return new IndeRunException({ errorClass: "AuthError", message, ...extra });
75
+ }
76
+ /**
77
+ * Factory helper for RateLimited error class.
78
+ */
79
+ export function createRateLimited(message, extra) {
80
+ return new IndeRunException({ errorClass: "RateLimited", message, ...extra });
81
+ }
82
+ /**
83
+ * Factory helper for Timeout error class.
84
+ */
85
+ export function createTimeout(message, extra) {
86
+ return new IndeRunException({ errorClass: "Timeout", message, ...extra });
87
+ }
88
+ /**
89
+ * Factory helper for Unavailable error class.
90
+ */
91
+ export function createUnavailable(message, extra) {
92
+ return new IndeRunException({ errorClass: "Unavailable", message, ...extra });
93
+ }
94
+ /**
95
+ * Factory helper for Internal error class.
96
+ */
97
+ export function createInternal(message, extra) {
98
+ return new IndeRunException({ errorClass: "Internal", message, ...extra });
99
+ }
100
+ /**
101
+ * Standardizes any caught error into an IndeRunException.
102
+ * If the input error is already an IndeRunException, merges additional fallback parameters (like totalMs).
103
+ */
104
+ export function toIndeRunException(error, fallbackParams) {
105
+ if (error instanceof IndeRunException) {
106
+ if (fallbackParams) {
107
+ const mergedParams = {
108
+ errorClass: error.errorClass,
109
+ message: error.message
110
+ };
111
+ const runId = error.runId ?? fallbackParams.runId;
112
+ if (runId !== undefined)
113
+ mergedParams.runId = runId;
114
+ const providerId = error.providerId ?? fallbackParams.providerId;
115
+ if (providerId !== undefined)
116
+ mergedParams.providerId = providerId;
117
+ const retryable = error.retryable ?? fallbackParams.retryable;
118
+ if (retryable !== undefined)
119
+ mergedParams.retryable = retryable;
120
+ const retryAfterMs = error.retryAfterMs ?? fallbackParams.retryAfterMs;
121
+ if (retryAfterMs !== undefined)
122
+ mergedParams.retryAfterMs = retryAfterMs;
123
+ if (error.details !== undefined || fallbackParams.details !== undefined) {
124
+ mergedParams.details = {
125
+ ...(error.details || {}),
126
+ ...(fallbackParams.details || {})
127
+ };
128
+ }
129
+ return new IndeRunException(mergedParams);
130
+ }
131
+ return error;
132
+ }
133
+ const message = error instanceof Error ? error.message : String(error);
134
+ const details = {
135
+ ...(fallbackParams?.details || {})
136
+ };
137
+ if (error instanceof Error) {
138
+ details.originalError = {
139
+ name: error.name,
140
+ message: error.message,
141
+ stack: error.stack
142
+ };
143
+ }
144
+ else {
145
+ details.originalError = {
146
+ message: String(error)
147
+ };
148
+ }
149
+ return new IndeRunException({
150
+ errorClass: "Internal",
151
+ message,
152
+ ...fallbackParams,
153
+ details
154
+ });
155
+ }
package/dist/host.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export type { ClockService, ConnectivityService, DeviceConstraintsService, HostServices, HttpClientService, HttpRequest, HttpResponse, SecureStorageService, TelemetryService, ThermalState } from "@independo/inderun-contracts";
2
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAC"}
package/dist/host.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ export { type ConnectivityService, type DeviceConstraintsService, type SecureStorageService, type ClockService, type HttpClientService, type HttpRequest, type HttpResponse, type HostServices, type ThermalState } from "./host.js";
2
+ export { type ProviderDescriptor, type ProviderDynamicCapabilities, type RunContext, type ProviderAdapter } from "./provider.js";
3
+ export { ProviderRegistry } from "./registry.js";
4
+ export { type RouteSelection, Router } from "./router.js";
5
+ export { type RoutePlanner, type SharedPlannerInput, type SharedPlannerRoutePlan, WasmRoutePlanner } from "./route-planner.js";
6
+ export { type IndeRunExceptionParams, IndeRunException, createCapabilityMismatch, createOffline, createAuthError, createRateLimited, createTimeout, createUnavailable, createInternal, toIndeRunException } from "./errors.js";
7
+ export { IndeRun } from "./engine.js";
8
+ export { type TelemetryEventType, type TelemetryEvent, type TelemetryService, NoOpTelemetryService } from "./telemetry.js";
9
+ export { BrowserConnectivityService, FetchHttpClient, SystemClockService, createBrowserHostServices, type CreateBrowserHostServicesOptions, type FetchHttpClientOptions } from "./browser-host.js";
10
+ export { createIndeRunWeb, type CreateIndeRunWebOptions } from "./web-sdk.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,oBAAoB,EACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export {} from "./host.js";
2
+ export {} from "./provider.js";
3
+ export { ProviderRegistry } from "./registry.js";
4
+ export { Router } from "./router.js";
5
+ export { WasmRoutePlanner } from "./route-planner.js";
6
+ export { IndeRunException, createCapabilityMismatch, createOffline, createAuthError, createRateLimited, createTimeout, createUnavailable, createInternal, toIndeRunException } from "./errors.js";
7
+ export { IndeRun } from "./engine.js";
8
+ export { NoOpTelemetryService } from "./telemetry.js";
9
+ export { BrowserConnectivityService, FetchHttpClient, SystemClockService, createBrowserHostServices } from "./browser-host.js";
10
+ export { createIndeRunWeb } from "./web-sdk.js";
11
+ // The OpenAI Responses adapter is provider-specific and intentionally excluded
12
+ // from this unified index. Import it from "@independo/inderun-web/openai".
@@ -0,0 +1,80 @@
1
+ import type { TaskRequest, TaskResult } from "@independo/inderun-contracts";
2
+ import type { HostServices } from "./host.js";
3
+ import type { ProviderAdapter, ProviderDescriptor, ProviderDynamicCapabilities, RunContext } from "./provider.js";
4
+ export declare const DEFAULT_OPENAI_RESPONSES_ENDPOINT = "https://api.openai.com/v1/responses";
5
+ /**
6
+ * Configuration for the OpenAI Responses provider.
7
+ */
8
+ export interface OpenAIProviderOptions {
9
+ /**
10
+ * Provider id exposed in telemetry and routing explanations.
11
+ */
12
+ id?: string;
13
+ /**
14
+ * OpenAI model id sent to the Responses API.
15
+ */
16
+ model: string;
17
+ /**
18
+ * Responses-compatible endpoint. Use a same-origin proxy endpoint in browser apps.
19
+ */
20
+ endpointUrl?: string;
21
+ /**
22
+ * Authentication mode. Use "none" for browser proxy endpoints that resolve
23
+ * OpenAI credentials server-side.
24
+ */
25
+ auth?: "authContextRef" | "none";
26
+ /**
27
+ * Default secure-storage slot used when the request does not provide authContextRef.
28
+ */
29
+ authContextRef?: string;
30
+ /**
31
+ * Optional HTTP timeout for the host transport attempt.
32
+ */
33
+ timeoutMs?: number;
34
+ }
35
+ /**
36
+ * Cloud provider adapter that executes Mode-1 text-to-text requests through the OpenAI Responses API.
37
+ *
38
+ * Browser applications should prefer a same-origin proxy endpoint with `auth: "none"` so OpenAI credentials
39
+ * stay server-side. Direct OpenAI authentication is available through `authContextRef` and `SecureStorageService`
40
+ * for controlled environments.
41
+ */
42
+ export declare class OpenAIResponsesProvider implements ProviderAdapter {
43
+ private readonly options;
44
+ private readonly id;
45
+ private readonly endpointUrl;
46
+ private readonly auth;
47
+ /**
48
+ * Creates an OpenAI Responses provider.
49
+ * @param options - Provider configuration, including required OpenAI model id.
50
+ */
51
+ constructor(options: OpenAIProviderOptions);
52
+ /**
53
+ * Returns static metadata used by the router for deterministic provider selection.
54
+ */
55
+ describe(): ProviderDescriptor;
56
+ /**
57
+ * Reports dynamic provider availability for the current host.
58
+ * @param host - Host services available to the engine.
59
+ */
60
+ capabilities(host: HostServices): Promise<ProviderDynamicCapabilities>;
61
+ /**
62
+ * Executes a normalized text-to-text task using the OpenAI Responses API.
63
+ * @param request - Canonical IndeRun task request.
64
+ * @param context - Engine execution context containing run id and host services.
65
+ * @returns Normalized IndeRun task result.
66
+ * @throws IndeRunException mapped to the standard error taxonomy.
67
+ */
68
+ run(request: TaskRequest, context: RunContext): Promise<TaskResult>;
69
+ private createRequestBody;
70
+ /**
71
+ * Maps an OpenAI HTTP error response onto the IndeRun error taxonomy:
72
+ * - `401` / `403` → `AuthError`
73
+ * - `429` → `RateLimited` (honors `Retry-After` when present)
74
+ * - `408` / `504` → `Timeout`
75
+ * - `409` / `5xx` → `Unavailable`
76
+ * - any other non-2xx status → `Internal`
77
+ */
78
+ private mapHttpError;
79
+ }
80
+ //# sourceMappingURL=openai-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../src/openai-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAQ5E,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAC3D,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,2BAA2B,EAC3B,UAAU,EACX,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,iCAAiC,wCAAwC,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACjC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwBD;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IASjD,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IAEjD;;;OAGG;gBAC0B,OAAO,EAAE,qBAAqB;IAM3D;;OAEG;IACH,QAAQ,IAAI,kBAAkB;IAsB9B;;;OAGG;IACG,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAkB5E;;;;;;OAMG;IACG,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAkHzE,OAAO,CAAC,iBAAiB;IAuBzB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;CAmErB"}
@@ -0,0 +1,345 @@
1
+ import { createAuthError, createInternal, createRateLimited, createTimeout, createUnavailable } from "./errors.js";
2
+ export const DEFAULT_OPENAI_RESPONSES_ENDPOINT = "https://api.openai.com/v1/responses";
3
+ /**
4
+ * Cloud provider adapter that executes Mode-1 text-to-text requests through the OpenAI Responses API.
5
+ *
6
+ * Browser applications should prefer a same-origin proxy endpoint with `auth: "none"` so OpenAI credentials
7
+ * stay server-side. Direct OpenAI authentication is available through `authContextRef` and `SecureStorageService`
8
+ * for controlled environments.
9
+ */
10
+ export class OpenAIResponsesProvider {
11
+ options;
12
+ id;
13
+ endpointUrl;
14
+ auth;
15
+ /**
16
+ * Creates an OpenAI Responses provider.
17
+ * @param options - Provider configuration, including required OpenAI model id.
18
+ */
19
+ constructor(options) {
20
+ this.options = options;
21
+ this.id = options.id ?? "openai";
22
+ this.endpointUrl = options.endpointUrl ?? DEFAULT_OPENAI_RESPONSES_ENDPOINT;
23
+ this.auth = options.auth ?? "authContextRef";
24
+ }
25
+ /**
26
+ * Returns static metadata used by the router for deterministic provider selection.
27
+ */
28
+ describe() {
29
+ return {
30
+ id: this.id,
31
+ type: "cloud",
32
+ transport: "http",
33
+ supports: {
34
+ run: true,
35
+ streaming: false,
36
+ realtime: false,
37
+ tools: false,
38
+ reasoningEvents: false,
39
+ structuredOutput: false,
40
+ multimodal: false
41
+ },
42
+ cancel: "hard",
43
+ tasks: ["text_to_text"],
44
+ privacy: {
45
+ dataLeavesDevice: true
46
+ }
47
+ };
48
+ }
49
+ /**
50
+ * Reports dynamic provider availability for the current host.
51
+ * @param host - Host services available to the engine.
52
+ */
53
+ async capabilities(host) {
54
+ if (!host.httpClient) {
55
+ return {
56
+ available: false,
57
+ reason: "OpenAI Responses provider requires an HttpClientService."
58
+ };
59
+ }
60
+ if (this.auth !== "none" && !host.secureStorage) {
61
+ return {
62
+ available: false,
63
+ reason: "OpenAI Responses provider requires a SecureStorageService when auth is enabled."
64
+ };
65
+ }
66
+ return { available: true };
67
+ }
68
+ /**
69
+ * Executes a normalized text-to-text task using the OpenAI Responses API.
70
+ * @param request - Canonical IndeRun task request.
71
+ * @param context - Engine execution context containing run id and host services.
72
+ * @returns Normalized IndeRun task result.
73
+ * @throws IndeRunException mapped to the standard error taxonomy.
74
+ */
75
+ async run(request, context) {
76
+ const httpClient = context.hostServices.httpClient;
77
+ if (!httpClient) {
78
+ throw createUnavailable("OpenAI Responses provider requires an HTTP client.", {
79
+ providerId: this.id,
80
+ runId: context.runId
81
+ });
82
+ }
83
+ const headers = {
84
+ "Content-Type": "application/json"
85
+ };
86
+ if (this.auth === "authContextRef") {
87
+ const slotId = request.authContextRef ?? this.options.authContextRef;
88
+ if (!slotId) {
89
+ throw createAuthError("OpenAI Responses provider requires authContextRef.", {
90
+ providerId: this.id,
91
+ runId: context.runId
92
+ });
93
+ }
94
+ const secureStorage = context.hostServices.secureStorage;
95
+ if (!secureStorage) {
96
+ throw createAuthError("OpenAI Responses provider requires a SecureStorageService when auth is enabled.", {
97
+ providerId: this.id,
98
+ runId: context.runId
99
+ });
100
+ }
101
+ const secret = await secureStorage.getSecret(slotId);
102
+ if (!secret) {
103
+ throw createAuthError(`No OpenAI credential found for authContextRef '${slotId}'.`, {
104
+ providerId: this.id,
105
+ runId: context.runId
106
+ });
107
+ }
108
+ headers.Authorization = `Bearer ${secret}`;
109
+ }
110
+ let response;
111
+ try {
112
+ const httpRequest = {
113
+ method: "POST",
114
+ url: this.endpointUrl,
115
+ headers,
116
+ body: JSON.stringify(this.createRequestBody(request))
117
+ };
118
+ if (this.options.timeoutMs !== undefined) {
119
+ httpRequest.timeoutMs = this.options.timeoutMs;
120
+ }
121
+ response = await httpClient.send(httpRequest);
122
+ }
123
+ catch (err) {
124
+ if (isAbortError(err)) {
125
+ throw createTimeout("OpenAI Responses request timed out.", {
126
+ providerId: this.id,
127
+ runId: context.runId
128
+ });
129
+ }
130
+ throw createUnavailable("OpenAI Responses request failed before a response was received.", {
131
+ providerId: this.id,
132
+ runId: context.runId,
133
+ details: { originalError: getErrorSummary(err) }
134
+ });
135
+ }
136
+ if (response.status < 200 || response.status >= 300) {
137
+ throw this.mapHttpError(response.status, response.statusText, response.headers, response.body, context);
138
+ }
139
+ const responseBody = parseJson(response.body);
140
+ const outputText = extractOutputText(responseBody);
141
+ if (outputText === undefined) {
142
+ throw createInternal("OpenAI Responses payload did not contain text output.", {
143
+ providerId: this.id,
144
+ runId: context.runId
145
+ });
146
+ }
147
+ const result = {
148
+ schemaVersion: "1.0",
149
+ runId: context.runId,
150
+ output: {
151
+ type: "text",
152
+ text: outputText
153
+ },
154
+ finishReason: getFinishReason(responseBody),
155
+ telemetry: {
156
+ providerUsed: this.id,
157
+ totalMs: 0
158
+ }
159
+ };
160
+ const usage = getUsage(responseBody);
161
+ if (usage) {
162
+ result.usage = usage;
163
+ }
164
+ return result;
165
+ }
166
+ createRequestBody(request) {
167
+ const body = {
168
+ model: this.options.model,
169
+ input: createInput(request)
170
+ };
171
+ const generation = request.generation;
172
+ if (generation?.maxOutputTokens !== undefined) {
173
+ body.max_output_tokens = generation.maxOutputTokens;
174
+ }
175
+ if (generation?.temperature !== undefined) {
176
+ body.temperature = generation.temperature;
177
+ }
178
+ if (generation?.topP !== undefined) {
179
+ body.top_p = generation.topP;
180
+ }
181
+ if (generation?.stop !== undefined) {
182
+ body.stop = generation.stop;
183
+ }
184
+ return body;
185
+ }
186
+ /**
187
+ * Maps an OpenAI HTTP error response onto the IndeRun error taxonomy:
188
+ * - `401` / `403` → `AuthError`
189
+ * - `429` → `RateLimited` (honors `Retry-After` when present)
190
+ * - `408` / `504` → `Timeout`
191
+ * - `409` / `5xx` → `Unavailable`
192
+ * - any other non-2xx status → `Internal`
193
+ */
194
+ mapHttpError(status, statusText, headers, body, context) {
195
+ const error = parseJson(body);
196
+ const message = getOpenAIErrorMessage(error, status, statusText);
197
+ const details = {
198
+ status,
199
+ statusText,
200
+ errorType: getString(error.error?.type),
201
+ errorCode: getString(error.error?.code)
202
+ };
203
+ if (status === 401 || status === 403) {
204
+ return createAuthError(message, {
205
+ providerId: this.id,
206
+ runId: context.runId,
207
+ details
208
+ });
209
+ }
210
+ if (status === 429) {
211
+ const retryAfterMs = parseRetryAfterMs(headers);
212
+ const params = {
213
+ providerId: this.id,
214
+ runId: context.runId,
215
+ retryable: true,
216
+ details
217
+ };
218
+ if (retryAfterMs !== undefined) {
219
+ return createRateLimited(message, {
220
+ ...params,
221
+ retryAfterMs
222
+ });
223
+ }
224
+ return createRateLimited(message, params);
225
+ }
226
+ if (status === 408 || status === 504) {
227
+ return createTimeout(message, {
228
+ providerId: this.id,
229
+ runId: context.runId,
230
+ retryable: true,
231
+ details
232
+ });
233
+ }
234
+ if (status === 409 || status >= 500) {
235
+ return createUnavailable(message, {
236
+ providerId: this.id,
237
+ runId: context.runId,
238
+ retryable: true,
239
+ details
240
+ });
241
+ }
242
+ return createInternal(message, {
243
+ providerId: this.id,
244
+ runId: context.runId,
245
+ details
246
+ });
247
+ }
248
+ }
249
+ function createInput(request) {
250
+ if (request.messages && request.messages.length > 0) {
251
+ return request.messages.map((message) => ({
252
+ role: message.role === "system" ? "developer" : message.role,
253
+ content: message.content
254
+ }));
255
+ }
256
+ return request.prompt ?? "";
257
+ }
258
+ function extractOutputText(response) {
259
+ if (typeof response.output_text === "string") {
260
+ return response.output_text;
261
+ }
262
+ if (!Array.isArray(response.output)) {
263
+ return undefined;
264
+ }
265
+ const textParts = [];
266
+ for (const item of response.output) {
267
+ if (!isRecord(item) || !Array.isArray(item.content)) {
268
+ continue;
269
+ }
270
+ for (const contentItem of item.content) {
271
+ if (isRecord(contentItem) &&
272
+ contentItem.type === "output_text" &&
273
+ typeof contentItem.text === "string") {
274
+ textParts.push(contentItem.text);
275
+ }
276
+ }
277
+ }
278
+ return textParts.length > 0 ? textParts.join("") : undefined;
279
+ }
280
+ function getFinishReason(response) {
281
+ if (response.status === "incomplete") {
282
+ return response.incomplete_details?.reason === "max_output_tokens" ? "length" : "error";
283
+ }
284
+ return "stop";
285
+ }
286
+ function getUsage(response) {
287
+ const usage = {};
288
+ if (typeof response.usage?.input_tokens === "number") {
289
+ usage.inputTokens = response.usage.input_tokens;
290
+ }
291
+ if (typeof response.usage?.output_tokens === "number") {
292
+ usage.outputTokens = response.usage.output_tokens;
293
+ }
294
+ if (typeof response.usage?.total_tokens === "number") {
295
+ usage.totalTokens = response.usage.total_tokens;
296
+ }
297
+ return Object.keys(usage).length > 0 ? usage : undefined;
298
+ }
299
+ function parseJson(value) {
300
+ try {
301
+ return JSON.parse(value);
302
+ }
303
+ catch {
304
+ return {};
305
+ }
306
+ }
307
+ function getOpenAIErrorMessage(response, status, statusText) {
308
+ if (typeof response.error?.message === "string" && response.error.message.length > 0) {
309
+ return response.error.message;
310
+ }
311
+ return `OpenAI Responses request failed with HTTP ${status} ${statusText}.`;
312
+ }
313
+ function parseRetryAfterMs(headers) {
314
+ const raw = headers["retry-after"] ?? headers["Retry-After"];
315
+ if (!raw) {
316
+ return undefined;
317
+ }
318
+ const seconds = Number(raw);
319
+ if (Number.isFinite(seconds)) {
320
+ return Math.max(0, seconds * 1000);
321
+ }
322
+ const dateMs = Date.parse(raw);
323
+ if (Number.isFinite(dateMs)) {
324
+ return Math.max(0, dateMs - Date.now());
325
+ }
326
+ return undefined;
327
+ }
328
+ function isAbortError(error) {
329
+ return isRecord(error) && getString(error.name) === "AbortError";
330
+ }
331
+ function getErrorSummary(error) {
332
+ if (error instanceof Error) {
333
+ return {
334
+ name: error.name,
335
+ message: error.message
336
+ };
337
+ }
338
+ return { message: String(error) };
339
+ }
340
+ function isRecord(value) {
341
+ return Boolean(value) && typeof value === "object";
342
+ }
343
+ function getString(value) {
344
+ return typeof value === "string" ? value : undefined;
345
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Provider-specific entry point for the OpenAI Responses adapter.
3
+ *
4
+ * Kept out of the unified SDK index (`@independo/inderun-web`) so the top-level
5
+ * surface stays provider-agnostic. Import from `@independo/inderun-web/openai`
6
+ * when registering the adapter manually; most browser apps should use
7
+ * `createIndeRunWeb` from the main entry point instead.
8
+ */
9
+ export { OpenAIResponsesProvider, type OpenAIProviderOptions, DEFAULT_OPENAI_RESPONSES_ENDPOINT } from "./openai-provider.js";
10
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../src/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,iCAAiC,EAClC,MAAM,sBAAsB,CAAC"}
package/dist/openai.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Provider-specific entry point for the OpenAI Responses adapter.
3
+ *
4
+ * Kept out of the unified SDK index (`@independo/inderun-web`) so the top-level
5
+ * surface stays provider-agnostic. Import from `@independo/inderun-web/openai`
6
+ * when registering the adapter manually; most browser apps should use
7
+ * `createIndeRunWeb` from the main entry point instead.
8
+ */
9
+ export { OpenAIResponsesProvider, DEFAULT_OPENAI_RESPONSES_ENDPOINT } from "./openai-provider.js";