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:
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"),
|
||||
adapterType: text("adapter_type").notNull().default("process"),
|
||||
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"),
|
||||
budgetMonthlyCents: integer("budget_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 { agents } from "./agents.js";
|
||||
import { agentWakeupRequests } from "./agent_wakeup_requests.js";
|
||||
|
||||
export const heartbeatRuns = pgTable(
|
||||
"heartbeat_runs",
|
||||
@@ -8,11 +9,27 @@ export const heartbeatRuns = pgTable(
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
companyId: uuid("company_id").notNull().references(() => companies.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"),
|
||||
startedAt: timestamp("started_at", { withTimezone: true }),
|
||||
finishedAt: timestamp("finished_at", { withTimezone: true }),
|
||||
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"),
|
||||
contextSnapshot: jsonb("context_snapshot").$type<Record<string, unknown>>(),
|
||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
export { companies } from "./companies.js";
|
||||
export { agents } from "./agents.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 { goals } from "./goals.js";
|
||||
export { issues } from "./issues.js";
|
||||
export { issueComments } from "./issue_comments.js";
|
||||
export { heartbeatRuns } from "./heartbeat_runs.js";
|
||||
export { heartbeatRunEvents } from "./heartbeat_run_events.js";
|
||||
export { costEvents } from "./cost_events.js";
|
||||
export { approvals } from "./approvals.js";
|
||||
export { activityLog } from "./activity_log.js";
|
||||
|
||||
Reference in New Issue
Block a user