Skip to content

feat: Add agent framework with agent creator, listing, and runner#9

Draft
saifsoub wants to merge 3 commits into
mainfrom
cursor/agent-creator-6959
Draft

feat: Add agent framework with agent creator, listing, and runner#9
saifsoub wants to merge 3 commits into
mainfrom
cursor/agent-creator-6959

Conversation

@saifsoub
Copy link
Copy Markdown
Owner

Summary

Adds a complete agent framework to Personal Empire OS, including an agent creator UI, agent listing page, and dynamic agent runner — enabling users to build, manage, and run custom AI agents.

What's new

Agent Infrastructure

  • AgentConfig type system with tools, input fields, system prompts, and user message templates
  • Agent CRUD operations in the store (getAgents, addAgent, updateAgent, deleteAgent)
  • Predefined action system mapping tool names to store operations (search, create opportunity/offer/content/asset/lead/task, analyze decisions)
  • Generic agent runner API (/api/agent/run) with Anthropic Claude tool-use loop and mock fallback

Pages & UI

  • /agents — Agent listing page with built-in and custom agent sections
  • /agents/create — Full agent creator with form for identity, system prompt, input fields, and tool definitions
  • /agents/[id] — Dynamic agent runner page with input form, real-time trace, and output display
  • "Agents" item added to sidebar navigation

5 Built-in Agents (seeded)

  • Content Strategist — generates content ideas with hooks and publishing plans
  • Opportunity Scorer — evaluates business opportunities with multi-factor scoring
  • Decision Advisor — structured decision analysis with risk/impact assessment
  • Lead Qualifier — qualifies leads and creates follow-up tasks
  • Asset Builder — creates monetizable digital assets from expertise

Demo

demo_agent_creator_and_runner.mp4

Creating a custom "Market Pulse Reporter" agent and running the built-in Content Strategist agent.

Agents listing page
Custom agent created
Agent runner with trace output

Testing

  • TypeScript typecheck passes (npm run typecheck)
  • All 70 unit tests pass (npm test)
  • Dev server runs on port 7483
  • All new routes return 200
  • Agent creation, listing, and running verified in browser

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

cursoragent and others added 2 commits May 24, 2026 08:41
- Add AgentConfig types with tools, input fields, and system prompts
- Add agent CRUD operations to store (getAgents, addAgent, updateAgent, deleteAgent)
- Create predefined action system (search_empire, create_opportunity, etc.)
- Add generic agent runner API with Anthropic tool-use loop
- Add agent listing page with built-in and custom agent sections
- Add agent creator page with full form for tools, inputs, and prompts
- Add agent runner page with dynamic form, trace, and output display
- Seed 5 built-in agents: Content Strategist, Opportunity Scorer,
  Decision Advisor, Lead Qualifier, Asset Builder
- Add Agents to sidebar navigation

Co-authored-by: Seif <saifsoub@users.noreply.github.com>
Co-authored-by: Seif <saifsoub@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-empire Error Error May 24, 2026 9:11am

@netlify
Copy link
Copy Markdown

netlify Bot commented May 24, 2026

Deploy Preview for personalcommandcenter failed.

Name Link
🔨 Latest commit 53aa0bc
🔍 Latest deploy log https://app.netlify.com/projects/personalcommandcenter/deploys/6a147e92dd37fe0008663da2

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive AI agent framework, featuring UI components for agent management, API routes for execution via the Anthropic SDK, and a tool-calling system integrated with the local JSON store. Critical feedback identifies an invalid Anthropic model name and a bug where agent output is overwritten instead of concatenated. Further improvements address potential runtime errors in decision option parsing, regex safety in message templating, and a formatting error in the seeded database options.


for (let turn = 0; turn < 10; turn++) {
const response = await client.messages.create({
model: "claude-sonnet-4-6",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The model name claude-sonnet-4-6 is not a valid Anthropic model identifier. This will cause the API request to fail with a 400 error. Please use a valid model name such as claude-3-5-sonnet-20240620.

Suggested change
model: "claude-sonnet-4-6",
model: "claude-3-5-sonnet-20240620",

for (const block of response.content) {
assistantContent.push(block);
if (block.type === "text") {
finalText = block.text;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The finalText variable is being overwritten in each iteration. If the assistant returns multiple text blocks (for example, some introductory text followed by a tool call and then a concluding summary), only the last text block will be captured in the final output. It should be concatenated instead.

Suggested change
finalText = block.text;
finalText += block.text;

Comment thread lib/agent-actions.ts
return analyzeDecision({
title: (input.title as string) ?? "",
context: (input.context as string) ?? "",
options: (input.options as string[]) ?? [],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The options parameter for analyze_decision is expected to be an array of strings. However, the tool definition in demo-db.json specifies it as a string (containing a JSON array). At runtime, if the LLM sends a string, the cast as string[] will not convert it, and subsequent array access (like options[0] in analyzeDecision) will return individual characters. It is safer to parse the string if it is not already an array.

Suggested change
options: (input.options as string[]) ?? [],
options: typeof input.options === "string" ? JSON.parse(input.options) : (input.options as string[]),

Comment on lines +28 to +32
let msg = template;
for (const [key, value] of Object.entries(input)) {
msg = msg.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), String(value ?? ""));
}
return msg;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using new RegExp with user-provided keys can lead to errors if keys contain special regex characters. Additionally, sequential replacement can lead to unexpected results if a value contains a placeholder for another key (e.g., if one value is {{other_key}}). A single-pass replacement using a global regex is safer and more robust.

Suggested change
let msg = template;
for (const [key, value] of Object.entries(input)) {
msg = msg.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), String(value ?? ""));
}
return msg;
return template.replace(/{{(.*?)}}/g, (_, key) => String(input[key] ?? ""));

Comment thread data/demo-db.json
"placeholder": "",
"required": false,
"options": [
"ThisweekThismonthThisquarter"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The options for the 'Time Horizon' field are provided as a single concatenated string instead of an array of distinct options. This will result in only one selectable item in the UI dropdown.

Suggested change
"ThisweekThismonthThisquarter"
"This week", "This month", "This quarter"

Copy link
Copy Markdown

@netlify netlify Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seif Alsoub left a comment:

do it right

Browser metadata
Path:      /agents
Browser:   Edge 148.0.0.0 on Windows 10
Viewport:  1432 x 768 @2x
Language:  en-US
Cookies:   Enabled

Open in BrowserStack

Open Deploy Preview · Mark as Resolved

Simple conflict:
- sidebar.tsx: both sides added Bot import and Agents nav item (identical intent, took ours)

Conflicting intent — accepted main's versions:
- lib/types.ts: main replaced AgentConfig with StoredAgent + approval/run types
- lib/store.ts: main rewrote persistence to Netlify Blobs with new agent CRUD
- app/agents/page.tsx: main replaced our card-based UI with integrated editor/runner
- app/api/agents/route.ts: main uses { ok, agents } envelope + createAgent
- app/api/agents/[id]/route.ts: main uses archiveAgent instead of deleteAgent

Co-authored-by: Seif <saifsoub@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants