ConusAI vendor v0.1.0-dev.20261027+9b1131fb
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-dev.20261027+9b1131fb
2026-10-27 18:05:17 +00:00
commit 3102273ec7
538 changed files with 80203 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
"use client"
// The approval queue: what a run's tool asked a person to decide. The panel renders the EXACT
// stored proposed arguments — a pretty-printed JSON of what the tool was called with — never a
// model's narration of them, and it carries the AI disclosure a reviewer reads before deciding.
import { AiDisclosureBadge, type ProjectSlugs, useTransport } from "@conusai-kit/ui"
import { type ReactElement, useState } from "react"
import type { ApprovalView } from "../contract/index.js"
export interface ApprovalQueueLabels {
readonly heading: string
readonly empty: string
readonly proposed: string
readonly review: string
readonly approve: string
readonly reject: string
readonly decided: string
readonly disclosure: string
readonly failed: string
}
export function ApprovalQueue({
slugs,
approvals,
labels,
}: {
slugs: ProjectSlugs
approvals: readonly ApprovalView[]
labels: ApprovalQueueLabels
}): ReactElement {
const { call, describe } = useTransport()
const [busy, setBusy] = useState<string | null>(null)
const [message, setMessage] = useState<string | null>(null)
const decide = async (approval: ApprovalView, decision: "approve" | "reject"): Promise<void> => {
setBusy(`${approval.runId}:${approval.stepKey}`)
setMessage(null)
try {
await call("agent.approval.review", { ...slugs, runId: approval.runId, stepKey: approval.stepKey, decision })
setMessage(labels.decided)
window.location.reload()
} catch (error) {
setMessage(labels.failed.replace("{detail}", describe(error)))
} finally {
setBusy(null)
}
}
return (
<section aria-labelledby="approvals-heading">
<h2 id="approvals-heading">{labels.heading}</h2>
{approvals.length === 0 ? <p>{labels.empty}</p> : null}
{approvals.map((approval) => (
<article key={`${approval.runId}:${approval.stepKey}`} aria-label={approval.tool}>
<h3>{approval.tool}</h3>
<p>{approval.goal}</p>
<AiDisclosureBadge label={labels.disclosure} />
<h4>{labels.proposed}</h4>
<pre>{JSON.stringify(approval.arguments, null, 2)}</pre>
<div>
<button type="button" disabled={busy !== null} onClick={() => void decide(approval, "approve")}>
{labels.approve}
</button>
<button type="button" disabled={busy !== null} onClick={() => void decide(approval, "reject")}>
{labels.reject}
</button>
{approval.reviewUrl !== null ? (
<a href={approval.reviewUrl} target="_blank" rel="noreferrer">
{labels.review}
</a>
) : null}
</div>
</article>
))}
{message !== null ? (
<p role="status" aria-live="polite">
{message}
</p>
) : null}
</section>
)
}