diff --git a/crates/arc-api/Cargo.toml b/crates/arc-api/Cargo.toml index 6a795f806..bb0d0928e 100644 --- a/crates/arc-api/Cargo.toml +++ b/crates/arc-api/Cargo.toml @@ -33,6 +33,7 @@ tower-service = "0.3" x509-parser = "0.16" serde.workspace = true serde_json.workspace = true +serde_yaml = "0.9" anyhow.workspace = true clap.workspace = true toml.workspace = true diff --git a/crates/arc-api/src/jwt_auth.rs b/crates/arc-api/src/jwt_auth.rs index e3b014fcf..7458db7fc 100644 --- a/crates/arc-api/src/jwt_auth.rs +++ b/crates/arc-api/src/jwt_auth.rs @@ -109,6 +109,39 @@ pub fn resolve_auth_mode( AuthMode::Strategies(strategies) } +/// Extract the login from JWT claims. +fn extract_jwt_login(parts: &Parts, key: &DecodingKey, validation: &Validation) -> Option { + let header = parts + .headers + .get("authorization") + .and_then(|v| v.to_str().ok())?; + let token = header.strip_prefix("Bearer ")?; + let token_data = jsonwebtoken::decode::(token, key, validation).ok()?; + token_data + .claims + .sub + .as_deref() + .and_then(|s| s.rsplit('/').next()) + .map(String::from) +} + +/// Extract the CN from mTLS peer certificates. +fn extract_mtls_cn(parts: &Parts) -> Option { + let peer_certs = parts + .extensions + .get::() + .and_then(|pc| pc.0.as_ref())?; + let cert = peer_certs.first()?; + let (_, parsed) = x509_parser::parse_x509_certificate(cert).ok()?; + let cn = parsed + .subject() + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .map(String::from); + cn +} + /// Try to authenticate via JWT. fn try_jwt( parts: &Parts, @@ -222,6 +255,68 @@ impl FromRequestParts for AuthenticatedService { } } +/// Axum extractor that authenticates and extracts the user's login. +/// +/// - Demo mode → `login: "demo"` +/// - JWT → login from the `sub` claim (last path segment of URL) +/// - mTLS → CN from the peer certificate +pub struct AuthenticatedUser { + pub login: String, +} + +impl FromRequestParts for AuthenticatedUser { + type Rejection = StatusCode; + + async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result { + let auth_mode = parts + .extensions + .get::() + .expect("AuthMode extension must be added to the router"); + + let strategies = match auth_mode { + AuthMode::Disabled => { + return Ok(AuthenticatedUser { + login: "demo".to_string(), + }) + } + AuthMode::Strategies(strategies) => strategies, + }; + + if strategies.is_empty() { + return Err(StatusCode::UNAUTHORIZED); + } + + let mut last_err = StatusCode::UNAUTHORIZED; + + for strategy in strategies { + match strategy { + AuthStrategy::Jwt { + key, + validation, + allowed_usernames, + } => { + if try_jwt(parts, key, validation, allowed_usernames).is_ok() { + if let Some(login) = extract_jwt_login(parts, key, validation) { + return Ok(AuthenticatedUser { login }); + } + } + last_err = StatusCode::UNAUTHORIZED; + } + AuthStrategy::Mtls => { + if try_mtls(parts).is_ok() { + if let Some(login) = extract_mtls_cn(parts) { + return Ok(AuthenticatedUser { login }); + } + } + last_err = StatusCode::UNAUTHORIZED; + } + } + } + + Err(last_err) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/arc-api/src/server.rs b/crates/arc-api/src/server.rs index 96cf631f1..831f9f3a5 100644 --- a/crates/arc-api/src/server.rs +++ b/crates/arc-api/src/server.rs @@ -16,7 +16,7 @@ use tracing::{error, info}; use arc_agent::LocalSandbox; -use crate::jwt_auth::{AuthMode, AuthenticatedService}; +use crate::jwt_auth::{AuthMode, AuthenticatedService, AuthenticatedUser}; use arc_workflows::checkpoint::Checkpoint; use arc_workflows::context::Context; use arc_workflows::engine::{RunConfig, WorkflowRunEngine}; @@ -57,7 +57,11 @@ pub struct AppState { pub fn build_router(state: Arc, auth_mode: AuthMode) -> Router { let is_demo = state.is_demo; - let mut router = Router::new(); + let mut router = Router::new() + .route("/", get(root)) + .route("/health", get(health)) + .route("/openapi.json", get(openapi_spec)) + .route("/user", get(get_user)); if is_demo { router = router @@ -190,6 +194,31 @@ async fn not_implemented() -> Response { StatusCode::NOT_IMPLEMENTED.into_response() } +async fn root() -> Response { + Json(serde_json::json!({ + "urls": { + "openapi_url": "/openapi.json", + "current_user_url": "/user", + "health_url": "/health" + } + })) + .into_response() +} + +async fn health() -> Response { + Json(serde_json::json!({"status": "ok"})).into_response() +} + +async fn openapi_spec() -> Response { + let yaml = include_str!("../../../openapi/arc-api.yaml"); + let value: serde_json::Value = serde_yaml::from_str(yaml).expect("embedded OpenAPI YAML is invalid"); + Json(value).into_response() +} + +async fn get_user(user: AuthenticatedUser) -> Response { + Json(serde_json::json!({"login": user.login})).into_response() +} + /// Create an `AppState` with the given registry factory and database pool. /// /// The factory receives the run's `WebInterviewer` so it can wire it diff --git a/docs/api-reference/arc-api.yaml b/docs/api-reference/arc-api.yaml index 18fe552fe..7fbd20b51 100644 --- a/docs/api-reference/arc-api.yaml +++ b/docs/api-reference/arc-api.yaml @@ -5,6 +5,8 @@ info: description: HTTP API for managing Arc workflow run executions. tags: + - name: Discovery + description: API discovery and health - name: Runs description: Run management operations - name: Human-in-the-Loop @@ -31,6 +33,65 @@ tags: description: Platform configuration paths: + # ── Discovery ──────────────────────────────────────────────────────── + + /: + get: + operationId: getRoot + tags: [Discovery] + summary: API Discovery + description: Returns discovery URLs for the API. + responses: + "200": + description: Discovery URLs + content: + application/json: + schema: + $ref: "#/components/schemas/RootResponse" + + /health: + get: + operationId: getHealth + tags: [Discovery] + summary: Health Check + responses: + "200": + description: Service is healthy + content: + application/json: + schema: + $ref: "#/components/schemas/HealthResponse" + + /openapi.json: + get: + operationId: getOpenApiSpec + tags: [Discovery] + summary: OpenAPI Specification + description: Returns the OpenAPI spec as JSON. + responses: + "200": + description: OpenAPI specification + content: + application/json: + schema: + type: object + + /user: + get: + operationId: getUser + tags: [Discovery] + summary: Current User + description: Returns info about the authenticated user. + responses: + "200": + description: User info + content: + application/json: + schema: + $ref: "#/components/schemas/UserResponse" + "401": + description: Not authenticated + # ── Runs ────────────────────────────────────────────────────────────── /runs: @@ -1834,3 +1895,43 @@ components: type: string name: type: string + + # ── Discovery Schemas ────────────────────────────────────────────── + + RootResponseUrls: + type: object + required: + - openapi_url + - current_user_url + - health_url + properties: + openapi_url: + type: string + current_user_url: + type: string + health_url: + type: string + + RootResponse: + type: object + required: + - urls + properties: + urls: + $ref: "#/components/schemas/RootResponseUrls" + + HealthResponse: + type: object + required: + - status + properties: + status: + type: string + + UserResponse: + type: object + required: + - login + properties: + login: + type: string diff --git a/openapi/arc-api.yaml b/openapi/arc-api.yaml index 18fe552fe..7fbd20b51 100644 --- a/openapi/arc-api.yaml +++ b/openapi/arc-api.yaml @@ -5,6 +5,8 @@ info: description: HTTP API for managing Arc workflow run executions. tags: + - name: Discovery + description: API discovery and health - name: Runs description: Run management operations - name: Human-in-the-Loop @@ -31,6 +33,65 @@ tags: description: Platform configuration paths: + # ── Discovery ──────────────────────────────────────────────────────── + + /: + get: + operationId: getRoot + tags: [Discovery] + summary: API Discovery + description: Returns discovery URLs for the API. + responses: + "200": + description: Discovery URLs + content: + application/json: + schema: + $ref: "#/components/schemas/RootResponse" + + /health: + get: + operationId: getHealth + tags: [Discovery] + summary: Health Check + responses: + "200": + description: Service is healthy + content: + application/json: + schema: + $ref: "#/components/schemas/HealthResponse" + + /openapi.json: + get: + operationId: getOpenApiSpec + tags: [Discovery] + summary: OpenAPI Specification + description: Returns the OpenAPI spec as JSON. + responses: + "200": + description: OpenAPI specification + content: + application/json: + schema: + type: object + + /user: + get: + operationId: getUser + tags: [Discovery] + summary: Current User + description: Returns info about the authenticated user. + responses: + "200": + description: User info + content: + application/json: + schema: + $ref: "#/components/schemas/UserResponse" + "401": + description: Not authenticated + # ── Runs ────────────────────────────────────────────────────────────── /runs: @@ -1834,3 +1895,43 @@ components: type: string name: type: string + + # ── Discovery Schemas ────────────────────────────────────────────── + + RootResponseUrls: + type: object + required: + - openapi_url + - current_user_url + - health_url + properties: + openapi_url: + type: string + current_user_url: + type: string + health_url: + type: string + + RootResponse: + type: object + required: + - urls + properties: + urls: + $ref: "#/components/schemas/RootResponseUrls" + + HealthResponse: + type: object + required: + - status + properties: + status: + type: string + + UserResponse: + type: object + required: + - login + properties: + login: + type: string diff --git a/packages/arc-api-client/src/.openapi-generator/FILES b/packages/arc-api-client/src/.openapi-generator/FILES index 9b89097c9..64f485a93 100644 --- a/packages/arc-api-client/src/.openapi-generator/FILES +++ b/packages/arc-api-client/src/.openapi-generator/FILES @@ -1,4 +1,5 @@ api.ts +api/discovery-api.ts api/human-in-the-loop-api.ts api/insights-api.ts api/projects-api.ts @@ -33,6 +34,7 @@ models/execute-query-request.ts models/execute-query-response.ts models/file-checkpoint.ts models/file-diff.ts +models/health-response.ts models/history-entry.ts models/index.ts models/preview-url-request.ts @@ -41,6 +43,8 @@ models/project.ts models/recent-control-result.ts models/retro-list-item.ts models/retro-stats.ts +models/root-response-urls.ts +models/root-response.ts models/run-files.ts models/run-list-item-status.ts models/run-list-item.ts @@ -74,6 +78,7 @@ models/tool-use.ts models/usage-by-model.ts models/usage-stage.ts models/usage-totals.ts +models/user-response.ts models/verification-category.ts models/verification-control.ts models/verification-detail-response.ts diff --git a/packages/arc-api-client/src/api.ts b/packages/arc-api-client/src/api.ts index 22e5f4272..ddad86f3a 100644 --- a/packages/arc-api-client/src/api.ts +++ b/packages/arc-api-client/src/api.ts @@ -14,6 +14,7 @@ +export * from './api/discovery-api'; export * from './api/human-in-the-loop-api'; export * from './api/insights-api'; export * from './api/projects-api'; diff --git a/packages/arc-api-client/src/api/discovery-api.ts b/packages/arc-api-client/src/api/discovery-api.ts new file mode 100644 index 000000000..22ce54e92 --- /dev/null +++ b/packages/arc-api-client/src/api/discovery-api.ts @@ -0,0 +1,304 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Arc Run API + * HTTP API for managing Arc workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction, replaceWithSerializableTypeIfNeeded } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { HealthResponse } from '../models'; +// @ts-ignore +import type { RootResponse } from '../models'; +// @ts-ignore +import type { UserResponse } from '../models'; +/** + * DiscoveryApi - axios parameter creator + */ +export const DiscoveryApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Health Check + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getHealth: async (options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/health`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Returns the OpenAPI spec as JSON. + * @summary OpenAPI Specification + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getOpenApiSpec: async (options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/openapi.json`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Returns discovery URLs for the API. + * @summary API Discovery + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getRoot: async (options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Returns info about the authenticated user. + * @summary Current User + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUser: async (options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/user`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * DiscoveryApi - functional programming interface + */ +export const DiscoveryApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = DiscoveryApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Health Check + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getHealth(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getHealth(options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['DiscoveryApi.getHealth']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Returns the OpenAPI spec as JSON. + * @summary OpenAPI Specification + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getOpenApiSpec(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getOpenApiSpec(options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['DiscoveryApi.getOpenApiSpec']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Returns discovery URLs for the API. + * @summary API Discovery + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getRoot(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getRoot(options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['DiscoveryApi.getRoot']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Returns info about the authenticated user. + * @summary Current User + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUser(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUser(options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['DiscoveryApi.getUser']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * DiscoveryApi - factory interface + */ +export const DiscoveryApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = DiscoveryApiFp(configuration) + return { + /** + * + * @summary Health Check + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getHealth(options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.getHealth(options).then((request) => request(axios, basePath)); + }, + /** + * Returns the OpenAPI spec as JSON. + * @summary OpenAPI Specification + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getOpenApiSpec(options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.getOpenApiSpec(options).then((request) => request(axios, basePath)); + }, + /** + * Returns discovery URLs for the API. + * @summary API Discovery + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getRoot(options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.getRoot(options).then((request) => request(axios, basePath)); + }, + /** + * Returns info about the authenticated user. + * @summary Current User + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUser(options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.getUser(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * DiscoveryApi - object-oriented interface + */ +export class DiscoveryApi extends BaseAPI { + /** + * + * @summary Health Check + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public getHealth(options?: RawAxiosRequestConfig) { + return DiscoveryApiFp(this.configuration).getHealth(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Returns the OpenAPI spec as JSON. + * @summary OpenAPI Specification + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public getOpenApiSpec(options?: RawAxiosRequestConfig) { + return DiscoveryApiFp(this.configuration).getOpenApiSpec(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Returns discovery URLs for the API. + * @summary API Discovery + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public getRoot(options?: RawAxiosRequestConfig) { + return DiscoveryApiFp(this.configuration).getRoot(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Returns info about the authenticated user. + * @summary Current User + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public getUser(options?: RawAxiosRequestConfig) { + return DiscoveryApiFp(this.configuration).getUser(options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/packages/arc-api-client/src/models/health-response.ts b/packages/arc-api-client/src/models/health-response.ts new file mode 100644 index 000000000..d77fda2bc --- /dev/null +++ b/packages/arc-api-client/src/models/health-response.ts @@ -0,0 +1,20 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Arc Run API + * HTTP API for managing Arc workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +export interface HealthResponse { + 'status': string; +} + diff --git a/packages/arc-api-client/src/models/index.ts b/packages/arc-api-client/src/models/index.ts index bae04dabe..1833ea26d 100644 --- a/packages/arc-api-client/src/models/index.ts +++ b/packages/arc-api-client/src/models/index.ts @@ -17,6 +17,7 @@ export * from './execute-query-request'; export * from './execute-query-response'; export * from './file-checkpoint'; export * from './file-diff'; +export * from './health-response'; export * from './history-entry'; export * from './preview-url-request'; export * from './preview-url-response'; @@ -24,6 +25,8 @@ export * from './project'; export * from './recent-control-result'; export * from './retro-list-item'; export * from './retro-stats'; +export * from './root-response'; +export * from './root-response-urls'; export * from './run-files'; export * from './run-list-item'; export * from './run-list-item-status'; @@ -57,6 +60,7 @@ export * from './tool-use'; export * from './usage-by-model'; export * from './usage-stage'; export * from './usage-totals'; +export * from './user-response'; export * from './verification-category'; export * from './verification-control'; export * from './verification-detail-response'; diff --git a/packages/arc-api-client/src/models/root-response-urls.ts b/packages/arc-api-client/src/models/root-response-urls.ts new file mode 100644 index 000000000..193168a0a --- /dev/null +++ b/packages/arc-api-client/src/models/root-response-urls.ts @@ -0,0 +1,22 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Arc Run API + * HTTP API for managing Arc workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +export interface RootResponseUrls { + 'openapi_url': string; + 'current_user_url': string; + 'health_url': string; +} + diff --git a/packages/arc-api-client/src/models/root-response.ts b/packages/arc-api-client/src/models/root-response.ts new file mode 100644 index 000000000..fff376c6d --- /dev/null +++ b/packages/arc-api-client/src/models/root-response.ts @@ -0,0 +1,23 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Arc Run API + * HTTP API for managing Arc workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { RootResponseUrls } from './root-response-urls'; + +export interface RootResponse { + 'urls': RootResponseUrls; +} + diff --git a/packages/arc-api-client/src/models/user-response.ts b/packages/arc-api-client/src/models/user-response.ts new file mode 100644 index 000000000..39079d607 --- /dev/null +++ b/packages/arc-api-client/src/models/user-response.ts @@ -0,0 +1,20 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Arc Run API + * HTTP API for managing Arc workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +export interface UserResponse { + 'login': string; +} +