summaryrefslogtreecommitdiffhomepage
path: root/packages/sdk/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/sdk/src')
-rw-r--r--packages/sdk/src/api-promise.ts2
-rw-r--r--packages/sdk/src/client.ts862
-rw-r--r--packages/sdk/src/core/README.md3
-rw-r--r--packages/sdk/src/core/api-promise.ts92
-rw-r--r--packages/sdk/src/core/error.ts130
-rw-r--r--packages/sdk/src/core/resource.ts11
-rw-r--r--packages/sdk/src/core/streaming.ts315
-rw-r--r--packages/sdk/src/core/uploads.ts2
-rw-r--r--packages/sdk/src/error.ts2
-rw-r--r--packages/sdk/src/index.ts22
-rw-r--r--packages/sdk/src/internal/README.md3
-rw-r--r--packages/sdk/src/internal/builtin-types.ts93
-rw-r--r--packages/sdk/src/internal/decoders/line.ts135
-rw-r--r--packages/sdk/src/internal/detect-platform.ts196
-rw-r--r--packages/sdk/src/internal/errors.ts33
-rw-r--r--packages/sdk/src/internal/headers.ts97
-rw-r--r--packages/sdk/src/internal/parse.ts64
-rw-r--r--packages/sdk/src/internal/request-options.ts93
-rw-r--r--packages/sdk/src/internal/shim-types.ts26
-rw-r--r--packages/sdk/src/internal/shims.ts107
-rw-r--r--packages/sdk/src/internal/to-file.ts154
-rw-r--r--packages/sdk/src/internal/types.ts95
-rw-r--r--packages/sdk/src/internal/uploads.ts187
-rw-r--r--packages/sdk/src/internal/utils.ts8
-rw-r--r--packages/sdk/src/internal/utils/base64.ts40
-rw-r--r--packages/sdk/src/internal/utils/bytes.ts32
-rw-r--r--packages/sdk/src/internal/utils/env.ts18
-rw-r--r--packages/sdk/src/internal/utils/log.ts126
-rw-r--r--packages/sdk/src/internal/utils/path.ts88
-rw-r--r--packages/sdk/src/internal/utils/sleep.ts3
-rw-r--r--packages/sdk/src/internal/utils/uuid.ts17
-rw-r--r--packages/sdk/src/internal/utils/values.ts105
-rw-r--r--packages/sdk/src/lib/.keep4
-rw-r--r--packages/sdk/src/resource.ts2
-rw-r--r--packages/sdk/src/resources.ts1
-rw-r--r--packages/sdk/src/resources/app.ts192
-rw-r--r--packages/sdk/src/resources/config.ts492
-rw-r--r--packages/sdk/src/resources/event.ts267
-rw-r--r--packages/sdk/src/resources/file.ts52
-rw-r--r--packages/sdk/src/resources/find.ts134
-rw-r--r--packages/sdk/src/resources/index.ts81
-rw-r--r--packages/sdk/src/resources/session.ts605
-rw-r--r--packages/sdk/src/resources/shared.ts33
-rw-r--r--packages/sdk/src/resources/tui.ts37
-rw-r--r--packages/sdk/src/streaming.ts2
-rw-r--r--packages/sdk/src/uploads.ts2
-rw-r--r--packages/sdk/src/version.ts1
47 files changed, 0 insertions, 5066 deletions
diff --git a/packages/sdk/src/api-promise.ts b/packages/sdk/src/api-promise.ts
deleted file mode 100644
index 8c775ee69..000000000
--- a/packages/sdk/src/api-promise.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** @deprecated Import from ./core/api-promise instead */
-export * from './core/api-promise';
diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts
deleted file mode 100644
index 9241bd582..000000000
--- a/packages/sdk/src/client.ts
+++ /dev/null
@@ -1,862 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types';
-import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types';
-import { uuid4 } from './internal/utils/uuid';
-import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values';
-import { sleep } from './internal/utils/sleep';
-export type { Logger, LogLevel } from './internal/utils/log';
-import { castToError, isAbortError } from './internal/errors';
-import type { APIResponseProps } from './internal/parse';
-import { getPlatformHeaders } from './internal/detect-platform';
-import * as Shims from './internal/shims';
-import * as Opts from './internal/request-options';
-import { VERSION } from './version';
-import * as Errors from './core/error';
-import * as Uploads from './core/uploads';
-import * as API from './resources/index';
-import { APIPromise } from './core/api-promise';
-import {
- App,
- AppInitResponse,
- AppLogParams,
- AppLogResponse,
- AppModesResponse,
- AppProvidersResponse,
- AppResource,
- Mode,
- Model,
- Provider,
-} from './resources/app';
-import {
- Config,
- ConfigResource,
- KeybindsConfig,
- McpLocalConfig,
- McpRemoteConfig,
- ModeConfig,
-} from './resources/config';
-import { Event, EventListResponse } from './resources/event';
-import { File, FileReadParams, FileReadResponse, FileResource, FileStatusResponse } from './resources/file';
-import {
- Find,
- FindFilesParams,
- FindFilesResponse,
- FindSymbolsParams,
- FindSymbolsResponse,
- FindTextParams,
- FindTextResponse,
- Symbol,
-} from './resources/find';
-import {
- AssistantMessage,
- FilePart,
- FilePartInput,
- FilePartSource,
- FilePartSourceText,
- FileSource,
- Message,
- Part,
- Session,
- SessionAbortResponse,
- SessionChatParams,
- SessionDeleteResponse,
- SessionInitParams,
- SessionInitResponse,
- SessionListResponse,
- SessionMessagesResponse,
- SessionResource,
- SessionRevertParams,
- SessionSummarizeParams,
- SessionSummarizeResponse,
- SnapshotPart,
- StepFinishPart,
- StepStartPart,
- SymbolSource,
- TextPart,
- TextPartInput,
- ToolPart,
- ToolStateCompleted,
- ToolStateError,
- ToolStatePending,
- ToolStateRunning,
- UserMessage,
-} from './resources/session';
-import { Tui, TuiAppendPromptParams, TuiAppendPromptResponse, TuiOpenHelpResponse } from './resources/tui';
-import { type Fetch } from './internal/builtin-types';
-import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
-import { FinalRequestOptions, RequestOptions } from './internal/request-options';
-import { readEnv } from './internal/utils/env';
-import {
- type LogLevel,
- type Logger,
- formatRequestDetails,
- loggerFor,
- parseLogLevel,
-} from './internal/utils/log';
-import { isEmptyObj } from './internal/utils/values';
-
-export interface ClientOptions {
- /**
- * Override the default base URL for the API, e.g., "https://api.example.com/v2/"
- *
- * Defaults to process.env['OPENCODE_BASE_URL'].
- */
- baseURL?: string | null | undefined;
-
- /**
- * The maximum amount of time (in milliseconds) that the client should wait for a response
- * from the server before timing out a single request.
- *
- * Note that request timeouts are retried by default, so in a worst-case scenario you may wait
- * much longer than this timeout before the promise succeeds or fails.
- *
- * @unit milliseconds
- */
- timeout?: number | undefined;
- /**
- * Additional `RequestInit` options to be passed to `fetch` calls.
- * Properties will be overridden by per-request `fetchOptions`.
- */
- fetchOptions?: MergedRequestInit | undefined;
-
- /**
- * Specify a custom `fetch` function implementation.
- *
- * If not provided, we expect that `fetch` is defined globally.
- */
- fetch?: Fetch | undefined;
-
- /**
- * The maximum number of times that the client will retry a request in case of a
- * temporary failure, like a network error or a 5XX error from the server.
- *
- * @default 2
- */
- maxRetries?: number | undefined;
-
- /**
- * Default headers to include with every request to the API.
- *
- * These can be removed in individual requests by explicitly setting the
- * header to `null` in request options.
- */
- defaultHeaders?: HeadersLike | undefined;
-
- /**
- * Default query parameters to include with every request to the API.
- *
- * These can be removed in individual requests by explicitly setting the
- * param to `undefined` in request options.
- */
- defaultQuery?: Record<string, string | undefined> | undefined;
-
- /**
- * Set the log level.
- *
- * Defaults to process.env['OPENCODE_LOG'] or 'warn' if it isn't set.
- */
- logLevel?: LogLevel | undefined;
-
- /**
- * Set the logger.
- *
- * Defaults to globalThis.console.
- */
- logger?: Logger | undefined;
-}
-
-/**
- * API Client for interfacing with the Opencode API.
- */
-export class Opencode {
- baseURL: string;
- maxRetries: number;
- timeout: number;
- logger: Logger | undefined;
- logLevel: LogLevel | undefined;
- fetchOptions: MergedRequestInit | undefined;
-
- private fetch: Fetch;
- #encoder: Opts.RequestEncoder;
- protected idempotencyHeader?: string;
- private _options: ClientOptions;
-
- /**
- * API Client for interfacing with the Opencode API.
- *
- * @param {string} [opts.baseURL=process.env['OPENCODE_BASE_URL'] ?? http://localhost:54321] - Override the default base URL for the API.
- * @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
- * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
- * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
- * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
- * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
- * @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
- */
- constructor({ baseURL = readEnv('OPENCODE_BASE_URL'), ...opts }: ClientOptions = {}) {
- const options: ClientOptions = {
- ...opts,
- baseURL: baseURL || `http://localhost:54321`,
- };
-
- this.baseURL = options.baseURL!;
- this.timeout = options.timeout ?? Opencode.DEFAULT_TIMEOUT /* 1 minute */;
- this.logger = options.logger ?? console;
- const defaultLogLevel = 'warn';
- // Set default logLevel early so that we can log a warning in parseLogLevel.
- this.logLevel = defaultLogLevel;
- this.logLevel =
- parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
- parseLogLevel(readEnv('OPENCODE_LOG'), "process.env['OPENCODE_LOG']", this) ??
- defaultLogLevel;
- this.fetchOptions = options.fetchOptions;
- this.maxRetries = options.maxRetries ?? 2;
- this.fetch = options.fetch ?? Shims.getDefaultFetch();
- this.#encoder = Opts.FallbackEncoder;
-
- this._options = options;
- }
-
- /**
- * Create a new client instance re-using the same options given to the current client with optional overriding.
- */
- withOptions(options: Partial<ClientOptions>): this {
- const client = new (this.constructor as any as new (props: ClientOptions) => typeof this)({
- ...this._options,
- baseURL: this.baseURL,
- maxRetries: this.maxRetries,
- timeout: this.timeout,
- logger: this.logger,
- logLevel: this.logLevel,
- fetch: this.fetch,
- fetchOptions: this.fetchOptions,
- ...options,
- });
- return client;
- }
-
- /**
- * Check whether the base URL is set to its default.
- */
- #baseURLOverridden(): boolean {
- return this.baseURL !== 'http://localhost:54321';
- }
-
- protected defaultQuery(): Record<string, string | undefined> | undefined {
- return this._options.defaultQuery;
- }
-
- protected validateHeaders({ values, nulls }: NullableHeaders) {
- return;
- }
-
- /**
- * Basic re-implementation of `qs.stringify` for primitive types.
- */
- protected stringifyQuery(query: Record<string, unknown>): string {
- return Object.entries(query)
- .filter(([_, value]) => typeof value !== 'undefined')
- .map(([key, value]) => {
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
- return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
- }
- if (value === null) {
- return `${encodeURIComponent(key)}=`;
- }
- throw new Errors.OpencodeError(
- `Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
- );
- })
- .join('&');
- }
-
- private getUserAgent(): string {
- return `${this.constructor.name}/JS ${VERSION}`;
- }
-
- protected defaultIdempotencyKey(): string {
- return `stainless-node-retry-${uuid4()}`;
- }
-
- protected makeStatusError(
- status: number,
- error: Object,
- message: string | undefined,
- headers: Headers,
- ): Errors.APIError {
- return Errors.APIError.generate(status, error, message, headers);
- }
-
- buildURL(
- path: string,
- query: Record<string, unknown> | null | undefined,
- defaultBaseURL?: string | undefined,
- ): string {
- const baseURL = (!this.#baseURLOverridden() && defaultBaseURL) || this.baseURL;
- const url =
- isAbsoluteURL(path) ?
- new URL(path)
- : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
-
- const defaultQuery = this.defaultQuery();
- if (!isEmptyObj(defaultQuery)) {
- query = { ...defaultQuery, ...query };
- }
-
- if (typeof query === 'object' && query && !Array.isArray(query)) {
- url.search = this.stringifyQuery(query as Record<string, unknown>);
- }
-
- return url.toString();
- }
-
- /**
- * Used as a callback for mutating the given `FinalRequestOptions` object.
- */
- protected async prepareOptions(options: FinalRequestOptions): Promise<void> {}
-
- /**
- * Used as a callback for mutating the given `RequestInit` object.
- *
- * This is useful for cases where you want to add certain headers based off of
- * the request properties, e.g. `method` or `url`.
- */
- protected async prepareRequest(
- request: RequestInit,
- { url, options }: { url: string; options: FinalRequestOptions },
- ): Promise<void> {}
-
- get<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
- return this.methodRequest('get', path, opts);
- }
-
- post<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
- return this.methodRequest('post', path, opts);
- }
-
- patch<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
- return this.methodRequest('patch', path, opts);
- }
-
- put<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
- return this.methodRequest('put', path, opts);
- }
-
- delete<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
- return this.methodRequest('delete', path, opts);
- }
-
- private methodRequest<Rsp>(
- method: HTTPMethod,
- path: string,
- opts?: PromiseOrValue<RequestOptions>,
- ): APIPromise<Rsp> {
- return this.request(
- Promise.resolve(opts).then((opts) => {
- return { method, path, ...opts };
- }),
- );
- }
-
- request<Rsp>(
- options: PromiseOrValue<FinalRequestOptions>,
- remainingRetries: number | null = null,
- ): APIPromise<Rsp> {
- return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
- }
-
- private async makeRequest(
- optionsInput: PromiseOrValue<FinalRequestOptions>,
- retriesRemaining: number | null,
- retryOfRequestLogID: string | undefined,
- ): Promise<APIResponseProps> {
- const options = await optionsInput;
- const maxRetries = options.maxRetries ?? this.maxRetries;
- if (retriesRemaining == null) {
- retriesRemaining = maxRetries;
- }
-
- await this.prepareOptions(options);
-
- const { req, url, timeout } = await this.buildRequest(options, {
- retryCount: maxRetries - retriesRemaining,
- });
-
- await this.prepareRequest(req, { url, options });
-
- /** Not an API request ID, just for correlating local log entries. */
- const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
- const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
- const startTime = Date.now();
-
- loggerFor(this).debug(
- `[${requestLogID}] sending request`,
- formatRequestDetails({
- retryOfRequestLogID,
- method: options.method,
- url,
- options,
- headers: req.headers,
- }),
- );
-
- if (options.signal?.aborted) {
- throw new Errors.APIUserAbortError();
- }
-
- const controller = new AbortController();
- const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
- const headersTime = Date.now();
-
- if (response instanceof Error) {
- const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
- if (options.signal?.aborted) {
- throw new Errors.APIUserAbortError();
- }
- // detect native connection timeout errors
- // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
- // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
- // others do not provide enough information to distinguish timeouts from other connection errors
- const isTimeout =
- isAbortError(response) ||
- /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
- if (retriesRemaining) {
- loggerFor(this).info(
- `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`,
- );
- loggerFor(this).debug(
- `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`,
- formatRequestDetails({
- retryOfRequestLogID,
- url,
- durationMs: headersTime - startTime,
- message: response.message,
- }),
- );
- return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
- }
- loggerFor(this).info(
- `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`,
- );
- loggerFor(this).debug(
- `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`,
- formatRequestDetails({
- retryOfRequestLogID,
- url,
- durationMs: headersTime - startTime,
- message: response.message,
- }),
- );
- if (isTimeout) {
- throw new Errors.APIConnectionTimeoutError();
- }
- throw new Errors.APIConnectionError({ cause: response });
- }
-
- const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${
- response.ok ? 'succeeded' : 'failed'
- } with status ${response.status} in ${headersTime - startTime}ms`;
-
- if (!response.ok) {
- const shouldRetry = await this.shouldRetry(response);
- if (retriesRemaining && shouldRetry) {
- const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
-
- // We don't need the body of this response.
- await Shims.CancelReadableStream(response.body);
- loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
- loggerFor(this).debug(
- `[${requestLogID}] response error (${retryMessage})`,
- formatRequestDetails({
- retryOfRequestLogID,
- url: response.url,
- status: response.status,
- headers: response.headers,
- durationMs: headersTime - startTime,
- }),
- );
- return this.retryRequest(
- options,
- retriesRemaining,
- retryOfRequestLogID ?? requestLogID,
- response.headers,
- );
- }
-
- const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
-
- loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
-
- const errText = await response.text().catch((err: any) => castToError(err).message);
- const errJSON = safeJSON(errText);
- const errMessage = errJSON ? undefined : errText;
-
- loggerFor(this).debug(
- `[${requestLogID}] response error (${retryMessage})`,
- formatRequestDetails({
- retryOfRequestLogID,
- url: response.url,
- status: response.status,
- headers: response.headers,
- message: errMessage,
- durationMs: Date.now() - startTime,
- }),
- );
-
- const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
- throw err;
- }
-
- loggerFor(this).info(responseInfo);
- loggerFor(this).debug(
- `[${requestLogID}] response start`,
- formatRequestDetails({
- retryOfRequestLogID,
- url: response.url,
- status: response.status,
- headers: response.headers,
- durationMs: headersTime - startTime,
- }),
- );
-
- return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
- }
-
- async fetchWithTimeout(
- url: RequestInfo,
- init: RequestInit | undefined,
- ms: number,
- controller: AbortController,
- ): Promise<Response> {
- const { signal, method, ...options } = init || {};
- if (signal) signal.addEventListener('abort', () => controller.abort());
-
- const timeout = setTimeout(() => controller.abort(), ms);
-
- const isReadableBody =
- ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
- (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
-
- const fetchOptions: RequestInit = {
- signal: controller.signal as any,
- ...(isReadableBody ? { duplex: 'half' } : {}),
- method: 'GET',
- ...options,
- };
- if (method) {
- // Custom methods like 'patch' need to be uppercased
- // See https://github.com/nodejs/undici/issues/2294
- fetchOptions.method = method.toUpperCase();
- }
-
- try {
- // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
- return await this.fetch.call(undefined, url, fetchOptions);
- } finally {
- clearTimeout(timeout);
- }
- }
-
- private async shouldRetry(response: Response): Promise<boolean> {
- // Note this is not a standard header.
- const shouldRetryHeader = response.headers.get('x-should-retry');
-
- // If the server explicitly says whether or not to retry, obey.
- if (shouldRetryHeader === 'true') return true;
- if (shouldRetryHeader === 'false') return false;
-
- // Retry on request timeouts.
- if (response.status === 408) return true;
-
- // Retry on lock timeouts.
- if (response.status === 409) return true;
-
- // Retry on rate limits.
- if (response.status === 429) return true;
-
- // Retry internal errors.
- if (response.status >= 500) return true;
-
- return false;
- }
-
- private async retryRequest(
- options: FinalRequestOptions,
- retriesRemaining: number,
- requestLogID: string,
- responseHeaders?: Headers | undefined,
- ): Promise<APIResponseProps> {
- let timeoutMillis: number | undefined;
-
- // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
- const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
- if (retryAfterMillisHeader) {
- const timeoutMs = parseFloat(retryAfterMillisHeader);
- if (!Number.isNaN(timeoutMs)) {
- timeoutMillis = timeoutMs;
- }
- }
-
- // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
- const retryAfterHeader = responseHeaders?.get('retry-after');
- if (retryAfterHeader && !timeoutMillis) {
- const timeoutSeconds = parseFloat(retryAfterHeader);
- if (!Number.isNaN(timeoutSeconds)) {
- timeoutMillis = timeoutSeconds * 1000;
- } else {
- timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
- }
- }
-
- // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
- // just do what it says, but otherwise calculate a default
- if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
- const maxRetries = options.maxRetries ?? this.maxRetries;
- timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
- }
- await sleep(timeoutMillis);
-
- return this.makeRequest(options, retriesRemaining - 1, requestLogID);
- }
-
- private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number {
- const initialRetryDelay = 0.5;
- const maxRetryDelay = 8.0;
-
- const numRetries = maxRetries - retriesRemaining;
-
- // Apply exponential backoff, but not more than the max.
- const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
-
- // Apply some jitter, take up to at most 25 percent of the retry time.
- const jitter = 1 - Math.random() * 0.25;
-
- return sleepSeconds * jitter * 1000;
- }
-
- async buildRequest(
- inputOptions: FinalRequestOptions,
- { retryCount = 0 }: { retryCount?: number } = {},
- ): Promise<{ req: FinalizedRequestInit; url: string; timeout: number }> {
- const options = { ...inputOptions };
- const { method, path, query, defaultBaseURL } = options;
-
- const url = this.buildURL(path!, query as Record<string, unknown>, defaultBaseURL);
- if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
- options.timeout = options.timeout ?? this.timeout;
- const { bodyHeaders, body } = this.buildBody({ options });
- const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
-
- const req: FinalizedRequestInit = {
- method,
- headers: reqHeaders,
- ...(options.signal && { signal: options.signal }),
- ...((globalThis as any).ReadableStream &&
- body instanceof (globalThis as any).ReadableStream && { duplex: 'half' }),
- ...(body && { body }),
- ...((this.fetchOptions as any) ?? {}),
- ...((options.fetchOptions as any) ?? {}),
- };
-
- return { req, url, timeout: options.timeout };
- }
-
- private async buildHeaders({
- options,
- method,
- bodyHeaders,
- retryCount,
- }: {
- options: FinalRequestOptions;
- method: HTTPMethod;
- bodyHeaders: HeadersLike;
- retryCount: number;
- }): Promise<Headers> {
- let idempotencyHeaders: HeadersLike = {};
- if (this.idempotencyHeader && method !== 'get') {
- if (!options.idempotencyKey) options.idempotencyKey = this.defaultIdempotencyKey();
- idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
- }
-
- const headers = buildHeaders([
- idempotencyHeaders,
- {
- Accept: 'application/json',
- 'User-Agent': this.getUserAgent(),
- 'X-Stainless-Retry-Count': String(retryCount),
- ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
- ...getPlatformHeaders(),
- },
- this._options.defaultHeaders,
- bodyHeaders,
- options.headers,
- ]);
-
- this.validateHeaders(headers);
-
- return headers.values;
- }
-
- private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): {
- bodyHeaders: HeadersLike;
- body: BodyInit | undefined;
- } {
- if (!body) {
- return { bodyHeaders: undefined, body: undefined };
- }
- const headers = buildHeaders([rawHeaders]);
- if (
- // Pass raw type verbatim
- ArrayBuffer.isView(body) ||
- body instanceof ArrayBuffer ||
- body instanceof DataView ||
- (typeof body === 'string' &&
- // Preserve legacy string encoding behavior for now
- headers.values.has('content-type')) ||
- // `Blob` is superset of `File`
- body instanceof Blob ||
- // `FormData` -> `multipart/form-data`
- body instanceof FormData ||
- // `URLSearchParams` -> `application/x-www-form-urlencoded`
- body instanceof URLSearchParams ||
- // Send chunked stream (each chunk has own `length`)
- ((globalThis as any).ReadableStream && body instanceof (globalThis as any).ReadableStream)
- ) {
- return { bodyHeaders: undefined, body: body as BodyInit };
- } else if (
- typeof body === 'object' &&
- (Symbol.asyncIterator in body ||
- (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))
- ) {
- return { bodyHeaders: undefined, body: Shims.ReadableStreamFrom(body as AsyncIterable<Uint8Array>) };
- } else {
- return this.#encoder({ body, headers });
- }
- }
-
- static Opencode = this;
- static DEFAULT_TIMEOUT = 60000; // 1 minute
-
- static OpencodeError = Errors.OpencodeError;
- static APIError = Errors.APIError;
- static APIConnectionError = Errors.APIConnectionError;
- static APIConnectionTimeoutError = Errors.APIConnectionTimeoutError;
- static APIUserAbortError = Errors.APIUserAbortError;
- static NotFoundError = Errors.NotFoundError;
- static ConflictError = Errors.ConflictError;
- static RateLimitError = Errors.RateLimitError;
- static BadRequestError = Errors.BadRequestError;
- static AuthenticationError = Errors.AuthenticationError;
- static InternalServerError = Errors.InternalServerError;
- static PermissionDeniedError = Errors.PermissionDeniedError;
- static UnprocessableEntityError = Errors.UnprocessableEntityError;
-
- static toFile = Uploads.toFile;
-
- event: API.Event = new API.Event(this);
- app: API.AppResource = new API.AppResource(this);
- find: API.Find = new API.Find(this);
- file: API.FileResource = new API.FileResource(this);
- config: API.ConfigResource = new API.ConfigResource(this);
- session: API.SessionResource = new API.SessionResource(this);
- tui: API.Tui = new API.Tui(this);
-}
-Opencode.Event = Event;
-Opencode.AppResource = AppResource;
-Opencode.Find = Find;
-Opencode.FileResource = FileResource;
-Opencode.ConfigResource = ConfigResource;
-Opencode.SessionResource = SessionResource;
-Opencode.Tui = Tui;
-export declare namespace Opencode {
- export type RequestOptions = Opts.RequestOptions;
-
- export { Event as Event, type EventListResponse as EventListResponse };
-
- export {
- AppResource as AppResource,
- type App as App,
- type Mode as Mode,
- type Model as Model,
- type Provider as Provider,
- type AppInitResponse as AppInitResponse,
- type AppLogResponse as AppLogResponse,
- type AppModesResponse as AppModesResponse,
- type AppProvidersResponse as AppProvidersResponse,
- type AppLogParams as AppLogParams,
- };
-
- export {
- Find as Find,
- type Symbol as Symbol,
- type FindFilesResponse as FindFilesResponse,
- type FindSymbolsResponse as FindSymbolsResponse,
- type FindTextResponse as FindTextResponse,
- type FindFilesParams as FindFilesParams,
- type FindSymbolsParams as FindSymbolsParams,
- type FindTextParams as FindTextParams,
- };
-
- export {
- FileResource as FileResource,
- type File as File,
- type FileReadResponse as FileReadResponse,
- type FileStatusResponse as FileStatusResponse,
- type FileReadParams as FileReadParams,
- };
-
- export {
- ConfigResource as ConfigResource,
- type Config as Config,
- type KeybindsConfig as KeybindsConfig,
- type McpLocalConfig as McpLocalConfig,
- type McpRemoteConfig as McpRemoteConfig,
- type ModeConfig as ModeConfig,
- };
-
- export {
- SessionResource as SessionResource,
- type AssistantMessage as AssistantMessage,
- type FilePart as FilePart,
- type FilePartInput as FilePartInput,
- type FilePartSource as FilePartSource,
- type FilePartSourceText as FilePartSourceText,
- type FileSource as FileSource,
- type Message as Message,
- type Part as Part,
- type Session as Session,
- type SnapshotPart as SnapshotPart,
- type StepFinishPart as StepFinishPart,
- type StepStartPart as StepStartPart,
- type SymbolSource as SymbolSource,
- type TextPart as TextPart,
- type TextPartInput as TextPartInput,
- type ToolPart as ToolPart,
- type ToolStateCompleted as ToolStateCompleted,
- type ToolStateError as ToolStateError,
- type ToolStatePending as ToolStatePending,
- type ToolStateRunning as ToolStateRunning,
- type UserMessage as UserMessage,
- type SessionListResponse as SessionListResponse,
- type SessionDeleteResponse as SessionDeleteResponse,
- type SessionAbortResponse as SessionAbortResponse,
- type SessionInitResponse as SessionInitResponse,
- type SessionMessagesResponse as SessionMessagesResponse,
- type SessionSummarizeResponse as SessionSummarizeResponse,
- type SessionChatParams as SessionChatParams,
- type SessionInitParams as SessionInitParams,
- type SessionRevertParams as SessionRevertParams,
- type SessionSummarizeParams as SessionSummarizeParams,
- };
-
- export {
- Tui as Tui,
- type TuiAppendPromptResponse as TuiAppendPromptResponse,
- type TuiOpenHelpResponse as TuiOpenHelpResponse,
- type TuiAppendPromptParams as TuiAppendPromptParams,
- };
-
- export type MessageAbortedError = API.MessageAbortedError;
- export type ProviderAuthError = API.ProviderAuthError;
- export type UnknownError = API.UnknownError;
-}
diff --git a/packages/sdk/src/core/README.md b/packages/sdk/src/core/README.md
deleted file mode 100644
index 485fce861..000000000
--- a/packages/sdk/src/core/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `core`
-
-This directory holds public modules implementing non-resource-specific SDK functionality.
diff --git a/packages/sdk/src/core/api-promise.ts b/packages/sdk/src/core/api-promise.ts
deleted file mode 100644
index fc1c6dd76..000000000
--- a/packages/sdk/src/core/api-promise.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { type Opencode } from '../client';
-
-import { type PromiseOrValue } from '../internal/types';
-import { APIResponseProps, defaultParseResponse } from '../internal/parse';
-
-/**
- * A subclass of `Promise` providing additional helper methods
- * for interacting with the SDK.
- */
-export class APIPromise<T> extends Promise<T> {
- private parsedPromise: Promise<T> | undefined;
- #client: Opencode;
-
- constructor(
- client: Opencode,
- private responsePromise: Promise<APIResponseProps>,
- private parseResponse: (
- client: Opencode,
- props: APIResponseProps,
- ) => PromiseOrValue<T> = defaultParseResponse,
- ) {
- super((resolve) => {
- // this is maybe a bit weird but this has to be a no-op to not implicitly
- // parse the response body; instead .then, .catch, .finally are overridden
- // to parse the response
- resolve(null as any);
- });
- this.#client = client;
- }
-
- _thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
- return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
- transform(await this.parseResponse(client, props), props),
- );
- }
-
- /**
- * Gets the raw `Response` instance instead of parsing the response
- * data.
- *
- * If you want to parse the response body but still get the `Response`
- * instance, you can use {@link withResponse()}.
- *
- * 👋 Getting the wrong TypeScript type for `Response`?
- * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
- * to your `tsconfig.json`.
- */
- asResponse(): Promise<Response> {
- return this.responsePromise.then((p) => p.response);
- }
-
- /**
- * Gets the parsed response data and the raw `Response` instance.
- *
- * If you just want to get the raw `Response` instance without parsing it,
- * you can use {@link asResponse()}.
- *
- * 👋 Getting the wrong TypeScript type for `Response`?
- * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
- * to your `tsconfig.json`.
- */
- async withResponse(): Promise<{ data: T; response: Response }> {
- const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
- return { data, response };
- }
-
- private parse(): Promise<T> {
- if (!this.parsedPromise) {
- this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data));
- }
- return this.parsedPromise;
- }
-
- override then<TResult1 = T, TResult2 = never>(
- onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
- onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
- ): Promise<TResult1 | TResult2> {
- return this.parse().then(onfulfilled, onrejected);
- }
-
- override catch<TResult = never>(
- onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
- ): Promise<T | TResult> {
- return this.parse().catch(onrejected);
- }
-
- override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
- return this.parse().finally(onfinally);
- }
-}
diff --git a/packages/sdk/src/core/error.ts b/packages/sdk/src/core/error.ts
deleted file mode 100644
index 44698c739..000000000
--- a/packages/sdk/src/core/error.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { castToError } from '../internal/errors';
-
-export class OpencodeError extends Error {}
-
-export class APIError<
- TStatus extends number | undefined = number | undefined,
- THeaders extends Headers | undefined = Headers | undefined,
- TError extends Object | undefined = Object | undefined,
-> extends OpencodeError {
- /** HTTP status for the response that caused the error */
- readonly status: TStatus;
- /** HTTP headers for the response that caused the error */
- readonly headers: THeaders;
- /** JSON body of the response that caused the error */
- readonly error: TError;
-
- constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) {
- super(`${APIError.makeMessage(status, error, message)}`);
- this.status = status;
- this.headers = headers;
- this.error = error;
- }
-
- private static makeMessage(status: number | undefined, error: any, message: string | undefined) {
- const msg =
- error?.message ?
- typeof error.message === 'string' ?
- error.message
- : JSON.stringify(error.message)
- : error ? JSON.stringify(error)
- : message;
-
- if (status && msg) {
- return `${status} ${msg}`;
- }
- if (status) {
- return `${status} status code (no body)`;
- }
- if (msg) {
- return msg;
- }
- return '(no status code or body)';
- }
-
- static generate(
- status: number | undefined,
- errorResponse: Object | undefined,
- message: string | undefined,
- headers: Headers | undefined,
- ): APIError {
- if (!status || !headers) {
- return new APIConnectionError({ message, cause: castToError(errorResponse) });
- }
-
- const error = errorResponse as Record<string, any>;
-
- if (status === 400) {
- return new BadRequestError(status, error, message, headers);
- }
-
- if (status === 401) {
- return new AuthenticationError(status, error, message, headers);
- }
-
- if (status === 403) {
- return new PermissionDeniedError(status, error, message, headers);
- }
-
- if (status === 404) {
- return new NotFoundError(status, error, message, headers);
- }
-
- if (status === 409) {
- return new ConflictError(status, error, message, headers);
- }
-
- if (status === 422) {
- return new UnprocessableEntityError(status, error, message, headers);
- }
-
- if (status === 429) {
- return new RateLimitError(status, error, message, headers);
- }
-
- if (status >= 500) {
- return new InternalServerError(status, error, message, headers);
- }
-
- return new APIError(status, error, message, headers);
- }
-}
-
-export class APIUserAbortError extends APIError<undefined, undefined, undefined> {
- constructor({ message }: { message?: string } = {}) {
- super(undefined, undefined, message || 'Request was aborted.', undefined);
- }
-}
-
-export class APIConnectionError extends APIError<undefined, undefined, undefined> {
- constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) {
- super(undefined, undefined, message || 'Connection error.', undefined);
- // in some environments the 'cause' property is already declared
- // @ts-ignore
- if (cause) this.cause = cause;
- }
-}
-
-export class APIConnectionTimeoutError extends APIConnectionError {
- constructor({ message }: { message?: string } = {}) {
- super({ message: message ?? 'Request timed out.' });
- }
-}
-
-export class BadRequestError extends APIError<400, Headers> {}
-
-export class AuthenticationError extends APIError<401, Headers> {}
-
-export class PermissionDeniedError extends APIError<403, Headers> {}
-
-export class NotFoundError extends APIError<404, Headers> {}
-
-export class ConflictError extends APIError<409, Headers> {}
-
-export class UnprocessableEntityError extends APIError<422, Headers> {}
-
-export class RateLimitError extends APIError<429, Headers> {}
-
-export class InternalServerError extends APIError<number, Headers> {}
diff --git a/packages/sdk/src/core/resource.ts b/packages/sdk/src/core/resource.ts
deleted file mode 100644
index ccf9032e4..000000000
--- a/packages/sdk/src/core/resource.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import type { Opencode } from '../client';
-
-export abstract class APIResource {
- protected _client: Opencode;
-
- constructor(client: Opencode) {
- this._client = client;
- }
-}
diff --git a/packages/sdk/src/core/streaming.ts b/packages/sdk/src/core/streaming.ts
deleted file mode 100644
index 33dcfd126..000000000
--- a/packages/sdk/src/core/streaming.ts
+++ /dev/null
@@ -1,315 +0,0 @@
-import { OpencodeError } from './error';
-import { type ReadableStream } from '../internal/shim-types';
-import { makeReadableStream } from '../internal/shims';
-import { findDoubleNewlineIndex, LineDecoder } from '../internal/decoders/line';
-import { ReadableStreamToAsyncIterable } from '../internal/shims';
-import { isAbortError } from '../internal/errors';
-import { encodeUTF8 } from '../internal/utils/bytes';
-import { loggerFor } from '../internal/utils/log';
-import type { Opencode } from '../client';
-
-type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
-
-export type ServerSentEvent = {
- event: string | null;
- data: string;
- raw: string[];
-};
-
-export class Stream<Item> implements AsyncIterable<Item> {
- controller: AbortController;
- #client: Opencode | undefined;
-
- constructor(
- private iterator: () => AsyncIterator<Item>,
- controller: AbortController,
- client?: Opencode,
- ) {
- this.controller = controller;
- this.#client = client;
- }
-
- static fromSSEResponse<Item>(
- response: Response,
- controller: AbortController,
- client?: Opencode,
- ): Stream<Item> {
- let consumed = false;
- const logger = client ? loggerFor(client) : console;
-
- async function* iterator(): AsyncIterator<Item, any, undefined> {
- if (consumed) {
- throw new OpencodeError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.');
- }
- consumed = true;
- let done = false;
- try {
- for await (const sse of _iterSSEMessages(response, controller)) {
- try {
- yield JSON.parse(sse.data);
- } catch (e) {
- logger.error(`Could not parse message into JSON:`, sse.data);
- logger.error(`From chunk:`, sse.raw);
- throw e;
- }
- }
- done = true;
- } catch (e) {
- // If the user calls `stream.controller.abort()`, we should exit without throwing.
- if (isAbortError(e)) return;
- throw e;
- } finally {
- // If the user `break`s, abort the ongoing request.
- if (!done) controller.abort();
- }
- }
-
- return new Stream(iterator, controller, client);
- }
-
- /**
- * Generates a Stream from a newline-separated ReadableStream
- * where each item is a JSON value.
- */
- static fromReadableStream<Item>(
- readableStream: ReadableStream,
- controller: AbortController,
- client?: Opencode,
- ): Stream<Item> {
- let consumed = false;
-
- async function* iterLines(): AsyncGenerator<string, void, unknown> {
- const lineDecoder = new LineDecoder();
-
- const iter = ReadableStreamToAsyncIterable<Bytes>(readableStream);
- for await (const chunk of iter) {
- for (const line of lineDecoder.decode(chunk)) {
- yield line;
- }
- }
-
- for (const line of lineDecoder.flush()) {
- yield line;
- }
- }
-
- async function* iterator(): AsyncIterator<Item, any, undefined> {
- if (consumed) {
- throw new OpencodeError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.');
- }
- consumed = true;
- let done = false;
- try {
- for await (const line of iterLines()) {
- if (done) continue;
- if (line) yield JSON.parse(line);
- }
- done = true;
- } catch (e) {
- // If the user calls `stream.controller.abort()`, we should exit without throwing.
- if (isAbortError(e)) return;
- throw e;
- } finally {
- // If the user `break`s, abort the ongoing request.
- if (!done) controller.abort();
- }
- }
-
- return new Stream(iterator, controller, client);
- }
-
- [Symbol.asyncIterator](): AsyncIterator<Item> {
- return this.iterator();
- }
-
- /**
- * Splits the stream into two streams which can be
- * independently read from at different speeds.
- */
- tee(): [Stream<Item>, Stream<Item>] {
- const left: Array<Promise<IteratorResult<Item>>> = [];
- const right: Array<Promise<IteratorResult<Item>>> = [];
- const iterator = this.iterator();
-
- const teeIterator = (queue: Array<Promise<IteratorResult<Item>>>): AsyncIterator<Item> => {
- return {
- next: () => {
- if (queue.length === 0) {
- const result = iterator.next();
- left.push(result);
- right.push(result);
- }
- return queue.shift()!;
- },
- };
- };
-
- return [
- new Stream(() => teeIterator(left), this.controller, this.#client),
- new Stream(() => teeIterator(right), this.controller, this.#client),
- ];
- }
-
- /**
- * Converts this stream to a newline-separated ReadableStream of
- * JSON stringified values in the stream
- * which can be turned back into a Stream with `Stream.fromReadableStream()`.
- */
- toReadableStream(): ReadableStream {
- const self = this;
- let iter: AsyncIterator<Item>;
-
- return makeReadableStream({
- async start() {
- iter = self[Symbol.asyncIterator]();
- },
- async pull(ctrl: any) {
- try {
- const { value, done } = await iter.next();
- if (done) return ctrl.close();
-
- const bytes = encodeUTF8(JSON.stringify(value) + '\n');
-
- ctrl.enqueue(bytes);
- } catch (err) {
- ctrl.error(err);
- }
- },
- async cancel() {
- await iter.return?.();
- },
- });
- }
-}
-
-export async function* _iterSSEMessages(
- response: Response,
- controller: AbortController,
-): AsyncGenerator<ServerSentEvent, void, unknown> {
- if (!response.body) {
- controller.abort();
- if (
- typeof (globalThis as any).navigator !== 'undefined' &&
- (globalThis as any).navigator.product === 'ReactNative'
- ) {
- throw new OpencodeError(
- `The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`,
- );
- }
- throw new OpencodeError(`Attempted to iterate over a response with no body`);
- }
-
- const sseDecoder = new SSEDecoder();
- const lineDecoder = new LineDecoder();
-
- const iter = ReadableStreamToAsyncIterable<Bytes>(response.body);
- for await (const sseChunk of iterSSEChunks(iter)) {
- for (const line of lineDecoder.decode(sseChunk)) {
- const sse = sseDecoder.decode(line);
- if (sse) yield sse;
- }
- }
-
- for (const line of lineDecoder.flush()) {
- const sse = sseDecoder.decode(line);
- if (sse) yield sse;
- }
-}
-
-/**
- * Given an async iterable iterator, iterates over it and yields full
- * SSE chunks, i.e. yields when a double new-line is encountered.
- */
-async function* iterSSEChunks(iterator: AsyncIterableIterator<Bytes>): AsyncGenerator<Uint8Array> {
- let data = new Uint8Array();
-
- for await (const chunk of iterator) {
- if (chunk == null) {
- continue;
- }
-
- const binaryChunk =
- chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
- : typeof chunk === 'string' ? encodeUTF8(chunk)
- : chunk;
-
- let newData = new Uint8Array(data.length + binaryChunk.length);
- newData.set(data);
- newData.set(binaryChunk, data.length);
- data = newData;
-
- let patternIndex;
- while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
- yield data.slice(0, patternIndex);
- data = data.slice(patternIndex);
- }
- }
-
- if (data.length > 0) {
- yield data;
- }
-}
-
-class SSEDecoder {
- private data: string[];
- private event: string | null;
- private chunks: string[];
-
- constructor() {
- this.event = null;
- this.data = [];
- this.chunks = [];
- }
-
- decode(line: string) {
- if (line.endsWith('\r')) {
- line = line.substring(0, line.length - 1);
- }
-
- if (!line) {
- // empty line and we didn't previously encounter any messages
- if (!this.event && !this.data.length) return null;
-
- const sse: ServerSentEvent = {
- event: this.event,
- data: this.data.join('\n'),
- raw: this.chunks,
- };
-
- this.event = null;
- this.data = [];
- this.chunks = [];
-
- return sse;
- }
-
- this.chunks.push(line);
-
- if (line.startsWith(':')) {
- return null;
- }
-
- let [fieldname, _, value] = partition(line, ':');
-
- if (value.startsWith(' ')) {
- value = value.substring(1);
- }
-
- if (fieldname === 'event') {
- this.event = value;
- } else if (fieldname === 'data') {
- this.data.push(value);
- }
-
- return null;
- }
-}
-
-function partition(str: string, delimiter: string): [string, string, string] {
- const index = str.indexOf(delimiter);
- if (index !== -1) {
- return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
- }
-
- return [str, '', ''];
-}
diff --git a/packages/sdk/src/core/uploads.ts b/packages/sdk/src/core/uploads.ts
deleted file mode 100644
index 2882ca6d1..000000000
--- a/packages/sdk/src/core/uploads.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { type Uploadable } from '../internal/uploads';
-export { toFile, type ToFileInput } from '../internal/to-file';
diff --git a/packages/sdk/src/error.ts b/packages/sdk/src/error.ts
deleted file mode 100644
index fc55f46c0..000000000
--- a/packages/sdk/src/error.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** @deprecated Import from ./core/error instead */
-export * from './core/error';
diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts
deleted file mode 100644
index 43d2f6363..000000000
--- a/packages/sdk/src/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export { Opencode as default } from './client';
-
-export { type Uploadable, toFile } from './core/uploads';
-export { APIPromise } from './core/api-promise';
-export { Opencode, type ClientOptions } from './client';
-export {
- OpencodeError,
- APIError,
- APIConnectionError,
- APIConnectionTimeoutError,
- APIUserAbortError,
- NotFoundError,
- ConflictError,
- RateLimitError,
- BadRequestError,
- AuthenticationError,
- InternalServerError,
- PermissionDeniedError,
- UnprocessableEntityError,
-} from './core/error';
diff --git a/packages/sdk/src/internal/README.md b/packages/sdk/src/internal/README.md
deleted file mode 100644
index 3ef5a25ba..000000000
--- a/packages/sdk/src/internal/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `internal`
-
-The modules in this directory are not importable outside this package and will change between releases.
diff --git a/packages/sdk/src/internal/builtin-types.ts b/packages/sdk/src/internal/builtin-types.ts
deleted file mode 100644
index c23d3bded..000000000
--- a/packages/sdk/src/internal/builtin-types.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export type Fetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
-
-/**
- * An alias to the builtin `RequestInit` type so we can
- * easily alias it in import statements if there are name clashes.
- *
- * https://developer.mozilla.org/docs/Web/API/RequestInit
- */
-type _RequestInit = RequestInit;
-
-/**
- * An alias to the builtin `Response` type so we can
- * easily alias it in import statements if there are name clashes.
- *
- * https://developer.mozilla.org/docs/Web/API/Response
- */
-type _Response = Response;
-
-/**
- * The type for the first argument to `fetch`.
- *
- * https://developer.mozilla.org/docs/Web/API/Window/fetch#resource
- */
-type _RequestInfo = Request | URL | string;
-
-/**
- * The type for constructing `RequestInit` Headers.
- *
- * https://developer.mozilla.org/docs/Web/API/RequestInit#setting_headers
- */
-type _HeadersInit = RequestInit['headers'];
-
-/**
- * The type for constructing `RequestInit` body.
- *
- * https://developer.mozilla.org/docs/Web/API/RequestInit#body
- */
-type _BodyInit = RequestInit['body'];
-
-/**
- * An alias to the builtin `Array<T>` type so we can
- * easily alias it in import statements if there are name clashes.
- */
-type _Array<T> = Array<T>;
-
-/**
- * An alias to the builtin `Record<K, T>` type so we can
- * easily alias it in import statements if there are name clashes.
- */
-type _Record<K extends keyof any, T> = Record<K, T>;
-
-export type {
- _Array as Array,
- _BodyInit as BodyInit,
- _HeadersInit as HeadersInit,
- _Record as Record,
- _RequestInfo as RequestInfo,
- _RequestInit as RequestInit,
- _Response as Response,
-};
-
-/**
- * A copy of the builtin `EndingType` type as it isn't fully supported in certain
- * environments and attempting to reference the global version will error.
- *
- * https://github.com/microsoft/TypeScript/blob/49ad1a3917a0ea57f5ff248159256e12bb1cb705/src/lib/dom.generated.d.ts#L27941
- */
-type EndingType = 'native' | 'transparent';
-
-/**
- * A copy of the builtin `BlobPropertyBag` type as it isn't fully supported in certain
- * environments and attempting to reference the global version will error.
- *
- * https://github.com/microsoft/TypeScript/blob/49ad1a3917a0ea57f5ff248159256e12bb1cb705/src/lib/dom.generated.d.ts#L154
- * https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob#options
- */
-export interface BlobPropertyBag {
- endings?: EndingType;
- type?: string;
-}
-
-/**
- * A copy of the builtin `FilePropertyBag` type as it isn't fully supported in certain
- * environments and attempting to reference the global version will error.
- *
- * https://github.com/microsoft/TypeScript/blob/49ad1a3917a0ea57f5ff248159256e12bb1cb705/src/lib/dom.generated.d.ts#L503
- * https://developer.mozilla.org/en-US/docs/Web/API/File/File#options
- */
-export interface FilePropertyBag extends BlobPropertyBag {
- lastModified?: number;
-}
diff --git a/packages/sdk/src/internal/decoders/line.ts b/packages/sdk/src/internal/decoders/line.ts
deleted file mode 100644
index b3bfa97cd..000000000
--- a/packages/sdk/src/internal/decoders/line.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import { concatBytes, decodeUTF8, encodeUTF8 } from '../utils/bytes';
-
-export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
-
-/**
- * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally
- * reading lines from text.
- *
- * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258
- */
-export class LineDecoder {
- // prettier-ignore
- static NEWLINE_CHARS = new Set(['\n', '\r']);
- static NEWLINE_REGEXP = /\r\n|[\n\r]/g;
-
- #buffer: Uint8Array;
- #carriageReturnIndex: number | null;
-
- constructor() {
- this.#buffer = new Uint8Array();
- this.#carriageReturnIndex = null;
- }
-
- decode(chunk: Bytes): string[] {
- if (chunk == null) {
- return [];
- }
-
- const binaryChunk =
- chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
- : typeof chunk === 'string' ? encodeUTF8(chunk)
- : chunk;
-
- this.#buffer = concatBytes([this.#buffer, binaryChunk]);
-
- const lines: string[] = [];
- let patternIndex;
- while ((patternIndex = findNewlineIndex(this.#buffer, this.#carriageReturnIndex)) != null) {
- if (patternIndex.carriage && this.#carriageReturnIndex == null) {
- // skip until we either get a corresponding `\n`, a new `\r` or nothing
- this.#carriageReturnIndex = patternIndex.index;
- continue;
- }
-
- // we got double \r or \rtext\n
- if (
- this.#carriageReturnIndex != null &&
- (patternIndex.index !== this.#carriageReturnIndex + 1 || patternIndex.carriage)
- ) {
- lines.push(decodeUTF8(this.#buffer.subarray(0, this.#carriageReturnIndex - 1)));
- this.#buffer = this.#buffer.subarray(this.#carriageReturnIndex);
- this.#carriageReturnIndex = null;
- continue;
- }
-
- const endIndex =
- this.#carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding;
-
- const line = decodeUTF8(this.#buffer.subarray(0, endIndex));
- lines.push(line);
-
- this.#buffer = this.#buffer.subarray(patternIndex.index);
- this.#carriageReturnIndex = null;
- }
-
- return lines;
- }
-
- flush(): string[] {
- if (!this.#buffer.length) {
- return [];
- }
- return this.decode('\n');
- }
-}
-
-/**
- * This function searches the buffer for the end patterns, (\r or \n)
- * and returns an object with the index preceding the matched newline and the
- * index after the newline char. `null` is returned if no new line is found.
- *
- * ```ts
- * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 }
- * ```
- */
-function findNewlineIndex(
- buffer: Uint8Array,
- startIndex: number | null,
-): { preceding: number; index: number; carriage: boolean } | null {
- const newline = 0x0a; // \n
- const carriage = 0x0d; // \r
-
- for (let i = startIndex ?? 0; i < buffer.length; i++) {
- if (buffer[i] === newline) {
- return { preceding: i, index: i + 1, carriage: false };
- }
-
- if (buffer[i] === carriage) {
- return { preceding: i, index: i + 1, carriage: true };
- }
- }
-
- return null;
-}
-
-export function findDoubleNewlineIndex(buffer: Uint8Array): number {
- // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n)
- // and returns the index right after the first occurrence of any pattern,
- // or -1 if none of the patterns are found.
- const newline = 0x0a; // \n
- const carriage = 0x0d; // \r
-
- for (let i = 0; i < buffer.length - 1; i++) {
- if (buffer[i] === newline && buffer[i + 1] === newline) {
- // \n\n
- return i + 2;
- }
- if (buffer[i] === carriage && buffer[i + 1] === carriage) {
- // \r\r
- return i + 2;
- }
- if (
- buffer[i] === carriage &&
- buffer[i + 1] === newline &&
- i + 3 < buffer.length &&
- buffer[i + 2] === carriage &&
- buffer[i + 3] === newline
- ) {
- // \r\n\r\n
- return i + 4;
- }
- }
-
- return -1;
-}
diff --git a/packages/sdk/src/internal/detect-platform.ts b/packages/sdk/src/internal/detect-platform.ts
deleted file mode 100644
index e82d95c92..000000000
--- a/packages/sdk/src/internal/detect-platform.ts
+++ /dev/null
@@ -1,196 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { VERSION } from '../version';
-
-export const isRunningInBrowser = () => {
- return (
- // @ts-ignore
- typeof window !== 'undefined' &&
- // @ts-ignore
- typeof window.document !== 'undefined' &&
- // @ts-ignore
- typeof navigator !== 'undefined'
- );
-};
-
-type DetectedPlatform = 'deno' | 'node' | 'edge' | 'unknown';
-
-/**
- * Note this does not detect 'browser'; for that, use getBrowserInfo().
- */
-function getDetectedPlatform(): DetectedPlatform {
- if (typeof Deno !== 'undefined' && Deno.build != null) {
- return 'deno';
- }
- if (typeof EdgeRuntime !== 'undefined') {
- return 'edge';
- }
- if (
- Object.prototype.toString.call(
- typeof (globalThis as any).process !== 'undefined' ? (globalThis as any).process : 0,
- ) === '[object process]'
- ) {
- return 'node';
- }
- return 'unknown';
-}
-
-declare const Deno: any;
-declare const EdgeRuntime: any;
-type Arch = 'x32' | 'x64' | 'arm' | 'arm64' | `other:${string}` | 'unknown';
-type PlatformName =
- | 'MacOS'
- | 'Linux'
- | 'Windows'
- | 'FreeBSD'
- | 'OpenBSD'
- | 'iOS'
- | 'Android'
- | `Other:${string}`
- | 'Unknown';
-type Browser = 'ie' | 'edge' | 'chrome' | 'firefox' | 'safari';
-type PlatformProperties = {
- 'X-Stainless-Lang': 'js';
- 'X-Stainless-Package-Version': string;
- 'X-Stainless-OS': PlatformName;
- 'X-Stainless-Arch': Arch;
- 'X-Stainless-Runtime': 'node' | 'deno' | 'edge' | `browser:${Browser}` | 'unknown';
- 'X-Stainless-Runtime-Version': string;
-};
-const getPlatformProperties = (): PlatformProperties => {
- const detectedPlatform = getDetectedPlatform();
- if (detectedPlatform === 'deno') {
- return {
- 'X-Stainless-Lang': 'js',
- 'X-Stainless-Package-Version': VERSION,
- 'X-Stainless-OS': normalizePlatform(Deno.build.os),
- 'X-Stainless-Arch': normalizeArch(Deno.build.arch),
- 'X-Stainless-Runtime': 'deno',
- 'X-Stainless-Runtime-Version':
- typeof Deno.version === 'string' ? Deno.version : Deno.version?.deno ?? 'unknown',
- };
- }
- if (typeof EdgeRuntime !== 'undefined') {
- return {
- 'X-Stainless-Lang': 'js',
- 'X-Stainless-Package-Version': VERSION,
- 'X-Stainless-OS': 'Unknown',
- 'X-Stainless-Arch': `other:${EdgeRuntime}`,
- 'X-Stainless-Runtime': 'edge',
- 'X-Stainless-Runtime-Version': (globalThis as any).process.version,
- };
- }
- // Check if Node.js
- if (detectedPlatform === 'node') {
- return {
- 'X-Stainless-Lang': 'js',
- 'X-Stainless-Package-Version': VERSION,
- 'X-Stainless-OS': normalizePlatform((globalThis as any).process.platform ?? 'unknown'),
- 'X-Stainless-Arch': normalizeArch((globalThis as any).process.arch ?? 'unknown'),
- 'X-Stainless-Runtime': 'node',
- 'X-Stainless-Runtime-Version': (globalThis as any).process.version ?? 'unknown',
- };
- }
-
- const browserInfo = getBrowserInfo();
- if (browserInfo) {
- return {
- 'X-Stainless-Lang': 'js',
- 'X-Stainless-Package-Version': VERSION,
- 'X-Stainless-OS': 'Unknown',
- 'X-Stainless-Arch': 'unknown',
- 'X-Stainless-Runtime': `browser:${browserInfo.browser}`,
- 'X-Stainless-Runtime-Version': browserInfo.version,
- };
- }
-
- // TODO add support for Cloudflare workers, etc.
- return {
- 'X-Stainless-Lang': 'js',
- 'X-Stainless-Package-Version': VERSION,
- 'X-Stainless-OS': 'Unknown',
- 'X-Stainless-Arch': 'unknown',
- 'X-Stainless-Runtime': 'unknown',
- 'X-Stainless-Runtime-Version': 'unknown',
- };
-};
-
-type BrowserInfo = {
- browser: Browser;
- version: string;
-};
-
-declare const navigator: { userAgent: string } | undefined;
-
-// Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts
-function getBrowserInfo(): BrowserInfo | null {
- if (typeof navigator === 'undefined' || !navigator) {
- return null;
- }
-
- // NOTE: The order matters here!
- const browserPatterns = [
- { key: 'edge' as const, pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
- { key: 'ie' as const, pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
- { key: 'ie' as const, pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
- { key: 'chrome' as const, pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
- { key: 'firefox' as const, pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
- { key: 'safari' as const, pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ },
- ];
-
- // Find the FIRST matching browser
- for (const { key, pattern } of browserPatterns) {
- const match = pattern.exec(navigator.userAgent);
- if (match) {
- const major = match[1] || 0;
- const minor = match[2] || 0;
- const patch = match[3] || 0;
-
- return { browser: key, version: `${major}.${minor}.${patch}` };
- }
- }
-
- return null;
-}
-
-const normalizeArch = (arch: string): Arch => {
- // Node docs:
- // - https://nodejs.org/api/process.html#processarch
- // Deno docs:
- // - https://doc.deno.land/deno/stable/~/Deno.build
- if (arch === 'x32') return 'x32';
- if (arch === 'x86_64' || arch === 'x64') return 'x64';
- if (arch === 'arm') return 'arm';
- if (arch === 'aarch64' || arch === 'arm64') return 'arm64';
- if (arch) return `other:${arch}`;
- return 'unknown';
-};
-
-const normalizePlatform = (platform: string): PlatformName => {
- // Node platforms:
- // - https://nodejs.org/api/process.html#processplatform
- // Deno platforms:
- // - https://doc.deno.land/deno/stable/~/Deno.build
- // - https://github.com/denoland/deno/issues/14799
-
- platform = platform.toLowerCase();
-
- // NOTE: this iOS check is untested and may not work
- // Node does not work natively on IOS, there is a fork at
- // https://github.com/nodejs-mobile/nodejs-mobile
- // however it is unknown at the time of writing how to detect if it is running
- if (platform.includes('ios')) return 'iOS';
- if (platform === 'android') return 'Android';
- if (platform === 'darwin') return 'MacOS';
- if (platform === 'win32') return 'Windows';
- if (platform === 'freebsd') return 'FreeBSD';
- if (platform === 'openbsd') return 'OpenBSD';
- if (platform === 'linux') return 'Linux';
- if (platform) return `Other:${platform}`;
- return 'Unknown';
-};
-
-let _platformHeaders: PlatformProperties;
-export const getPlatformHeaders = () => {
- return (_platformHeaders ??= getPlatformProperties());
-};
diff --git a/packages/sdk/src/internal/errors.ts b/packages/sdk/src/internal/errors.ts
deleted file mode 100644
index 82c7b14d5..000000000
--- a/packages/sdk/src/internal/errors.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export function isAbortError(err: unknown) {
- return (
- typeof err === 'object' &&
- err !== null &&
- // Spec-compliant fetch implementations
- (('name' in err && (err as any).name === 'AbortError') ||
- // Expo fetch
- ('message' in err && String((err as any).message).includes('FetchRequestCanceledException')))
- );
-}
-
-export const castToError = (err: any): Error => {
- if (err instanceof Error) return err;
- if (typeof err === 'object' && err !== null) {
- try {
- if (Object.prototype.toString.call(err) === '[object Error]') {
- // @ts-ignore - not all envs have native support for cause yet
- const error = new Error(err.message, err.cause ? { cause: err.cause } : {});
- if (err.stack) error.stack = err.stack;
- // @ts-ignore - not all envs have native support for cause yet
- if (err.cause && !error.cause) error.cause = err.cause;
- if (err.name) error.name = err.name;
- return error;
- }
- } catch {}
- try {
- return new Error(JSON.stringify(err));
- } catch {}
- }
- return new Error(err);
-};
diff --git a/packages/sdk/src/internal/headers.ts b/packages/sdk/src/internal/headers.ts
deleted file mode 100644
index c724a9d22..000000000
--- a/packages/sdk/src/internal/headers.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { isReadonlyArray } from './utils/values';
-
-type HeaderValue = string | undefined | null;
-export type HeadersLike =
- | Headers
- | readonly HeaderValue[][]
- | Record<string, HeaderValue | readonly HeaderValue[]>
- | undefined
- | null
- | NullableHeaders;
-
-const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders');
-
-/**
- * @internal
- * Users can pass explicit nulls to unset default headers. When we parse them
- * into a standard headers type we need to preserve that information.
- */
-export type NullableHeaders = {
- /** Brand check, prevent users from creating a NullableHeaders. */
- [brand_privateNullableHeaders]: true;
- /** Parsed headers. */
- values: Headers;
- /** Set of lowercase header names explicitly set to null. */
- nulls: Set<string>;
-};
-
-function* iterateHeaders(headers: HeadersLike): IterableIterator<readonly [string, string | null]> {
- if (!headers) return;
-
- if (brand_privateNullableHeaders in headers) {
- const { values, nulls } = headers;
- yield* values.entries();
- for (const name of nulls) {
- yield [name, null];
- }
- return;
- }
-
- let shouldClear = false;
- let iter: Iterable<readonly (HeaderValue | readonly HeaderValue[])[]>;
- if (headers instanceof Headers) {
- iter = headers.entries();
- } else if (isReadonlyArray(headers)) {
- iter = headers;
- } else {
- shouldClear = true;
- iter = Object.entries(headers ?? {});
- }
- for (let row of iter) {
- const name = row[0];
- if (typeof name !== 'string') throw new TypeError('expected header name to be a string');
- const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
- let didClear = false;
- for (const value of values) {
- if (value === undefined) continue;
-
- // Objects keys always overwrite older headers, they never append.
- // Yield a null to clear the header before adding the new values.
- if (shouldClear && !didClear) {
- didClear = true;
- yield [name, null];
- }
- yield [name, value];
- }
- }
-}
-
-export const buildHeaders = (newHeaders: HeadersLike[]): NullableHeaders => {
- const targetHeaders = new Headers();
- const nullHeaders = new Set<string>();
- for (const headers of newHeaders) {
- const seenHeaders = new Set<string>();
- for (const [name, value] of iterateHeaders(headers)) {
- const lowerName = name.toLowerCase();
- if (!seenHeaders.has(lowerName)) {
- targetHeaders.delete(name);
- seenHeaders.add(lowerName);
- }
- if (value === null) {
- targetHeaders.delete(name);
- nullHeaders.add(lowerName);
- } else {
- targetHeaders.append(name, value);
- nullHeaders.delete(lowerName);
- }
- }
- }
- return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders };
-};
-
-export const isEmptyHeaders = (headers: HeadersLike) => {
- for (const _ of iterateHeaders(headers)) return false;
- return true;
-};
diff --git a/packages/sdk/src/internal/parse.ts b/packages/sdk/src/internal/parse.ts
deleted file mode 100644
index dcb4026e3..000000000
--- a/packages/sdk/src/internal/parse.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import type { FinalRequestOptions } from './request-options';
-import { Stream } from '../core/streaming';
-import { type Opencode } from '../client';
-import { formatRequestDetails, loggerFor } from './utils/log';
-
-export type APIResponseProps = {
- response: Response;
- options: FinalRequestOptions;
- controller: AbortController;
- requestLogID: string;
- retryOfRequestLogID: string | undefined;
- startTime: number;
-};
-
-export async function defaultParseResponse<T>(client: Opencode, props: APIResponseProps): Promise<T> {
- const { response, requestLogID, retryOfRequestLogID, startTime } = props;
- const body = await (async () => {
- if (props.options.stream) {
- loggerFor(client).debug('response', response.status, response.url, response.headers, response.body);
-
- // Note: there is an invariant here that isn't represented in the type system
- // that if you set `stream: true` the response type must also be `Stream<T>`
-
- if (props.options.__streamClass) {
- return props.options.__streamClass.fromSSEResponse(response, props.controller, client) as any;
- }
-
- return Stream.fromSSEResponse(response, props.controller, client) as any;
- }
-
- // fetch refuses to read the body when the status code is 204.
- if (response.status === 204) {
- return null as T;
- }
-
- if (props.options.__binaryResponse) {
- return response as unknown as T;
- }
-
- const contentType = response.headers.get('content-type');
- const mediaType = contentType?.split(';')[0]?.trim();
- const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json');
- if (isJSON) {
- const json = await response.json();
- return json as T;
- }
-
- const text = await response.text();
- return text as unknown as T;
- })();
- loggerFor(client).debug(
- `[${requestLogID}] response parsed`,
- formatRequestDetails({
- retryOfRequestLogID,
- url: response.url,
- status: response.status,
- body,
- durationMs: Date.now() - startTime,
- }),
- );
- return body;
-}
diff --git a/packages/sdk/src/internal/request-options.ts b/packages/sdk/src/internal/request-options.ts
deleted file mode 100644
index 56765e5aa..000000000
--- a/packages/sdk/src/internal/request-options.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { NullableHeaders } from './headers';
-
-import type { BodyInit } from './builtin-types';
-import { Stream } from '../core/streaming';
-import type { HTTPMethod, MergedRequestInit } from './types';
-import { type HeadersLike } from './headers';
-
-export type FinalRequestOptions = RequestOptions & { method: HTTPMethod; path: string };
-
-export type RequestOptions = {
- /**
- * The HTTP method for the request (e.g., 'get', 'post', 'put', 'delete').
- */
- method?: HTTPMethod;
-
- /**
- * The URL path for the request.
- *
- * @example "/v1/foo"
- */
- path?: string;
-
- /**
- * Query parameters to include in the request URL.
- */
- query?: object | undefined | null;
-
- /**
- * The request body. Can be a string, JSON object, FormData, or other supported types.
- */
- body?: unknown;
-
- /**
- * HTTP headers to include with the request. Can be a Headers object, plain object, or array of tuples.
- */
- headers?: HeadersLike;
-
- /**
- * The maximum number of times that the client will retry a request in case of a
- * temporary failure, like a network error or a 5XX error from the server.
- *
- * @default 2
- */
- maxRetries?: number;
-
- stream?: boolean | undefined;
-
- /**
- * The maximum amount of time (in milliseconds) that the client should wait for a response
- * from the server before timing out a single request.
- *
- * @unit milliseconds
- */
- timeout?: number;
-
- /**
- * Additional `RequestInit` options to be passed to the underlying `fetch` call.
- * These options will be merged with the client's default fetch options.
- */
- fetchOptions?: MergedRequestInit;
-
- /**
- * An AbortSignal that can be used to cancel the request.
- */
- signal?: AbortSignal | undefined | null;
-
- /**
- * A unique key for this request to enable idempotency.
- */
- idempotencyKey?: string;
-
- /**
- * Override the default base URL for this specific request.
- */
- defaultBaseURL?: string | undefined;
-
- __binaryResponse?: boolean | undefined;
- __streamClass?: typeof Stream;
-};
-
-export type EncodedContent = { bodyHeaders: HeadersLike; body: BodyInit };
-export type RequestEncoder = (request: { headers: NullableHeaders; body: unknown }) => EncodedContent;
-
-export const FallbackEncoder: RequestEncoder = ({ headers, body }) => {
- return {
- bodyHeaders: {
- 'content-type': 'application/json',
- },
- body: JSON.stringify(body),
- };
-};
diff --git a/packages/sdk/src/internal/shim-types.ts b/packages/sdk/src/internal/shim-types.ts
deleted file mode 100644
index 8ddf7b0ad..000000000
--- a/packages/sdk/src/internal/shim-types.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-/**
- * Shims for types that we can't always rely on being available globally.
- *
- * Note: these only exist at the type-level, there is no corresponding runtime
- * version for any of these symbols.
- */
-
-type NeverToAny<T> = T extends never ? any : T;
-
-/** @ts-ignore */
-type _DOMReadableStream<R = any> = globalThis.ReadableStream<R>;
-
-/** @ts-ignore */
-type _NodeReadableStream<R = any> = import('stream/web').ReadableStream<R>;
-
-type _ConditionalNodeReadableStream<R = any> =
- typeof globalThis extends { ReadableStream: any } ? never : _NodeReadableStream<R>;
-
-type _ReadableStream<R = any> = NeverToAny<
- | ([0] extends [1 & _DOMReadableStream<R>] ? never : _DOMReadableStream<R>)
- | ([0] extends [1 & _ConditionalNodeReadableStream<R>] ? never : _ConditionalNodeReadableStream<R>)
->;
-
-export type { _ReadableStream as ReadableStream };
diff --git a/packages/sdk/src/internal/shims.ts b/packages/sdk/src/internal/shims.ts
deleted file mode 100644
index 17a7967aa..000000000
--- a/packages/sdk/src/internal/shims.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-/**
- * This module provides internal shims and utility functions for environments where certain Node.js or global types may not be available.
- *
- * These are used to ensure we can provide a consistent behaviour between different JavaScript environments and good error
- * messages in cases where an environment isn't fully supported.
- */
-
-import type { Fetch } from './builtin-types';
-import type { ReadableStream } from './shim-types';
-
-export function getDefaultFetch(): Fetch {
- if (typeof fetch !== 'undefined') {
- return fetch as any;
- }
-
- throw new Error(
- '`fetch` is not defined as a global; Either pass `fetch` to the client, `new Opencode({ fetch })` or polyfill the global, `globalThis.fetch = fetch`',
- );
-}
-
-type ReadableStreamArgs = ConstructorParameters<typeof ReadableStream>;
-
-export function makeReadableStream(...args: ReadableStreamArgs): ReadableStream {
- const ReadableStream = (globalThis as any).ReadableStream;
- if (typeof ReadableStream === 'undefined') {
- // Note: All of the platforms / runtimes we officially support already define
- // `ReadableStream` as a global, so this should only ever be hit on unsupported runtimes.
- throw new Error(
- '`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`',
- );
- }
-
- return new ReadableStream(...args);
-}
-
-export function ReadableStreamFrom<T>(iterable: Iterable<T> | AsyncIterable<T>): ReadableStream<T> {
- let iter: AsyncIterator<T> | Iterator<T> =
- Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
-
- return makeReadableStream({
- start() {},
- async pull(controller: any) {
- const { done, value } = await iter.next();
- if (done) {
- controller.close();
- } else {
- controller.enqueue(value);
- }
- },
- async cancel() {
- await iter.return?.();
- },
- });
-}
-
-/**
- * Most browsers don't yet have async iterable support for ReadableStream,
- * and Node has a very different way of reading bytes from its "ReadableStream".
- *
- * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490
- */
-export function ReadableStreamToAsyncIterable<T>(stream: any): AsyncIterableIterator<T> {
- if (stream[Symbol.asyncIterator]) return stream;
-
- const reader = stream.getReader();
- return {
- async next() {
- try {
- const result = await reader.read();
- if (result?.done) reader.releaseLock(); // release lock when stream becomes closed
- return result;
- } catch (e) {
- reader.releaseLock(); // release lock when stream becomes errored
- throw e;
- }
- },
- async return() {
- const cancelPromise = reader.cancel();
- reader.releaseLock();
- await cancelPromise;
- return { done: true, value: undefined };
- },
- [Symbol.asyncIterator]() {
- return this;
- },
- };
-}
-
-/**
- * Cancels a ReadableStream we don't need to consume.
- * See https://undici.nodejs.org/#/?id=garbage-collection
- */
-export async function CancelReadableStream(stream: any): Promise<void> {
- if (stream === null || typeof stream !== 'object') return;
-
- if (stream[Symbol.asyncIterator]) {
- await stream[Symbol.asyncIterator]().return?.();
- return;
- }
-
- const reader = stream.getReader();
- const cancelPromise = reader.cancel();
- reader.releaseLock();
- await cancelPromise;
-}
diff --git a/packages/sdk/src/internal/to-file.ts b/packages/sdk/src/internal/to-file.ts
deleted file mode 100644
index 245e84933..000000000
--- a/packages/sdk/src/internal/to-file.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads';
-import type { FilePropertyBag } from './builtin-types';
-import { checkFileSupport } from './uploads';
-
-type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView;
-
-/**
- * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc.
- * Don't add arrayBuffer here, node-fetch doesn't have it
- */
-interface BlobLike {
- /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */
- readonly size: number;
- /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */
- readonly type: string;
- /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */
- text(): Promise<string>;
- /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */
- slice(start?: number, end?: number): BlobLike;
-}
-
-/**
- * This check adds the arrayBuffer() method type because it is available and used at runtime
- */
-const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise<ArrayBuffer> } =>
- value != null &&
- typeof value === 'object' &&
- typeof value.size === 'number' &&
- typeof value.type === 'string' &&
- typeof value.text === 'function' &&
- typeof value.slice === 'function' &&
- typeof value.arrayBuffer === 'function';
-
-/**
- * Intended to match DOM File, node:buffer File, undici File, etc.
- */
-interface FileLike extends BlobLike {
- /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */
- readonly lastModified: number;
- /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */
- readonly name?: string | undefined;
-}
-
-/**
- * This check adds the arrayBuffer() method type because it is available and used at runtime
- */
-const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise<ArrayBuffer> } =>
- value != null &&
- typeof value === 'object' &&
- typeof value.name === 'string' &&
- typeof value.lastModified === 'number' &&
- isBlobLike(value);
-
-/**
- * Intended to match DOM Response, node-fetch Response, undici Response, etc.
- */
-export interface ResponseLike {
- url: string;
- blob(): Promise<BlobLike>;
-}
-
-const isResponseLike = (value: any): value is ResponseLike =>
- value != null &&
- typeof value === 'object' &&
- typeof value.url === 'string' &&
- typeof value.blob === 'function';
-
-export type ToFileInput =
- | FileLike
- | ResponseLike
- | Exclude<BlobLikePart, string>
- | AsyncIterable<BlobLikePart>;
-
-/**
- * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
- * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s
- * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
- * @param {Object=} options additional properties
- * @param {string=} options.type the MIME type of the content
- * @param {number=} options.lastModified the last modified timestamp
- * @returns a {@link File} with the given properties
- */
-export async function toFile(
- value: ToFileInput | PromiseLike<ToFileInput>,
- name?: string | null | undefined,
- options?: FilePropertyBag | undefined,
-): Promise<File> {
- checkFileSupport();
-
- // If it's a promise, resolve it.
- value = await value;
-
- // If we've been given a `File` we don't need to do anything
- if (isFileLike(value)) {
- if (value instanceof File) {
- return value;
- }
- return makeFile([await value.arrayBuffer()], value.name);
- }
-
- if (isResponseLike(value)) {
- const blob = await value.blob();
- name ||= new URL(value.url).pathname.split(/[\\/]/).pop();
-
- return makeFile(await getBytes(blob), name, options);
- }
-
- const parts = await getBytes(value);
-
- name ||= getName(value);
-
- if (!options?.type) {
- const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type);
- if (typeof type === 'string') {
- options = { ...options, type };
- }
- }
-
- return makeFile(parts, name, options);
-}
-
-async function getBytes(value: BlobLikePart | AsyncIterable<BlobLikePart>): Promise<Array<BlobPart>> {
- let parts: Array<BlobPart> = [];
- if (
- typeof value === 'string' ||
- ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc.
- value instanceof ArrayBuffer
- ) {
- parts.push(value);
- } else if (isBlobLike(value)) {
- parts.push(value instanceof Blob ? value : await value.arrayBuffer());
- } else if (
- isAsyncIterable(value) // includes Readable, ReadableStream, etc.
- ) {
- for await (const chunk of value) {
- parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating?
- }
- } else {
- const constructor = value?.constructor?.name;
- throw new Error(
- `Unexpected data type: ${typeof value}${
- constructor ? `; constructor: ${constructor}` : ''
- }${propsForError(value)}`,
- );
- }
-
- return parts;
-}
-
-function propsForError(value: unknown): string {
- if (typeof value !== 'object' || value === null) return '';
- const props = Object.getOwnPropertyNames(value);
- return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`;
-}
diff --git a/packages/sdk/src/internal/types.ts b/packages/sdk/src/internal/types.ts
deleted file mode 100644
index b668dfc0f..000000000
--- a/packages/sdk/src/internal/types.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export type PromiseOrValue<T> = T | Promise<T>;
-export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
-
-export type KeysEnum<T> = { [P in keyof Required<T>]: true };
-
-export type FinalizedRequestInit = RequestInit & { headers: Headers };
-
-type NotAny<T> = [0] extends [1 & T] ? never : T;
-
-/**
- * Some environments overload the global fetch function, and Parameters<T> only gets the last signature.
- */
-type OverloadedParameters<T> =
- T extends (
- {
- (...args: infer A): unknown;
- (...args: infer B): unknown;
- (...args: infer C): unknown;
- (...args: infer D): unknown;
- }
- ) ?
- A | B | C | D
- : T extends (
- {
- (...args: infer A): unknown;
- (...args: infer B): unknown;
- (...args: infer C): unknown;
- }
- ) ?
- A | B | C
- : T extends (
- {
- (...args: infer A): unknown;
- (...args: infer B): unknown;
- }
- ) ?
- A | B
- : 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
- * would cause typescript to show types not present at runtime. To avoid this, we import
- * directly from parent node_modules folders.
- *
- * We need to check multiple levels because we don't know what directory structure we'll be in.
- * For example, pnpm generates directories like this:
- * ```
- * node_modules
- * ├── .pnpm
- * │ └── [email protected]
- * │ └── node_modules
- * │ └── pkg
- * │ └── internal
- * │ └── types.d.ts
- * ├── pkg -> .pnpm/[email protected]/node_modules/pkg
- * └── undici
- * ```
- *
- * [1]: https://www.typescriptlang.org/tsconfig/#typeAcquisition
- */
-/** @ts-ignore For users with \@types/node */
-type UndiciTypesRequestInit = NotAny<import('../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/undici-types/index.d.ts').RequestInit>;
-/** @ts-ignore For users with undici */
-type UndiciRequestInit = NotAny<import('../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/undici/index.d.ts').RequestInit>;
-/** @ts-ignore For users with \@types/bun */
-type BunRequestInit = globalThis.FetchRequestInit;
-/** @ts-ignore For users with node-fetch@2 */
-type NodeFetch2RequestInit = NotAny<import('../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit>;
-/** @ts-ignore For users with node-fetch@3, doesn't need file extension because types are at ./@types/index.d.ts */
-type NodeFetch3RequestInit = NotAny<import('../node_modules/node-fetch').RequestInit> | NotAny<import('../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/node-fetch').RequestInit>;
-/** @ts-ignore For users who use Deno */
-type FetchRequestInit = NonNullable<OverloadedParameters<typeof fetch>[1]>;
-/* eslint-enable */
-
-type RequestInits =
- | NotAny<UndiciTypesRequestInit>
- | NotAny<UndiciRequestInit>
- | NotAny<BunRequestInit>
- | NotAny<NodeFetch2RequestInit>
- | NotAny<NodeFetch3RequestInit>
- | NotAny<RequestInit>
- | NotAny<FetchRequestInit>;
-
-/**
- * This type contains `RequestInit` options that may be available on the current runtime,
- * including per-platform extensions like `dispatcher`, `agent`, `client`, etc.
- */
-export type MergedRequestInit = RequestInits &
- /** We don't include these in the types as they'll be overridden for every request. */
- Partial<Record<'body' | 'headers' | 'method' | 'signal', never>>;
diff --git a/packages/sdk/src/internal/uploads.ts b/packages/sdk/src/internal/uploads.ts
deleted file mode 100644
index eb55f834e..000000000
--- a/packages/sdk/src/internal/uploads.ts
+++ /dev/null
@@ -1,187 +0,0 @@
-import { type RequestOptions } from './request-options';
-import type { FilePropertyBag, Fetch } from './builtin-types';
-import type { Opencode } from '../client';
-import { ReadableStreamFrom } from './shims';
-
-export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView;
-type FsReadStream = AsyncIterable<Uint8Array> & { path: string | { toString(): string } };
-
-// https://github.com/oven-sh/bun/issues/5980
-interface BunFile extends Blob {
- readonly name?: string | undefined;
-}
-
-export const checkFileSupport = () => {
- if (typeof File === 'undefined') {
- const { process } = globalThis as any;
- const isOldNode =
- typeof process?.versions?.node === 'string' && parseInt(process.versions.node.split('.')) < 20;
- throw new Error(
- '`File` is not defined as a global, which is required for file uploads.' +
- (isOldNode ?
- " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`."
- : ''),
- );
- }
-};
-
-/**
- * Typically, this is a native "File" class.
- *
- * We provide the {@link toFile} utility to convert a variety of objects
- * into the File class.
- *
- * For convenience, you can also pass a fetch Response, or in Node,
- * the result of fs.createReadStream().
- */
-export type Uploadable = File | Response | FsReadStream | BunFile;
-
-/**
- * Construct a `File` instance. This is used to ensure a helpful error is thrown
- * for environments that don't define a global `File` yet.
- */
-export function makeFile(
- fileBits: BlobPart[],
- fileName: string | undefined,
- options?: FilePropertyBag,
-): File {
- checkFileSupport();
- return new File(fileBits as any, fileName ?? 'unknown_file', options);
-}
-
-export function getName(value: any): string | undefined {
- return (
- (
- (typeof value === 'object' &&
- value !== null &&
- (('name' in value && value.name && String(value.name)) ||
- ('url' in value && value.url && String(value.url)) ||
- ('filename' in value && value.filename && String(value.filename)) ||
- ('path' in value && value.path && String(value.path)))) ||
- ''
- )
- .split(/[\\/]/)
- .pop() || undefined
- );
-}
-
-export const isAsyncIterable = (value: any): value is AsyncIterable<any> =>
- value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function';
-
-/**
- * Returns a multipart/form-data request if any part of the given request body contains a File / Blob value.
- * Otherwise returns the request as is.
- */
-export const maybeMultipartFormRequestOptions = async (
- opts: RequestOptions,
- fetch: Opencode | Fetch,
-): Promise<RequestOptions> => {
- if (!hasUploadableValue(opts.body)) return opts;
-
- return { ...opts, body: await createForm(opts.body, fetch) };
-};
-
-type MultipartFormRequestOptions = Omit<RequestOptions, 'body'> & { body: unknown };
-
-export const multipartFormRequestOptions = async (
- opts: MultipartFormRequestOptions,
- fetch: Opencode | Fetch,
-): Promise<RequestOptions> => {
- return { ...opts, body: await createForm(opts.body, fetch) };
-};
-
-const supportsFormDataMap = /* @__PURE__ */ new WeakMap<Fetch, Promise<boolean>>();
-
-/**
- * node-fetch doesn't support the global FormData object in recent node versions. Instead of sending
- * properly-encoded form data, it just stringifies the object, resulting in a request body of "[object FormData]".
- * This function detects if the fetch function provided supports the global FormData object to avoid
- * confusing error messages later on.
- */
-function supportsFormData(fetchObject: Opencode | Fetch): Promise<boolean> {
- const fetch: Fetch = typeof fetchObject === 'function' ? fetchObject : (fetchObject as any).fetch;
- const cached = supportsFormDataMap.get(fetch);
- if (cached) return cached;
- const promise = (async () => {
- try {
- const FetchResponse = (
- 'Response' in fetch ?
- fetch.Response
- : (await fetch('data:,')).constructor) as typeof Response;
- const data = new FormData();
- if (data.toString() === (await new FetchResponse(data).text())) {
- return false;
- }
- return true;
- } catch {
- // avoid false negatives
- return true;
- }
- })();
- supportsFormDataMap.set(fetch, promise);
- return promise;
-}
-
-export const createForm = async <T = Record<string, unknown>>(
- body: T | undefined,
- fetch: Opencode | Fetch,
-): Promise<FormData> => {
- if (!(await supportsFormData(fetch))) {
- throw new TypeError(
- 'The provided fetch function does not support file uploads with the current global FormData class.',
- );
- }
- const form = new FormData();
- await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value)));
- return form;
-};
-
-// We check for Blob not File because Bun.File doesn't inherit from File,
-// but they both inherit from Blob and have a `name` property at runtime.
-const isNamedBlob = (value: unknown) => value instanceof Blob && 'name' in value;
-
-const isUploadable = (value: unknown) =>
- typeof value === 'object' &&
- value !== null &&
- (value instanceof Response || isAsyncIterable(value) || isNamedBlob(value));
-
-const hasUploadableValue = (value: unknown): boolean => {
- if (isUploadable(value)) return true;
- if (Array.isArray(value)) return value.some(hasUploadableValue);
- if (value && typeof value === 'object') {
- for (const k in value) {
- if (hasUploadableValue((value as any)[k])) return true;
- }
- }
- return false;
-};
-
-const addFormValue = async (form: FormData, key: string, value: unknown): Promise<void> => {
- if (value === undefined) return;
- if (value == null) {
- throw new TypeError(
- `Received null for "${key}"; to pass null in FormData, you must use the string 'null'`,
- );
- }
-
- // TODO: make nested formats configurable
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
- form.append(key, String(value));
- } else if (value instanceof Response) {
- form.append(key, makeFile([await value.blob()], getName(value)));
- } else if (isAsyncIterable(value)) {
- form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value)));
- } else if (isNamedBlob(value)) {
- form.append(key, value, getName(value));
- } else if (Array.isArray(value)) {
- await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry)));
- } else if (typeof value === 'object') {
- await Promise.all(
- Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)),
- );
- } else {
- throw new TypeError(
- `Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`,
- );
- }
-};
diff --git a/packages/sdk/src/internal/utils.ts b/packages/sdk/src/internal/utils.ts
deleted file mode 100644
index 3cbfacce2..000000000
--- a/packages/sdk/src/internal/utils.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export * from './utils/values';
-export * from './utils/base64';
-export * from './utils/env';
-export * from './utils/log';
-export * from './utils/uuid';
-export * from './utils/sleep';
diff --git a/packages/sdk/src/internal/utils/base64.ts b/packages/sdk/src/internal/utils/base64.ts
deleted file mode 100644
index 05d7bd9b4..000000000
--- a/packages/sdk/src/internal/utils/base64.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { OpencodeError } from '../../core/error';
-import { encodeUTF8 } from './bytes';
-
-export const toBase64 = (data: string | Uint8Array | null | undefined): string => {
- if (!data) return '';
-
- if (typeof (globalThis as any).Buffer !== 'undefined') {
- return (globalThis as any).Buffer.from(data).toString('base64');
- }
-
- if (typeof data === 'string') {
- data = encodeUTF8(data);
- }
-
- if (typeof btoa !== 'undefined') {
- return btoa(String.fromCharCode.apply(null, data as any));
- }
-
- throw new OpencodeError('Cannot generate base64 string; Expected `Buffer` or `btoa` to be defined');
-};
-
-export const fromBase64 = (str: string): Uint8Array => {
- if (typeof (globalThis as any).Buffer !== 'undefined') {
- const buf = (globalThis as any).Buffer.from(str, 'base64');
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
- }
-
- if (typeof atob !== 'undefined') {
- const bstr = atob(str);
- const buf = new Uint8Array(bstr.length);
- for (let i = 0; i < bstr.length; i++) {
- buf[i] = bstr.charCodeAt(i);
- }
- return buf;
- }
-
- throw new OpencodeError('Cannot decode base64 string; Expected `Buffer` or `atob` to be defined');
-};
diff --git a/packages/sdk/src/internal/utils/bytes.ts b/packages/sdk/src/internal/utils/bytes.ts
deleted file mode 100644
index 8da627abe..000000000
--- a/packages/sdk/src/internal/utils/bytes.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-export function concatBytes(buffers: Uint8Array[]): Uint8Array {
- let length = 0;
- for (const buffer of buffers) {
- length += buffer.length;
- }
- const output = new Uint8Array(length);
- let index = 0;
- for (const buffer of buffers) {
- output.set(buffer, index);
- index += buffer.length;
- }
-
- return output;
-}
-
-let encodeUTF8_: (str: string) => Uint8Array;
-export function encodeUTF8(str: string) {
- let encoder;
- return (
- encodeUTF8_ ??
- ((encoder = new (globalThis as any).TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder)))
- )(str);
-}
-
-let decodeUTF8_: (bytes: Uint8Array) => string;
-export function decodeUTF8(bytes: Uint8Array) {
- let decoder;
- return (
- decodeUTF8_ ??
- ((decoder = new (globalThis as any).TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder)))
- )(bytes);
-}
diff --git a/packages/sdk/src/internal/utils/env.ts b/packages/sdk/src/internal/utils/env.ts
deleted file mode 100644
index 2d8480077..000000000
--- a/packages/sdk/src/internal/utils/env.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-/**
- * Read an environment variable.
- *
- * Trims beginning and trailing whitespace.
- *
- * Will return undefined if the environment variable doesn't exist or cannot be accessed.
- */
-export const readEnv = (env: string): string | undefined => {
- if (typeof (globalThis as any).process !== 'undefined') {
- return (globalThis as any).process.env?.[env]?.trim() ?? undefined;
- }
- if (typeof (globalThis as any).Deno !== 'undefined') {
- return (globalThis as any).Deno.env?.get?.(env)?.trim();
- }
- return undefined;
-};
diff --git a/packages/sdk/src/internal/utils/log.ts b/packages/sdk/src/internal/utils/log.ts
deleted file mode 100644
index 44ac16a02..000000000
--- a/packages/sdk/src/internal/utils/log.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { hasOwn } from './values';
-import { type Opencode } from '../../client';
-import { RequestOptions } from '../request-options';
-
-type LogFn = (message: string, ...rest: unknown[]) => void;
-export type Logger = {
- error: LogFn;
- warn: LogFn;
- info: LogFn;
- debug: LogFn;
-};
-export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug';
-
-const levelNumbers = {
- off: 0,
- error: 200,
- warn: 300,
- info: 400,
- debug: 500,
-};
-
-export const parseLogLevel = (
- maybeLevel: string | undefined,
- sourceName: string,
- client: Opencode,
-): LogLevel | undefined => {
- if (!maybeLevel) {
- return undefined;
- }
- if (hasOwn(levelNumbers, maybeLevel)) {
- return maybeLevel;
- }
- loggerFor(client).warn(
- `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(
- Object.keys(levelNumbers),
- )}`,
- );
- return undefined;
-};
-
-function noop() {}
-
-function makeLogFn(fnLevel: keyof Logger, logger: Logger | undefined, logLevel: LogLevel) {
- if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
- return noop;
- } else {
- // Don't wrap logger functions, we want the stacktrace intact!
- return logger[fnLevel].bind(logger);
- }
-}
-
-const noopLogger = {
- error: noop,
- warn: noop,
- info: noop,
- debug: noop,
-};
-
-let cachedLoggers = /* @__PURE__ */ new WeakMap<Logger, [LogLevel, Logger]>();
-
-export function loggerFor(client: Opencode): Logger {
- const logger = client.logger;
- const logLevel = client.logLevel ?? 'off';
- if (!logger) {
- return noopLogger;
- }
-
- const cachedLogger = cachedLoggers.get(logger);
- if (cachedLogger && cachedLogger[0] === logLevel) {
- return cachedLogger[1];
- }
-
- const levelLogger = {
- error: makeLogFn('error', logger, logLevel),
- warn: makeLogFn('warn', logger, logLevel),
- info: makeLogFn('info', logger, logLevel),
- debug: makeLogFn('debug', logger, logLevel),
- };
-
- cachedLoggers.set(logger, [logLevel, levelLogger]);
-
- return levelLogger;
-}
-
-export const formatRequestDetails = (details: {
- options?: RequestOptions | undefined;
- headers?: Headers | Record<string, string> | undefined;
- retryOfRequestLogID?: string | undefined;
- retryOf?: string | undefined;
- url?: string | undefined;
- status?: number | undefined;
- method?: string | undefined;
- durationMs?: number | undefined;
- message?: unknown;
- body?: unknown;
-}) => {
- if (details.options) {
- details.options = { ...details.options };
- delete details.options['headers']; // redundant + leaks internals
- }
- if (details.headers) {
- details.headers = Object.fromEntries(
- (details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(
- ([name, value]) => [
- name,
- (
- name.toLowerCase() === 'authorization' ||
- name.toLowerCase() === 'cookie' ||
- name.toLowerCase() === 'set-cookie'
- ) ?
- '***'
- : value,
- ],
- ),
- );
- }
- if ('retryOfRequestLogID' in details) {
- if (details.retryOfRequestLogID) {
- details.retryOf = details.retryOfRequestLogID;
- }
- delete details.retryOfRequestLogID;
- }
- return details;
-};
diff --git a/packages/sdk/src/internal/utils/path.ts b/packages/sdk/src/internal/utils/path.ts
deleted file mode 100644
index 6ca96e0dd..000000000
--- a/packages/sdk/src/internal/utils/path.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { OpencodeError } from '../../core/error';
-
-/**
- * Percent-encode everything that isn't safe to have in a path without encoding safe chars.
- *
- * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3:
- * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
- * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
- * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
- */
-export function encodeURIPath(str: string) {
- return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
-}
-
-const EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
-
-export const createPathTagFunction = (pathEncoder = encodeURIPath) =>
- function path(statics: readonly string[], ...params: readonly unknown[]): string {
- // If there are no params, no processing is needed.
- if (statics.length === 1) return statics[0]!;
-
- let postPath = false;
- const invalidSegments = [];
- const path = statics.reduce((previousValue, currentValue, index) => {
- if (/[?#]/.test(currentValue)) {
- postPath = true;
- }
- const value = params[index];
- let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value);
- if (
- index !== params.length &&
- (value == null ||
- (typeof value === 'object' &&
- // handle values from other realms
- value.toString ===
- Object.getPrototypeOf(Object.getPrototypeOf((value as any).hasOwnProperty ?? EMPTY) ?? EMPTY)
- ?.toString))
- ) {
- encoded = value + '';
- invalidSegments.push({
- start: previousValue.length + currentValue.length,
- length: encoded.length,
- error: `Value of type ${Object.prototype.toString
- .call(value)
- .slice(8, -1)} is not a valid path parameter`,
- });
- }
- return previousValue + currentValue + (index === params.length ? '' : encoded);
- }, '');
-
- const pathOnly = path.split(/[?#]/, 1)[0]!;
- const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
- let match;
-
- // Find all invalid segments
- while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
- invalidSegments.push({
- start: match.index,
- length: match[0].length,
- error: `Value "${match[0]}" can\'t be safely passed as a path parameter`,
- });
- }
-
- invalidSegments.sort((a, b) => a.start - b.start);
-
- if (invalidSegments.length > 0) {
- let lastEnd = 0;
- const underline = invalidSegments.reduce((acc, segment) => {
- const spaces = ' '.repeat(segment.start - lastEnd);
- const arrows = '^'.repeat(segment.length);
- lastEnd = segment.start + segment.length;
- return acc + spaces + arrows;
- }, '');
-
- throw new OpencodeError(
- `Path parameters result in path with invalid segments:\n${invalidSegments
- .map((e) => e.error)
- .join('\n')}\n${path}\n${underline}`,
- );
- }
-
- return path;
- };
-
-/**
- * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced.
- */
-export const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
diff --git a/packages/sdk/src/internal/utils/sleep.ts b/packages/sdk/src/internal/utils/sleep.ts
deleted file mode 100644
index 65e52962b..000000000
--- a/packages/sdk/src/internal/utils/sleep.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
diff --git a/packages/sdk/src/internal/utils/uuid.ts b/packages/sdk/src/internal/utils/uuid.ts
deleted file mode 100644
index b0e53aaf7..000000000
--- a/packages/sdk/src/internal/utils/uuid.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-/**
- * https://stackoverflow.com/a/2117523
- */
-export let uuid4 = function () {
- const { crypto } = globalThis as any;
- if (crypto?.randomUUID) {
- uuid4 = crypto.randomUUID.bind(crypto);
- return crypto.randomUUID();
- }
- const u8 = new Uint8Array(1);
- const randomByte = crypto ? () => crypto.getRandomValues(u8)[0]! : () => (Math.random() * 0xff) & 0xff;
- return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) =>
- (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16),
- );
-};
diff --git a/packages/sdk/src/internal/utils/values.ts b/packages/sdk/src/internal/utils/values.ts
deleted file mode 100644
index b2421fd88..000000000
--- a/packages/sdk/src/internal/utils/values.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { OpencodeError } from '../../core/error';
-
-// https://url.spec.whatwg.org/#url-scheme-string
-const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
-
-export const isAbsoluteURL = (url: string): boolean => {
- return startsWithSchemeRegexp.test(url);
-};
-
-export let isArray = (val: unknown): val is unknown[] => ((isArray = Array.isArray), isArray(val));
-export let isReadonlyArray = isArray as (val: unknown) => val is readonly unknown[];
-
-/** Returns an object if the given value isn't an object, otherwise returns as-is */
-export function maybeObj(x: unknown): object {
- if (typeof x !== 'object') {
- return {};
- }
-
- return x ?? {};
-}
-
-// https://stackoverflow.com/a/34491287
-export function isEmptyObj(obj: Object | null | undefined): boolean {
- if (!obj) return true;
- for (const _k in obj) return false;
- return true;
-}
-
-// https://eslint.org/docs/latest/rules/no-prototype-builtins
-export function hasOwn<T extends object = object>(obj: T, key: PropertyKey): key is keyof T {
- return Object.prototype.hasOwnProperty.call(obj, key);
-}
-
-export function isObj(obj: unknown): obj is Record<string, unknown> {
- return obj != null && typeof obj === 'object' && !Array.isArray(obj);
-}
-
-export const ensurePresent = <T>(value: T | null | undefined): T => {
- if (value == null) {
- throw new OpencodeError(`Expected a value to be given but received ${value} instead.`);
- }
-
- return value;
-};
-
-export const validatePositiveInteger = (name: string, n: unknown): number => {
- if (typeof n !== 'number' || !Number.isInteger(n)) {
- throw new OpencodeError(`${name} must be an integer`);
- }
- if (n < 0) {
- throw new OpencodeError(`${name} must be a positive integer`);
- }
- return n;
-};
-
-export const coerceInteger = (value: unknown): number => {
- if (typeof value === 'number') return Math.round(value);
- if (typeof value === 'string') return parseInt(value, 10);
-
- throw new OpencodeError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
-};
-
-export const coerceFloat = (value: unknown): number => {
- if (typeof value === 'number') return value;
- if (typeof value === 'string') return parseFloat(value);
-
- throw new OpencodeError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
-};
-
-export const coerceBoolean = (value: unknown): boolean => {
- if (typeof value === 'boolean') return value;
- if (typeof value === 'string') return value === 'true';
- return Boolean(value);
-};
-
-export const maybeCoerceInteger = (value: unknown): number | undefined => {
- if (value === undefined) {
- return undefined;
- }
- return coerceInteger(value);
-};
-
-export const maybeCoerceFloat = (value: unknown): number | undefined => {
- if (value === undefined) {
- return undefined;
- }
- return coerceFloat(value);
-};
-
-export const maybeCoerceBoolean = (value: unknown): boolean | undefined => {
- if (value === undefined) {
- return undefined;
- }
- return coerceBoolean(value);
-};
-
-export const safeJSON = (text: string) => {
- try {
- return JSON.parse(text);
- } catch (err) {
- return undefined;
- }
-};
diff --git a/packages/sdk/src/lib/.keep b/packages/sdk/src/lib/.keep
deleted file mode 100644
index 7554f8b20..000000000
--- a/packages/sdk/src/lib/.keep
+++ /dev/null
@@ -1,4 +0,0 @@
-File generated from our OpenAPI spec by Stainless.
-
-This directory can be used to store custom files to expand the SDK.
-It is ignored by Stainless code generation and its content (other than this keep file) won't be touched.
diff --git a/packages/sdk/src/resource.ts b/packages/sdk/src/resource.ts
deleted file mode 100644
index 363e3516b..000000000
--- a/packages/sdk/src/resource.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** @deprecated Import from ./core/resource instead */
-export * from './core/resource';
diff --git a/packages/sdk/src/resources.ts b/packages/sdk/src/resources.ts
deleted file mode 100644
index b283d5781..000000000
--- a/packages/sdk/src/resources.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './resources/index';
diff --git a/packages/sdk/src/resources/app.ts b/packages/sdk/src/resources/app.ts
deleted file mode 100644
index 8ee56e320..000000000
--- a/packages/sdk/src/resources/app.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../core/resource';
-import { APIPromise } from '../core/api-promise';
-import { RequestOptions } from '../internal/request-options';
-
-export class AppResource extends APIResource {
- /**
- * Get app info
- */
- get(options?: RequestOptions): APIPromise<App> {
- return this._client.get('/app', options);
- }
-
- /**
- * Initialize the app
- */
- init(options?: RequestOptions): APIPromise<AppInitResponse> {
- return this._client.post('/app/init', options);
- }
-
- /**
- * Write a log entry to the server logs
- */
- log(body: AppLogParams, options?: RequestOptions): APIPromise<AppLogResponse> {
- return this._client.post('/log', { body, ...options });
- }
-
- /**
- * List all modes
- */
- modes(options?: RequestOptions): APIPromise<AppModesResponse> {
- return this._client.get('/mode', options);
- }
-
- /**
- * List all providers
- */
- providers(options?: RequestOptions): APIPromise<AppProvidersResponse> {
- return this._client.get('/config/providers', options);
- }
-}
-
-export interface App {
- git: boolean;
-
- hostname: string;
-
- path: App.Path;
-
- time: App.Time;
-}
-
-export namespace App {
- export interface Path {
- config: string;
-
- cwd: string;
-
- data: string;
-
- root: string;
-
- state: string;
- }
-
- export interface Time {
- initialized?: number;
- }
-}
-
-export interface Mode {
- name: string;
-
- tools: { [key: string]: boolean };
-
- model?: Mode.Model;
-
- prompt?: string;
-
- temperature?: number;
-}
-
-export namespace Mode {
- export interface Model {
- modelID: string;
-
- providerID: string;
- }
-}
-
-export interface Model {
- id: string;
-
- attachment: boolean;
-
- cost: Model.Cost;
-
- limit: Model.Limit;
-
- name: string;
-
- options: { [key: string]: unknown };
-
- reasoning: boolean;
-
- release_date: string;
-
- temperature: boolean;
-
- tool_call: boolean;
-}
-
-export namespace Model {
- export interface Cost {
- input: number;
-
- output: number;
-
- cache_read?: number;
-
- cache_write?: number;
- }
-
- export interface Limit {
- context: number;
-
- output: number;
- }
-}
-
-export interface Provider {
- id: string;
-
- env: Array<string>;
-
- models: { [key: string]: Model };
-
- name: string;
-
- api?: string;
-
- npm?: string;
-}
-
-export type AppInitResponse = boolean;
-
-export type AppLogResponse = boolean;
-
-export type AppModesResponse = Array<Mode>;
-
-export interface AppProvidersResponse {
- default: { [key: string]: string };
-
- providers: Array<Provider>;
-}
-
-export interface AppLogParams {
- /**
- * Log level
- */
- level: 'debug' | 'info' | 'error' | 'warn';
-
- /**
- * Log message
- */
- message: string;
-
- /**
- * Service name for the log entry
- */
- service: string;
-
- /**
- * Additional metadata for the log entry
- */
- extra?: { [key: string]: unknown };
-}
-
-export declare namespace AppResource {
- export {
- type App as App,
- type Mode as Mode,
- type Model as Model,
- type Provider as Provider,
- type AppInitResponse as AppInitResponse,
- type AppLogResponse as AppLogResponse,
- type AppModesResponse as AppModesResponse,
- type AppProvidersResponse as AppProvidersResponse,
- type AppLogParams as AppLogParams,
- };
-}
diff --git a/packages/sdk/src/resources/config.ts b/packages/sdk/src/resources/config.ts
deleted file mode 100644
index 11592f4aa..000000000
--- a/packages/sdk/src/resources/config.ts
+++ /dev/null
@@ -1,492 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../core/resource';
-import * as ConfigAPI from './config';
-import { APIPromise } from '../core/api-promise';
-import { RequestOptions } from '../internal/request-options';
-
-export class ConfigResource extends APIResource {
- /**
- * Get config info
- */
- get(options?: RequestOptions): APIPromise<Config> {
- return this._client.get('/config', options);
- }
-}
-
-export interface Config {
- /**
- * JSON schema reference for configuration validation
- */
- $schema?: string;
-
- /**
- * Modes configuration, see https://opencode.ai/docs/modes
- */
- agent?: Config.Agent;
-
- /**
- * @deprecated Use 'share' field instead. Share newly created sessions
- * automatically
- */
- autoshare?: boolean;
-
- /**
- * Automatically update to the latest version
- */
- autoupdate?: boolean;
-
- /**
- * Disable providers that are loaded automatically
- */
- disabled_providers?: Array<string>;
-
- experimental?: Config.Experimental;
-
- /**
- * Additional instruction files or patterns to include
- */
- instructions?: Array<string>;
-
- /**
- * Custom keybind configurations
- */
- keybinds?: KeybindsConfig;
-
- /**
- * @deprecated Always uses stretch layout.
- */
- layout?: 'auto' | 'stretch';
-
- /**
- * MCP (Model Context Protocol) server configurations
- */
- mcp?: { [key: string]: McpLocalConfig | McpRemoteConfig };
-
- /**
- * Modes configuration, see https://opencode.ai/docs/modes
- */
- mode?: Config.Mode;
-
- /**
- * Model to use in the format of provider/model, eg anthropic/claude-2
- */
- model?: string;
-
- /**
- * Custom provider configurations and model overrides
- */
- provider?: { [key: string]: Config.Provider };
-
- /**
- * Control sharing behavior:'manual' allows manual sharing via commands, 'auto'
- * enables automatic sharing, 'disabled' disables all sharing
- */
- share?: 'manual' | 'auto' | 'disabled';
-
- /**
- * Small model to use for tasks like summarization and title generation in the
- * format of provider/model
- */
- small_model?: string;
-
- /**
- * Theme name to use for the interface
- */
- theme?: string;
-
- /**
- * Custom username to display in conversations instead of system username
- */
- username?: string;
-}
-
-export namespace Config {
- /**
- * Modes configuration, see https://opencode.ai/docs/modes
- */
- export interface Agent {
- general?: Agent.General;
-
- [k: string]: Agent.AgentConfig | undefined;
- }
-
- export namespace Agent {
- export interface General extends ConfigAPI.ModeConfig {
- description: string;
- }
-
- export interface AgentConfig extends ConfigAPI.ModeConfig {
- description: string;
- }
- }
-
- export interface AgentConfig extends ConfigAPI.ModeConfig {
- description: string;
- }
-
- export interface AgentConfig extends ConfigAPI.ModeConfig {
- description: string;
- }
-
- export interface Experimental {
- hook?: Experimental.Hook;
- }
-
- export namespace Experimental {
- export interface Hook {
- file_edited?: { [key: string]: Array<Hook.FileEdited> };
-
- session_completed?: Array<Hook.SessionCompleted>;
- }
-
- export namespace Hook {
- export interface FileEdited {
- command: Array<string>;
-
- environment?: { [key: string]: string };
- }
-
- export interface SessionCompleted {
- command: Array<string>;
-
- environment?: { [key: string]: string };
- }
- }
- }
-
- /**
- * Modes configuration, see https://opencode.ai/docs/modes
- */
- export interface Mode {
- build?: ConfigAPI.ModeConfig;
-
- plan?: ConfigAPI.ModeConfig;
-
- [k: string]: ConfigAPI.ModeConfig | undefined;
- }
-
- export interface Provider {
- models: { [key: string]: Provider.Models };
-
- id?: string;
-
- api?: string;
-
- env?: Array<string>;
-
- name?: string;
-
- npm?: string;
-
- options?: Provider.Options;
- }
-
- export namespace Provider {
- export interface Models {
- id?: string;
-
- attachment?: boolean;
-
- cost?: Models.Cost;
-
- limit?: Models.Limit;
-
- name?: string;
-
- options?: { [key: string]: unknown };
-
- reasoning?: boolean;
-
- release_date?: string;
-
- temperature?: boolean;
-
- tool_call?: boolean;
- }
-
- export namespace Models {
- export interface Cost {
- input: number;
-
- output: number;
-
- cache_read?: number;
-
- cache_write?: number;
- }
-
- export interface Limit {
- context: number;
-
- output: number;
- }
- }
-
- export interface Options {
- apiKey?: string;
-
- baseURL?: string;
-
- [k: string]: unknown;
- }
- }
-}
-
-export interface KeybindsConfig {
- /**
- * Exit the application
- */
- app_exit: string;
-
- /**
- * Show help dialog
- */
- app_help: string;
-
- /**
- * Open external editor
- */
- editor_open: string;
-
- /**
- * Close file
- */
- file_close: string;
-
- /**
- * Split/unified diff
- */
- file_diff_toggle: string;
-
- /**
- * List files
- */
- file_list: string;
-
- /**
- * Search file
- */
- file_search: string;
-
- /**
- * Clear input field
- */
- input_clear: string;
-
- /**
- * Insert newline in input
- */
- input_newline: string;
-
- /**
- * Paste from clipboard
- */
- input_paste: string;
-
- /**
- * Submit input
- */
- input_submit: string;
-
- /**
- * Leader key for keybind combinations
- */
- leader: string;
-
- /**
- * Copy message
- */
- messages_copy: string;
-
- /**
- * Navigate to first message
- */
- messages_first: string;
-
- /**
- * Scroll messages down by half page
- */
- messages_half_page_down: string;
-
- /**
- * Scroll messages up by half page
- */
- messages_half_page_up: string;
-
- /**
- * Navigate to last message
- */
- messages_last: string;
-
- /**
- * Toggle layout
- */
- messages_layout_toggle: string;
-
- /**
- * Navigate to next message
- */
- messages_next: string;
-
- /**
- * Scroll messages down by one page
- */
- messages_page_down: string;
-
- /**
- * Scroll messages up by one page
- */
- messages_page_up: string;
-
- /**
- * Navigate to previous message
- */
- messages_previous: string;
-
- /**
- * Redo message
- */
- messages_redo: string;
-
- /**
- * @deprecated use messages_undo. Revert message
- */
- messages_revert: string;
-
- /**
- * Undo message
- */
- messages_undo: string;
-
- /**
- * List available models
- */
- model_list: string;
-
- /**
- * Create/update AGENTS.md
- */
- project_init: string;
-
- /**
- * Compact the session
- */
- session_compact: string;
-
- /**
- * Export session to editor
- */
- session_export: string;
-
- /**
- * Interrupt current session
- */
- session_interrupt: string;
-
- /**
- * List all sessions
- */
- session_list: string;
-
- /**
- * Create a new session
- */
- session_new: string;
-
- /**
- * Share current session
- */
- session_share: string;
-
- /**
- * Unshare current session
- */
- session_unshare: string;
-
- /**
- * Next mode
- */
- switch_mode: string;
-
- /**
- * Previous Mode
- */
- switch_mode_reverse: string;
-
- /**
- * List available themes
- */
- theme_list: string;
-
- /**
- * Toggle tool details
- */
- tool_details: string;
-}
-
-export interface McpLocalConfig {
- /**
- * Command and arguments to run the MCP server
- */
- command: Array<string>;
-
- /**
- * Type of MCP server connection
- */
- type: 'local';
-
- /**
- * Enable or disable the MCP server on startup
- */
- enabled?: boolean;
-
- /**
- * Environment variables to set when running the MCP server
- */
- environment?: { [key: string]: string };
-}
-
-export interface McpRemoteConfig {
- /**
- * Type of MCP server connection
- */
- type: 'remote';
-
- /**
- * URL of the remote MCP server
- */
- url: string;
-
- /**
- * Enable or disable the MCP server on startup
- */
- enabled?: boolean;
-
- /**
- * Headers to send with the request
- */
- headers?: { [key: string]: string };
-}
-
-export interface ModeConfig {
- disable?: boolean;
-
- model?: string;
-
- prompt?: string;
-
- temperature?: number;
-
- tools?: { [key: string]: boolean };
-}
-
-export declare namespace ConfigResource {
- export {
- type Config as Config,
- type KeybindsConfig as KeybindsConfig,
- type McpLocalConfig as McpLocalConfig,
- type McpRemoteConfig as McpRemoteConfig,
- type ModeConfig as ModeConfig,
- };
-}
diff --git a/packages/sdk/src/resources/event.ts b/packages/sdk/src/resources/event.ts
deleted file mode 100644
index bd51b22b3..000000000
--- a/packages/sdk/src/resources/event.ts
+++ /dev/null
@@ -1,267 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../core/resource';
-import * as SessionAPI from './session';
-import * as Shared from './shared';
-import { APIPromise } from '../core/api-promise';
-import { Stream } from '../core/streaming';
-import { RequestOptions } from '../internal/request-options';
-
-export class Event extends APIResource {
- /**
- * Get events
- */
- list(options?: RequestOptions): APIPromise<Stream<EventListResponse>> {
- return this._client.get('/event', { ...options, stream: true }) as APIPromise<Stream<EventListResponse>>;
- }
-}
-
-export type EventListResponse =
- | EventListResponse.EventInstallationUpdated
- | EventListResponse.EventLspClientDiagnostics
- | EventListResponse.EventMessageUpdated
- | EventListResponse.EventMessageRemoved
- | EventListResponse.EventMessagePartUpdated
- | EventListResponse.EventMessagePartRemoved
- | EventListResponse.EventStorageWrite
- | EventListResponse.EventPermissionUpdated
- | EventListResponse.EventFileEdited
- | EventListResponse.EventSessionUpdated
- | EventListResponse.EventSessionDeleted
- | EventListResponse.EventSessionIdle
- | EventListResponse.EventSessionError
- | EventListResponse.EventServerConnected
- | EventListResponse.EventFileWatcherUpdated
- | EventListResponse.EventIdeInstalled;
-
-export namespace EventListResponse {
- export interface EventInstallationUpdated {
- properties: EventInstallationUpdated.Properties;
-
- type: 'installation.updated';
- }
-
- export namespace EventInstallationUpdated {
- export interface Properties {
- version: string;
- }
- }
-
- export interface EventLspClientDiagnostics {
- properties: EventLspClientDiagnostics.Properties;
-
- type: 'lsp.client.diagnostics';
- }
-
- export namespace EventLspClientDiagnostics {
- export interface Properties {
- path: string;
-
- serverID: string;
- }
- }
-
- export interface EventMessageUpdated {
- properties: EventMessageUpdated.Properties;
-
- type: 'message.updated';
- }
-
- export namespace EventMessageUpdated {
- export interface Properties {
- info: SessionAPI.Message;
- }
- }
-
- export interface EventMessageRemoved {
- properties: EventMessageRemoved.Properties;
-
- type: 'message.removed';
- }
-
- export namespace EventMessageRemoved {
- export interface Properties {
- messageID: string;
-
- sessionID: string;
- }
- }
-
- export interface EventMessagePartUpdated {
- properties: EventMessagePartUpdated.Properties;
-
- type: 'message.part.updated';
- }
-
- export namespace EventMessagePartUpdated {
- export interface Properties {
- part: SessionAPI.Part;
- }
- }
-
- export interface EventMessagePartRemoved {
- properties: EventMessagePartRemoved.Properties;
-
- type: 'message.part.removed';
- }
-
- export namespace EventMessagePartRemoved {
- export interface Properties {
- messageID: string;
-
- partID: string;
-
- sessionID: string;
- }
- }
-
- export interface EventStorageWrite {
- properties: EventStorageWrite.Properties;
-
- type: 'storage.write';
- }
-
- export namespace EventStorageWrite {
- export interface Properties {
- key: string;
-
- content?: unknown;
- }
- }
-
- export interface EventPermissionUpdated {
- properties: EventPermissionUpdated.Properties;
-
- type: 'permission.updated';
- }
-
- export namespace EventPermissionUpdated {
- export interface Properties {
- id: string;
-
- metadata: { [key: string]: unknown };
-
- sessionID: string;
-
- time: Properties.Time;
-
- title: string;
- }
-
- export namespace Properties {
- export interface Time {
- created: number;
- }
- }
- }
-
- export interface EventFileEdited {
- properties: EventFileEdited.Properties;
-
- type: 'file.edited';
- }
-
- export namespace EventFileEdited {
- export interface Properties {
- file: string;
- }
- }
-
- export interface EventSessionUpdated {
- properties: EventSessionUpdated.Properties;
-
- type: 'session.updated';
- }
-
- export namespace EventSessionUpdated {
- export interface Properties {
- info: SessionAPI.Session;
- }
- }
-
- export interface EventSessionDeleted {
- properties: EventSessionDeleted.Properties;
-
- type: 'session.deleted';
- }
-
- export namespace EventSessionDeleted {
- export interface Properties {
- info: SessionAPI.Session;
- }
- }
-
- export interface EventSessionIdle {
- properties: EventSessionIdle.Properties;
-
- type: 'session.idle';
- }
-
- export namespace EventSessionIdle {
- export interface Properties {
- sessionID: string;
- }
- }
-
- export interface EventSessionError {
- properties: EventSessionError.Properties;
-
- type: 'session.error';
- }
-
- export namespace EventSessionError {
- export interface Properties {
- error?:
- | Shared.ProviderAuthError
- | Shared.UnknownError
- | Properties.MessageOutputLengthError
- | Shared.MessageAbortedError;
-
- sessionID?: string;
- }
-
- export namespace Properties {
- export interface MessageOutputLengthError {
- data: unknown;
-
- name: 'MessageOutputLengthError';
- }
- }
- }
-
- export interface EventServerConnected {
- properties: unknown;
-
- type: 'server.connected';
- }
-
- export interface EventFileWatcherUpdated {
- properties: EventFileWatcherUpdated.Properties;
-
- type: 'file.watcher.updated';
- }
-
- export namespace EventFileWatcherUpdated {
- export interface Properties {
- event: 'rename' | 'change';
-
- file: string;
- }
- }
-
- export interface EventIdeInstalled {
- properties: EventIdeInstalled.Properties;
-
- type: 'ide.installed';
- }
-
- export namespace EventIdeInstalled {
- export interface Properties {
- ide: string;
- }
- }
-}
-
-export declare namespace Event {
- export { type EventListResponse as EventListResponse };
-}
diff --git a/packages/sdk/src/resources/file.ts b/packages/sdk/src/resources/file.ts
deleted file mode 100644
index fd7bdac69..000000000
--- a/packages/sdk/src/resources/file.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../core/resource';
-import { APIPromise } from '../core/api-promise';
-import { RequestOptions } from '../internal/request-options';
-
-export class FileResource extends APIResource {
- /**
- * Read a file
- */
- read(query: FileReadParams, options?: RequestOptions): APIPromise<FileReadResponse> {
- return this._client.get('/file', { query, ...options });
- }
-
- /**
- * Get file status
- */
- status(options?: RequestOptions): APIPromise<FileStatusResponse> {
- return this._client.get('/file/status', options);
- }
-}
-
-export interface File {
- added: number;
-
- path: string;
-
- removed: number;
-
- status: 'added' | 'deleted' | 'modified';
-}
-
-export interface FileReadResponse {
- content: string;
-
- type: 'raw' | 'patch';
-}
-
-export type FileStatusResponse = Array<File>;
-
-export interface FileReadParams {
- path: string;
-}
-
-export declare namespace FileResource {
- export {
- type File as File,
- type FileReadResponse as FileReadResponse,
- type FileStatusResponse as FileStatusResponse,
- type FileReadParams as FileReadParams,
- };
-}
diff --git a/packages/sdk/src/resources/find.ts b/packages/sdk/src/resources/find.ts
deleted file mode 100644
index d9d6597e5..000000000
--- a/packages/sdk/src/resources/find.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../core/resource';
-import { APIPromise } from '../core/api-promise';
-import { RequestOptions } from '../internal/request-options';
-
-export class Find extends APIResource {
- /**
- * Find files
- */
- files(query: FindFilesParams, options?: RequestOptions): APIPromise<FindFilesResponse> {
- return this._client.get('/find/file', { query, ...options });
- }
-
- /**
- * Find workspace symbols
- */
- symbols(query: FindSymbolsParams, options?: RequestOptions): APIPromise<FindSymbolsResponse> {
- return this._client.get('/find/symbol', { query, ...options });
- }
-
- /**
- * Find text in files
- */
- text(query: FindTextParams, options?: RequestOptions): APIPromise<FindTextResponse> {
- return this._client.get('/find', { query, ...options });
- }
-}
-
-export interface Symbol {
- kind: number;
-
- location: Symbol.Location;
-
- name: string;
-}
-
-export namespace Symbol {
- export interface Location {
- range: Location.Range;
-
- uri: string;
- }
-
- export namespace Location {
- export interface Range {
- end: Range.End;
-
- start: Range.Start;
- }
-
- export namespace Range {
- export interface End {
- character: number;
-
- line: number;
- }
-
- export interface Start {
- character: number;
-
- line: number;
- }
- }
- }
-}
-
-export type FindFilesResponse = Array<string>;
-
-export type FindSymbolsResponse = Array<Symbol>;
-
-export type FindTextResponse = Array<FindTextResponse.FindTextResponseItem>;
-
-export namespace FindTextResponse {
- export interface FindTextResponseItem {
- absolute_offset: number;
-
- line_number: number;
-
- lines: FindTextResponseItem.Lines;
-
- path: FindTextResponseItem.Path;
-
- submatches: Array<FindTextResponseItem.Submatch>;
- }
-
- export namespace FindTextResponseItem {
- export interface Lines {
- text: string;
- }
-
- export interface Path {
- text: string;
- }
-
- export interface Submatch {
- end: number;
-
- match: Submatch.Match;
-
- start: number;
- }
-
- export namespace Submatch {
- export interface Match {
- text: string;
- }
- }
- }
-}
-
-export interface FindFilesParams {
- query: string;
-}
-
-export interface FindSymbolsParams {
- query: string;
-}
-
-export interface FindTextParams {
- pattern: string;
-}
-
-export declare namespace Find {
- export {
- type Symbol as Symbol,
- type FindFilesResponse as FindFilesResponse,
- type FindSymbolsResponse as FindSymbolsResponse,
- type FindTextResponse as FindTextResponse,
- type FindFilesParams as FindFilesParams,
- type FindSymbolsParams as FindSymbolsParams,
- type FindTextParams as FindTextParams,
- };
-}
diff --git a/packages/sdk/src/resources/index.ts b/packages/sdk/src/resources/index.ts
deleted file mode 100644
index 4e7934af1..000000000
--- a/packages/sdk/src/resources/index.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export * from './shared';
-export {
- AppResource,
- type App,
- type Mode,
- type Model,
- type Provider,
- type AppInitResponse,
- type AppLogResponse,
- type AppModesResponse,
- type AppProvidersResponse,
- type AppLogParams,
-} from './app';
-export {
- ConfigResource,
- type Config,
- type KeybindsConfig,
- type McpLocalConfig,
- type McpRemoteConfig,
- type ModeConfig,
-} from './config';
-export { Event, type EventListResponse } from './event';
-export {
- FileResource,
- type File,
- type FileReadResponse,
- type FileStatusResponse,
- type FileReadParams,
-} from './file';
-export {
- Find,
- type Symbol,
- type FindFilesResponse,
- type FindSymbolsResponse,
- type FindTextResponse,
- type FindFilesParams,
- type FindSymbolsParams,
- type FindTextParams,
-} from './find';
-export {
- SessionResource,
- type AssistantMessage,
- type FilePart,
- type FilePartInput,
- type FilePartSource,
- type FilePartSourceText,
- type FileSource,
- type Message,
- type Part,
- type Session,
- type SnapshotPart,
- type StepFinishPart,
- type StepStartPart,
- type SymbolSource,
- type TextPart,
- type TextPartInput,
- type ToolPart,
- type ToolStateCompleted,
- type ToolStateError,
- type ToolStatePending,
- type ToolStateRunning,
- type UserMessage,
- type SessionListResponse,
- type SessionDeleteResponse,
- type SessionAbortResponse,
- type SessionInitResponse,
- type SessionMessagesResponse,
- type SessionSummarizeResponse,
- type SessionChatParams,
- type SessionInitParams,
- type SessionRevertParams,
- type SessionSummarizeParams,
-} from './session';
-export {
- Tui,
- type TuiAppendPromptResponse,
- type TuiOpenHelpResponse,
- type TuiAppendPromptParams,
-} from './tui';
diff --git a/packages/sdk/src/resources/session.ts b/packages/sdk/src/resources/session.ts
deleted file mode 100644
index 5dbdc31f8..000000000
--- a/packages/sdk/src/resources/session.ts
+++ /dev/null
@@ -1,605 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../core/resource';
-import * as SessionAPI from './session';
-import * as Shared from './shared';
-import { APIPromise } from '../core/api-promise';
-import { RequestOptions } from '../internal/request-options';
-import { path } from '../internal/utils/path';
-
-export class SessionResource extends APIResource {
- /**
- * Create a new session
- */
- create(options?: RequestOptions): APIPromise<Session> {
- return this._client.post('/session', options);
- }
-
- /**
- * List all sessions
- */
- list(options?: RequestOptions): APIPromise<SessionListResponse> {
- return this._client.get('/session', options);
- }
-
- /**
- * Delete a session and all its data
- */
- delete(id: string, options?: RequestOptions): APIPromise<SessionDeleteResponse> {
- return this._client.delete(path`/session/${id}`, options);
- }
-
- /**
- * Abort a session
- */
- abort(id: string, options?: RequestOptions): APIPromise<SessionAbortResponse> {
- return this._client.post(path`/session/${id}/abort`, options);
- }
-
- /**
- * Create and send a new message to a session
- */
- chat(id: string, body: SessionChatParams, options?: RequestOptions): APIPromise<AssistantMessage> {
- return this._client.post(path`/session/${id}/message`, { body, ...options });
- }
-
- /**
- * Analyze the app and create an AGENTS.md file
- */
- init(id: string, body: SessionInitParams, options?: RequestOptions): APIPromise<SessionInitResponse> {
- return this._client.post(path`/session/${id}/init`, { body, ...options });
- }
-
- /**
- * List messages for a session
- */
- messages(id: string, options?: RequestOptions): APIPromise<SessionMessagesResponse> {
- return this._client.get(path`/session/${id}/message`, options);
- }
-
- /**
- * Revert a message
- */
- revert(id: string, body: SessionRevertParams, options?: RequestOptions): APIPromise<Session> {
- return this._client.post(path`/session/${id}/revert`, { body, ...options });
- }
-
- /**
- * Share a session
- */
- share(id: string, options?: RequestOptions): APIPromise<Session> {
- return this._client.post(path`/session/${id}/share`, options);
- }
-
- /**
- * Summarize the session
- */
- summarize(
- id: string,
- body: SessionSummarizeParams,
- options?: RequestOptions,
- ): APIPromise<SessionSummarizeResponse> {
- return this._client.post(path`/session/${id}/summarize`, { body, ...options });
- }
-
- /**
- * Restore all reverted messages
- */
- unrevert(id: string, options?: RequestOptions): APIPromise<Session> {
- return this._client.post(path`/session/${id}/unrevert`, options);
- }
-
- /**
- * Unshare the session
- */
- unshare(id: string, options?: RequestOptions): APIPromise<Session> {
- return this._client.delete(path`/session/${id}/share`, options);
- }
-}
-
-export interface AssistantMessage {
- id: string;
-
- cost: number;
-
- mode: string;
-
- modelID: string;
-
- path: AssistantMessage.Path;
-
- providerID: string;
-
- role: 'assistant';
-
- sessionID: string;
-
- system: Array<string>;
-
- time: AssistantMessage.Time;
-
- tokens: AssistantMessage.Tokens;
-
- error?:
- | Shared.ProviderAuthError
- | Shared.UnknownError
- | AssistantMessage.MessageOutputLengthError
- | Shared.MessageAbortedError;
-
- summary?: boolean;
-}
-
-export namespace AssistantMessage {
- export interface Path {
- cwd: string;
-
- root: string;
- }
-
- export interface Time {
- created: number;
-
- completed?: number;
- }
-
- export interface Tokens {
- cache: Tokens.Cache;
-
- input: number;
-
- output: number;
-
- reasoning: number;
- }
-
- export namespace Tokens {
- export interface Cache {
- read: number;
-
- write: number;
- }
- }
-
- export interface MessageOutputLengthError {
- data: unknown;
-
- name: 'MessageOutputLengthError';
- }
-}
-
-export interface FilePart {
- id: string;
-
- messageID: string;
-
- mime: string;
-
- sessionID: string;
-
- type: 'file';
-
- url: string;
-
- filename?: string;
-
- source?: FilePartSource;
-}
-
-export interface FilePartInput {
- mime: string;
-
- type: 'file';
-
- url: string;
-
- id?: string;
-
- filename?: string;
-
- source?: FilePartSource;
-}
-
-export type FilePartSource = FileSource | SymbolSource;
-
-export interface FilePartSourceText {
- end: number;
-
- start: number;
-
- value: string;
-}
-
-export interface FileSource {
- path: string;
-
- text: FilePartSourceText;
-
- type: 'file';
-}
-
-export type Message = UserMessage | AssistantMessage;
-
-export type Part =
- | TextPart
- | FilePart
- | ToolPart
- | StepStartPart
- | StepFinishPart
- | SnapshotPart
- | Part.PatchPart;
-
-export namespace Part {
- export interface PatchPart {
- id: string;
-
- files: Array<string>;
-
- hash: string;
-
- messageID: string;
-
- sessionID: string;
-
- type: 'patch';
- }
-}
-
-export interface Session {
- id: string;
-
- time: Session.Time;
-
- title: string;
-
- version: string;
-
- parentID?: string;
-
- revert?: Session.Revert;
-
- share?: Session.Share;
-}
-
-export namespace Session {
- export interface Time {
- created: number;
-
- updated: number;
- }
-
- export interface Revert {
- messageID: string;
-
- diff?: string;
-
- partID?: string;
-
- snapshot?: string;
- }
-
- export interface Share {
- url: string;
- }
-}
-
-export interface SnapshotPart {
- id: string;
-
- messageID: string;
-
- sessionID: string;
-
- snapshot: string;
-
- type: 'snapshot';
-}
-
-export interface StepFinishPart {
- id: string;
-
- cost: number;
-
- messageID: string;
-
- sessionID: string;
-
- tokens: StepFinishPart.Tokens;
-
- type: 'step-finish';
-}
-
-export namespace StepFinishPart {
- export interface Tokens {
- cache: Tokens.Cache;
-
- input: number;
-
- output: number;
-
- reasoning: number;
- }
-
- export namespace Tokens {
- export interface Cache {
- read: number;
-
- write: number;
- }
- }
-}
-
-export interface StepStartPart {
- id: string;
-
- messageID: string;
-
- sessionID: string;
-
- type: 'step-start';
-}
-
-export interface SymbolSource {
- kind: number;
-
- name: string;
-
- path: string;
-
- range: SymbolSource.Range;
-
- text: FilePartSourceText;
-
- type: 'symbol';
-}
-
-export namespace SymbolSource {
- export interface Range {
- end: Range.End;
-
- start: Range.Start;
- }
-
- export namespace Range {
- export interface End {
- character: number;
-
- line: number;
- }
-
- export interface Start {
- character: number;
-
- line: number;
- }
- }
-}
-
-export interface TextPart {
- id: string;
-
- messageID: string;
-
- sessionID: string;
-
- text: string;
-
- type: 'text';
-
- synthetic?: boolean;
-
- time?: TextPart.Time;
-}
-
-export namespace TextPart {
- export interface Time {
- start: number;
-
- end?: number;
- }
-}
-
-export interface TextPartInput {
- text: string;
-
- type: 'text';
-
- id?: string;
-
- synthetic?: boolean;
-
- time?: TextPartInput.Time;
-}
-
-export namespace TextPartInput {
- export interface Time {
- start: number;
-
- end?: number;
- }
-}
-
-export interface ToolPart {
- id: string;
-
- callID: string;
-
- messageID: string;
-
- sessionID: string;
-
- state: ToolStatePending | ToolStateRunning | ToolStateCompleted | ToolStateError;
-
- tool: string;
-
- type: 'tool';
-}
-
-export interface ToolStateCompleted {
- input: { [key: string]: unknown };
-
- metadata: { [key: string]: unknown };
-
- output: string;
-
- status: 'completed';
-
- time: ToolStateCompleted.Time;
-
- title: string;
-}
-
-export namespace ToolStateCompleted {
- export interface Time {
- end: number;
-
- start: number;
- }
-}
-
-export interface ToolStateError {
- error: string;
-
- input: { [key: string]: unknown };
-
- status: 'error';
-
- time: ToolStateError.Time;
-}
-
-export namespace ToolStateError {
- export interface Time {
- end: number;
-
- start: number;
- }
-}
-
-export interface ToolStatePending {
- status: 'pending';
-}
-
-export interface ToolStateRunning {
- status: 'running';
-
- time: ToolStateRunning.Time;
-
- input?: unknown;
-
- metadata?: { [key: string]: unknown };
-
- title?: string;
-}
-
-export namespace ToolStateRunning {
- export interface Time {
- start: number;
- }
-}
-
-export interface UserMessage {
- id: string;
-
- role: 'user';
-
- sessionID: string;
-
- time: UserMessage.Time;
-}
-
-export namespace UserMessage {
- export interface Time {
- created: number;
- }
-}
-
-export type SessionListResponse = Array<Session>;
-
-export type SessionDeleteResponse = boolean;
-
-export type SessionAbortResponse = boolean;
-
-export type SessionInitResponse = boolean;
-
-export type SessionMessagesResponse = Array<SessionMessagesResponse.SessionMessagesResponseItem>;
-
-export namespace SessionMessagesResponse {
- export interface SessionMessagesResponseItem {
- info: SessionAPI.Message;
-
- parts: Array<SessionAPI.Part>;
- }
-}
-
-export type SessionSummarizeResponse = boolean;
-
-export interface SessionChatParams {
- modelID: string;
-
- parts: Array<TextPartInput | FilePartInput>;
-
- providerID: string;
-
- messageID?: string;
-
- mode?: string;
-
- system?: string;
-
- tools?: { [key: string]: boolean };
-}
-
-export interface SessionInitParams {
- messageID: string;
-
- modelID: string;
-
- providerID: string;
-}
-
-export interface SessionRevertParams {
- messageID: string;
-
- partID?: string;
-}
-
-export interface SessionSummarizeParams {
- modelID: string;
-
- providerID: string;
-}
-
-export declare namespace SessionResource {
- export {
- type AssistantMessage as AssistantMessage,
- type FilePart as FilePart,
- type FilePartInput as FilePartInput,
- type FilePartSource as FilePartSource,
- type FilePartSourceText as FilePartSourceText,
- type FileSource as FileSource,
- type Message as Message,
- type Part as Part,
- type Session as Session,
- type SnapshotPart as SnapshotPart,
- type StepFinishPart as StepFinishPart,
- type StepStartPart as StepStartPart,
- type SymbolSource as SymbolSource,
- type TextPart as TextPart,
- type TextPartInput as TextPartInput,
- type ToolPart as ToolPart,
- type ToolStateCompleted as ToolStateCompleted,
- type ToolStateError as ToolStateError,
- type ToolStatePending as ToolStatePending,
- type ToolStateRunning as ToolStateRunning,
- type UserMessage as UserMessage,
- type SessionListResponse as SessionListResponse,
- type SessionDeleteResponse as SessionDeleteResponse,
- type SessionAbortResponse as SessionAbortResponse,
- type SessionInitResponse as SessionInitResponse,
- type SessionMessagesResponse as SessionMessagesResponse,
- type SessionSummarizeResponse as SessionSummarizeResponse,
- type SessionChatParams as SessionChatParams,
- type SessionInitParams as SessionInitParams,
- type SessionRevertParams as SessionRevertParams,
- type SessionSummarizeParams as SessionSummarizeParams,
- };
-}
diff --git a/packages/sdk/src/resources/shared.ts b/packages/sdk/src/resources/shared.ts
deleted file mode 100644
index 31378f6fe..000000000
--- a/packages/sdk/src/resources/shared.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export interface MessageAbortedError {
- data: unknown;
-
- name: 'MessageAbortedError';
-}
-
-export interface ProviderAuthError {
- data: ProviderAuthError.Data;
-
- name: 'ProviderAuthError';
-}
-
-export namespace ProviderAuthError {
- export interface Data {
- message: string;
-
- providerID: string;
- }
-}
-
-export interface UnknownError {
- data: UnknownError.Data;
-
- name: 'UnknownError';
-}
-
-export namespace UnknownError {
- export interface Data {
- message: string;
- }
-}
diff --git a/packages/sdk/src/resources/tui.ts b/packages/sdk/src/resources/tui.ts
deleted file mode 100644
index c7efbdd6c..000000000
--- a/packages/sdk/src/resources/tui.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../core/resource';
-import { APIPromise } from '../core/api-promise';
-import { RequestOptions } from '../internal/request-options';
-
-export class Tui extends APIResource {
- /**
- * Append prompt to the TUI
- */
- appendPrompt(body: TuiAppendPromptParams, options?: RequestOptions): APIPromise<TuiAppendPromptResponse> {
- return this._client.post('/tui/append-prompt', { body, ...options });
- }
-
- /**
- * Open the help dialog
- */
- openHelp(options?: RequestOptions): APIPromise<TuiOpenHelpResponse> {
- return this._client.post('/tui/open-help', options);
- }
-}
-
-export type TuiAppendPromptResponse = boolean;
-
-export type TuiOpenHelpResponse = boolean;
-
-export interface TuiAppendPromptParams {
- text: string;
-}
-
-export declare namespace Tui {
- export {
- type TuiAppendPromptResponse as TuiAppendPromptResponse,
- type TuiOpenHelpResponse as TuiOpenHelpResponse,
- type TuiAppendPromptParams as TuiAppendPromptParams,
- };
-}
diff --git a/packages/sdk/src/streaming.ts b/packages/sdk/src/streaming.ts
deleted file mode 100644
index 9e6da1063..000000000
--- a/packages/sdk/src/streaming.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** @deprecated Import from ./core/streaming instead */
-export * from './core/streaming';
diff --git a/packages/sdk/src/uploads.ts b/packages/sdk/src/uploads.ts
deleted file mode 100644
index b2ef64710..000000000
--- a/packages/sdk/src/uploads.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** @deprecated Import from ./core/uploads instead */
-export * from './core/uploads';
diff --git a/packages/sdk/src/version.ts b/packages/sdk/src/version.ts
deleted file mode 100644
index 48ca0ae07..000000000
--- a/packages/sdk/src/version.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const VERSION = '0.1.0-alpha.20'; // x-release-please-version