mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-15 23:32:46 +00:00
refactor: add run store HTTP endpoints
Define the new run-store contract in the OpenAPI spec, regenerate the Rust and TypeScript clients, and implement the matching store and server support for run state, event access, blobs, and stage artifacts.
This commit is contained in:
parent
ddebb888b6
commit
39980b5404
25 changed files with 2554 additions and 127 deletions
|
|
@ -335,14 +335,93 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/events:
|
||||
/api/v1/runs/{id}/state:
|
||||
get:
|
||||
operationId: streamRunEvents
|
||||
tags: [Runs]
|
||||
summary: Stream Run Events
|
||||
description: Opens a server-sent event (SSE) stream for real-time run updates. Returns 410 if the stream has been closed.
|
||||
operationId: getRunState
|
||||
tags: [Run Internals]
|
||||
summary: Get Run State
|
||||
description: Returns the internal event-sourced run projection. This is not a stable public contract.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
responses:
|
||||
"200":
|
||||
description: Current run projection
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/RunProjection"
|
||||
"404":
|
||||
description: Run not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/events:
|
||||
get:
|
||||
operationId: listRunEvents
|
||||
tags: [Run Internals]
|
||||
summary: List Run Events
|
||||
description: Returns a paginated JSON list of stored run events.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
- $ref: "#/components/parameters/SinceSeq"
|
||||
- $ref: "#/components/parameters/EventLimit"
|
||||
responses:
|
||||
"200":
|
||||
description: Paginated list of run events
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PaginatedEventList"
|
||||
"404":
|
||||
description: Run not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
post:
|
||||
operationId: appendRunEvent
|
||||
tags: [Run Internals]
|
||||
summary: Append Run Event
|
||||
description: Appends a validated event to the run event log. Intended for trusted internal callers.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/RunEvent"
|
||||
responses:
|
||||
"200":
|
||||
description: Event appended
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/AppendEventResponse"
|
||||
"400":
|
||||
description: Invalid event payload
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"404":
|
||||
description: Run not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/attach:
|
||||
get:
|
||||
operationId: attachRunEvents
|
||||
tags: [Run Internals]
|
||||
summary: Attach Run Events
|
||||
description: Opens a server-sent event stream for a live run. Optionally replays stored events from `since_seq` before switching to live updates.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
- $ref: "#/components/parameters/SinceSeq"
|
||||
responses:
|
||||
"200":
|
||||
description: Server-sent event stream
|
||||
|
|
@ -357,7 +436,60 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"410":
|
||||
description: Event stream closed
|
||||
description: Run is not live on this server
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/blobs:
|
||||
post:
|
||||
operationId: writeRunBlob
|
||||
tags: [Run Internals]
|
||||
summary: Write Run Blob
|
||||
description: Writes an opaque binary blob and returns its content-addressed blob identifier.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
responses:
|
||||
"200":
|
||||
description: Blob written
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WriteBlobResponse"
|
||||
"404":
|
||||
description: Run not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/blobs/{blobId}:
|
||||
get:
|
||||
operationId: readRunBlob
|
||||
tags: [Run Internals]
|
||||
summary: Read Run Blob
|
||||
description: Reads a previously stored blob by identifier.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
- $ref: "#/components/parameters/BlobId"
|
||||
responses:
|
||||
"200":
|
||||
description: Blob contents
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
"404":
|
||||
description: Run or blob not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
|
@ -497,6 +629,91 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/stages/{stageId}/artifacts:
|
||||
get:
|
||||
operationId: listStageArtifacts
|
||||
tags: [Run Internals]
|
||||
summary: List Stage Artifacts
|
||||
description: Lists artifact filenames stored for a stage.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
- $ref: "#/components/parameters/StageId"
|
||||
responses:
|
||||
"200":
|
||||
description: Artifact filenames for the stage
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ArtifactListResponse"
|
||||
"404":
|
||||
description: Run not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
post:
|
||||
operationId: putStageArtifact
|
||||
tags: [Run Internals]
|
||||
summary: Put Stage Artifact
|
||||
description: Uploads an artifact for a stage. Intended for trusted internal callers.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
- $ref: "#/components/parameters/StageId"
|
||||
- $ref: "#/components/parameters/ArtifactFilename"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
responses:
|
||||
"204":
|
||||
description: Artifact written
|
||||
"400":
|
||||
description: Missing filename
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"404":
|
||||
description: Run not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/stages/{stageId}/artifacts/download:
|
||||
get:
|
||||
operationId: getStageArtifact
|
||||
tags: [Run Internals]
|
||||
summary: Get Stage Artifact
|
||||
description: Downloads an artifact by filename.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/RunId"
|
||||
- $ref: "#/components/parameters/StageId"
|
||||
- $ref: "#/components/parameters/ArtifactFilename"
|
||||
responses:
|
||||
"200":
|
||||
description: Artifact contents
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
"400":
|
||||
description: Missing filename
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"404":
|
||||
description: Run, stage, or artifact not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/files:
|
||||
get:
|
||||
operationId: retrieveRunFiles
|
||||
|
|
@ -1318,10 +1535,52 @@ components:
|
|||
name: stageId
|
||||
in: path
|
||||
required: true
|
||||
description: Identifier of a stage within a run's workflow graph.
|
||||
description: Identifier of a stage within a run's workflow graph, serialized as `node_id@visit`.
|
||||
schema:
|
||||
type: string
|
||||
example: propose-changes
|
||||
example: code@2
|
||||
|
||||
BlobId:
|
||||
name: blobId
|
||||
in: path
|
||||
required: true
|
||||
description: Content-addressed blob identifier.
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
example: 550e8400-e29b-41d4-a716-446655440000
|
||||
|
||||
ArtifactFilename:
|
||||
name: filename
|
||||
in: query
|
||||
required: true
|
||||
description: Artifact filename. May contain path separators.
|
||||
schema:
|
||||
type: string
|
||||
example: src/lib.rs
|
||||
|
||||
SinceSeq:
|
||||
name: since_seq
|
||||
in: query
|
||||
required: false
|
||||
description: First event sequence number to include.
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
default: 1
|
||||
example: 42
|
||||
|
||||
EventLimit:
|
||||
name: limit
|
||||
in: query
|
||||
required: false
|
||||
description: Maximum number of events to return.
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 1000
|
||||
default: 100
|
||||
example: 100
|
||||
|
||||
QuestionId:
|
||||
name: qid
|
||||
|
|
@ -2076,6 +2335,291 @@ components:
|
|||
items:
|
||||
$ref: "#/components/schemas/ErrorResponseEntry"
|
||||
|
||||
RunEvent:
|
||||
description: >
|
||||
Internal RunEvent-compatible JSON payload. The server validates this
|
||||
body by deserializing into the typed RunEvent struct.
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- ts
|
||||
- run_id
|
||||
- event
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
ts:
|
||||
type: string
|
||||
format: date-time
|
||||
run_id:
|
||||
type: string
|
||||
node_id:
|
||||
type: string
|
||||
nullable: true
|
||||
node_label:
|
||||
type: string
|
||||
nullable: true
|
||||
session_id:
|
||||
type: string
|
||||
nullable: true
|
||||
parent_session_id:
|
||||
type: string
|
||||
nullable: true
|
||||
event:
|
||||
type: string
|
||||
description: Event type discriminator.
|
||||
example: stage.started
|
||||
properties:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
additionalProperties: true
|
||||
|
||||
EventEnvelope:
|
||||
description: Stored event envelope with assigned sequence number.
|
||||
type: object
|
||||
required:
|
||||
- seq
|
||||
- payload
|
||||
properties:
|
||||
seq:
|
||||
type: integer
|
||||
description: Assigned event sequence number.
|
||||
example: 42
|
||||
payload:
|
||||
$ref: "#/components/schemas/RunEvent"
|
||||
|
||||
PaginatedEventList:
|
||||
description: Paginated list of stored run events.
|
||||
type: object
|
||||
required:
|
||||
- data
|
||||
- meta
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/EventEnvelope"
|
||||
meta:
|
||||
$ref: "#/components/schemas/PaginationMeta"
|
||||
|
||||
AppendEventResponse:
|
||||
description: Assigned sequence number for an appended event.
|
||||
type: object
|
||||
required:
|
||||
- seq
|
||||
properties:
|
||||
seq:
|
||||
type: integer
|
||||
description: Assigned event sequence number.
|
||||
example: 42
|
||||
|
||||
WriteBlobResponse:
|
||||
description: Content-addressed identifier for a stored blob.
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Blob identifier.
|
||||
example: 550e8400-e29b-41d4-a716-446655440000
|
||||
|
||||
ArtifactEntry:
|
||||
description: A single artifact filename.
|
||||
type: object
|
||||
required:
|
||||
- filename
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
description: Artifact filename.
|
||||
example: src/lib.rs
|
||||
|
||||
ArtifactListResponse:
|
||||
description: List of artifact filenames for a stage.
|
||||
type: object
|
||||
required:
|
||||
- data
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ArtifactEntry"
|
||||
|
||||
InternalRunStatus:
|
||||
description: Internal event-sourced run status.
|
||||
type: string
|
||||
enum:
|
||||
- submitted
|
||||
- starting
|
||||
- running
|
||||
- paused
|
||||
- removing
|
||||
- succeeded
|
||||
- failed
|
||||
- dead
|
||||
|
||||
StatusReason:
|
||||
description: Optional reason attached to a run status transition.
|
||||
type: string
|
||||
enum:
|
||||
- completed
|
||||
- partial_success
|
||||
- workflow_error
|
||||
- cancelled
|
||||
- terminated
|
||||
- transient_infra
|
||||
- budget_exhausted
|
||||
- launch_failed
|
||||
- bootstrap_failed
|
||||
- sandbox_init_failed
|
||||
- sandbox_initializing
|
||||
|
||||
RunStatusRecord:
|
||||
description: Internal run status record from the event projection.
|
||||
type: object
|
||||
required:
|
||||
- status
|
||||
- updated_at
|
||||
properties:
|
||||
status:
|
||||
$ref: "#/components/schemas/InternalRunStatus"
|
||||
reason:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/StatusReason"
|
||||
- type: "null"
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
InternalStageStatus:
|
||||
description: Internal stage status from outcomes and node status records.
|
||||
type: string
|
||||
enum:
|
||||
- success
|
||||
- fail
|
||||
- skipped
|
||||
- partial_success
|
||||
- retry
|
||||
|
||||
NodeStatusRecord:
|
||||
description: Internal node status record.
|
||||
type: object
|
||||
required:
|
||||
- status
|
||||
- timestamp
|
||||
properties:
|
||||
status:
|
||||
$ref: "#/components/schemas/InternalStageStatus"
|
||||
notes:
|
||||
type: string
|
||||
nullable: true
|
||||
failure_reason:
|
||||
type: string
|
||||
nullable: true
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
NodeState:
|
||||
description: Internal node projection state.
|
||||
type: object
|
||||
properties:
|
||||
prompt:
|
||||
type: string
|
||||
nullable: true
|
||||
response:
|
||||
type: string
|
||||
nullable: true
|
||||
status:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/NodeStatusRecord"
|
||||
- type: "null"
|
||||
provider_used:
|
||||
nullable: true
|
||||
diff:
|
||||
type: string
|
||||
nullable: true
|
||||
script_invocation:
|
||||
nullable: true
|
||||
script_timing:
|
||||
nullable: true
|
||||
parallel_results:
|
||||
nullable: true
|
||||
stdout:
|
||||
type: string
|
||||
nullable: true
|
||||
stderr:
|
||||
type: string
|
||||
nullable: true
|
||||
|
||||
RunProjection:
|
||||
description: Raw internal run projection derived from the event log.
|
||||
type: object
|
||||
required:
|
||||
- nodes
|
||||
properties:
|
||||
run:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
nullable: true
|
||||
graph_source:
|
||||
type: string
|
||||
nullable: true
|
||||
start:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
nullable: true
|
||||
status:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/RunStatusRecord"
|
||||
- type: "null"
|
||||
checkpoint:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/RunCheckpoint"
|
||||
- type: "null"
|
||||
checkpoints:
|
||||
type: array
|
||||
description: Sequence-tagged checkpoint history entries as `[seq, checkpoint]`.
|
||||
items:
|
||||
type: array
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
oneOf:
|
||||
- type: integer
|
||||
- $ref: "#/components/schemas/RunCheckpoint"
|
||||
conclusion:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
nullable: true
|
||||
retro:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
nullable: true
|
||||
retro_prompt:
|
||||
type: string
|
||||
nullable: true
|
||||
retro_response:
|
||||
type: string
|
||||
nullable: true
|
||||
sandbox:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
nullable: true
|
||||
final_patch:
|
||||
type: string
|
||||
nullable: true
|
||||
pull_request:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
nullable: true
|
||||
nodes:
|
||||
type: object
|
||||
description: Map from StageId (`node_id@visit`) to NodeState.
|
||||
additionalProperties:
|
||||
$ref: "#/components/schemas/NodeState"
|
||||
|
||||
# ── Run Board Schemas ────────────────────────────────────────────────
|
||||
|
||||
BoardColumn:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::time::Duration;
|
||||
|
|
@ -13,14 +14,15 @@ use axum::response::{IntoResponse, Response};
|
|||
use axum::routing::{get, post};
|
||||
use axum::{Json, Router};
|
||||
use axum_extra::extract::cookie::Key;
|
||||
use bytes::Bytes;
|
||||
use fabro_llm::client::Client as LlmClient;
|
||||
use fabro_llm::generate::{GenerateParams, generate, generate_object};
|
||||
use fabro_llm::types::{
|
||||
ContentPart, FinishReason, Message as LlmMessage, Request as LlmRequest,
|
||||
Response as LlmResponse, Role, StreamEvent, ToolChoice, ToolDefinition, Usage,
|
||||
};
|
||||
use fabro_store::StoreHandle;
|
||||
use fabro_types::{RunEvent, RunId, Settings};
|
||||
use fabro_store::{EventEnvelope, EventPayload, StageId, StoreHandle};
|
||||
use fabro_types::{RunBlobId, RunEvent, RunId, Settings};
|
||||
use fabro_util::redact::redact_jsonl_line;
|
||||
use fabro_workflow::error::FabroError;
|
||||
use fabro_workflow::handler::HandlerRegistry;
|
||||
|
|
@ -32,7 +34,6 @@ use tokio::sync::{Notify, OnceCell};
|
|||
use tokio::task::spawn_blocking;
|
||||
use tokio::time::{sleep, timeout};
|
||||
use tokio_stream::StreamExt;
|
||||
use tokio_stream::wrappers::BroadcastStream;
|
||||
use tower::{ServiceExt, service_fn};
|
||||
use ulid::Ulid;
|
||||
|
||||
|
|
@ -53,11 +54,13 @@ use fabro_workflow::records::Checkpoint;
|
|||
|
||||
use fabro_api::types::AggregateUsageTotals;
|
||||
pub use fabro_api::types::{
|
||||
AggregateUsage, ApiQuestion, ApiQuestionOption, CompletionContentPart, CompletionMessage,
|
||||
CompletionMessageRole, CompletionResponse, CompletionToolChoiceMode, CompletionUsage,
|
||||
CreateCompletionRequest, CreateRunRequest, ModelReference, PaginatedRunList, PaginationMeta,
|
||||
QuestionType as ApiQuestionType, RunError, RunStatus, RunStatusResponse, SubmitAnswerRequest,
|
||||
TokenUsage, UsageByModel,
|
||||
AggregateUsage, ApiQuestion, ApiQuestionOption, AppendEventResponse, ArtifactEntry,
|
||||
ArtifactListResponse, CompletionContentPart, CompletionMessage, CompletionMessageRole,
|
||||
CompletionResponse, CompletionToolChoiceMode, CompletionUsage, CreateCompletionRequest,
|
||||
CreateRunRequest, EventEnvelope as ApiEventEnvelope, ModelReference, PaginatedEventList,
|
||||
PaginatedRunList, PaginationMeta, QuestionType as ApiQuestionType, RunError, RunEvent as ApiRunEvent,
|
||||
RunStatus, RunStatusResponse, SubmitAnswerRequest, TokenUsage, UsageByModel,
|
||||
WriteBlobResponse,
|
||||
};
|
||||
|
||||
pub fn default_page_limit() -> u32 {
|
||||
|
|
@ -72,6 +75,36 @@ pub struct PaginationParams {
|
|||
pub offset: u32,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct EventListParams {
|
||||
#[serde(default)]
|
||||
since_seq: Option<u32>,
|
||||
#[serde(default)]
|
||||
limit: Option<usize>,
|
||||
}
|
||||
|
||||
impl EventListParams {
|
||||
fn since_seq(&self) -> u32 {
|
||||
self.since_seq.unwrap_or(1).max(1)
|
||||
}
|
||||
|
||||
fn limit(&self) -> usize {
|
||||
self.limit.unwrap_or(100).clamp(1, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct AttachParams {
|
||||
#[serde(default)]
|
||||
since_seq: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct ArtifactFilenameParams {
|
||||
#[serde(default)]
|
||||
filename: Option<String>,
|
||||
}
|
||||
|
||||
/// Non-paginated list response wrapper with `has_more: false`.
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct ListResponse<T: serde::Serialize> {
|
||||
|
|
@ -199,7 +232,11 @@ fn demo_routes() -> Router<Arc<AppState>> {
|
|||
.route("/runs/{id}", get(demo::get_run_status))
|
||||
.route("/runs/{id}/questions", get(demo::get_questions_stub))
|
||||
.route("/runs/{id}/questions/{qid}/answer", post(demo::answer_stub))
|
||||
.route("/runs/{id}/events", get(demo::run_events_stub))
|
||||
.route("/runs/{id}/state", get(not_implemented))
|
||||
.route("/runs/{id}/events", get(not_implemented).post(not_implemented))
|
||||
.route("/runs/{id}/attach", get(demo::run_events_stub))
|
||||
.route("/runs/{id}/blobs", post(not_implemented))
|
||||
.route("/runs/{id}/blobs/{blobId}", get(not_implemented))
|
||||
.route("/runs/{id}/checkpoint", get(demo::checkpoint_stub))
|
||||
.route("/runs/{id}/cancel", post(demo::cancel_stub))
|
||||
.route("/runs/{id}/start", post(demo::start_run_stub))
|
||||
|
|
@ -212,6 +249,14 @@ fn demo_routes() -> Router<Arc<AppState>> {
|
|||
"/runs/{id}/stages/{stageId}/turns",
|
||||
get(demo::get_stage_turns),
|
||||
)
|
||||
.route(
|
||||
"/runs/{id}/stages/{stageId}/artifacts",
|
||||
get(not_implemented).post(not_implemented),
|
||||
)
|
||||
.route(
|
||||
"/runs/{id}/stages/{stageId}/artifacts/download",
|
||||
get(not_implemented),
|
||||
)
|
||||
.route("/runs/{id}/files", get(demo::get_run_files))
|
||||
.route("/runs/{id}/usage", get(demo::get_run_usage))
|
||||
.route("/runs/{id}/verification", get(demo::get_run_verification))
|
||||
|
|
@ -275,7 +320,11 @@ fn real_routes() -> Router<Arc<AppState>> {
|
|||
.route("/runs/{id}", get(get_run_status))
|
||||
.route("/runs/{id}/questions", get(get_questions))
|
||||
.route("/runs/{id}/questions/{qid}/answer", post(submit_answer))
|
||||
.route("/runs/{id}/events", get(get_events))
|
||||
.route("/runs/{id}/state", get(get_run_state))
|
||||
.route("/runs/{id}/events", get(list_run_events).post(append_run_event))
|
||||
.route("/runs/{id}/attach", get(attach_run_events))
|
||||
.route("/runs/{id}/blobs", post(write_run_blob))
|
||||
.route("/runs/{id}/blobs/{blobId}", get(read_run_blob))
|
||||
.route("/runs/{id}/checkpoint", get(get_checkpoint))
|
||||
.route("/runs/{id}/cancel", post(cancel_run))
|
||||
.route("/runs/{id}/start", post(start_run))
|
||||
|
|
@ -285,6 +334,14 @@ fn real_routes() -> Router<Arc<AppState>> {
|
|||
.route("/runs/{id}/retro", get(get_retro))
|
||||
.route("/runs/{id}/stages", get(not_implemented))
|
||||
.route("/runs/{id}/stages/{stageId}/turns", get(not_implemented))
|
||||
.route(
|
||||
"/runs/{id}/stages/{stageId}/artifacts",
|
||||
get(list_stage_artifacts).post(put_stage_artifact),
|
||||
)
|
||||
.route(
|
||||
"/runs/{id}/stages/{stageId}/artifacts/download",
|
||||
get(get_stage_artifact),
|
||||
)
|
||||
.route("/runs/{id}/files", get(not_implemented))
|
||||
.route("/runs/{id}/usage", get(not_implemented))
|
||||
.route("/runs/{id}/verification", get(not_implemented))
|
||||
|
|
@ -521,6 +578,54 @@ fn parse_run_id_path(id: &str) -> Result<RunId, Response> {
|
|||
.map_err(|_| ApiError::bad_request("Invalid run ID.").into_response())
|
||||
}
|
||||
|
||||
#[allow(clippy::result_large_err)]
|
||||
fn parse_stage_id_path(stage_id: &str) -> Result<StageId, Response> {
|
||||
StageId::from_str(stage_id)
|
||||
.map_err(|_| ApiError::bad_request("Invalid stage ID.").into_response())
|
||||
}
|
||||
|
||||
#[allow(clippy::result_large_err)]
|
||||
fn parse_blob_id_path(blob_id: &str) -> Result<RunBlobId, Response> {
|
||||
RunBlobId::from_str(blob_id)
|
||||
.map_err(|_| ApiError::bad_request("Invalid blob ID.").into_response())
|
||||
}
|
||||
|
||||
#[allow(clippy::result_large_err)]
|
||||
fn required_filename(params: ArtifactFilenameParams) -> Result<String, Response> {
|
||||
match params.filename {
|
||||
Some(filename) if !filename.is_empty() => Ok(filename),
|
||||
_ => Err(ApiError::bad_request("Missing filename query parameter.").into_response()),
|
||||
}
|
||||
}
|
||||
|
||||
fn octet_stream_response(bytes: Bytes) -> Response {
|
||||
(
|
||||
StatusCode::OK,
|
||||
[("content-type", "application/octet-stream")],
|
||||
bytes,
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
#[allow(clippy::result_large_err)]
|
||||
fn api_run_event_from_store(payload: &EventPayload) -> Result<ApiRunEvent, Response> {
|
||||
serde_json::from_value(payload.as_value().clone()).map_err(|err| {
|
||||
ApiError::new(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Failed to serialize stored event: {err}"),
|
||||
)
|
||||
.into_response()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::result_large_err)]
|
||||
fn api_event_envelope_from_store(event: &EventEnvelope) -> Result<ApiEventEnvelope, Response> {
|
||||
Ok(ApiEventEnvelope {
|
||||
payload: api_run_event_from_store(&event.payload)?,
|
||||
seq: i64::from(event.seq),
|
||||
})
|
||||
}
|
||||
|
||||
fn clear_live_run_state(run: &mut ManagedRun) {
|
||||
run.interviewer = None;
|
||||
run.event_tx = None;
|
||||
|
|
@ -1033,7 +1138,7 @@ async fn submit_answer(
|
|||
}
|
||||
}
|
||||
|
||||
async fn get_events(
|
||||
async fn get_run_state(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(id): Path<String>,
|
||||
|
|
@ -1042,28 +1147,144 @@ async fn get_events(
|
|||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let rx = {
|
||||
let runs = state.runs.lock().expect("runs lock poisoned");
|
||||
match runs.get(&id) {
|
||||
Some(managed_run) => match &managed_run.event_tx {
|
||||
Some(tx) => tx.subscribe(),
|
||||
None => {
|
||||
return ApiError::new(StatusCode::GONE, "Event stream closed.").into_response();
|
||||
}
|
||||
},
|
||||
None => return ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
match state.store.open_run_reader(&id).await {
|
||||
Ok(run_store) => match run_store.state().await {
|
||||
Ok(run_state) => Json(run_state).into_response(),
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn append_run_event(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(id): Path<String>,
|
||||
Json(value): Json<serde_json::Value>,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let event = match RunEvent::from_value(value.clone()) {
|
||||
Ok(event) => event,
|
||||
Err(err) => return ApiError::bad_request(format!("Invalid run event: {err}")).into_response(),
|
||||
};
|
||||
if event.run_id != id {
|
||||
return ApiError::bad_request("Event run_id does not match path run ID.").into_response();
|
||||
}
|
||||
let payload = match EventPayload::new(value, &id) {
|
||||
Ok(payload) => payload,
|
||||
Err(err) => return ApiError::bad_request(err.to_string()).into_response(),
|
||||
};
|
||||
|
||||
let stream = BroadcastStream::new(rx).filter_map(|result| match result {
|
||||
Ok(event) => {
|
||||
let data = serde_json::to_string(&event).unwrap_or_default();
|
||||
let data = redact_jsonl_line(&data);
|
||||
Some(Ok::<Event, std::convert::Infallible>(
|
||||
Event::default().data(data),
|
||||
))
|
||||
match state.store.open_run(&id).await {
|
||||
Ok(run_store) => match run_store.append_event(&payload).await {
|
||||
Ok(seq) => Json(AppendEventResponse { seq: i64::from(seq) }).into_response(),
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_run_events(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(id): Path<String>,
|
||||
Query(params): Query<EventListParams>,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let since_seq = params.since_seq();
|
||||
let limit = params.limit();
|
||||
|
||||
match state.store.open_run_reader(&id).await {
|
||||
Ok(run_store) => match run_store.list_events_from_with_limit(since_seq, limit).await {
|
||||
Ok(mut events) => {
|
||||
let has_more = events.len() > limit;
|
||||
events.truncate(limit);
|
||||
let mut data = Vec::with_capacity(events.len());
|
||||
for event in events {
|
||||
let event = match api_event_envelope_from_store(&event) {
|
||||
Ok(event) => event,
|
||||
Err(response) => return response,
|
||||
};
|
||||
data.push(event);
|
||||
}
|
||||
Json(PaginatedEventList {
|
||||
data,
|
||||
meta: PaginationMeta { has_more },
|
||||
})
|
||||
.into_response()
|
||||
}
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn attach_run_events(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(id): Path<String>,
|
||||
Query(params): Query<AttachParams>,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
{
|
||||
let runs = state.runs.lock().expect("runs lock poisoned");
|
||||
let Some(managed_run) = runs.get(&id) else {
|
||||
return ApiError::not_found("Run not found.").into_response();
|
||||
};
|
||||
if !matches!(
|
||||
managed_run.status,
|
||||
RunStatus::Queued | RunStatus::Starting | RunStatus::Running | RunStatus::Paused
|
||||
) {
|
||||
return ApiError::new(StatusCode::GONE, "Run is not live on this server.")
|
||||
.into_response();
|
||||
}
|
||||
}
|
||||
|
||||
let Ok(run_store) = state.store.open_run_reader(&id).await else {
|
||||
return ApiError::not_found("Run not found.").into_response();
|
||||
};
|
||||
let start_seq = match params.since_seq {
|
||||
Some(seq) if seq >= 1 => seq,
|
||||
Some(_) => 1,
|
||||
None => match run_store.list_events().await {
|
||||
Ok(events) => events.last().map_or(1, |event| event.seq.saturating_add(1)),
|
||||
Err(err) => {
|
||||
return ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response();
|
||||
}
|
||||
},
|
||||
};
|
||||
let stream = match run_store.watch_events_from(start_seq) {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => {
|
||||
return ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
let stream = stream.filter_map(|result| {
|
||||
match result {
|
||||
Ok(event) => {
|
||||
let event = api_event_envelope_from_store(&event).ok()?;
|
||||
let data = serde_json::to_string(&event).ok()?;
|
||||
let data = redact_jsonl_line(&data);
|
||||
Some(Ok::<Event, std::convert::Infallible>(
|
||||
Event::default().data(data),
|
||||
))
|
||||
}
|
||||
Err(_) => None,
|
||||
}
|
||||
Err(_) => None,
|
||||
});
|
||||
|
||||
Sse::new(stream).into_response()
|
||||
|
|
@ -1107,6 +1328,140 @@ async fn get_checkpoint(
|
|||
}
|
||||
}
|
||||
|
||||
async fn write_run_blob(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(id): Path<String>,
|
||||
body: Bytes,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
match state.store.open_run(&id).await {
|
||||
Ok(run_store) => match run_store.write_blob(&body).await {
|
||||
Ok(blob_id) => Json(WriteBlobResponse {
|
||||
id: blob_id.to_string(),
|
||||
})
|
||||
.into_response(),
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_run_blob(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path((id, blob_id)): Path<(String, String)>,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let blob_id = match parse_blob_id_path(&blob_id) {
|
||||
Ok(blob_id) => blob_id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
match state.store.open_run_reader(&id).await {
|
||||
Ok(run_store) => match run_store.read_blob(&blob_id).await {
|
||||
Ok(Some(bytes)) => octet_stream_response(bytes),
|
||||
Ok(None) => ApiError::not_found("Blob not found.").into_response(),
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_stage_artifacts(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path((id, stage_id)): Path<(String, String)>,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let stage_id = match parse_stage_id_path(&stage_id) {
|
||||
Ok(stage_id) => stage_id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
match state.store.open_run_reader(&id).await {
|
||||
Ok(run_store) => match run_store.list_artifacts_for_stage(&stage_id).await {
|
||||
Ok(filenames) => Json(ArtifactListResponse {
|
||||
data: filenames
|
||||
.into_iter()
|
||||
.map(|filename| ArtifactEntry { filename })
|
||||
.collect(),
|
||||
})
|
||||
.into_response(),
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn put_stage_artifact(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path((id, stage_id)): Path<(String, String)>,
|
||||
Query(params): Query<ArtifactFilenameParams>,
|
||||
body: Bytes,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let stage_id = match parse_stage_id_path(&stage_id) {
|
||||
Ok(stage_id) => stage_id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let filename = match required_filename(params) {
|
||||
Ok(filename) => filename,
|
||||
Err(response) => return response,
|
||||
};
|
||||
match state.store.open_run(&id).await {
|
||||
Ok(run_store) => match run_store.put_artifact(&stage_id, &filename, &body).await {
|
||||
Ok(()) => StatusCode::NO_CONTENT.into_response(),
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_stage_artifact(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path((id, stage_id)): Path<(String, String)>,
|
||||
Query(params): Query<ArtifactFilenameParams>,
|
||||
) -> Response {
|
||||
let id = match parse_run_id_path(&id) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let stage_id = match parse_stage_id_path(&stage_id) {
|
||||
Ok(stage_id) => stage_id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let filename = match required_filename(params) {
|
||||
Ok(filename) => filename,
|
||||
Err(response) => return response,
|
||||
};
|
||||
match state.store.open_run_reader(&id).await {
|
||||
Ok(run_store) => match run_store.get_artifact(&stage_id, &filename).await {
|
||||
Ok(Some(bytes)) => octet_stream_response(bytes),
|
||||
Ok(None) => ApiError::not_found("Artifact not found.").into_response(),
|
||||
Err(err) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||
.into_response(),
|
||||
},
|
||||
Err(_) => ApiError::not_found("Run not found.").into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn cancel_run(
|
||||
_auth: AuthenticatedService,
|
||||
State(state): State<Arc<AppState>>,
|
||||
|
|
@ -2031,6 +2386,105 @@ mod tests {
|
|||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_run_state_returns_projection() {
|
||||
let state = create_app_state();
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api("/runs"))
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::to_string(&serde_json::json!({"dot_source": MINIMAL_DOT})).unwrap(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
let body = body_json(response.into_body()).await;
|
||||
let run_id = body["id"].as_str().unwrap();
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!("/runs/{run_id}/state")))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let body = body_json(response.into_body()).await;
|
||||
assert!(body["nodes"].is_object());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn list_run_events_returns_paginated_json() {
|
||||
let state = create_app_state();
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api("/runs"))
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::to_string(&serde_json::json!({"dot_source": MINIMAL_DOT})).unwrap(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
let body = body_json(response.into_body()).await;
|
||||
let run_id = body["id"].as_str().unwrap();
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!("/runs/{run_id}/events?since_seq=1&limit=5")))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let body = body_json(response.into_body()).await;
|
||||
assert!(body["data"].is_array());
|
||||
assert!(body["meta"]["has_more"].is_boolean());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn append_run_event_rejects_run_id_mismatch() {
|
||||
let state = create_app_state();
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api("/runs"))
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::to_string(&serde_json::json!({"dot_source": MINIMAL_DOT})).unwrap(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
let body = body_json(response.into_body()).await;
|
||||
let run_id = body["id"].as_str().unwrap();
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api(&format!("/runs/{run_id}/events")))
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::json!({
|
||||
"id": "evt-test",
|
||||
"ts": "2026-03-27T12:00:00Z",
|
||||
"run_id": fixtures::RUN_64.to_string(),
|
||||
"event": "run.submitted",
|
||||
"properties": {}
|
||||
})
|
||||
.to_string(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_checkpoint_returns_null_initially() {
|
||||
let state = create_app_state();
|
||||
|
|
@ -2061,6 +2515,99 @@ mod tests {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_and_read_run_blob_round_trip() {
|
||||
let state = create_app_state();
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api("/runs"))
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::to_string(&serde_json::json!({"dot_source": MINIMAL_DOT})).unwrap(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
let body = body_json(response.into_body()).await;
|
||||
let run_id = body["id"].as_str().unwrap();
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api(&format!("/runs/{run_id}/blobs")))
|
||||
.header("content-type", "application/octet-stream")
|
||||
.body(Body::from("hello blob"))
|
||||
.unwrap();
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let body = body_json(response.into_body()).await;
|
||||
let blob_id = body["id"].as_str().unwrap();
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!("/runs/{run_id}/blobs/{blob_id}")))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap();
|
||||
assert_eq!(&bytes[..], b"hello blob");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn stage_artifacts_round_trip() {
|
||||
let state = create_app_state();
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api("/runs"))
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::to_string(&serde_json::json!({"dot_source": MINIMAL_DOT})).unwrap(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
let body = body_json(response.into_body()).await;
|
||||
let run_id = body["id"].as_str().unwrap();
|
||||
let stage_id = "code@2";
|
||||
|
||||
let req = Request::builder()
|
||||
.method("POST")
|
||||
.uri(api(&format!(
|
||||
"/runs/{run_id}/stages/{stage_id}/artifacts?filename=src/lib.rs"
|
||||
)))
|
||||
.header("content-type", "application/octet-stream")
|
||||
.body(Body::from("fn main() {}"))
|
||||
.unwrap();
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::NO_CONTENT);
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!("/runs/{run_id}/stages/{stage_id}/artifacts")))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let body = body_json(response.into_body()).await;
|
||||
assert_eq!(body["data"][0]["filename"], "src/lib.rs");
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!(
|
||||
"/runs/{run_id}/stages/{stage_id}/artifacts/download?filename=src/lib.rs"
|
||||
)))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap();
|
||||
assert_eq!(&bytes[..], b"fn main() {}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_run_returns_submitted() {
|
||||
let state = create_app_state();
|
||||
|
|
@ -2198,25 +2745,23 @@ mod tests {
|
|||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn get_events_returns_sse_stream() {
|
||||
async fn attach_run_events_returns_sse_stream() {
|
||||
let state = create_app_state();
|
||||
let app = test_app_with_scheduler(state);
|
||||
|
||||
let run_id_str = create_and_start_run(&app, MINIMAL_DOT).await;
|
||||
let run_id = run_id_str.parse::<RunId>().unwrap();
|
||||
|
||||
// Wait for scheduler to promote run (creates event_tx)
|
||||
// Wait for scheduler to promote run.
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
|
||||
// Request the SSE stream
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!("/runs/{run_id}/events")))
|
||||
.uri(api(&format!("/runs/{run_id}/attach")))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
// May be 200 (stream open) or 410 (run completed before we connect)
|
||||
let status = response.status();
|
||||
assert!(
|
||||
status == StatusCode::OK || status == StatusCode::GONE,
|
||||
|
|
@ -2714,7 +3259,7 @@ mod tests {
|
|||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!("/runs/{run_id}/events")))
|
||||
.uri(api(&format!("/runs/{run_id}/attach")))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
|
|
|
|||
|
|
@ -757,7 +757,7 @@ mod sse_events {
|
|||
// Get SSE stream
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api(&format!("/runs/{run_id}/events")))
|
||||
.uri(api(&format!("/runs/{run_id}/attach")))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let response = app.clone().oneshot(req).await.unwrap();
|
||||
|
|
@ -796,7 +796,7 @@ mod sse_events {
|
|||
if let Some(json_str) = line.strip_prefix("data:") {
|
||||
let json_str = json_str.trim();
|
||||
if let Ok(event) = serde_json::from_str::<serde_json::Value>(json_str) {
|
||||
if let Some(event_name) = event["event"].as_str() {
|
||||
if let Some(event_name) = event["payload"]["event"].as_str() {
|
||||
event_types.push(event_name.to_string());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use fabro_types::{
|
|||
SandboxRecord, StageStatus, StageUsage, StartRecord, StatusReason, TokenUsage,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone, Default, serde::Serialize)]
|
||||
pub struct RunProjection {
|
||||
pub run: Option<RunRecord>,
|
||||
pub graph_source: Option<String>,
|
||||
|
|
@ -34,7 +34,7 @@ pub struct RunProjection {
|
|||
nodes: HashMap<StageId, NodeState>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone, Default, serde::Serialize)]
|
||||
pub struct NodeState {
|
||||
pub prompt: Option<String>,
|
||||
pub response: Option<String>,
|
||||
|
|
|
|||
|
|
@ -1231,6 +1231,57 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn slate_run_store_lists_events_with_limit() {
|
||||
let (_object_store, store) = make_store();
|
||||
let run = store.create_run(&test_run_id("run-1")).await.unwrap();
|
||||
|
||||
for (idx, ts) in [
|
||||
"2026-03-27T12:00:00Z",
|
||||
"2026-03-27T12:00:01Z",
|
||||
"2026-03-27T12:00:02Z",
|
||||
]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
run.append_event(&event_payload(
|
||||
"run-1",
|
||||
ts,
|
||||
"run.submitted",
|
||||
None,
|
||||
serde_json::json!({"index": idx}),
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let events = run.list_events_from_with_limit(2, 1).await.unwrap();
|
||||
assert_eq!(events.iter().map(|event| event.seq).collect::<Vec<_>>(), vec![2, 3]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn slate_run_store_lists_artifacts_for_stage_only() {
|
||||
let (_object_store, store) = make_store();
|
||||
let run = store.create_run(&test_run_id("run-1")).await.unwrap();
|
||||
let code_stage = StageId::new("code", 2);
|
||||
let build_stage = StageId::new("build", 1);
|
||||
|
||||
run.put_artifact(&code_stage, "src/lib.rs", b"fn main() {}")
|
||||
.await
|
||||
.unwrap();
|
||||
run.put_artifact(&code_stage, "src/main.rs", b"fn main() {}")
|
||||
.await
|
||||
.unwrap();
|
||||
run.put_artifact(&build_stage, "target/output.txt", b"ok")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
run.list_artifacts_for_stage(&code_stage).await.unwrap(),
|
||||
vec!["src/lib.rs".to_string(), "src/main.rs".to_string()]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_run_state_and_node_storage_round_trip() {
|
||||
let (_object_store, store) = make_store();
|
||||
|
|
|
|||
|
|
@ -175,6 +175,17 @@ impl SlateRunStore {
|
|||
self.inner.db.list_events_from(1).await
|
||||
}
|
||||
|
||||
pub async fn list_events_from_with_limit(
|
||||
&self,
|
||||
start_seq: u32,
|
||||
limit: usize,
|
||||
) -> Result<Vec<EventEnvelope>> {
|
||||
self.inner
|
||||
.db
|
||||
.list_events_from_with_limit(start_seq, limit)
|
||||
.await
|
||||
}
|
||||
|
||||
pub fn watch_events_from(
|
||||
&self,
|
||||
seq: u32,
|
||||
|
|
@ -245,6 +256,10 @@ impl SlateRunStore {
|
|||
self.inner.db.list_all_artifacts().await
|
||||
}
|
||||
|
||||
pub async fn list_artifacts_for_stage(&self, stage_id: &StageId) -> Result<Vec<String>> {
|
||||
self.inner.db.list_artifacts_for_stage(stage_id).await
|
||||
}
|
||||
|
||||
pub async fn state(&self) -> Result<RunProjection> {
|
||||
self.projected_state().await
|
||||
}
|
||||
|
|
@ -287,6 +302,17 @@ impl SlateRunDb {
|
|||
}
|
||||
}
|
||||
|
||||
async fn list_events_from_with_limit(
|
||||
&self,
|
||||
start_seq: u32,
|
||||
limit: usize,
|
||||
) -> Result<Vec<EventEnvelope>> {
|
||||
match self {
|
||||
Self::Writer(db) => list_events_from_with_limit(db, start_seq, limit).await,
|
||||
Self::Reader(db) => list_events_from_with_limit(db.as_ref(), start_seq, limit).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_blobs(&self) -> Result<Vec<RunBlobId>> {
|
||||
match self {
|
||||
Self::Writer(db) => list_blobs(db).await,
|
||||
|
|
@ -300,6 +326,13 @@ impl SlateRunDb {
|
|||
Self::Reader(db) => list_all_artifacts(db.as_ref()).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_artifacts_for_stage(&self, stage_id: &StageId) -> Result<Vec<String>> {
|
||||
match self {
|
||||
Self::Writer(db) => list_artifacts_for_stage(db, stage_id).await,
|
||||
Self::Reader(db) => list_artifacts_for_stage(db.as_ref(), stage_id).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn put_json<T: Serialize>(db: &slatedb::Db, key: &str, value: &T) -> Result<()> {
|
||||
|
|
@ -366,6 +399,19 @@ where
|
|||
Ok(events)
|
||||
}
|
||||
|
||||
async fn list_events_from_with_limit<R>(
|
||||
db: &R,
|
||||
start_seq: u32,
|
||||
limit: usize,
|
||||
) -> Result<Vec<EventEnvelope>>
|
||||
where
|
||||
R: DbRead + Sync,
|
||||
{
|
||||
let mut events = list_events_from(db, start_seq).await?;
|
||||
events.truncate(limit.saturating_add(1));
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
async fn list_blobs<R>(db: &R) -> Result<Vec<RunBlobId>>
|
||||
where
|
||||
R: DbRead + Sync,
|
||||
|
|
@ -402,6 +448,26 @@ where
|
|||
Ok(assets)
|
||||
}
|
||||
|
||||
async fn list_artifacts_for_stage<R>(db: &R, stage_id: &StageId) -> Result<Vec<String>>
|
||||
where
|
||||
R: DbRead + Sync,
|
||||
{
|
||||
let prefix = keys::node_artifact_prefix(stage_id);
|
||||
let mut iter = db.scan_prefix(prefix.as_bytes()).await?;
|
||||
let mut filenames = Vec::new();
|
||||
while let Some(entry) = iter.next().await? {
|
||||
let key = key_to_string(&entry.key)?;
|
||||
let Some((node, filename)) = keys::parse_node_artifact_key(&key) else {
|
||||
continue;
|
||||
};
|
||||
if &node == stage_id {
|
||||
filenames.push(filename);
|
||||
}
|
||||
}
|
||||
filenames.sort();
|
||||
Ok(filenames)
|
||||
}
|
||||
|
||||
fn key_to_string(key: &Bytes) -> Result<String> {
|
||||
String::from_utf8(key.to_vec())
|
||||
.map_err(|err| StoreError::Other(format!("stored key is not valid UTF-8: {err}")))
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ models/aggregate-usage.ts
|
|||
models/api-question-option.ts
|
||||
models/api-question.ts
|
||||
models/api-settings.ts
|
||||
models/append-event-response.ts
|
||||
models/artifact-entry.ts
|
||||
models/artifact-list-response.ts
|
||||
models/artifacts-settings.ts
|
||||
models/assistant-stage-turn.ts
|
||||
models/assistant-turn.ts
|
||||
|
|
@ -55,6 +58,7 @@ models/diff-file.ts
|
|||
models/diff-stats.ts
|
||||
models/error-response-entry.ts
|
||||
models/error-response.ts
|
||||
models/event-envelope.ts
|
||||
models/execute-query-request.ts
|
||||
models/execute-query-response-rows-inner-inner.ts
|
||||
models/execute-query-response.ts
|
||||
|
|
@ -70,6 +74,8 @@ models/health-response.ts
|
|||
models/history-entry.ts
|
||||
models/hook-definition.ts
|
||||
models/index.ts
|
||||
models/internal-run-status.ts
|
||||
models/internal-stage-status.ts
|
||||
models/learning-category.ts
|
||||
models/learning.ts
|
||||
models/llm-settings.ts
|
||||
|
|
@ -82,9 +88,12 @@ models/model-limits.ts
|
|||
models/model-reference.ts
|
||||
models/model-test-result.ts
|
||||
models/model.ts
|
||||
models/node-state.ts
|
||||
models/node-status-record.ts
|
||||
models/open-item-kind.ts
|
||||
models/open-item.ts
|
||||
models/paginated-api-question-list.ts
|
||||
models/paginated-event-list.ts
|
||||
models/paginated-history-entry-list.ts
|
||||
models/paginated-model-list.ts
|
||||
models/paginated-retro-list.ts
|
||||
|
|
@ -113,13 +122,17 @@ models/root-response-urls.ts
|
|||
models/root-response.ts
|
||||
models/run-checkpoint.ts
|
||||
models/run-error.ts
|
||||
models/run-event.ts
|
||||
models/run-list-item.ts
|
||||
models/run-projection-checkpoints-inner-inner.ts
|
||||
models/run-projection.ts
|
||||
models/run-pull-request.ts
|
||||
models/run-question.ts
|
||||
models/run-reference.ts
|
||||
models/run-sandbox.ts
|
||||
models/run-settings.ts
|
||||
models/run-stage.ts
|
||||
models/run-status-record.ts
|
||||
models/run-status-response.ts
|
||||
models/run-status.ts
|
||||
models/run-timings.ts
|
||||
|
|
@ -144,6 +157,7 @@ models/smoothness-rating.ts
|
|||
models/stage-retro.ts
|
||||
models/stage-status.ts
|
||||
models/stage-turn.ts
|
||||
models/status-reason.ts
|
||||
models/steer-request.ts
|
||||
models/submit-answer-request.ts
|
||||
models/system-stage-turn.ts
|
||||
|
|
@ -173,3 +187,4 @@ models/workflow-last-run.ts
|
|||
models/workflow-list-item.ts
|
||||
models/workflow-reference.ts
|
||||
models/workflow-schedule.ts
|
||||
models/write-blob-response.ts
|
||||
|
|
|
|||
|
|
@ -22,20 +22,268 @@ import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObj
|
|||
// @ts-ignore
|
||||
import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';
|
||||
// @ts-ignore
|
||||
import type { AppendEventResponse } from '../models';
|
||||
// @ts-ignore
|
||||
import type { ArtifactListResponse } from '../models';
|
||||
// @ts-ignore
|
||||
import type { ErrorResponse } from '../models';
|
||||
// @ts-ignore
|
||||
import type { PaginatedEventList } from '../models';
|
||||
// @ts-ignore
|
||||
import type { PaginatedRunStageList } from '../models';
|
||||
// @ts-ignore
|
||||
import type { PaginatedStageTurnList } from '../models';
|
||||
// @ts-ignore
|
||||
import type { RunCheckpoint } from '../models';
|
||||
// @ts-ignore
|
||||
import type { RunEvent } from '../models';
|
||||
// @ts-ignore
|
||||
import type { RunProjection } from '../models';
|
||||
// @ts-ignore
|
||||
import type { RunSettings } from '../models';
|
||||
// @ts-ignore
|
||||
import type { WriteBlobResponse } from '../models';
|
||||
/**
|
||||
* RunInternalsApi - axios parameter creator
|
||||
*/
|
||||
export const RunInternalsApiAxiosParamCreator = function (configuration?: Configuration) {
|
||||
return {
|
||||
/**
|
||||
* Appends a validated event to the run event log. Intended for trusted internal callers.
|
||||
* @summary Append Run Event
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {RunEvent} runEvent
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
appendRunEvent: async (id: string, runEvent: RunEvent, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('appendRunEvent', 'id', id)
|
||||
// verify required parameter 'runEvent' is not null or undefined
|
||||
assertParamExists('appendRunEvent', 'runEvent', runEvent)
|
||||
const localVarPath = `/api/v1/runs/{id}/events`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// 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: 'POST', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||
localVarHeaderParameter['Accept'] = 'application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
localVarRequestOptions.data = serializeDataIfNeeded(runEvent, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Opens a server-sent event stream for a live run. Optionally replays stored events from `since_seq` before switching to live updates.
|
||||
* @summary Attach Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
attachRunEvents: async (id: string, sinceSeq?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('attachRunEvents', 'id', id)
|
||||
const localVarPath = `/api/v1/runs/{id}/attach`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// 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;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
if (sinceSeq !== undefined) {
|
||||
localVarQueryParameter['since_seq'] = sinceSeq;
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Accept'] = 'text/event-stream,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 internal event-sourced run projection. This is not a stable public contract.
|
||||
* @summary Get Run State
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getRunState: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('getRunState', 'id', id)
|
||||
const localVarPath = `/api/v1/runs/{id}/state`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// 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;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
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,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Downloads an artifact by filename.
|
||||
* @summary Get Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getStageArtifact: async (id: string, stageId: string, filename: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('getStageArtifact', 'id', id)
|
||||
// verify required parameter 'stageId' is not null or undefined
|
||||
assertParamExists('getStageArtifact', 'stageId', stageId)
|
||||
// verify required parameter 'filename' is not null or undefined
|
||||
assertParamExists('getStageArtifact', 'filename', filename)
|
||||
const localVarPath = `/api/v1/runs/{id}/stages/{stageId}/artifacts/download`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)))
|
||||
.replace(`{${"stageId"}}`, encodeURIComponent(String(stageId)));
|
||||
// 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;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
if (filename !== undefined) {
|
||||
localVarQueryParameter['filename'] = filename;
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Accept'] = 'application/octet-stream,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 a paginated JSON list of stored run events.
|
||||
* @summary List Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {number} [limit] Maximum number of events to return.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
listRunEvents: async (id: string, sinceSeq?: number, limit?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('listRunEvents', 'id', id)
|
||||
const localVarPath = `/api/v1/runs/{id}/events`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// 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;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
if (sinceSeq !== undefined) {
|
||||
localVarQueryParameter['since_seq'] = sinceSeq;
|
||||
}
|
||||
|
||||
if (limit !== undefined) {
|
||||
localVarQueryParameter['limit'] = limit;
|
||||
}
|
||||
|
||||
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 ordered list of stages in a run\'s workflow graph with their current status and timing. Stages are bounded by the workflow graph size, typically fewer than 20.
|
||||
* @summary List Run Stages
|
||||
|
|
@ -87,11 +335,56 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Lists artifact filenames stored for a stage.
|
||||
* @summary List Stage Artifacts
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
listStageArtifacts: async (id: string, stageId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('listStageArtifacts', 'id', id)
|
||||
// verify required parameter 'stageId' is not null or undefined
|
||||
assertParamExists('listStageArtifacts', 'stageId', stageId)
|
||||
const localVarPath = `/api/v1/runs/{id}/stages/{stageId}/artifacts`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)))
|
||||
.replace(`{${"stageId"}}`, encodeURIComponent(String(stageId)));
|
||||
// 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;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
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 a paginated list of conversation turns within a specific stage, including system prompts, assistant responses, and tool invocations.
|
||||
* @summary List Stage Turns
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph.
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -142,6 +435,108 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Uploads an artifact for a stage. Intended for trusted internal callers.
|
||||
* @summary Put Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
putStageArtifact: async (id: string, stageId: string, filename: string, body: File, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('putStageArtifact', 'id', id)
|
||||
// verify required parameter 'stageId' is not null or undefined
|
||||
assertParamExists('putStageArtifact', 'stageId', stageId)
|
||||
// verify required parameter 'filename' is not null or undefined
|
||||
assertParamExists('putStageArtifact', 'filename', filename)
|
||||
// verify required parameter 'body' is not null or undefined
|
||||
assertParamExists('putStageArtifact', 'body', body)
|
||||
const localVarPath = `/api/v1/runs/{id}/stages/{stageId}/artifacts`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)))
|
||||
.replace(`{${"stageId"}}`, encodeURIComponent(String(stageId)));
|
||||
// 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: 'POST', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
if (filename !== undefined) {
|
||||
localVarQueryParameter['filename'] = filename;
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/octet-stream';
|
||||
localVarHeaderParameter['Accept'] = 'application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
localVarRequestOptions.data = serializeDataIfNeeded(body, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Reads a previously stored blob by identifier.
|
||||
* @summary Read Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} blobId Content-addressed blob identifier.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
readRunBlob: async (id: string, blobId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('readRunBlob', 'id', id)
|
||||
// verify required parameter 'blobId' is not null or undefined
|
||||
assertParamExists('readRunBlob', 'blobId', blobId)
|
||||
const localVarPath = `/api/v1/runs/{id}/blobs/{blobId}`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)))
|
||||
.replace(`{${"blobId"}}`, encodeURIComponent(String(blobId)));
|
||||
// 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;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
localVarHeaderParameter['Accept'] = 'application/octet-stream,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 latest checkpoint data for a run, or null if no checkpoint has been recorded yet.
|
||||
* @summary Retrieve Run Checkpoint
|
||||
|
|
@ -219,6 +614,52 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Writes an opaque binary blob and returns its content-addressed blob identifier.
|
||||
* @summary Write Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
writeRunBlob: async (id: string, body: File, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('writeRunBlob', 'id', id)
|
||||
// verify required parameter 'body' is not null or undefined
|
||||
assertParamExists('writeRunBlob', 'body', body)
|
||||
const localVarPath = `/api/v1/runs/{id}/blobs`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// 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: 'POST', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/octet-stream';
|
||||
localVarHeaderParameter['Accept'] = 'application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
localVarRequestOptions.data = serializeDataIfNeeded(body, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
|
|
@ -233,6 +674,77 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
export const RunInternalsApiFp = function(configuration?: Configuration) {
|
||||
const localVarAxiosParamCreator = RunInternalsApiAxiosParamCreator(configuration)
|
||||
return {
|
||||
/**
|
||||
* Appends a validated event to the run event log. Intended for trusted internal callers.
|
||||
* @summary Append Run Event
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {RunEvent} runEvent
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async appendRunEvent(id: string, runEvent: RunEvent, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AppendEventResponse>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.appendRunEvent(id, runEvent, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.appendRunEvent']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Opens a server-sent event stream for a live run. Optionally replays stored events from `since_seq` before switching to live updates.
|
||||
* @summary Attach Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async attachRunEvents(id: string, sinceSeq?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<string>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.attachRunEvents(id, sinceSeq, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.attachRunEvents']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Returns the internal event-sourced run projection. This is not a stable public contract.
|
||||
* @summary Get Run State
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getRunState(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RunProjection>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getRunState(id, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.getRunState']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Downloads an artifact by filename.
|
||||
* @summary Get Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getStageArtifact(id: string, stageId: string, filename: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getStageArtifact(id, stageId, filename, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.getStageArtifact']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Returns a paginated JSON list of stored run events.
|
||||
* @summary List Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {number} [limit] Maximum number of events to return.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async listRunEvents(id: string, sinceSeq?: number, limit?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedEventList>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.listRunEvents(id, sinceSeq, limit, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.listRunEvents']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Returns the ordered list of stages in a run\'s workflow graph with their current status and timing. Stages are bounded by the workflow graph size, typically fewer than 20.
|
||||
* @summary List Run Stages
|
||||
|
|
@ -248,11 +760,25 @@ export const RunInternalsApiFp = function(configuration?: Configuration) {
|
|||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.listRunStages']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Lists artifact filenames stored for a stage.
|
||||
* @summary List Stage Artifacts
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async listStageArtifacts(id: string, stageId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ArtifactListResponse>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.listStageArtifacts(id, stageId, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.listStageArtifacts']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Returns a paginated list of conversation turns within a specific stage, including system prompts, assistant responses, and tool invocations.
|
||||
* @summary List Stage Turns
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph.
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -264,6 +790,36 @@ export const RunInternalsApiFp = function(configuration?: Configuration) {
|
|||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.listStageTurns']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Uploads an artifact for a stage. Intended for trusted internal callers.
|
||||
* @summary Put Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async putStageArtifact(id: string, stageId: string, filename: string, body: File, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.putStageArtifact(id, stageId, filename, body, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.putStageArtifact']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Reads a previously stored blob by identifier.
|
||||
* @summary Read Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} blobId Content-addressed blob identifier.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async readRunBlob(id: string, blobId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.readRunBlob(id, blobId, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.readRunBlob']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Returns the latest checkpoint data for a run, or null if no checkpoint has been recorded yet.
|
||||
* @summary Retrieve Run Checkpoint
|
||||
|
|
@ -290,6 +846,20 @@ export const RunInternalsApiFp = function(configuration?: Configuration) {
|
|||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.retrieveRunSettings']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Writes an opaque binary blob and returns its content-addressed blob identifier.
|
||||
* @summary Write Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async writeRunBlob(id: string, body: File, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<WriteBlobResponse>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.writeRunBlob(id, body, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.writeRunBlob']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -299,6 +869,62 @@ export const RunInternalsApiFp = function(configuration?: Configuration) {
|
|||
export const RunInternalsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
|
||||
const localVarFp = RunInternalsApiFp(configuration)
|
||||
return {
|
||||
/**
|
||||
* Appends a validated event to the run event log. Intended for trusted internal callers.
|
||||
* @summary Append Run Event
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {RunEvent} runEvent
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
appendRunEvent(id: string, runEvent: RunEvent, options?: RawAxiosRequestConfig): AxiosPromise<AppendEventResponse> {
|
||||
return localVarFp.appendRunEvent(id, runEvent, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Opens a server-sent event stream for a live run. Optionally replays stored events from `since_seq` before switching to live updates.
|
||||
* @summary Attach Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
attachRunEvents(id: string, sinceSeq?: number, options?: RawAxiosRequestConfig): AxiosPromise<string> {
|
||||
return localVarFp.attachRunEvents(id, sinceSeq, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Returns the internal event-sourced run projection. This is not a stable public contract.
|
||||
* @summary Get Run State
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getRunState(id: string, options?: RawAxiosRequestConfig): AxiosPromise<RunProjection> {
|
||||
return localVarFp.getRunState(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Downloads an artifact by filename.
|
||||
* @summary Get Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getStageArtifact(id: string, stageId: string, filename: string, options?: RawAxiosRequestConfig): AxiosPromise<File> {
|
||||
return localVarFp.getStageArtifact(id, stageId, filename, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Returns a paginated JSON list of stored run events.
|
||||
* @summary List Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {number} [limit] Maximum number of events to return.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
listRunEvents(id: string, sinceSeq?: number, limit?: number, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedEventList> {
|
||||
return localVarFp.listRunEvents(id, sinceSeq, limit, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Returns the ordered list of stages in a run\'s workflow graph with their current status and timing. Stages are bounded by the workflow graph size, typically fewer than 20.
|
||||
* @summary List Run Stages
|
||||
|
|
@ -311,11 +937,22 @@ export const RunInternalsApiFactory = function (configuration?: Configuration, b
|
|||
listRunStages(id: string, pageLimit?: number, pageOffset?: number, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedRunStageList> {
|
||||
return localVarFp.listRunStages(id, pageLimit, pageOffset, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Lists artifact filenames stored for a stage.
|
||||
* @summary List Stage Artifacts
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
listStageArtifacts(id: string, stageId: string, options?: RawAxiosRequestConfig): AxiosPromise<ArtifactListResponse> {
|
||||
return localVarFp.listStageArtifacts(id, stageId, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Returns a paginated list of conversation turns within a specific stage, including system prompts, assistant responses, and tool invocations.
|
||||
* @summary List Stage Turns
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph.
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -324,6 +961,30 @@ export const RunInternalsApiFactory = function (configuration?: Configuration, b
|
|||
listStageTurns(id: string, stageId: string, pageLimit?: number, pageOffset?: number, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedStageTurnList> {
|
||||
return localVarFp.listStageTurns(id, stageId, pageLimit, pageOffset, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Uploads an artifact for a stage. Intended for trusted internal callers.
|
||||
* @summary Put Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
putStageArtifact(id: string, stageId: string, filename: string, body: File, options?: RawAxiosRequestConfig): AxiosPromise<void> {
|
||||
return localVarFp.putStageArtifact(id, stageId, filename, body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Reads a previously stored blob by identifier.
|
||||
* @summary Read Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} blobId Content-addressed blob identifier.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
readRunBlob(id: string, blobId: string, options?: RawAxiosRequestConfig): AxiosPromise<File> {
|
||||
return localVarFp.readRunBlob(id, blobId, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Returns the latest checkpoint data for a run, or null if no checkpoint has been recorded yet.
|
||||
* @summary Retrieve Run Checkpoint
|
||||
|
|
@ -344,6 +1005,17 @@ export const RunInternalsApiFactory = function (configuration?: Configuration, b
|
|||
retrieveRunSettings(id: string, options?: RawAxiosRequestConfig): AxiosPromise<RunSettings> {
|
||||
return localVarFp.retrieveRunSettings(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Writes an opaque binary blob and returns its content-addressed blob identifier.
|
||||
* @summary Write Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
writeRunBlob(id: string, body: File, options?: RawAxiosRequestConfig): AxiosPromise<WriteBlobResponse> {
|
||||
return localVarFp.writeRunBlob(id, body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -351,6 +1023,67 @@ export const RunInternalsApiFactory = function (configuration?: Configuration, b
|
|||
* RunInternalsApi - object-oriented interface
|
||||
*/
|
||||
export class RunInternalsApi extends BaseAPI {
|
||||
/**
|
||||
* Appends a validated event to the run event log. Intended for trusted internal callers.
|
||||
* @summary Append Run Event
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {RunEvent} runEvent
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public appendRunEvent(id: string, runEvent: RunEvent, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).appendRunEvent(id, runEvent, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a server-sent event stream for a live run. Optionally replays stored events from `since_seq` before switching to live updates.
|
||||
* @summary Attach Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public attachRunEvents(id: string, sinceSeq?: number, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).attachRunEvents(id, sinceSeq, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal event-sourced run projection. This is not a stable public contract.
|
||||
* @summary Get Run State
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public getRunState(id: string, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).getRunState(id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads an artifact by filename.
|
||||
* @summary Get Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public getStageArtifact(id: string, stageId: string, filename: string, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).getStageArtifact(id, stageId, filename, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a paginated JSON list of stored run events.
|
||||
* @summary List Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {number} [sinceSeq] First event sequence number to include.
|
||||
* @param {number} [limit] Maximum number of events to return.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public listRunEvents(id: string, sinceSeq?: number, limit?: number, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).listRunEvents(id, sinceSeq, limit, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ordered list of stages in a run\'s workflow graph with their current status and timing. Stages are bounded by the workflow graph size, typically fewer than 20.
|
||||
* @summary List Run Stages
|
||||
|
|
@ -364,11 +1097,23 @@ export class RunInternalsApi extends BaseAPI {
|
|||
return RunInternalsApiFp(this.configuration).listRunStages(id, pageLimit, pageOffset, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists artifact filenames stored for a stage.
|
||||
* @summary List Stage Artifacts
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public listStageArtifacts(id: string, stageId: string, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).listStageArtifacts(id, stageId, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a paginated list of conversation turns within a specific stage, including system prompts, assistant responses, and tool invocations.
|
||||
* @summary List Stage Turns
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph.
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -378,6 +1123,32 @@ export class RunInternalsApi extends BaseAPI {
|
|||
return RunInternalsApiFp(this.configuration).listStageTurns(id, stageId, pageLimit, pageOffset, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads an artifact for a stage. Intended for trusted internal callers.
|
||||
* @summary Put Stage Artifact
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} stageId Identifier of a stage within a run\'s workflow graph, serialized as `node_id@visit`.
|
||||
* @param {string} filename Artifact filename. May contain path separators.
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public putStageArtifact(id: string, stageId: string, filename: string, body: File, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).putStageArtifact(id, stageId, filename, body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a previously stored blob by identifier.
|
||||
* @summary Read Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {string} blobId Content-addressed blob identifier.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public readRunBlob(id: string, blobId: string, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).readRunBlob(id, blobId, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latest checkpoint data for a run, or null if no checkpoint has been recorded yet.
|
||||
* @summary Retrieve Run Checkpoint
|
||||
|
|
@ -399,5 +1170,17 @@ export class RunInternalsApi extends BaseAPI {
|
|||
public retrieveRunSettings(id: string, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).retrieveRunSettings(id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an opaque binary blob and returns its content-addressed blob identifier.
|
||||
* @summary Write Run Blob
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {File} body
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public writeRunBlob(id: string, body: File, options?: RawAxiosRequestConfig) {
|
||||
return RunInternalsApiFp(this.configuration).writeRunBlob(id, body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -328,47 +328,6 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Opens a server-sent event (SSE) stream for real-time run updates. Returns 410 if the stream has been closed.
|
||||
* @summary Stream Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
streamRunEvents: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('streamRunEvents', 'id', id)
|
||||
const localVarPath = `/api/v1/runs/{id}/events`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// 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;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
localVarHeaderParameter['Accept'] = 'text/event-stream,application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Resumes a paused run. Returns 409 if the run is not paused.
|
||||
* @summary Unpause Run
|
||||
|
|
@ -511,19 +470,6 @@ export const RunsApiFp = function(configuration?: Configuration) {
|
|||
const localVarOperationServerBasePath = operationServerMap['RunsApi.startRun']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Opens a server-sent event (SSE) stream for real-time run updates. Returns 410 if the stream has been closed.
|
||||
* @summary Stream Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async streamRunEvents(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<string>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.streamRunEvents(id, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunsApi.streamRunEvents']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Resumes a paused run. Returns 409 if the run is not paused.
|
||||
* @summary Unpause Run
|
||||
|
|
@ -617,16 +563,6 @@ export const RunsApiFactory = function (configuration?: Configuration, basePath?
|
|||
startRun(id: string, options?: RawAxiosRequestConfig): AxiosPromise<RunStatusResponse> {
|
||||
return localVarFp.startRun(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Opens a server-sent event (SSE) stream for real-time run updates. Returns 410 if the stream has been closed.
|
||||
* @summary Stream Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
streamRunEvents(id: string, options?: RawAxiosRequestConfig): AxiosPromise<string> {
|
||||
return localVarFp.streamRunEvents(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Resumes a paused run. Returns 409 if the run is not paused.
|
||||
* @summary Unpause Run
|
||||
|
|
@ -722,17 +658,6 @@ export class RunsApi extends BaseAPI {
|
|||
return RunsApiFp(this.configuration).startRun(id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a server-sent event (SSE) stream for real-time run updates. Returns 410 if the stream has been closed.
|
||||
* @summary Stream Run Events
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public streamRunEvents(id: string, options?: RawAxiosRequestConfig) {
|
||||
return RunsApiFp(this.configuration).streamRunEvents(id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes a paused run. Returns 409 if the run is not paused.
|
||||
* @summary Unpause Run
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assigned sequence number for an appended event.
|
||||
*/
|
||||
export interface AppendEventResponse {
|
||||
/**
|
||||
* Assigned event sequence number.
|
||||
*/
|
||||
'seq': number;
|
||||
}
|
||||
|
||||
26
lib/packages/fabro-api-client/src/models/artifact-entry.ts
Normal file
26
lib/packages/fabro-api-client/src/models/artifact-entry.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A single artifact filename.
|
||||
*/
|
||||
export interface ArtifactEntry {
|
||||
/**
|
||||
* Artifact filename.
|
||||
*/
|
||||
'filename': string;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { ArtifactEntry } from './artifact-entry';
|
||||
|
||||
/**
|
||||
* List of artifact filenames for a stage.
|
||||
*/
|
||||
export interface ArtifactListResponse {
|
||||
'data': Array<ArtifactEntry>;
|
||||
}
|
||||
|
||||
30
lib/packages/fabro-api-client/src/models/event-envelope.ts
Normal file
30
lib/packages/fabro-api-client/src/models/event-envelope.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { RunEvent } from './run-event';
|
||||
|
||||
/**
|
||||
* Stored event envelope with assigned sequence number.
|
||||
*/
|
||||
export interface EventEnvelope {
|
||||
/**
|
||||
* Assigned event sequence number.
|
||||
*/
|
||||
'seq': number;
|
||||
'payload': RunEvent;
|
||||
}
|
||||
|
||||
|
|
@ -3,6 +3,9 @@ export * from './aggregate-usage-totals';
|
|||
export * from './api-question';
|
||||
export * from './api-question-option';
|
||||
export * from './api-settings';
|
||||
export * from './append-event-response';
|
||||
export * from './artifact-entry';
|
||||
export * from './artifact-list-response';
|
||||
export * from './artifacts-settings';
|
||||
export * from './assistant-stage-turn';
|
||||
export * from './assistant-turn';
|
||||
|
|
@ -36,6 +39,7 @@ export * from './diff-file';
|
|||
export * from './diff-stats';
|
||||
export * from './error-response';
|
||||
export * from './error-response-entry';
|
||||
export * from './event-envelope';
|
||||
export * from './execute-query-request';
|
||||
export * from './execute-query-response';
|
||||
export * from './execute-query-response-rows-inner-inner';
|
||||
|
|
@ -50,6 +54,8 @@ export * from './git-settings';
|
|||
export * from './health-response';
|
||||
export * from './history-entry';
|
||||
export * from './hook-definition';
|
||||
export * from './internal-run-status';
|
||||
export * from './internal-stage-status';
|
||||
export * from './learning';
|
||||
export * from './learning-category';
|
||||
export * from './llm-settings';
|
||||
|
|
@ -62,9 +68,12 @@ export * from './model-features';
|
|||
export * from './model-limits';
|
||||
export * from './model-reference';
|
||||
export * from './model-test-result';
|
||||
export * from './node-state';
|
||||
export * from './node-status-record';
|
||||
export * from './open-item';
|
||||
export * from './open-item-kind';
|
||||
export * from './paginated-api-question-list';
|
||||
export * from './paginated-event-list';
|
||||
export * from './paginated-history-entry-list';
|
||||
export * from './paginated-model-list';
|
||||
export * from './paginated-retro-list';
|
||||
|
|
@ -93,7 +102,10 @@ export * from './root-response';
|
|||
export * from './root-response-urls';
|
||||
export * from './run-checkpoint';
|
||||
export * from './run-error';
|
||||
export * from './run-event';
|
||||
export * from './run-list-item';
|
||||
export * from './run-projection';
|
||||
export * from './run-projection-checkpoints-inner-inner';
|
||||
export * from './run-pull-request';
|
||||
export * from './run-question';
|
||||
export * from './run-reference';
|
||||
|
|
@ -101,6 +113,7 @@ export * from './run-sandbox';
|
|||
export * from './run-settings';
|
||||
export * from './run-stage';
|
||||
export * from './run-status';
|
||||
export * from './run-status-record';
|
||||
export * from './run-status-response';
|
||||
export * from './run-timings';
|
||||
export * from './run-usage';
|
||||
|
|
@ -124,6 +137,7 @@ export * from './smoothness-rating';
|
|||
export * from './stage-retro';
|
||||
export * from './stage-status';
|
||||
export * from './stage-turn';
|
||||
export * from './status-reason';
|
||||
export * from './steer-request';
|
||||
export * from './submit-answer-request';
|
||||
export * from './system-stage-turn';
|
||||
|
|
@ -153,3 +167,4 @@ export * from './workflow-last-run';
|
|||
export * from './workflow-list-item';
|
||||
export * from './workflow-reference';
|
||||
export * from './workflow-schedule';
|
||||
export * from './write-blob-response';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal event-sourced run status.
|
||||
*/
|
||||
|
||||
export const InternalRunStatus = {
|
||||
SUBMITTED: 'submitted',
|
||||
STARTING: 'starting',
|
||||
RUNNING: 'running',
|
||||
PAUSED: 'paused',
|
||||
REMOVING: 'removing',
|
||||
SUCCEEDED: 'succeeded',
|
||||
FAILED: 'failed',
|
||||
DEAD: 'dead'
|
||||
} as const;
|
||||
|
||||
export type InternalRunStatus = typeof InternalRunStatus[keyof typeof InternalRunStatus];
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal stage status from outcomes and node status records.
|
||||
*/
|
||||
|
||||
export const InternalStageStatus = {
|
||||
SUCCESS: 'success',
|
||||
FAIL: 'fail',
|
||||
SKIPPED: 'skipped',
|
||||
PARTIAL_SUCCESS: 'partial_success',
|
||||
RETRY: 'retry'
|
||||
} as const;
|
||||
|
||||
export type InternalStageStatus = typeof InternalStageStatus[keyof typeof InternalStageStatus];
|
||||
|
||||
|
||||
|
||||
35
lib/packages/fabro-api-client/src/models/node-state.ts
Normal file
35
lib/packages/fabro-api-client/src/models/node-state.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { NodeStatusRecord } from './node-status-record';
|
||||
|
||||
/**
|
||||
* Internal node projection state.
|
||||
*/
|
||||
export interface NodeState {
|
||||
'prompt'?: string;
|
||||
'response'?: string;
|
||||
'status'?: NodeStatusRecord | null;
|
||||
'provider_used'?: any;
|
||||
'diff'?: string;
|
||||
'script_invocation'?: any;
|
||||
'script_timing'?: any;
|
||||
'parallel_results'?: any;
|
||||
'stdout'?: string;
|
||||
'stderr'?: string;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { InternalStageStatus } from './internal-stage-status';
|
||||
|
||||
/**
|
||||
* Internal node status record.
|
||||
*/
|
||||
export interface NodeStatusRecord {
|
||||
'status': InternalStageStatus;
|
||||
'notes'?: string;
|
||||
'failure_reason'?: string;
|
||||
'timestamp': string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { EventEnvelope } from './event-envelope';
|
||||
// May contain unused imports in some cases
|
||||
// @ts-ignore
|
||||
import type { PaginationMeta } from './pagination-meta';
|
||||
|
||||
/**
|
||||
* Paginated list of stored run events.
|
||||
*/
|
||||
export interface PaginatedEventList {
|
||||
'data': Array<EventEnvelope>;
|
||||
'meta': PaginationMeta;
|
||||
}
|
||||
|
||||
36
lib/packages/fabro-api-client/src/models/run-event.ts
Normal file
36
lib/packages/fabro-api-client/src/models/run-event.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal RunEvent-compatible JSON payload. The server validates this body by deserializing into the typed RunEvent struct.
|
||||
*/
|
||||
export interface RunEvent {
|
||||
[key: string]: any;
|
||||
|
||||
'id': string;
|
||||
'ts': string;
|
||||
'run_id': string;
|
||||
'node_id'?: string;
|
||||
'node_label'?: string;
|
||||
'session_id'?: string;
|
||||
'parent_session_id'?: string;
|
||||
/**
|
||||
* Event type discriminator.
|
||||
*/
|
||||
'event': string;
|
||||
'properties'?: { [key: string]: any; };
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { RunCheckpoint } from './run-checkpoint';
|
||||
|
||||
/**
|
||||
* @type RunProjectionCheckpointsInnerInner
|
||||
*/
|
||||
export type RunProjectionCheckpointsInnerInner = RunCheckpoint | number;
|
||||
|
||||
|
||||
54
lib/packages/fabro-api-client/src/models/run-projection.ts
Normal file
54
lib/packages/fabro-api-client/src/models/run-projection.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { NodeState } from './node-state';
|
||||
// May contain unused imports in some cases
|
||||
// @ts-ignore
|
||||
import type { RunCheckpoint } from './run-checkpoint';
|
||||
// May contain unused imports in some cases
|
||||
// @ts-ignore
|
||||
import type { RunProjectionCheckpointsInnerInner } from './run-projection-checkpoints-inner-inner';
|
||||
// May contain unused imports in some cases
|
||||
// @ts-ignore
|
||||
import type { RunStatusRecord } from './run-status-record';
|
||||
|
||||
/**
|
||||
* Raw internal run projection derived from the event log.
|
||||
*/
|
||||
export interface RunProjection {
|
||||
'run'?: { [key: string]: any; };
|
||||
'graph_source'?: string;
|
||||
'start'?: { [key: string]: any; };
|
||||
'status'?: RunStatusRecord | null;
|
||||
'checkpoint'?: RunCheckpoint | null;
|
||||
/**
|
||||
* Sequence-tagged checkpoint history entries as `[seq, checkpoint]`.
|
||||
*/
|
||||
'checkpoints'?: Array<Array<RunProjectionCheckpointsInnerInner>>;
|
||||
'conclusion'?: { [key: string]: any; };
|
||||
'retro'?: { [key: string]: any; };
|
||||
'retro_prompt'?: string;
|
||||
'retro_response'?: string;
|
||||
'sandbox'?: { [key: string]: any; };
|
||||
'final_patch'?: string;
|
||||
'pull_request'?: { [key: string]: any; };
|
||||
/**
|
||||
* Map from StageId (`node_id@visit`) to NodeState.
|
||||
*/
|
||||
'nodes': { [key: string]: NodeState; };
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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 { InternalRunStatus } from './internal-run-status';
|
||||
// May contain unused imports in some cases
|
||||
// @ts-ignore
|
||||
import type { StatusReason } from './status-reason';
|
||||
|
||||
/**
|
||||
* Internal run status record from the event projection.
|
||||
*/
|
||||
export interface RunStatusRecord {
|
||||
'status': InternalRunStatus;
|
||||
'reason'?: StatusReason | null;
|
||||
'updated_at': string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
38
lib/packages/fabro-api-client/src/models/status-reason.ts
Normal file
38
lib/packages/fabro-api-client/src/models/status-reason.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Optional reason attached to a run status transition.
|
||||
*/
|
||||
|
||||
export const StatusReason = {
|
||||
COMPLETED: 'completed',
|
||||
PARTIAL_SUCCESS: 'partial_success',
|
||||
WORKFLOW_ERROR: 'workflow_error',
|
||||
CANCELLED: 'cancelled',
|
||||
TERMINATED: 'terminated',
|
||||
TRANSIENT_INFRA: 'transient_infra',
|
||||
BUDGET_EXHAUSTED: 'budget_exhausted',
|
||||
LAUNCH_FAILED: 'launch_failed',
|
||||
BOOTSTRAP_FAILED: 'bootstrap_failed',
|
||||
SANDBOX_INIT_FAILED: 'sandbox_init_failed',
|
||||
SANDBOX_INITIALIZING: 'sandbox_initializing'
|
||||
} as const;
|
||||
|
||||
export type StatusReason = typeof StatusReason[keyof typeof StatusReason];
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Fabro Run API
|
||||
* HTTP API for managing Fabro 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Content-addressed identifier for a stored blob.
|
||||
*/
|
||||
export interface WriteBlobResponse {
|
||||
/**
|
||||
* Blob identifier.
|
||||
*/
|
||||
'id': string;
|
||||
}
|
||||
|
||||
Loading…
Add table
Reference in a new issue