نسخهٔ وب مستقل — پلتفرم نیروی کار هوش مصنوعی
مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت. تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
This commit is contained in:
@@ -0,0 +1,617 @@
|
||||
/**
|
||||
* Shared API contracts.
|
||||
*
|
||||
* These types mirror the FastAPI response schemas. They are intentionally
|
||||
* hand-written and small: the backend is the source of truth, and a drift here
|
||||
* surfaces immediately as a TypeScript error at the call site.
|
||||
*/
|
||||
|
||||
export type Role = "owner" | "admin" | "manager" | "member" | "viewer";
|
||||
|
||||
export type MembershipStatus = "active" | "invited" | "suspended";
|
||||
|
||||
/** Provider kinds the AI Control Plane can talk to. */
|
||||
export type ProviderType =
|
||||
| "mock"
|
||||
| "openai_compatible"
|
||||
| "anthropic"
|
||||
| "gemini"
|
||||
| "openrouter";
|
||||
|
||||
/** What a model can do. Routing picks models by required capability. */
|
||||
export type Capability = "text" | "vision" | "tools" | "reasoning" | "long_context" | "code";
|
||||
|
||||
/** Routing intents. Customers never see these names — only the platform owner does. */
|
||||
export type RoutingMode = "fast" | "cheap" | "balanced" | "reasoning" | "vision" | "coding";
|
||||
|
||||
export type TaskStatus =
|
||||
| "new"
|
||||
| "triaged"
|
||||
| "waiting_approval"
|
||||
| "running"
|
||||
| "done"
|
||||
| "failed"
|
||||
| "cancelled";
|
||||
|
||||
export type RunStatus =
|
||||
| "queued"
|
||||
| "planning"
|
||||
| "waiting_approval"
|
||||
| "running"
|
||||
| "tool_calling"
|
||||
| "sandbox_running"
|
||||
| "completed"
|
||||
| "failed"
|
||||
| "cancelled"
|
||||
| "timed_out";
|
||||
|
||||
export type RoleKey =
|
||||
| "manager"
|
||||
| "planner"
|
||||
| "developer"
|
||||
| "reviewer"
|
||||
| "tester"
|
||||
| "researcher"
|
||||
| "content_creator"
|
||||
| "support";
|
||||
|
||||
export type EmployeeStatus = "active" | "paused" | "archived";
|
||||
|
||||
export type PreviewDomainStatus = "active" | "disabled" | "failed";
|
||||
|
||||
export type RateUnit =
|
||||
| "model_input_tokens"
|
||||
| "model_output_tokens"
|
||||
| "sandbox_cpu_second"
|
||||
| "sandbox_memory_gb_second"
|
||||
| "storage_gb_day"
|
||||
| "tool_call"
|
||||
| "premium_employee_run";
|
||||
|
||||
export interface ApiErrorBody {
|
||||
error: {
|
||||
code: string;
|
||||
message: string;
|
||||
details?: unknown;
|
||||
/**
|
||||
* Correlates this response with the row the API wrote to its error console
|
||||
* (and with the `X-Request-ID` response header). Surfacing it lets a user
|
||||
* quote one string that points at exactly one server-side record.
|
||||
*/
|
||||
request_id?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
avatar_url?: string | null;
|
||||
is_platform_owner: boolean;
|
||||
}
|
||||
|
||||
export interface Organization {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
owner_user_id: string;
|
||||
}
|
||||
|
||||
export interface OrganizationWithRole extends Organization {
|
||||
role: Role;
|
||||
}
|
||||
|
||||
export interface Member {
|
||||
id: string;
|
||||
user_id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
role: Role;
|
||||
status: MembershipStatus;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Invite {
|
||||
id: string;
|
||||
email: string;
|
||||
role: Role;
|
||||
expires_at: string;
|
||||
invite_token: string;
|
||||
invite_url: string;
|
||||
}
|
||||
|
||||
export interface TokenResponse {
|
||||
access_token: string;
|
||||
token_type: string;
|
||||
user: User;
|
||||
}
|
||||
|
||||
export interface MeResponse {
|
||||
user: User;
|
||||
organizations: OrganizationWithRole[];
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
id: string;
|
||||
organization_id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
description: string;
|
||||
default_branch: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface RepoStatus {
|
||||
exists: boolean;
|
||||
private: boolean;
|
||||
default_branch: string;
|
||||
branches: string[];
|
||||
open_pull_requests: number;
|
||||
}
|
||||
|
||||
export interface Repository {
|
||||
id: string;
|
||||
provider: string;
|
||||
owner: string;
|
||||
repo_name: string;
|
||||
clone_url: string;
|
||||
web_url: string;
|
||||
default_branch: string;
|
||||
private: boolean;
|
||||
}
|
||||
|
||||
export interface AdminProvider {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
base_url: string;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface AdminModel {
|
||||
id: string;
|
||||
provider_id: string;
|
||||
internal_name: string;
|
||||
display_name_for_admin: string;
|
||||
capabilities: string[];
|
||||
input_price_per_1m: number;
|
||||
output_price_per_1m: number;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
export interface AdminRoutingPolicy {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
mode: string;
|
||||
is_default: boolean;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
export interface AdminRateCard {
|
||||
id: string;
|
||||
name: string;
|
||||
unit: RateUnit;
|
||||
customer_price: number;
|
||||
internal_cost_estimate: number;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
export interface AdminOrganization {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
member_count: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A stored provider credential.
|
||||
*
|
||||
* There is no field here that can carry a plaintext key — the API only ever
|
||||
* returns a masked form, and on list it returns a fixed mask because the
|
||||
* plaintext is unrecoverable by design.
|
||||
*/
|
||||
export interface AdminCredential {
|
||||
id: string;
|
||||
provider_id: string;
|
||||
name: string;
|
||||
masked_key: string;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
/** Result of a routing dry-run: which model a mode would pick, and why. */
|
||||
export interface ModelChoice {
|
||||
mode: string;
|
||||
model_id: string;
|
||||
internal_name: string;
|
||||
capabilities: string[];
|
||||
estimated_input_price_per_1m: number;
|
||||
estimated_output_price_per_1m: number;
|
||||
}
|
||||
|
||||
export interface AdminUsageRow {
|
||||
organization_id: string;
|
||||
quantity: number;
|
||||
total_price: number;
|
||||
}
|
||||
|
||||
export interface PreviewDomain {
|
||||
id: string;
|
||||
host: string;
|
||||
port: number;
|
||||
status: PreviewDomainStatus;
|
||||
protected: boolean;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Employee {
|
||||
id: string;
|
||||
organization_id: string;
|
||||
project_id?: string | null;
|
||||
template_id?: string | null;
|
||||
name: string;
|
||||
role_key: RoleKey;
|
||||
status: EmployeeStatus;
|
||||
routing_policy_id?: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
id: string;
|
||||
organization_id: string;
|
||||
project_id?: string | null;
|
||||
thread_id?: string | null;
|
||||
title: string;
|
||||
description: string;
|
||||
status: TaskStatus;
|
||||
assigned_employee_id?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface Run {
|
||||
id: string;
|
||||
task_id: string;
|
||||
employee_id?: string | null;
|
||||
status: RunStatus;
|
||||
error?: string | null;
|
||||
started_at?: string | null;
|
||||
finished_at?: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Thread {
|
||||
id: string;
|
||||
organization_id: string;
|
||||
project_id?: string | null;
|
||||
title: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
id: string;
|
||||
thread_id: string;
|
||||
role: "user" | "assistant" | "system";
|
||||
content: string;
|
||||
employee_id?: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface ThreadDetail extends Thread {
|
||||
messages: Message[];
|
||||
}
|
||||
|
||||
export interface RunStep {
|
||||
id: string;
|
||||
index: number;
|
||||
kind: string;
|
||||
title: string;
|
||||
payload_json: Record<string, unknown>;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface ToolCall {
|
||||
id: string;
|
||||
tool_key: string;
|
||||
status: string;
|
||||
requires_approval: boolean;
|
||||
arguments_json: Record<string, unknown>;
|
||||
result_json: Record<string, unknown>;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface ArtifactDetail extends Artifact {
|
||||
content_ref: string;
|
||||
run_id?: string | null;
|
||||
}
|
||||
|
||||
export interface RunDetail extends Run {
|
||||
steps: RunStep[];
|
||||
tool_calls: ToolCall[];
|
||||
artifacts: ArtifactDetail[];
|
||||
}
|
||||
|
||||
export interface TaskDetail extends Task {
|
||||
runs: Run[];
|
||||
}
|
||||
|
||||
export interface AgentTemplate {
|
||||
id: string;
|
||||
name: string;
|
||||
role_key: RoleKey;
|
||||
description: string;
|
||||
default_tools_json: string[];
|
||||
}
|
||||
|
||||
/** A routing policy as a customer may see it — no mode, no model hints. */
|
||||
export interface RoutingChoice {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface PromptVersion {
|
||||
id: string;
|
||||
version: number;
|
||||
content: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface ToolPermission {
|
||||
tool_key: string;
|
||||
allowed: boolean;
|
||||
}
|
||||
|
||||
/** One entry in the tool catalog an employee can be granted. */
|
||||
export interface ToolSpec {
|
||||
key: string;
|
||||
label: string;
|
||||
description: string;
|
||||
requires_approval: boolean;
|
||||
destructive: boolean;
|
||||
category: string;
|
||||
}
|
||||
|
||||
export interface EmployeeDetail extends Employee {
|
||||
prompt_versions: PromptVersion[];
|
||||
tool_permissions: ToolPermission[];
|
||||
open_task_count: number;
|
||||
}
|
||||
|
||||
export interface PostMessageResponse {
|
||||
user_message: Message;
|
||||
assistant_message: Message;
|
||||
}
|
||||
|
||||
export interface Artifact {
|
||||
id: string;
|
||||
name: string;
|
||||
kind: string;
|
||||
size_bytes: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface BillingSummary {
|
||||
balance: number;
|
||||
currency: string;
|
||||
low_balance: boolean;
|
||||
low_balance_threshold: number;
|
||||
total_spend: number;
|
||||
by_unit: { unit: RateUnit; quantity: number; total_price: number }[];
|
||||
by_employee: Record<string, number>;
|
||||
by_project: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface UsageEvent {
|
||||
id: string;
|
||||
unit: RateUnit;
|
||||
quantity: number;
|
||||
unit_price: number;
|
||||
total_price: number;
|
||||
project_id?: string | null;
|
||||
employee_id?: string | null;
|
||||
run_id?: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Invoice {
|
||||
id: string;
|
||||
amount: number;
|
||||
currency: string;
|
||||
status: string;
|
||||
period_start?: string | null;
|
||||
period_end?: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Payment {
|
||||
id: string;
|
||||
amount: number;
|
||||
currency: string;
|
||||
status: string;
|
||||
provider: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Wallet {
|
||||
balance: number;
|
||||
currency: string;
|
||||
low_balance: boolean;
|
||||
}
|
||||
|
||||
export interface AuditEvent {
|
||||
id: string;
|
||||
action: string;
|
||||
actor_user_id?: string | null;
|
||||
target_type: string;
|
||||
target_id: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
// --- sandbox ----------------------------------------------------------------
|
||||
|
||||
export type NetworkPolicy = "deny_all" | "allowlist" | "open";
|
||||
|
||||
export interface SandboxTemplate {
|
||||
id: string;
|
||||
name: string;
|
||||
provider: string;
|
||||
image: string;
|
||||
description: string;
|
||||
default_cpu: number;
|
||||
default_memory_mb: number;
|
||||
default_disk_mb: number;
|
||||
}
|
||||
|
||||
export interface SandboxWorkspace {
|
||||
id: string;
|
||||
project_id: string;
|
||||
template_id: string;
|
||||
provider: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface SandboxSession {
|
||||
id: string;
|
||||
workspace_id: string;
|
||||
status: string;
|
||||
started_at: string;
|
||||
last_active_at: string;
|
||||
}
|
||||
|
||||
export interface SandboxCommandRun {
|
||||
id: string;
|
||||
command: string;
|
||||
exit_code: number | null;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
duration_ms: number;
|
||||
truncated: boolean;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface SandboxFileRead {
|
||||
path: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface SandboxSnapshot {
|
||||
id: string;
|
||||
name: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface SandboxPreviewUrl {
|
||||
port: number;
|
||||
url: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Effective limits are resolved server-side (project -> organization ->
|
||||
* platform) and clamped. The UI only ever displays them.
|
||||
*/
|
||||
export interface SandboxResourceLimit {
|
||||
cpu: number;
|
||||
memory_mb: number;
|
||||
disk_mb: number;
|
||||
timeout_seconds: number;
|
||||
max_output_bytes: number;
|
||||
network_policy: NetworkPolicy;
|
||||
}
|
||||
|
||||
export interface HealthResponse {
|
||||
status: string;
|
||||
app: string;
|
||||
env: string;
|
||||
}
|
||||
|
||||
export interface ReadinessResponse {
|
||||
status: string;
|
||||
checks: {
|
||||
database: string;
|
||||
model_provider: string;
|
||||
adapters: Record<string, string>;
|
||||
};
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Error console (platform owner) */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
export type ErrorSeverity = "warning" | "error" | "critical";
|
||||
export type ErrorSource = "http" | "worker" | "startup";
|
||||
export type ErrorStatusFilter = "open" | "resolved";
|
||||
|
||||
/**
|
||||
* One persisted failure. Deliberately wide: a record that lacks the request
|
||||
* path or the exception class forces whoever is debugging to reproduce the bug
|
||||
* just to learn what it was.
|
||||
*/
|
||||
export interface ErrorEvent {
|
||||
id: string;
|
||||
kind: string;
|
||||
message: string;
|
||||
stack: string;
|
||||
severity: ErrorSeverity;
|
||||
source: ErrorSource;
|
||||
error_type: string;
|
||||
fingerprint: string;
|
||||
status_code: number | null;
|
||||
method: string;
|
||||
path: string;
|
||||
organization_id: string | null;
|
||||
user_id: string | null;
|
||||
run_id: string | null;
|
||||
request_id: string;
|
||||
ip: string;
|
||||
user_agent: string;
|
||||
metadata_json: Record<string, unknown>;
|
||||
resolved_at: string | null;
|
||||
resolved_note: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/** Every occurrence of one distinct bug, collapsed into a single row. */
|
||||
export interface ErrorGroup {
|
||||
fingerprint: string;
|
||||
occurrences: number;
|
||||
open_count: number;
|
||||
first_seen: string;
|
||||
last_seen: string;
|
||||
kind: string;
|
||||
error_type: string;
|
||||
severity: ErrorSeverity;
|
||||
source: ErrorSource;
|
||||
path: string;
|
||||
sample_message: string;
|
||||
}
|
||||
|
||||
export interface ErrorSummary {
|
||||
open_by_severity: Record<string, number>;
|
||||
total_open: number;
|
||||
}
|
||||
|
||||
export interface ErrorListResponse {
|
||||
items: ErrorEvent[];
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export interface ResolveErrorResponse {
|
||||
fingerprint: string;
|
||||
resolved: number;
|
||||
}
|
||||
|
||||
export interface ErrorQuery {
|
||||
status?: ErrorStatusFilter;
|
||||
severity?: ErrorSeverity;
|
||||
source?: ErrorSource;
|
||||
organization_id?: string;
|
||||
search?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}
|
||||
Reference in New Issue
Block a user