Agents: CRUD, DB table, session binding, replace model picker
- agents table with name, avatar, description, model, persona, instructions, soft-delete - AgentEndpoint (GET/POST/PUT/DELETE /api/agents) - sessions + chains now reference agent_id - ChatEndpoint resolves agent from session (no agent = no chat) - system prompt built from agent persona + instructions - frontend: agent editor with avatar upload, agent cards on dashboard - session: agent dropdown replaces model picker, choice persisted
This commit is contained in:
1 parent
0cd2d51d32
commit
449c872296
16 files changed
+552
-46
No files matched your search
@@ -78,10 +78,83 @@ public class DatabaseService
|
||||
FOREIGN KEY (chain_id) REFERENCES chains(chain_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agents (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
agent_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
avatar TEXT,
|
||||
description TEXT,
|
||||
model TEXT NOT NULL DEFAULT 'sonnet',
|
||||
persona TEXT,
|
||||
instructions TEXT,
|
||||
is_deleted INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_chains_session ON chains(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chains_archive ON chains(archive_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_chain ON messages(chain_id);
|
||||
");
|
||||
|
||||
// Migrations
|
||||
TryAddColumn(conn, "sessions", "agent_id", "TEXT");
|
||||
TryAddColumn(conn, "chains", "agent_id", "TEXT");
|
||||
}
|
||||
|
||||
private void TryAddColumn(SqliteConnection conn, string table, string column, string type)
|
||||
{
|
||||
try { conn.Execute($"ALTER TABLE {table} ADD COLUMN {column} {type}"); }
|
||||
catch { /* column already exists */ }
|
||||
}
|
||||
|
||||
// ── Agents ──
|
||||
|
||||
public async Task<AgentRecord> CreateAgent(AgentRecord agent)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
agent.AgentId = Guid.NewGuid().ToString("N");
|
||||
agent.CreatedAt = now;
|
||||
agent.UpdatedAt = now;
|
||||
await conn.ExecuteAsync(@"
|
||||
INSERT INTO agents (agent_id, name, avatar, description, model, persona, instructions, is_deleted, created_at, updated_at)
|
||||
VALUES (@AgentId, @Name, @Avatar, @Description, @Model, @Persona, @Instructions, 0, @CreatedAt, @UpdatedAt)
|
||||
", agent);
|
||||
return agent;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AgentRecord>> GetAgents()
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<AgentRecord>(
|
||||
"SELECT * FROM agents WHERE is_deleted = 0 ORDER BY name");
|
||||
}
|
||||
|
||||
public async Task<AgentRecord> GetAgent(string agentId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QuerySingleOrDefaultAsync<AgentRecord>(
|
||||
"SELECT * FROM agents WHERE agent_id = @agentId AND is_deleted = 0", new { agentId });
|
||||
}
|
||||
|
||||
public async Task UpdateAgent(AgentRecord agent)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
agent.UpdatedAt = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
UPDATE agents SET name = @Name, avatar = @Avatar, description = @Description,
|
||||
model = @Model, persona = @Persona, instructions = @Instructions, updated_at = @UpdatedAt
|
||||
WHERE agent_id = @AgentId
|
||||
", agent);
|
||||
}
|
||||
|
||||
public async Task DeleteAgent(string agentId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE agents SET is_deleted = 1, updated_at = @now WHERE agent_id = @agentId",
|
||||
new { agentId, now = DateTime.UtcNow.ToString("o") });
|
||||
}
|
||||
|
||||
// ── Sessions ──
|
||||
@@ -134,6 +207,14 @@ public class DatabaseService
|
||||
new { sessionId, name, now = DateTime.UtcNow.ToString("o") });
|
||||
}
|
||||
|
||||
public async Task UpdateSessionAgent(string sessionId, string agentId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE sessions SET agent_id = @agentId, updated_at = @now WHERE session_id = @sessionId",
|
||||
new { sessionId, agentId, now = DateTime.UtcNow.ToString("o") });
|
||||
}
|
||||
|
||||
// ── Archives ──
|
||||
|
||||
public async Task<ArchiveRecord> CreateArchive(string sessionId, string name = null)
|
||||
@@ -195,8 +276,8 @@ public class DatabaseService
|
||||
using var conn = CreateConnection();
|
||||
chain.CreatedAt = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
INSERT INTO chains (chain_id, session_id, archive_id, model, system_prompt, input_tokens, output_tokens, iterations, stop_reason, duration_ms, created_at)
|
||||
VALUES (@ChainId, @SessionId, @ArchiveId, @Model, @SystemPrompt, @InputTokens, @OutputTokens, @Iterations, @StopReason, @DurationMs, @CreatedAt)
|
||||
INSERT INTO chains (chain_id, session_id, archive_id, agent_id, model, system_prompt, input_tokens, output_tokens, iterations, stop_reason, duration_ms, created_at)
|
||||
VALUES (@ChainId, @SessionId, @ArchiveId, @AgentId, @Model, @SystemPrompt, @InputTokens, @OutputTokens, @Iterations, @StopReason, @DurationMs, @CreatedAt)
|
||||
", chain);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user