Add agent runtime DB schemas and expand shared types
New schemas: agent_runtime_state, agent_wakeup_requests, heartbeat_run_events. New migrations for runtime tables. Expand heartbeat types with run events, wakeup reasons, and adapter state. Add live event types. Update agent schema and shared constants. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
87
packages/db/src/migrations/0001_fast_northstar.sql
Normal file
87
packages/db/src/migrations/0001_fast_northstar.sql
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
CREATE TABLE "agent_runtime_state" (
|
||||||
|
"agent_id" uuid PRIMARY KEY NOT NULL,
|
||||||
|
"company_id" uuid NOT NULL,
|
||||||
|
"adapter_type" text NOT NULL,
|
||||||
|
"session_id" text,
|
||||||
|
"state_json" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||||
|
"last_run_id" uuid,
|
||||||
|
"last_run_status" text,
|
||||||
|
"total_input_tokens" bigint DEFAULT 0 NOT NULL,
|
||||||
|
"total_output_tokens" bigint DEFAULT 0 NOT NULL,
|
||||||
|
"total_cached_input_tokens" bigint DEFAULT 0 NOT NULL,
|
||||||
|
"total_cost_cents" bigint DEFAULT 0 NOT NULL,
|
||||||
|
"last_error" text,
|
||||||
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||||
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "agent_wakeup_requests" (
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"company_id" uuid NOT NULL,
|
||||||
|
"agent_id" uuid NOT NULL,
|
||||||
|
"source" text NOT NULL,
|
||||||
|
"trigger_detail" text,
|
||||||
|
"reason" text,
|
||||||
|
"payload" jsonb,
|
||||||
|
"status" text DEFAULT 'queued' NOT NULL,
|
||||||
|
"coalesced_count" integer DEFAULT 0 NOT NULL,
|
||||||
|
"requested_by_actor_type" text,
|
||||||
|
"requested_by_actor_id" text,
|
||||||
|
"idempotency_key" text,
|
||||||
|
"run_id" uuid,
|
||||||
|
"requested_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||||
|
"claimed_at" timestamp with time zone,
|
||||||
|
"finished_at" timestamp with time zone,
|
||||||
|
"error" text,
|
||||||
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||||
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE "heartbeat_run_events" (
|
||||||
|
"id" bigserial PRIMARY KEY NOT NULL,
|
||||||
|
"company_id" uuid NOT NULL,
|
||||||
|
"run_id" uuid NOT NULL,
|
||||||
|
"agent_id" uuid NOT NULL,
|
||||||
|
"seq" integer NOT NULL,
|
||||||
|
"event_type" text NOT NULL,
|
||||||
|
"stream" text,
|
||||||
|
"level" text,
|
||||||
|
"color" text,
|
||||||
|
"message" text,
|
||||||
|
"payload" jsonb,
|
||||||
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ALTER COLUMN "invocation_source" SET DEFAULT 'on_demand';--> statement-breakpoint
|
||||||
|
ALTER TABLE "agents" ADD COLUMN "runtime_config" jsonb DEFAULT '{}'::jsonb NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "trigger_detail" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "wakeup_request_id" uuid;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "exit_code" integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "signal" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "usage_json" jsonb;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "result_json" jsonb;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "session_id_before" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "session_id_after" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "log_store" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "log_ref" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "log_bytes" bigint;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "log_sha256" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "log_compressed" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "stdout_excerpt" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "stderr_excerpt" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_runs" ADD COLUMN "error_code" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "agent_runtime_state" ADD CONSTRAINT "agent_runtime_state_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "agent_runtime_state" ADD CONSTRAINT "agent_runtime_state_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "agent_wakeup_requests" ADD CONSTRAINT "agent_wakeup_requests_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "agent_wakeup_requests" ADD CONSTRAINT "agent_wakeup_requests_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_run_events" ADD CONSTRAINT "heartbeat_run_events_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_run_events" ADD CONSTRAINT "heartbeat_run_events_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
ALTER TABLE "heartbeat_run_events" ADD CONSTRAINT "heartbeat_run_events_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||||
|
CREATE INDEX "agent_runtime_state_company_agent_idx" ON "agent_runtime_state" USING btree ("company_id","agent_id");--> statement-breakpoint
|
||||||
|
CREATE INDEX "agent_runtime_state_company_updated_idx" ON "agent_runtime_state" USING btree ("company_id","updated_at");--> statement-breakpoint
|
||||||
|
CREATE INDEX "agent_wakeup_requests_company_agent_status_idx" ON "agent_wakeup_requests" USING btree ("company_id","agent_id","status");--> statement-breakpoint
|
||||||
|
CREATE INDEX "agent_wakeup_requests_company_requested_idx" ON "agent_wakeup_requests" USING btree ("company_id","requested_at");--> statement-breakpoint
|
||||||
|
CREATE INDEX "agent_wakeup_requests_agent_requested_idx" ON "agent_wakeup_requests" USING btree ("agent_id","requested_at");--> statement-breakpoint
|
||||||
|
CREATE INDEX "heartbeat_run_events_run_seq_idx" ON "heartbeat_run_events" USING btree ("run_id","seq");--> statement-breakpoint
|
||||||
|
CREATE INDEX "heartbeat_run_events_company_run_idx" ON "heartbeat_run_events" USING btree ("company_id","run_id");--> statement-breakpoint
|
||||||
|
CREATE INDEX "heartbeat_run_events_company_created_idx" ON "heartbeat_run_events" USING btree ("company_id","created_at");
|
||||||
1
packages/db/src/migrations/0002_big_zaladane.sql
Normal file
1
packages/db/src/migrations/0002_big_zaladane.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "heartbeat_runs" ADD CONSTRAINT "heartbeat_runs_wakeup_request_id_agent_wakeup_requests_id_fk" FOREIGN KEY ("wakeup_request_id") REFERENCES "public"."agent_wakeup_requests"("id") ON DELETE no action ON UPDATE no action;
|
||||||
2441
packages/db/src/migrations/meta/0001_snapshot.json
Normal file
2441
packages/db/src/migrations/meta/0001_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2454
packages/db/src/migrations/meta/0002_snapshot.json
Normal file
2454
packages/db/src/migrations/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,20 @@
|
|||||||
"when": 1771300567463,
|
"when": 1771300567463,
|
||||||
"tag": "0000_mature_masked_marvel",
|
"tag": "0000_mature_masked_marvel",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 1,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1771349039633,
|
||||||
|
"tag": "0001_fast_northstar",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1771349403162,
|
||||||
|
"tag": "0002_big_zaladane",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
28
packages/db/src/schema/agent_runtime_state.ts
Normal file
28
packages/db/src/schema/agent_runtime_state.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { pgTable, uuid, text, timestamp, jsonb, bigint, index } from "drizzle-orm/pg-core";
|
||||||
|
import { agents } from "./agents.js";
|
||||||
|
import { companies } from "./companies.js";
|
||||||
|
|
||||||
|
export const agentRuntimeState = pgTable(
|
||||||
|
"agent_runtime_state",
|
||||||
|
{
|
||||||
|
agentId: uuid("agent_id").primaryKey().references(() => agents.id),
|
||||||
|
companyId: uuid("company_id").notNull().references(() => companies.id),
|
||||||
|
adapterType: text("adapter_type").notNull(),
|
||||||
|
sessionId: text("session_id"),
|
||||||
|
stateJson: jsonb("state_json").$type<Record<string, unknown>>().notNull().default({}),
|
||||||
|
lastRunId: uuid("last_run_id"),
|
||||||
|
lastRunStatus: text("last_run_status"),
|
||||||
|
totalInputTokens: bigint("total_input_tokens", { mode: "number" }).notNull().default(0),
|
||||||
|
totalOutputTokens: bigint("total_output_tokens", { mode: "number" }).notNull().default(0),
|
||||||
|
totalCachedInputTokens: bigint("total_cached_input_tokens", { mode: "number" }).notNull().default(0),
|
||||||
|
totalCostCents: bigint("total_cost_cents", { mode: "number" }).notNull().default(0),
|
||||||
|
lastError: text("last_error"),
|
||||||
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
},
|
||||||
|
(table) => ({
|
||||||
|
companyAgentIdx: index("agent_runtime_state_company_agent_idx").on(table.companyId, table.agentId),
|
||||||
|
companyUpdatedIdx: index("agent_runtime_state_company_updated_idx").on(table.companyId, table.updatedAt),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
40
packages/db/src/schema/agent_wakeup_requests.ts
Normal file
40
packages/db/src/schema/agent_wakeup_requests.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { pgTable, uuid, text, timestamp, jsonb, integer, index } from "drizzle-orm/pg-core";
|
||||||
|
import { companies } from "./companies.js";
|
||||||
|
import { agents } from "./agents.js";
|
||||||
|
|
||||||
|
export const agentWakeupRequests = pgTable(
|
||||||
|
"agent_wakeup_requests",
|
||||||
|
{
|
||||||
|
id: uuid("id").primaryKey().defaultRandom(),
|
||||||
|
companyId: uuid("company_id").notNull().references(() => companies.id),
|
||||||
|
agentId: uuid("agent_id").notNull().references(() => agents.id),
|
||||||
|
source: text("source").notNull(),
|
||||||
|
triggerDetail: text("trigger_detail"),
|
||||||
|
reason: text("reason"),
|
||||||
|
payload: jsonb("payload").$type<Record<string, unknown>>(),
|
||||||
|
status: text("status").notNull().default("queued"),
|
||||||
|
coalescedCount: integer("coalesced_count").notNull().default(0),
|
||||||
|
requestedByActorType: text("requested_by_actor_type"),
|
||||||
|
requestedByActorId: text("requested_by_actor_id"),
|
||||||
|
idempotencyKey: text("idempotency_key"),
|
||||||
|
runId: uuid("run_id"),
|
||||||
|
requestedAt: timestamp("requested_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
claimedAt: timestamp("claimed_at", { withTimezone: true }),
|
||||||
|
finishedAt: timestamp("finished_at", { withTimezone: true }),
|
||||||
|
error: text("error"),
|
||||||
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
},
|
||||||
|
(table) => ({
|
||||||
|
companyAgentStatusIdx: index("agent_wakeup_requests_company_agent_status_idx").on(
|
||||||
|
table.companyId,
|
||||||
|
table.agentId,
|
||||||
|
table.status,
|
||||||
|
),
|
||||||
|
companyRequestedIdx: index("agent_wakeup_requests_company_requested_idx").on(
|
||||||
|
table.companyId,
|
||||||
|
table.requestedAt,
|
||||||
|
),
|
||||||
|
agentRequestedIdx: index("agent_wakeup_requests_agent_requested_idx").on(table.agentId, table.requestedAt),
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -23,6 +23,7 @@ export const agents = pgTable(
|
|||||||
capabilities: text("capabilities"),
|
capabilities: text("capabilities"),
|
||||||
adapterType: text("adapter_type").notNull().default("process"),
|
adapterType: text("adapter_type").notNull().default("process"),
|
||||||
adapterConfig: jsonb("adapter_config").$type<Record<string, unknown>>().notNull().default({}),
|
adapterConfig: jsonb("adapter_config").$type<Record<string, unknown>>().notNull().default({}),
|
||||||
|
runtimeConfig: jsonb("runtime_config").$type<Record<string, unknown>>().notNull().default({}),
|
||||||
contextMode: text("context_mode").notNull().default("thin"),
|
contextMode: text("context_mode").notNull().default("thin"),
|
||||||
budgetMonthlyCents: integer("budget_monthly_cents").notNull().default(0),
|
budgetMonthlyCents: integer("budget_monthly_cents").notNull().default(0),
|
||||||
spentMonthlyCents: integer("spent_monthly_cents").notNull().default(0),
|
spentMonthlyCents: integer("spent_monthly_cents").notNull().default(0),
|
||||||
|
|||||||
28
packages/db/src/schema/heartbeat_run_events.ts
Normal file
28
packages/db/src/schema/heartbeat_run_events.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { pgTable, uuid, text, timestamp, integer, jsonb, index, bigserial } from "drizzle-orm/pg-core";
|
||||||
|
import { companies } from "./companies.js";
|
||||||
|
import { agents } from "./agents.js";
|
||||||
|
import { heartbeatRuns } from "./heartbeat_runs.js";
|
||||||
|
|
||||||
|
export const heartbeatRunEvents = pgTable(
|
||||||
|
"heartbeat_run_events",
|
||||||
|
{
|
||||||
|
id: bigserial("id", { mode: "number" }).primaryKey(),
|
||||||
|
companyId: uuid("company_id").notNull().references(() => companies.id),
|
||||||
|
runId: uuid("run_id").notNull().references(() => heartbeatRuns.id),
|
||||||
|
agentId: uuid("agent_id").notNull().references(() => agents.id),
|
||||||
|
seq: integer("seq").notNull(),
|
||||||
|
eventType: text("event_type").notNull(),
|
||||||
|
stream: text("stream"),
|
||||||
|
level: text("level"),
|
||||||
|
color: text("color"),
|
||||||
|
message: text("message"),
|
||||||
|
payload: jsonb("payload").$type<Record<string, unknown>>(),
|
||||||
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
},
|
||||||
|
(table) => ({
|
||||||
|
runSeqIdx: index("heartbeat_run_events_run_seq_idx").on(table.runId, table.seq),
|
||||||
|
companyRunIdx: index("heartbeat_run_events_company_run_idx").on(table.companyId, table.runId),
|
||||||
|
companyCreatedIdx: index("heartbeat_run_events_company_created_idx").on(table.companyId, table.createdAt),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { pgTable, uuid, text, timestamp, jsonb, index } from "drizzle-orm/pg-core";
|
import { pgTable, uuid, text, timestamp, jsonb, index, integer, bigint, boolean } from "drizzle-orm/pg-core";
|
||||||
import { companies } from "./companies.js";
|
import { companies } from "./companies.js";
|
||||||
import { agents } from "./agents.js";
|
import { agents } from "./agents.js";
|
||||||
|
import { agentWakeupRequests } from "./agent_wakeup_requests.js";
|
||||||
|
|
||||||
export const heartbeatRuns = pgTable(
|
export const heartbeatRuns = pgTable(
|
||||||
"heartbeat_runs",
|
"heartbeat_runs",
|
||||||
@@ -8,11 +9,27 @@ export const heartbeatRuns = pgTable(
|
|||||||
id: uuid("id").primaryKey().defaultRandom(),
|
id: uuid("id").primaryKey().defaultRandom(),
|
||||||
companyId: uuid("company_id").notNull().references(() => companies.id),
|
companyId: uuid("company_id").notNull().references(() => companies.id),
|
||||||
agentId: uuid("agent_id").notNull().references(() => agents.id),
|
agentId: uuid("agent_id").notNull().references(() => agents.id),
|
||||||
invocationSource: text("invocation_source").notNull().default("manual"),
|
invocationSource: text("invocation_source").notNull().default("on_demand"),
|
||||||
|
triggerDetail: text("trigger_detail"),
|
||||||
status: text("status").notNull().default("queued"),
|
status: text("status").notNull().default("queued"),
|
||||||
startedAt: timestamp("started_at", { withTimezone: true }),
|
startedAt: timestamp("started_at", { withTimezone: true }),
|
||||||
finishedAt: timestamp("finished_at", { withTimezone: true }),
|
finishedAt: timestamp("finished_at", { withTimezone: true }),
|
||||||
error: text("error"),
|
error: text("error"),
|
||||||
|
wakeupRequestId: uuid("wakeup_request_id").references(() => agentWakeupRequests.id),
|
||||||
|
exitCode: integer("exit_code"),
|
||||||
|
signal: text("signal"),
|
||||||
|
usageJson: jsonb("usage_json").$type<Record<string, unknown>>(),
|
||||||
|
resultJson: jsonb("result_json").$type<Record<string, unknown>>(),
|
||||||
|
sessionIdBefore: text("session_id_before"),
|
||||||
|
sessionIdAfter: text("session_id_after"),
|
||||||
|
logStore: text("log_store"),
|
||||||
|
logRef: text("log_ref"),
|
||||||
|
logBytes: bigint("log_bytes", { mode: "number" }),
|
||||||
|
logSha256: text("log_sha256"),
|
||||||
|
logCompressed: boolean("log_compressed").notNull().default(false),
|
||||||
|
stdoutExcerpt: text("stdout_excerpt"),
|
||||||
|
stderrExcerpt: text("stderr_excerpt"),
|
||||||
|
errorCode: text("error_code"),
|
||||||
externalRunId: text("external_run_id"),
|
externalRunId: text("external_run_id"),
|
||||||
contextSnapshot: jsonb("context_snapshot").$type<Record<string, unknown>>(),
|
contextSnapshot: jsonb("context_snapshot").$type<Record<string, unknown>>(),
|
||||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
export { companies } from "./companies.js";
|
export { companies } from "./companies.js";
|
||||||
export { agents } from "./agents.js";
|
export { agents } from "./agents.js";
|
||||||
export { agentApiKeys } from "./agent_api_keys.js";
|
export { agentApiKeys } from "./agent_api_keys.js";
|
||||||
|
export { agentRuntimeState } from "./agent_runtime_state.js";
|
||||||
|
export { agentWakeupRequests } from "./agent_wakeup_requests.js";
|
||||||
export { projects } from "./projects.js";
|
export { projects } from "./projects.js";
|
||||||
export { goals } from "./goals.js";
|
export { goals } from "./goals.js";
|
||||||
export { issues } from "./issues.js";
|
export { issues } from "./issues.js";
|
||||||
export { issueComments } from "./issue_comments.js";
|
export { issueComments } from "./issue_comments.js";
|
||||||
export { heartbeatRuns } from "./heartbeat_runs.js";
|
export { heartbeatRuns } from "./heartbeat_runs.js";
|
||||||
|
export { heartbeatRunEvents } from "./heartbeat_run_events.js";
|
||||||
export { costEvents } from "./cost_events.js";
|
export { costEvents } from "./cost_events.js";
|
||||||
export { approvals } from "./approvals.js";
|
export { approvals } from "./approvals.js";
|
||||||
export { activityLog } from "./activity_log.js";
|
export { activityLog } from "./activity_log.js";
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export type AgentStatus = (typeof AGENT_STATUSES)[number];
|
|||||||
export const AGENT_CONTEXT_MODES = ["thin", "fat"] as const;
|
export const AGENT_CONTEXT_MODES = ["thin", "fat"] as const;
|
||||||
export type AgentContextMode = (typeof AGENT_CONTEXT_MODES)[number];
|
export type AgentContextMode = (typeof AGENT_CONTEXT_MODES)[number];
|
||||||
|
|
||||||
export const AGENT_ADAPTER_TYPES = ["process", "http"] as const;
|
export const AGENT_ADAPTER_TYPES = ["process", "http", "claude_local", "codex_local"] as const;
|
||||||
export type AgentAdapterType = (typeof AGENT_ADAPTER_TYPES)[number];
|
export type AgentAdapterType = (typeof AGENT_ADAPTER_TYPES)[number];
|
||||||
|
|
||||||
export const AGENT_ROLES = [
|
export const AGENT_ROLES = [
|
||||||
@@ -67,9 +67,28 @@ export type ApprovalType = (typeof APPROVAL_TYPES)[number];
|
|||||||
export const APPROVAL_STATUSES = ["pending", "approved", "rejected", "cancelled"] as const;
|
export const APPROVAL_STATUSES = ["pending", "approved", "rejected", "cancelled"] as const;
|
||||||
export type ApprovalStatus = (typeof APPROVAL_STATUSES)[number];
|
export type ApprovalStatus = (typeof APPROVAL_STATUSES)[number];
|
||||||
|
|
||||||
export const HEARTBEAT_INVOCATION_SOURCES = ["scheduler", "manual", "callback"] as const;
|
export const HEARTBEAT_INVOCATION_SOURCES = [
|
||||||
|
"timer",
|
||||||
|
"assignment",
|
||||||
|
"on_demand",
|
||||||
|
"automation",
|
||||||
|
] as const;
|
||||||
export type HeartbeatInvocationSource = (typeof HEARTBEAT_INVOCATION_SOURCES)[number];
|
export type HeartbeatInvocationSource = (typeof HEARTBEAT_INVOCATION_SOURCES)[number];
|
||||||
|
|
||||||
|
export const WAKEUP_TRIGGER_DETAILS = ["manual", "ping", "callback", "system"] as const;
|
||||||
|
export type WakeupTriggerDetail = (typeof WAKEUP_TRIGGER_DETAILS)[number];
|
||||||
|
|
||||||
|
export const WAKEUP_REQUEST_STATUSES = [
|
||||||
|
"queued",
|
||||||
|
"claimed",
|
||||||
|
"coalesced",
|
||||||
|
"skipped",
|
||||||
|
"completed",
|
||||||
|
"failed",
|
||||||
|
"cancelled",
|
||||||
|
] as const;
|
||||||
|
export type WakeupRequestStatus = (typeof WAKEUP_REQUEST_STATUSES)[number];
|
||||||
|
|
||||||
export const HEARTBEAT_RUN_STATUSES = [
|
export const HEARTBEAT_RUN_STATUSES = [
|
||||||
"queued",
|
"queued",
|
||||||
"running",
|
"running",
|
||||||
@@ -79,3 +98,13 @@ export const HEARTBEAT_RUN_STATUSES = [
|
|||||||
"timed_out",
|
"timed_out",
|
||||||
] as const;
|
] as const;
|
||||||
export type HeartbeatRunStatus = (typeof HEARTBEAT_RUN_STATUSES)[number];
|
export type HeartbeatRunStatus = (typeof HEARTBEAT_RUN_STATUSES)[number];
|
||||||
|
|
||||||
|
export const LIVE_EVENT_TYPES = [
|
||||||
|
"heartbeat.run.queued",
|
||||||
|
"heartbeat.run.status",
|
||||||
|
"heartbeat.run.event",
|
||||||
|
"heartbeat.run.log",
|
||||||
|
"agent.status",
|
||||||
|
"activity.logged",
|
||||||
|
] as const;
|
||||||
|
export type LiveEventType = (typeof LIVE_EVENT_TYPES)[number];
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ export {
|
|||||||
APPROVAL_STATUSES,
|
APPROVAL_STATUSES,
|
||||||
HEARTBEAT_INVOCATION_SOURCES,
|
HEARTBEAT_INVOCATION_SOURCES,
|
||||||
HEARTBEAT_RUN_STATUSES,
|
HEARTBEAT_RUN_STATUSES,
|
||||||
|
WAKEUP_TRIGGER_DETAILS,
|
||||||
|
WAKEUP_REQUEST_STATUSES,
|
||||||
|
LIVE_EVENT_TYPES,
|
||||||
type CompanyStatus,
|
type CompanyStatus,
|
||||||
type AgentStatus,
|
type AgentStatus,
|
||||||
type AgentContextMode,
|
type AgentContextMode,
|
||||||
@@ -27,6 +30,9 @@ export {
|
|||||||
type ApprovalStatus,
|
type ApprovalStatus,
|
||||||
type HeartbeatInvocationSource,
|
type HeartbeatInvocationSource,
|
||||||
type HeartbeatRunStatus,
|
type HeartbeatRunStatus,
|
||||||
|
type WakeupTriggerDetail,
|
||||||
|
type WakeupRequestStatus,
|
||||||
|
type LiveEventType,
|
||||||
} from "./constants.js";
|
} from "./constants.js";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
@@ -41,6 +47,10 @@ export type {
|
|||||||
CostEvent,
|
CostEvent,
|
||||||
CostSummary,
|
CostSummary,
|
||||||
HeartbeatRun,
|
HeartbeatRun,
|
||||||
|
HeartbeatRunEvent,
|
||||||
|
AgentRuntimeState,
|
||||||
|
AgentWakeupRequest,
|
||||||
|
LiveEvent,
|
||||||
DashboardSummary,
|
DashboardSummary,
|
||||||
ActivityEvent,
|
ActivityEvent,
|
||||||
} from "./types/index.js";
|
} from "./types/index.js";
|
||||||
@@ -53,9 +63,11 @@ export {
|
|||||||
createAgentSchema,
|
createAgentSchema,
|
||||||
updateAgentSchema,
|
updateAgentSchema,
|
||||||
createAgentKeySchema,
|
createAgentKeySchema,
|
||||||
|
wakeAgentSchema,
|
||||||
type CreateAgent,
|
type CreateAgent,
|
||||||
type UpdateAgent,
|
type UpdateAgent,
|
||||||
type CreateAgentKey,
|
type CreateAgentKey,
|
||||||
|
type WakeAgent,
|
||||||
createProjectSchema,
|
createProjectSchema,
|
||||||
updateProjectSchema,
|
updateProjectSchema,
|
||||||
type CreateProject,
|
type CreateProject,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export interface Agent {
|
|||||||
capabilities: string | null;
|
capabilities: string | null;
|
||||||
adapterType: AgentAdapterType;
|
adapterType: AgentAdapterType;
|
||||||
adapterConfig: Record<string, unknown>;
|
adapterConfig: Record<string, unknown>;
|
||||||
|
runtimeConfig: Record<string, unknown>;
|
||||||
contextMode: AgentContextMode;
|
contextMode: AgentContextMode;
|
||||||
budgetMonthlyCents: number;
|
budgetMonthlyCents: number;
|
||||||
spentMonthlyCents: number;
|
spentMonthlyCents: number;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import type {
|
import type {
|
||||||
HeartbeatInvocationSource,
|
HeartbeatInvocationSource,
|
||||||
HeartbeatRunStatus,
|
HeartbeatRunStatus,
|
||||||
|
WakeupTriggerDetail,
|
||||||
|
WakeupRequestStatus,
|
||||||
} from "../constants.js";
|
} from "../constants.js";
|
||||||
|
|
||||||
export interface HeartbeatRun {
|
export interface HeartbeatRun {
|
||||||
@@ -8,12 +10,82 @@ export interface HeartbeatRun {
|
|||||||
companyId: string;
|
companyId: string;
|
||||||
agentId: string;
|
agentId: string;
|
||||||
invocationSource: HeartbeatInvocationSource;
|
invocationSource: HeartbeatInvocationSource;
|
||||||
|
triggerDetail: WakeupTriggerDetail | null;
|
||||||
status: HeartbeatRunStatus;
|
status: HeartbeatRunStatus;
|
||||||
startedAt: Date | null;
|
startedAt: Date | null;
|
||||||
finishedAt: Date | null;
|
finishedAt: Date | null;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
|
wakeupRequestId: string | null;
|
||||||
|
exitCode: number | null;
|
||||||
|
signal: string | null;
|
||||||
|
usageJson: Record<string, unknown> | null;
|
||||||
|
resultJson: Record<string, unknown> | null;
|
||||||
|
sessionIdBefore: string | null;
|
||||||
|
sessionIdAfter: string | null;
|
||||||
|
logStore: string | null;
|
||||||
|
logRef: string | null;
|
||||||
|
logBytes: number | null;
|
||||||
|
logSha256: string | null;
|
||||||
|
logCompressed: boolean;
|
||||||
|
stdoutExcerpt: string | null;
|
||||||
|
stderrExcerpt: string | null;
|
||||||
|
errorCode: string | null;
|
||||||
externalRunId: string | null;
|
externalRunId: string | null;
|
||||||
contextSnapshot: Record<string, unknown> | null;
|
contextSnapshot: Record<string, unknown> | null;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HeartbeatRunEvent {
|
||||||
|
id: number;
|
||||||
|
companyId: string;
|
||||||
|
runId: string;
|
||||||
|
agentId: string;
|
||||||
|
seq: number;
|
||||||
|
eventType: string;
|
||||||
|
stream: "system" | "stdout" | "stderr" | null;
|
||||||
|
level: "info" | "warn" | "error" | null;
|
||||||
|
color: string | null;
|
||||||
|
message: string | null;
|
||||||
|
payload: Record<string, unknown> | null;
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentRuntimeState {
|
||||||
|
agentId: string;
|
||||||
|
companyId: string;
|
||||||
|
adapterType: string;
|
||||||
|
sessionId: string | null;
|
||||||
|
stateJson: Record<string, unknown>;
|
||||||
|
lastRunId: string | null;
|
||||||
|
lastRunStatus: string | null;
|
||||||
|
totalInputTokens: number;
|
||||||
|
totalOutputTokens: number;
|
||||||
|
totalCachedInputTokens: number;
|
||||||
|
totalCostCents: number;
|
||||||
|
lastError: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentWakeupRequest {
|
||||||
|
id: string;
|
||||||
|
companyId: string;
|
||||||
|
agentId: string;
|
||||||
|
source: HeartbeatInvocationSource;
|
||||||
|
triggerDetail: WakeupTriggerDetail | null;
|
||||||
|
reason: string | null;
|
||||||
|
payload: Record<string, unknown> | null;
|
||||||
|
status: WakeupRequestStatus;
|
||||||
|
coalescedCount: number;
|
||||||
|
requestedByActorType: "user" | "agent" | "system" | null;
|
||||||
|
requestedByActorId: string | null;
|
||||||
|
idempotencyKey: string | null;
|
||||||
|
runId: string | null;
|
||||||
|
requestedAt: Date;
|
||||||
|
claimedAt: Date | null;
|
||||||
|
finishedAt: Date | null;
|
||||||
|
error: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ export type { Issue, IssueComment } from "./issue.js";
|
|||||||
export type { Goal } from "./goal.js";
|
export type { Goal } from "./goal.js";
|
||||||
export type { Approval } from "./approval.js";
|
export type { Approval } from "./approval.js";
|
||||||
export type { CostEvent, CostSummary } from "./cost.js";
|
export type { CostEvent, CostSummary } from "./cost.js";
|
||||||
export type { HeartbeatRun } from "./heartbeat.js";
|
export type {
|
||||||
|
HeartbeatRun,
|
||||||
|
HeartbeatRunEvent,
|
||||||
|
AgentRuntimeState,
|
||||||
|
AgentWakeupRequest,
|
||||||
|
} from "./heartbeat.js";
|
||||||
|
export type { LiveEvent } from "./live.js";
|
||||||
export type { DashboardSummary } from "./dashboard.js";
|
export type { DashboardSummary } from "./dashboard.js";
|
||||||
export type { ActivityEvent } from "./activity.js";
|
export type { ActivityEvent } from "./activity.js";
|
||||||
|
|||||||
9
packages/shared/src/types/live.ts
Normal file
9
packages/shared/src/types/live.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import type { LiveEventType } from "../constants.js";
|
||||||
|
|
||||||
|
export interface LiveEvent {
|
||||||
|
id: number;
|
||||||
|
companyId: string;
|
||||||
|
type: LiveEventType;
|
||||||
|
createdAt: string;
|
||||||
|
payload: Record<string, unknown>;
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ export const createAgentSchema = z.object({
|
|||||||
capabilities: z.string().optional().nullable(),
|
capabilities: z.string().optional().nullable(),
|
||||||
adapterType: z.enum(AGENT_ADAPTER_TYPES).optional().default("process"),
|
adapterType: z.enum(AGENT_ADAPTER_TYPES).optional().default("process"),
|
||||||
adapterConfig: z.record(z.unknown()).optional().default({}),
|
adapterConfig: z.record(z.unknown()).optional().default({}),
|
||||||
|
runtimeConfig: z.record(z.unknown()).optional().default({}),
|
||||||
contextMode: z.enum(AGENT_CONTEXT_MODES).optional().default("thin"),
|
contextMode: z.enum(AGENT_CONTEXT_MODES).optional().default("thin"),
|
||||||
budgetMonthlyCents: z.number().int().nonnegative().optional().default(0),
|
budgetMonthlyCents: z.number().int().nonnegative().optional().default(0),
|
||||||
metadata: z.record(z.unknown()).optional().nullable(),
|
metadata: z.record(z.unknown()).optional().nullable(),
|
||||||
@@ -35,3 +36,13 @@ export const createAgentKeySchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export type CreateAgentKey = z.infer<typeof createAgentKeySchema>;
|
export type CreateAgentKey = z.infer<typeof createAgentKeySchema>;
|
||||||
|
|
||||||
|
export const wakeAgentSchema = z.object({
|
||||||
|
source: z.enum(["timer", "assignment", "on_demand", "automation"]).optional().default("on_demand"),
|
||||||
|
triggerDetail: z.enum(["manual", "ping", "callback", "system"]).optional(),
|
||||||
|
reason: z.string().optional().nullable(),
|
||||||
|
payload: z.record(z.unknown()).optional().nullable(),
|
||||||
|
idempotencyKey: z.string().optional().nullable(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type WakeAgent = z.infer<typeof wakeAgentSchema>;
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ export {
|
|||||||
createAgentSchema,
|
createAgentSchema,
|
||||||
updateAgentSchema,
|
updateAgentSchema,
|
||||||
createAgentKeySchema,
|
createAgentKeySchema,
|
||||||
|
wakeAgentSchema,
|
||||||
type CreateAgent,
|
type CreateAgent,
|
||||||
type UpdateAgent,
|
type UpdateAgent,
|
||||||
type CreateAgentKey,
|
type CreateAgentKey,
|
||||||
|
type WakeAgent,
|
||||||
} from "./agent.js";
|
} from "./agent.js";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
35
pnpm-lock.yaml
generated
35
pnpm-lock.yaml
generated
@@ -73,6 +73,9 @@ importers:
|
|||||||
pino-http:
|
pino-http:
|
||||||
specifier: ^10.4.0
|
specifier: ^10.4.0
|
||||||
version: 10.5.0
|
version: 10.5.0
|
||||||
|
ws:
|
||||||
|
specifier: ^8.19.0
|
||||||
|
version: 8.19.0
|
||||||
zod:
|
zod:
|
||||||
specifier: ^3.24.2
|
specifier: ^3.24.2
|
||||||
version: 3.25.76
|
version: 3.25.76
|
||||||
@@ -107,6 +110,9 @@ importers:
|
|||||||
'@radix-ui/react-slot':
|
'@radix-ui/react-slot':
|
||||||
specifier: ^1.2.4
|
specifier: ^1.2.4
|
||||||
version: 1.2.4(@types/react@19.2.14)(react@19.2.4)
|
version: 1.2.4(@types/react@19.2.14)(react@19.2.4)
|
||||||
|
'@tanstack/react-query':
|
||||||
|
specifier: ^5.90.21
|
||||||
|
version: 5.90.21(react@19.2.4)
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.1
|
specifier: ^0.7.1
|
||||||
version: 0.7.1
|
version: 0.7.1
|
||||||
@@ -1664,6 +1670,14 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: ^5.2.0 || ^6 || ^7
|
vite: ^5.2.0 || ^6 || ^7
|
||||||
|
|
||||||
|
'@tanstack/query-core@5.90.20':
|
||||||
|
resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==}
|
||||||
|
|
||||||
|
'@tanstack/react-query@5.90.21':
|
||||||
|
resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^18 || ^19
|
||||||
|
|
||||||
'@types/babel__core@7.20.5':
|
'@types/babel__core@7.20.5':
|
||||||
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
||||||
|
|
||||||
@@ -2819,6 +2833,18 @@ packages:
|
|||||||
wrappy@1.0.2:
|
wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
|
ws@8.19.0:
|
||||||
|
resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
bufferutil: ^4.0.1
|
||||||
|
utf-8-validate: '>=5.0.2'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
bufferutil:
|
||||||
|
optional: true
|
||||||
|
utf-8-validate:
|
||||||
|
optional: true
|
||||||
|
|
||||||
yallist@3.1.1:
|
yallist@3.1.1:
|
||||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||||
|
|
||||||
@@ -4118,6 +4144,13 @@ snapshots:
|
|||||||
tailwindcss: 4.1.18
|
tailwindcss: 4.1.18
|
||||||
vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)
|
vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)
|
||||||
|
|
||||||
|
'@tanstack/query-core@5.90.20': {}
|
||||||
|
|
||||||
|
'@tanstack/react-query@5.90.21(react@19.2.4)':
|
||||||
|
dependencies:
|
||||||
|
'@tanstack/query-core': 5.90.20
|
||||||
|
react: 19.2.4
|
||||||
|
|
||||||
'@types/babel__core@7.20.5':
|
'@types/babel__core@7.20.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.29.0
|
'@babel/parser': 7.29.0
|
||||||
@@ -5310,6 +5343,8 @@ snapshots:
|
|||||||
|
|
||||||
wrappy@1.0.2: {}
|
wrappy@1.0.2: {}
|
||||||
|
|
||||||
|
ws@8.19.0: {}
|
||||||
|
|
||||||
yallist@3.1.1: {}
|
yallist@3.1.1: {}
|
||||||
|
|
||||||
zod@3.25.76: {}
|
zod@3.25.76: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user