Agent loop state machine refactor, unified LLM interface, and UI improvements
- Rewrite agent loop as Planning→Executing(N)→Completed state machine with per-step context isolation to prevent token explosion - Split tools and prompts by phase (planning vs execution) - Add advance_step/save_memo tools for step transitions and cross-step memory - Unify LLM interface: remove duplicate types, single chat_with_tools path - Add UTF-8 safe truncation (truncate_str) to prevent panics on Chinese text - Extract CreateForm component, add auto-scroll to execution log - Add report generation with app access URL, non-blocking title generation - Add timer system, file serving, app proxy, exec module - Update Dockerfile with uv, deployment config Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
61
src/db.rs
61
src/db.rs
@@ -47,6 +47,7 @@ impl Database {
|
||||
workflow_id TEXT NOT NULL REFERENCES workflows(id),
|
||||
step_order INTEGER NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
command TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
output TEXT NOT NULL DEFAULT ''
|
||||
)"
|
||||
@@ -65,6 +66,49 @@ impl Database {
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
// Migration: add report column to workflows
|
||||
let _ = sqlx::query(
|
||||
"ALTER TABLE workflows ADD COLUMN report TEXT NOT NULL DEFAULT ''"
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await;
|
||||
|
||||
// Migration: add created_at to plan_steps
|
||||
let _ = sqlx::query(
|
||||
"ALTER TABLE plan_steps ADD COLUMN created_at TEXT NOT NULL DEFAULT ''"
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await;
|
||||
|
||||
// Migration: add kind to plan_steps ('plan' or 'log')
|
||||
let _ = sqlx::query(
|
||||
"ALTER TABLE plan_steps ADD COLUMN kind TEXT NOT NULL DEFAULT 'log'"
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await;
|
||||
|
||||
// Migration: add plan_step_id to plan_steps (log entries reference their parent plan step)
|
||||
let _ = sqlx::query(
|
||||
"ALTER TABLE plan_steps ADD COLUMN plan_step_id TEXT NOT NULL DEFAULT ''"
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await;
|
||||
|
||||
sqlx::query(
|
||||
"CREATE TABLE IF NOT EXISTS timers (
|
||||
id TEXT PRIMARY KEY,
|
||||
project_id TEXT NOT NULL REFERENCES projects(id),
|
||||
name TEXT NOT NULL,
|
||||
interval_secs INTEGER NOT NULL,
|
||||
requirement TEXT NOT NULL,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
last_run_at TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)"
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -85,6 +129,7 @@ pub struct Workflow {
|
||||
pub requirement: String,
|
||||
pub status: String,
|
||||
pub created_at: String,
|
||||
pub report: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
||||
@@ -93,8 +138,12 @@ pub struct PlanStep {
|
||||
pub workflow_id: String,
|
||||
pub step_order: i32,
|
||||
pub description: String,
|
||||
pub command: String,
|
||||
pub status: String,
|
||||
pub output: String,
|
||||
pub created_at: String,
|
||||
pub kind: String,
|
||||
pub plan_step_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
||||
@@ -104,3 +153,15 @@ pub struct Comment {
|
||||
pub content: String,
|
||||
pub created_at: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
||||
pub struct Timer {
|
||||
pub id: String,
|
||||
pub project_id: String,
|
||||
pub name: String,
|
||||
pub interval_secs: i64,
|
||||
pub requirement: String,
|
||||
pub enabled: bool,
|
||||
pub last_run_at: String,
|
||||
pub created_at: String,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user