mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-10 03:30:59 +00:00
feat: show archived runs on the runs page
Extend GET /api/v1/boards/runs with include_archived=true (matching the existing flag on listRuns), add an Archived BoardColumn that the server appends only when the flag is set, and surface a "Show archived" toggle on /runs that flips between request shapes. Default behavior is unchanged — archived runs stay hidden. Server: list_board_runs now takes ListRunsParams; board_column maps RunStatus::Archived to BoardColumn::Archived; board_columns(include_archived) appends the column conditionally. Two new handler tests cover the default and flag-on paths. Web: useBoardsRuns(includeArchived) keys requests so SWR refetches on toggle; columnStatuses + columnStatusDisplay + columnStyles get an "archived" entry; buildSkeletonColumns filters by the flag so the loading state matches the eventual response. Two new buildBoardColumns tests cover both column shapes. Touched generated TS client files include unrelated whitespace drift from openapi-generator-cli; including them keeps the working tree consistent with what `bun run generate` produces. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9b10f7d4fb
commit
c8336a250e
15 changed files with 296 additions and 52 deletions
|
|
@ -48,6 +48,7 @@ export const columnStatuses = [
|
|||
BoardColumn.BLOCKED,
|
||||
BoardColumn.SUCCEEDED,
|
||||
BoardColumn.FAILED,
|
||||
BoardColumn.ARCHIVED,
|
||||
] as const satisfies readonly ColumnStatus[];
|
||||
|
||||
export const columnStatusDisplay: Record<ColumnStatus, { label: string; dot: string; text: string }> = {
|
||||
|
|
@ -57,6 +58,7 @@ export const columnStatusDisplay: Record<ColumnStatus, { label: string; dot: str
|
|||
blocked: { label: "Blocked", dot: "bg-amber", text: "text-amber" },
|
||||
succeeded: { label: "Succeeded", dot: "bg-teal-300", text: "text-teal-300" },
|
||||
failed: { label: "Failed", dot: "bg-coral", text: "text-coral" },
|
||||
archived: { label: "Archived", dot: "bg-fg-muted", text: "text-fg-muted" },
|
||||
};
|
||||
|
||||
export interface RunWithStatus extends RunItem {
|
||||
|
|
|
|||
|
|
@ -63,8 +63,11 @@ export function useSystemInfo() {
|
|||
);
|
||||
}
|
||||
|
||||
export function useBoardsRuns() {
|
||||
return useSWR<BoardRunsEnvelope>(queryKeys.boards.runs(), apiPaginatedFetcher);
|
||||
export function useBoardsRuns(includeArchived: boolean = false) {
|
||||
return useSWR<BoardRunsEnvelope>(
|
||||
queryKeys.boards.runs(includeArchived),
|
||||
apiPaginatedFetcher,
|
||||
);
|
||||
}
|
||||
|
||||
export function useRun(id: string | undefined) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@ export const queryKeys = {
|
|||
attach: () => "/api/v1/attach",
|
||||
},
|
||||
boards: {
|
||||
runs: () => "/api/v1/boards/runs",
|
||||
runs: (includeArchived = false) =>
|
||||
withQuery("/api/v1/boards/runs", {
|
||||
include_archived: includeArchived ? "true" : null,
|
||||
}),
|
||||
},
|
||||
runs: {
|
||||
detail: (id: string) => `/api/v1/runs/${pathSegment(id)}`,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,58 @@ describe("runs route board mapping", () => {
|
|||
expect(columns.find((column) => column.id === "blocked")?.items[0]?.question).toBe("Older unresolved question?");
|
||||
});
|
||||
|
||||
test("renders an archived column when the response includes one", () => {
|
||||
const columns = buildBoardColumns({
|
||||
columns: [
|
||||
{ id: "queued", name: "Queued" },
|
||||
{ id: "initializing", name: "Initializing" },
|
||||
{ id: "running", name: "Running" },
|
||||
{ id: "blocked", name: "Blocked" },
|
||||
{ id: "succeeded", name: "Succeeded" },
|
||||
{ id: "failed", name: "Failed" },
|
||||
{ id: "archived", name: "Archived" },
|
||||
],
|
||||
data: [
|
||||
boardRun("succeeded-run", "succeeded"),
|
||||
boardRun("archived-run", "archived"),
|
||||
],
|
||||
meta: { has_more: false },
|
||||
});
|
||||
|
||||
expect(columns.map((column) => column.id)).toEqual([
|
||||
"queued",
|
||||
"initializing",
|
||||
"running",
|
||||
"blocked",
|
||||
"succeeded",
|
||||
"failed",
|
||||
"archived",
|
||||
]);
|
||||
expect(
|
||||
columns.find((column) => column.id === "archived")?.items.map((item) => item.id),
|
||||
).toEqual(["archived-run"]);
|
||||
expect(
|
||||
columns.find((column) => column.id === "succeeded")?.items.map((item) => item.id),
|
||||
).toEqual(["succeeded-run"]);
|
||||
});
|
||||
|
||||
test("omits the archived column when the response does not include it", () => {
|
||||
const columns = buildBoardColumns({
|
||||
columns: [
|
||||
{ id: "queued", name: "Queued" },
|
||||
{ id: "initializing", name: "Initializing" },
|
||||
{ id: "running", name: "Running" },
|
||||
{ id: "blocked", name: "Blocked" },
|
||||
{ id: "succeeded", name: "Succeeded" },
|
||||
{ id: "failed", name: "Failed" },
|
||||
],
|
||||
data: [boardRun("succeeded-run", "succeeded")],
|
||||
meta: { has_more: false },
|
||||
});
|
||||
|
||||
expect(columns.some((column) => column.id === "archived")).toBe(false);
|
||||
});
|
||||
|
||||
test("refreshes for blocked status and interview events", () => {
|
||||
expect(shouldRefreshBoardForEvent("run.queued")).toBe(true);
|
||||
expect(shouldRefreshBoardForEvent("run.blocked")).toBe(true);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useState, useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { Link } from "react-router";
|
||||
import { ChevronDownIcon, CommandLineIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
import { ArchiveBoxIcon, ChevronDownIcon, CommandLineIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
import { EllipsisVerticalIcon } from "@heroicons/react/20/solid";
|
||||
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
|
||||
import { useSWRConfig } from "swr";
|
||||
|
|
@ -50,6 +50,7 @@ const columnStyles: Record<ColumnStatus, ColumnStyle> = {
|
|||
blocked: { iconType: "branch", actions: ["Answer Question"] },
|
||||
succeeded: { iconType: "pr", actions: [] },
|
||||
failed: { iconType: "branch", actions: [] },
|
||||
archived: { iconType: "branch", actions: [] },
|
||||
};
|
||||
|
||||
const defaultColumnStyle: ColumnStyle = { iconType: "branch", actions: [] };
|
||||
|
|
@ -71,18 +72,20 @@ type Column = {
|
|||
items: RunItem[];
|
||||
};
|
||||
|
||||
function buildSkeletonColumns(): Column[] {
|
||||
return columnStatuses.map((id) => {
|
||||
const colors = columnStatusDisplay[id];
|
||||
return {
|
||||
id,
|
||||
name: colors.label,
|
||||
dot: colors.dot,
|
||||
text: colors.text,
|
||||
...(columnStyles[id] ?? defaultColumnStyle),
|
||||
items: [],
|
||||
};
|
||||
});
|
||||
function buildSkeletonColumns(includeArchived: boolean): Column[] {
|
||||
return columnStatuses
|
||||
.filter((id) => includeArchived || id !== "archived")
|
||||
.map((id) => {
|
||||
const colors = columnStatusDisplay[id];
|
||||
return {
|
||||
id,
|
||||
name: colors.label,
|
||||
dot: colors.dot,
|
||||
text: colors.text,
|
||||
...(columnStyles[id] ?? defaultColumnStyle),
|
||||
items: [],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function buildBoardColumns(response: BoardRunsResponse): Column[] {
|
||||
|
|
@ -750,7 +753,8 @@ function RunsLandingEmpty({
|
|||
}
|
||||
|
||||
export default function Runs() {
|
||||
const boardRuns = useBoardsRuns();
|
||||
const [includeArchived, setIncludeArchived] = useState(false);
|
||||
const boardRuns = useBoardsRuns(includeArchived);
|
||||
const authConfig = useAuthConfig();
|
||||
const systemInfo = useSystemInfo();
|
||||
const isLandingReady =
|
||||
|
|
@ -758,8 +762,11 @@ export default function Runs() {
|
|||
authConfig.data !== undefined &&
|
||||
systemInfo.data !== undefined;
|
||||
const initialColumns = useMemo(
|
||||
() => boardRuns.data ? buildBoardColumns(boardRuns.data) : buildSkeletonColumns(),
|
||||
[boardRuns.data],
|
||||
() =>
|
||||
boardRuns.data
|
||||
? buildBoardColumns(boardRuns.data)
|
||||
: buildSkeletonColumns(includeArchived),
|
||||
[boardRuns.data, includeArchived],
|
||||
);
|
||||
const hasGitHubAuth = authConfig.data?.methods.includes("github") === true;
|
||||
const serverUrl = systemInfo.data?.server_url;
|
||||
|
|
@ -851,6 +858,16 @@ export default function Runs() {
|
|||
</select>
|
||||
<ChevronDownIcon className="pointer-events-none absolute right-2 top-1/2 size-4 -translate-y-1/2 text-fg-muted" />
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIncludeArchived((v) => !v)}
|
||||
aria-pressed={includeArchived}
|
||||
title={includeArchived ? "Hide archived runs" : "Show archived runs"}
|
||||
className={`inline-flex items-center gap-1.5 rounded-md border border-line bg-panel/80 px-3 py-2 text-xs font-medium transition-colors ${includeArchived ? "text-teal-500" : "text-fg-muted hover:text-fg-3"}`}
|
||||
>
|
||||
<ArchiveBoxIcon className="size-4" aria-hidden="true" />
|
||||
<span>Show archived</span>
|
||||
</button>
|
||||
<div role="group" aria-label="Run list view" className="flex rounded-md border border-line bg-panel/80 p-0.5">
|
||||
<button
|
||||
type="button"
|
||||
|
|
|
|||
|
|
@ -1417,10 +1417,11 @@ paths:
|
|||
operationId: listBoardRuns
|
||||
tags: [Runs]
|
||||
summary: List Board Runs
|
||||
description: Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves.
|
||||
description: Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves. Archived runs are hidden by default; pass `include_archived=true` to include them under the `archived` column.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PageLimit"
|
||||
- $ref: "#/components/parameters/PageOffset"
|
||||
- $ref: "#/components/parameters/IncludeArchived"
|
||||
responses:
|
||||
"200":
|
||||
description: Paginated list of runs for the board view
|
||||
|
|
@ -5805,6 +5806,7 @@ components:
|
|||
- blocked
|
||||
- succeeded
|
||||
- failed
|
||||
- archived
|
||||
|
||||
BoardColumnDefinition:
|
||||
type: object
|
||||
|
|
|
|||
|
|
@ -92,12 +92,13 @@ fn board_column(status: RunStatus) -> Option<BoardColumn> {
|
|||
RunStatus::Blocked { .. } => Some(BoardColumn::Blocked),
|
||||
RunStatus::Succeeded { .. } => Some(BoardColumn::Succeeded),
|
||||
RunStatus::Failed { .. } | RunStatus::Dead => Some(BoardColumn::Failed),
|
||||
RunStatus::Removing | RunStatus::Archived { .. } => None,
|
||||
RunStatus::Archived { .. } => Some(BoardColumn::Archived),
|
||||
RunStatus::Removing => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn board_columns() -> Vec<BoardColumnDefinition> {
|
||||
vec![
|
||||
pub(crate) fn board_columns(include_archived: bool) -> Vec<BoardColumnDefinition> {
|
||||
let mut columns = vec![
|
||||
BoardColumnDefinition {
|
||||
id: BoardColumn::Queued,
|
||||
name: "Queued".into(),
|
||||
|
|
@ -122,7 +123,14 @@ pub(crate) fn board_columns() -> Vec<BoardColumnDefinition> {
|
|||
id: BoardColumn::Failed,
|
||||
name: "Failed".into(),
|
||||
},
|
||||
]
|
||||
];
|
||||
if include_archived {
|
||||
columns.push(BoardColumnDefinition {
|
||||
id: BoardColumn::Archived,
|
||||
name: "Archived".into(),
|
||||
});
|
||||
}
|
||||
columns
|
||||
}
|
||||
|
||||
fn board_run_metadata_from_projection(
|
||||
|
|
@ -187,7 +195,7 @@ fn paginate_items<T>(items: Vec<T>, pagination: &PaginationParams) -> (Vec<T>, b
|
|||
async fn list_board_runs(
|
||||
_auth: RequiredUser,
|
||||
State(state): State<Arc<AppState>>,
|
||||
Query(pagination): Query<PaginationParams>,
|
||||
Query(params): Query<ListRunsParams>,
|
||||
) -> Response {
|
||||
let entries = match state
|
||||
.store
|
||||
|
|
@ -200,14 +208,18 @@ async fn list_board_runs(
|
|||
.into_response();
|
||||
}
|
||||
};
|
||||
let include_archived = params.include_archived;
|
||||
let board_summaries: Vec<_> = entries
|
||||
.into_iter()
|
||||
.filter_map(|entry| {
|
||||
let column = board_column(entry.summary.status)?;
|
||||
if column == BoardColumn::Archived && !include_archived {
|
||||
return None;
|
||||
}
|
||||
Some((entry, column))
|
||||
})
|
||||
.collect();
|
||||
let (page_summaries, has_more) = paginate_items(board_summaries, &pagination);
|
||||
let (page_summaries, has_more) = paginate_items(board_summaries, ¶ms.pagination());
|
||||
|
||||
let mut data = Vec::with_capacity(page_summaries.len());
|
||||
for (entry, column) in page_summaries {
|
||||
|
|
@ -222,7 +234,7 @@ async fn list_board_runs(
|
|||
(
|
||||
StatusCode::OK,
|
||||
Json(serde_json::json!({
|
||||
"columns": board_columns(),
|
||||
"columns": board_columns(include_archived),
|
||||
"data": data,
|
||||
"meta": { "has_more": has_more }
|
||||
})),
|
||||
|
|
|
|||
|
|
@ -8282,6 +8282,139 @@ async fn boards_runs_excludes_removing_status() {
|
|||
assert!(!found, "removing run should not appear on the board");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn boards_runs_excludes_archived_by_default() {
|
||||
let state = test_app_state();
|
||||
let app = crate::test_support::build_test_router(Arc::clone(&state));
|
||||
let run_id = fixtures::RUN_1;
|
||||
|
||||
create_durable_run_with_events(&state, run_id, &[
|
||||
workflow_event::Event::RunSubmitted {
|
||||
definition_blob: None,
|
||||
},
|
||||
workflow_event::Event::RunStarting,
|
||||
workflow_event::Event::RunRunning,
|
||||
workflow_event::Event::WorkflowRunCompleted {
|
||||
duration_ms: 1000,
|
||||
artifact_count: 0,
|
||||
status: "succeeded".to_string(),
|
||||
reason: SuccessReason::Completed,
|
||||
total_usd_micros: None,
|
||||
final_git_commit_sha: None,
|
||||
final_patch: None,
|
||||
billing: None,
|
||||
},
|
||||
workflow_event::Event::RunArchived { actor: None },
|
||||
])
|
||||
.await;
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api("/boards/runs"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
let body = response_json!(response, StatusCode::OK).await;
|
||||
let data = body["data"].as_array().expect("data should be array");
|
||||
assert!(
|
||||
!data
|
||||
.iter()
|
||||
.any(|i| i["run_id"].as_str() == Some(&run_id.to_string())),
|
||||
"archived run should be hidden when include_archived is unset",
|
||||
);
|
||||
let columns = body["columns"].as_array().expect("columns should be array");
|
||||
assert!(
|
||||
!columns.iter().any(|c| c["id"].as_str() == Some("archived")),
|
||||
"archived column should not appear in default response",
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn boards_runs_includes_archived_when_flag_set() {
|
||||
let state = test_app_state();
|
||||
let app = crate::test_support::build_test_router(Arc::clone(&state));
|
||||
let archived_id = fixtures::RUN_1;
|
||||
let succeeded_id = fixtures::RUN_2;
|
||||
|
||||
create_durable_run_with_events(&state, archived_id, &[
|
||||
workflow_event::Event::RunSubmitted {
|
||||
definition_blob: None,
|
||||
},
|
||||
workflow_event::Event::RunStarting,
|
||||
workflow_event::Event::RunRunning,
|
||||
workflow_event::Event::WorkflowRunCompleted {
|
||||
duration_ms: 1000,
|
||||
artifact_count: 0,
|
||||
status: "succeeded".to_string(),
|
||||
reason: SuccessReason::Completed,
|
||||
total_usd_micros: None,
|
||||
final_git_commit_sha: None,
|
||||
final_patch: None,
|
||||
billing: None,
|
||||
},
|
||||
workflow_event::Event::RunArchived { actor: None },
|
||||
])
|
||||
.await;
|
||||
create_durable_run_with_events(&state, succeeded_id, &[
|
||||
workflow_event::Event::RunSubmitted {
|
||||
definition_blob: None,
|
||||
},
|
||||
workflow_event::Event::RunStarting,
|
||||
workflow_event::Event::RunRunning,
|
||||
workflow_event::Event::WorkflowRunCompleted {
|
||||
duration_ms: 1000,
|
||||
artifact_count: 0,
|
||||
status: "succeeded".to_string(),
|
||||
reason: SuccessReason::Completed,
|
||||
total_usd_micros: None,
|
||||
final_git_commit_sha: None,
|
||||
final_patch: None,
|
||||
billing: None,
|
||||
},
|
||||
])
|
||||
.await;
|
||||
|
||||
let req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(api("/boards/runs?include_archived=true"))
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
let body = response_json!(response, StatusCode::OK).await;
|
||||
let data = body["data"].as_array().expect("data should be array");
|
||||
|
||||
let archived_item = data
|
||||
.iter()
|
||||
.find(|i| i["run_id"].as_str() == Some(&archived_id.to_string()))
|
||||
.expect("archived run should appear when include_archived=true");
|
||||
assert_eq!(archived_item["column"].as_str().unwrap(), "archived");
|
||||
assert_eq!(archived_item["status"]["kind"].as_str().unwrap(), "archived");
|
||||
|
||||
let succeeded_item = data
|
||||
.iter()
|
||||
.find(|i| i["run_id"].as_str() == Some(&succeeded_id.to_string()))
|
||||
.expect("non-archived run should still appear");
|
||||
assert_eq!(succeeded_item["column"].as_str().unwrap(), "succeeded");
|
||||
|
||||
let columns = body["columns"].as_array().expect("columns should be array");
|
||||
let column_ids: Vec<_> = columns
|
||||
.iter()
|
||||
.map(|c| c["id"].as_str().unwrap().to_string())
|
||||
.collect();
|
||||
assert_eq!(
|
||||
column_ids,
|
||||
vec![
|
||||
"queued",
|
||||
"initializing",
|
||||
"running",
|
||||
"blocked",
|
||||
"succeeded",
|
||||
"failed",
|
||||
"archived",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_run_exposes_canonical_operator_statuses() {
|
||||
let state = test_app_state();
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
};
|
||||
},
|
||||
/**
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* @summary Interrupt Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -376,10 +376,10 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
};
|
||||
},
|
||||
/**
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* @summary Steer Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
|
|
@ -521,7 +521,7 @@ export const HumanInTheLoopApiFp = function(configuration?: Configuration) {
|
|||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* @summary Interrupt Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -579,10 +579,10 @@ export const HumanInTheLoopApiFp = function(configuration?: Configuration) {
|
|||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* @summary Steer Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
|
|
@ -650,7 +650,7 @@ export const HumanInTheLoopApiFactory = function (configuration?: Configuration,
|
|||
return localVarFp.getSandboxFile(id, path, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* @summary Interrupt Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -696,10 +696,10 @@ export const HumanInTheLoopApiFactory = function (configuration?: Configuration,
|
|||
return localVarFp.putSandboxFile(id, path, body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* @summary Steer Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
|
|
@ -762,7 +762,7 @@ export class HumanInTheLoopApi extends BaseAPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* Interrupt the active API-mode agent round without sending steering text. The agent keeps its steering lease and waits for a later steer message before starting another LLM round.
|
||||
* @summary Interrupt Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -812,10 +812,10 @@ export class HumanInTheLoopApi extends BaseAPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* Send a mid-run steering message to the live agent session(s) of a running run. Set `interrupt=true` to atomically interrupt the active API-mode agent round first, then deliver this message as the next user turn. Without `interrupt=true`, the message is appended to the steering queue and may buffer until the next API-mode agent session.
|
||||
* @summary Steer Run
|
||||
* @param {string} id Unique run identifier (ULID).
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {SteerRunRequest} steerRunRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
|
|
@ -836,3 +836,4 @@ export class HumanInTheLoopApi extends BaseAPI {
|
|||
return HumanInTheLoopApiFp(this.configuration).submitRunAnswer(id, qid, submitAnswerRequest, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -443,14 +443,15 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
};
|
||||
},
|
||||
/**
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves.
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves. Archived runs are hidden by default; pass `include_archived=true` to include them under the `archived` column.
|
||||
* @summary List Board Runs
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {boolean} [includeArchived] Whether to include archived runs in the response. Defaults to `false`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
listBoardRuns: async (pageLimit?: number, pageOffset?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
listBoardRuns: async (pageLimit?: number, pageOffset?: number, includeArchived?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/v1/boards/runs`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
|
|
@ -477,6 +478,10 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
localVarQueryParameter['page[offset]'] = pageOffset;
|
||||
}
|
||||
|
||||
if (includeArchived !== undefined) {
|
||||
localVarQueryParameter['include_archived'] = includeArchived;
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Accept'] = 'application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
|
|
@ -1206,15 +1211,16 @@ export const RunsApiFp = function(configuration?: Configuration) {
|
|||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves.
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves. Archived runs are hidden by default; pass `include_archived=true` to include them under the `archived` column.
|
||||
* @summary List Board Runs
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {boolean} [includeArchived] Whether to include archived runs in the response. Defaults to `false`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async listBoardRuns(pageLimit?: number, pageOffset?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedBoardRunList>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.listBoardRuns(pageLimit, pageOffset, options);
|
||||
async listBoardRuns(pageLimit?: number, pageOffset?: number, includeArchived?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedBoardRunList>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.listBoardRuns(pageLimit, pageOffset, includeArchived, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['RunsApi.listBoardRuns']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
|
|
@ -1509,15 +1515,16 @@ export const RunsApiFactory = function (configuration?: Configuration, basePath?
|
|||
return localVarFp.getRunTimeline(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves.
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves. Archived runs are hidden by default; pass `include_archived=true` to include them under the `archived` column.
|
||||
* @summary List Board Runs
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {boolean} [includeArchived] Whether to include archived runs in the response. Defaults to `false`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
listBoardRuns(pageLimit?: number, pageOffset?: number, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedBoardRunList> {
|
||||
return localVarFp.listBoardRuns(pageLimit, pageOffset, options).then((request) => request(axios, basePath));
|
||||
listBoardRuns(pageLimit?: number, pageOffset?: number, includeArchived?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedBoardRunList> {
|
||||
return localVarFp.listBoardRuns(pageLimit, pageOffset, includeArchived, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Returns durable run summaries from the backing store, including runs persisted before the current server boot. Archived runs are hidden by default; pass `include_archived=true` to include them in the response.
|
||||
|
|
@ -1774,15 +1781,16 @@ export class RunsApi extends BaseAPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves.
|
||||
* Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves. Archived runs are hidden by default; pass `include_archived=true` to include them under the `archived` column.
|
||||
* @summary List Board Runs
|
||||
* @param {number} [pageLimit] Maximum number of items to return per page.
|
||||
* @param {number} [pageOffset] Number of items to skip before returning results.
|
||||
* @param {boolean} [includeArchived] Whether to include archived runs in the response. Defaults to `false`.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public listBoardRuns(pageLimit?: number, pageOffset?: number, options?: RawAxiosRequestConfig) {
|
||||
return RunsApiFp(this.configuration).listBoardRuns(pageLimit, pageOffset, options).then((request) => request(this.axios, this.basePath));
|
||||
public listBoardRuns(pageLimit?: number, pageOffset?: number, includeArchived?: boolean, options?: RawAxiosRequestConfig) {
|
||||
return RunsApiFp(this.configuration).listBoardRuns(pageLimit, pageOffset, includeArchived, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,3 +21,6 @@ export interface BoardColumnDefinition {
|
|||
'id': BoardColumn;
|
||||
'name': string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ export const BoardColumn = {
|
|||
RUNNING: 'running',
|
||||
BLOCKED: 'blocked',
|
||||
SUCCEEDED: 'succeeded',
|
||||
FAILED: 'failed'
|
||||
FAILED: 'failed',
|
||||
ARCHIVED: 'archived'
|
||||
} as const;
|
||||
|
||||
export type BoardColumn = typeof BoardColumn[keyof typeof BoardColumn];
|
||||
|
|
|
|||
|
|
@ -43,3 +43,6 @@ export interface RunBillingStage {
|
|||
'started_at'?: string | null;
|
||||
'state'?: StageState | null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -65,3 +65,6 @@ export interface StageProjection {
|
|||
'duration_ms'?: number | null;
|
||||
'state'?: StageState | null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ export interface SteerRunRequest {
|
|||
*/
|
||||
'text': string;
|
||||
/**
|
||||
* When true, apply a worker-control interrupt first, then deliver this text as steering in the same control operation. When false (default), append to the steering queue and let the agent pick it up at the next turn boundary.
|
||||
* When true, apply a worker-control interrupt first, then deliver this text as steering in the same control operation. When false (default), append to the steering queue and let the agent pick it up at the next turn boundary.
|
||||
*/
|
||||
'interrupt'?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue