Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions deploy/policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,8 @@ venue_instructions:
# #app-alerts
C099YDUFQ9Z: >-
prod alert feed; noah follows it religiously. you are the only triager here, and the
ticket is where triage lands (real receipts from ops_read/github_read, not
channel-history guesses). suspected user-facing or revenue impact belongs to
<@U096GG0F354>. Every alert is worth independent investigation — do not assume
another person's ownership, a prior false-positive, or similarity to an older
alert covers a new one; inspect each on its own and respond with the finding.
Narrow exception: nightly VRT alert/workflow posts are dead signal unless Noah
explicitly says they are revived.
ticket is where triage lands (real receipts, not channel-history guesses). suspected
user-facing or revenue impact belongs to <@U096GG0F354>. nightly VRT posts are dead signal.
# #releases-eng
C0BAQK9PECA: >-
noah and anya run the train; julia runs qa. when the release train posts a release ready
Expand Down
4 changes: 4 additions & 0 deletions drizzle/0004_conversations_last_woken.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE `conversations` ADD `last` text NOT NULL;--> statement-breakpoint
ALTER TABLE `conversations` ADD `woken` integer NOT NULL;--> statement-breakpoint
ALTER TABLE `conversations` DROP COLUMN `judged`;--> statement-breakpoint
ALTER TABLE `conversations` DROP COLUMN `wake_why`;
274 changes: 274 additions & 0 deletions drizzle/meta/0004_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
{
"version": "6",
"dialect": "sqlite",
"id": "0be1bb01-172d-4215-9da5-e36b2411ccd1",
"prevId": "2698e3b3-5c25-42db-8694-53e2d539cddc",
"tables": {
"conversations": {
"name": "conversations",
"columns": {
"channel": {
"name": "channel",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"thread_ts": {
"name": "thread_ts",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"since": {
"name": "since",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"last": {
"name": "last",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"direct": {
"name": "direct",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"woken": {
"name": "woken",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"conversations_channel_thread_ts_pk": {
"columns": ["channel", "thread_ts"],
"name": "conversations_channel_thread_ts_pk"
}
},
"uniqueConstraints": {},
"checkConstraints": {}
},
"muted_threads": {
"name": "muted_threads",
"columns": {
"channel": {
"name": "channel",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"thread_ts": {
"name": "thread_ts",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"why": {
"name": "why",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"at": {
"name": "at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"muted_threads_channel_thread_ts_pk": {
"columns": ["channel", "thread_ts"],
"name": "muted_threads_channel_thread_ts_pk"
}
},
"uniqueConstraints": {},
"checkConstraints": {}
},
"tasks": {
"name": "tasks",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"spec": {
"name": "spec",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"waiting_on": {
"name": "waiting_on",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"waiting_why": {
"name": "waiting_why",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"wake_at": {
"name": "wake_at",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"outcome": {
"name": "outcome",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"report": {
"name": "report",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"seen_at": {
"name": "seen_at",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"channel": {
"name": "channel",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"thread_ts": {
"name": "thread_ts",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"tier": {
"name": "tier",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'high'"
},
"interruptions": {
"name": "interruptions",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": 0
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"opened_at": {
"name": "opened_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"tasks_dispatch": {
"name": "tasks_dispatch",
"columns": ["status", "opened_at"],
"isUnique": false
},
"tasks_due": {
"name": "tasks_due",
"columns": ["status", "wake_at"],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {
"tasks_waiting_on": {
"name": "tasks_waiting_on",
"value": "(\"tasks\".\"status\" = 'waiting') = (\"tasks\".\"waiting_on\" IS NOT NULL)"
},
"tasks_wake_at": {
"name": "tasks_wake_at",
"value": "\"tasks\".\"wake_at\" IS NULL OR \"tasks\".\"status\" = 'waiting'"
},
"tasks_waiting_why": {
"name": "tasks_waiting_why",
"value": "\"tasks\".\"waiting_on\" IS NOT 'human' OR (\"tasks\".\"waiting_why\" IS NOT NULL AND trim(\"tasks\".\"waiting_why\") <> '')"
},
"tasks_outcome": {
"name": "tasks_outcome",
"value": "(\"tasks\".\"status\" = 'done') = (\"tasks\".\"outcome\" IS NOT NULL)"
},
"tasks_report": {
"name": "tasks_report",
"value": "\"tasks\".\"status\" <> 'done' OR (\"tasks\".\"report\" IS NOT NULL AND trim(\"tasks\".\"report\") <> '')"
}
}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}
7 changes: 7 additions & 0 deletions drizzle/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
"when": 1788812956600,
"tag": "0003_conversations",
"breakpoints": true
},
{
"idx": 4,
"version": "6",
"when": 1788904893450,
"tag": "0004_conversations_last_woken",
"breakpoints": true
}
]
}
19 changes: 7 additions & 12 deletions src/codex.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { codexThread, maybeRotateGateway, type Tools } from "@bevyl-ai/agent-tools";
import { inject, singleton } from "tsyringe";
import { LedgerService } from "./ledger-service";
import type { Task } from "./ledger/schema";
import { log } from "./log";
import { POLICY, type Policy } from "./policy";
Expand All @@ -16,30 +15,23 @@ export class Codex {
constructor(
@inject(POLICY) private readonly policy: Policy,
private readonly soul: Soul,
private readonly ledger: LedgerService,
private readonly workspaces: Workspaces,
) {}

respond(prompt: string): Promise<void> {
return this.once("resident", residentTools, {}, this.policy.turns.timeout_ms, prompt);
}

async shouldAgentRespond(prompt: string): Promise<boolean> {
await this.once("ear", earTools, this.policy.models.low, this.policy.turns.timeout_ms, prompt);
return this.ledger.wantsResponse();
judge(prompt: string): Promise<void> {
return this.once("ear", earTools, this.policy.models.low, this.policy.turns.timeout_ms, prompt);
}

async runWorker(taskId: string, tier: Task["tier"], next: () => string | null): Promise<void> {
const { executions, models } = this.policy;
const { thread, close } = await this.thread("worker", workerTools(taskId), models[tier]);
try {
for (let prompt = next(); prompt !== null; prompt = next())
await this.turn(thread, taskId, prompt, executions.turn_timeout_ms).catch(
(error: unknown) => {
this.ledger.interrupt(taskId);
throw error;
},
);
await this.turn(thread, taskId, prompt, executions.turn_timeout_ms);
} finally {
close();
}
Expand Down Expand Up @@ -72,7 +64,10 @@ export class Codex {
if (event.type === "item.completed") {
const { item } = event;
if (item.type === "command_execution") log.info(label, { line: `$ ${item.command}` });
else if (item.type === "mcp_tool_call") log.info(label, { line: `⚙ ${item.tool}` });
else if (item.type === "mcp_tool_call")
log.info(label, {
line: `⚙ ${item.tool} ${JSON.stringify(item.arguments)}${item.error ? ` ✗ ${item.error.message}` : ""}`,
});
else if (item.type === "agent_message") log.info(label, { line: `● ${item.text}` });
} else if (event.type === "turn.failed") {
maybeRotateGateway({ reason: event.error.message });
Expand Down
Loading
Loading