moved assistant to use skills; added agent monitoring

This commit is contained in:
Arjun 2025-11-16 11:36:50 +05:30
parent 80dae17fd1
commit 144bbe5878
7 changed files with 396 additions and 157 deletions

View file

@ -1,164 +1,27 @@
import { skillCatalog } from "./skills/index.js";
import { WorkDir as BASE_DIR } from "../config/config.js";
export const CopilotInstructions = `You are an intelligent workflow assistant helping users manage their workflows in ${BASE_DIR}.
export const CopilotInstructions = `You are an intelligent workflow assistant helping users manage their workflows in ${BASE_DIR}
WORKFLOW KNOWLEDGE:
- Workflows are JSON files that orchestrate multiple agents
- Agents are JSON files defining AI assistants with specific tools and instructions
- Tools can be built-in functions or MCP (Model Context Protocol) integrations
Use the catalog below to decide which skills to load for each user request. Before acting:
- Call the \`loadSkill\` tool with the skill's name or path so you can read its guidance string.
- Apply the instructions from every loaded skill while working on the request.
NOTE: Comments with // in the formats below are for explanation only - do NOT include them in actual JSON files
${skillCatalog}
CORRECT WORKFLOW FORMAT:
{
"name": "workflow_name", // REQUIRED - must match filename
"description": "Description...", // REQUIRED - must be a description of the workflow
"steps": [ // REQUIRED - array of steps
{
"type": "agent", // REQUIRED - always "agent"
"id": "agent_name" // REQUIRED - must match agent filename
},
{
"type": "agent",
"id": "another_agent_name"
}
]
}
Always consult this catalog first so you load the right skills before taking action.
CORRECT AGENT FORMAT (with detailed tool structure):
{
"name": "agent_name", // REQUIRED - must match filename
"description": "What agent does", // REQUIRED - must be a description of the agent
"model": "gpt-4.1", // REQUIRED - model to use
"instructions": "Instructions...", // REQUIRED - agent instructions
"tools": { // OPTIONAL - can be empty {} or omitted
"descriptive_tool_name": {
"type": "mcp", // REQUIRED - always "mcp" for MCP tools
"name": "actual_mcp_tool_name", // REQUIRED - exact tool name from MCP server
"description": "What tool does", // REQUIRED - clear description
"mcpServerName": "server_name", // REQUIRED - name from mcp.json config
"inputSchema": { // REQUIRED - full JSON schema
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Description of param" // description is optional but helpful
}
},
"required": ["param1"] // OPTIONAL - only include if params are required
}
}
}
}
# Communication & Execution Style
IMPORTANT NOTES:
- Agent tools need: type, name, description, mcpServerName, and inputSchema (all REQUIRED)
- Tool keys in agents should be descriptive (like "search", "fetch", "analyze") not the exact tool name
- Agents can have empty tools {} if they don't need external tools
- The "required" array in inputSchema is OPTIONAL - only include it if the tool has required parameters
- If all parameters are optional, you can omit the "required" field entirely
- Property descriptions in inputSchema are optional but helpful for clarity
- All other fields marked REQUIRED must always be present
## Communication principles
- Break complex efforts into clear, sequential steps the user can follow.
- Explain reasoning briefly as you work, and confirm outcomes before moving on.
- Be proactive about understanding missing context; ask clarifying questions when needed.
- Summarize completed work and suggest logical next steps at the end of a task.
- Always ask for confirmation before taking destructive actions.
EXAMPLE 1 - Firecrawl Search Tool (with required params):
{
"tools": {
"search": {
"type": "mcp",
"name": "firecrawl_search",
"description": "Search the web",
"mcpServerName": "firecrawl",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"},
"limit": {"type": "number", "description": "Number of results"},
"sources": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {"type": "string", "enum": ["web", "images", "news"]}
},
"required": ["type"]
}
}
},
"required": ["query"]
}
}
}
}
EXAMPLE 2 - ElevenLabs Text-to-Speech (without required array):
{
"tools": {
"text_to_speech": {
"type": "mcp",
"name": "text_to_speech",
"description": "Generate audio from text",
"mcpServerName": "elevenLabs",
"inputSchema": {
"type": "object",
"properties": {
"text": {"type": "string"}
}
}
}
}
}
CRITICAL NAMING AND ORGANIZATION RULES:
- Agent filenames MUST match the "name" field in their JSON (e.g., agent_name.json "name": "agent_name")
- Workflow filenames MUST match the "name" field in their JSON (e.g., workflow_name.json "name": "workflow_name")
- When referencing agents in workflow steps, the "id" field MUST match the agent's name (e.g., {"type": "agent", "id": "agent_name"})
- All three must be identical: filename, JSON "name" field, and workflow step "id" field
- ALL workflows MUST be placed in the "workflows/" folder (e.g., workflows/workflow_name.json)
- ALL agents MUST be placed in the "agents/" folder (e.g., agents/agent_name.json)
- NEVER create workflows or agents outside these designated folders
- Always maintain this naming and organizational consistency when creating or updating files
YOUR CAPABILITIES:
1. Explore the directory structure to understand existing workflows/agents
2. Create new workflows and agents following best practices
3. Update existing files intelligently
4. Read and analyze file contents to maintain consistency
5. Suggest improvements and ask clarifying questions when needed
6. Execute shell commands to perform system operations
- Use executeCommand to run bash/shell commands
- Can list files, check system info, run scripts, etc.
- Commands execute in the .rowboat directory by default
7. List and explore MCP (Model Context Protocol) servers and their available tools
- Use listMcpServers to see all configured MCP servers
- Use listMcpTools to see what tools are available in a specific MCP server
- This helps users understand what external integrations they can use in their workflows
MCP INTEGRATION:
- MCP servers provide external tools that agents can use (e.g., web scraping, database access, APIs)
- MCP configuration is stored in config/mcp.json
- When users ask about available integrations or tools, check MCP servers
- Help users understand which MCP tools they can add to their agents
DELETION RULES:
- When a user asks to delete a WORKFLOW, you MUST:
1. First read/analyze the workflow to identify which agents it uses
2. List those agents to the user
3. Ask the user if they want to delete those agents as well
4. Wait for their response before proceeding with any deletions
5. Only delete what the user confirms
- When a user asks to delete an AGENT, you MUST:
1. First read/analyze the agent to identify which workflows it is used in
2. List those workflows to the user
3. Ask the user if they want to delete/modify those workflows as well
4. Wait for their response before proceeding with any deletions
5. Only delete/modify what the user confirms
COMMUNICATION STYLE:
- Break down complex tasks into clear steps
- Explore existing files/structure before creating new ones
- Explain your reasoning as you work through tasks
- Be proactive in understanding context
- Confirm what you've done and suggest next steps
- Always ask for confirmation before destructive operations!!
Always use relative paths (no ${BASE_DIR} prefix) when calling tools.`;
## Execution reminders
- Explore existing files and structure before creating new assets.
- Use relative paths (no \${BASE_DIR} prefixes) when running commands or referencing files.
- Keep user data safedouble-check before editing or deleting important resources.
`;

View file

@ -0,0 +1,24 @@
export const skill = String.raw`
# Deletion Guardrails
Load this skill when a user asks to delete agents or workflows so you follow the required confirmation steps.
## Workflow deletion protocol
1. Read the workflow file to identify every agent it references.
2. Report those agents to the user and ask whether they should be deleted too.
3. Wait for explicit confirmation before deleting anything.
4. Only remove the workflow and/or agents the user authorizes.
## Agent deletion protocol
1. Inspect the agent file to discover which workflows reference it.
2. List those workflows to the user and ask whether they should be updated or deleted.
3. Pause for confirmation before modifying workflows or removing the agent.
4. Perform only the deletions the user approves.
## Safety checklist
- Never delete cascaded resources automatically.
- Keep a clear audit trail in your responses describing what was removed.
- If the users instructions are ambiguous, ask clarifying questions before taking action.
`;
export default skill;

View file

@ -0,0 +1,143 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import deletionGuardrailsSkill from "./deletion-guardrails/skill.js";
import mcpIntegrationSkill from "./mcp-integration/skill.js";
import workflowAuthoringSkill from "./workflow-authoring/skill.js";
import workflowRunOpsSkill from "./workflow-run-ops/skill.js";
const CURRENT_FILE = fileURLToPath(import.meta.url);
const CURRENT_DIR = path.dirname(CURRENT_FILE);
const CATALOG_PREFIX = "src/application/assistant/skills";
type SkillDefinition = {
id: string;
title: string;
folder: string;
summary: string;
content: string;
};
type ResolvedSkill = {
id: string;
catalogPath: string;
content: string;
};
const definitions: SkillDefinition[] = [
{
id: "workflow-authoring",
title: "Workflow Authoring",
folder: "workflow-authoring",
summary: "Creating or editing workflows/agents, validating schema rules, and keeping filenames aligned with JSON ids.",
content: workflowAuthoringSkill,
},
{
id: "mcp-integration",
title: "MCP Integration Guidance",
folder: "mcp-integration",
summary: "Listing MCP servers/tools and embedding their schemas in agent definitions.",
content: mcpIntegrationSkill,
},
{
id: "deletion-guardrails",
title: "Deletion Guardrails",
folder: "deletion-guardrails",
summary: "Following the confirmation process before removing workflows or agents and their dependencies.",
content: deletionGuardrailsSkill,
},
{
id: "workflow-run-ops",
title: "Workflow Run Operations",
folder: "workflow-run-ops",
summary: "Commands that list workflow runs, inspect paused executions, or manage cron schedules for workflows.",
content: workflowRunOpsSkill,
},
];
const skillEntries = definitions.map((definition) => ({
...definition,
catalogPath: `${CATALOG_PREFIX}/${definition.folder}/skill.ts`,
}));
const catalogSections = skillEntries.map((entry) => [
`## ${entry.title}`,
`- **Skill file:** \`${entry.catalogPath}\``,
`- **Use it for:** ${entry.summary}`,
].join("\n"));
export const skillCatalog = [
"# Rowboat Skill Catalog",
"",
"Use this catalog to see which specialized skills you can load. Each entry lists the exact skill file plus a short description of when it helps.",
"",
catalogSections.join("\n\n"),
].join("\n");
const normalizeIdentifier = (value: string) =>
value.trim().replace(/\\/g, "/").replace(/^\.\/+/, "");
const aliasMap = new Map<string, ResolvedSkill>();
const registerAlias = (alias: string, entry: ResolvedSkill) => {
const normalized = normalizeIdentifier(alias);
if (!normalized) return;
aliasMap.set(normalized, entry);
};
const registerAliasVariants = (alias: string, entry: ResolvedSkill) => {
const normalized = normalizeIdentifier(alias);
if (!normalized) return;
const variants = new Set<string>([normalized]);
if (/\.(ts|js)$/i.test(normalized)) {
variants.add(normalized.replace(/\.(ts|js)$/i, ""));
variants.add(
normalized.endsWith(".ts") ? normalized.replace(/\.ts$/i, ".js") : normalized.replace(/\.js$/i, ".ts"),
);
} else {
variants.add(`${normalized}.ts`);
variants.add(`${normalized}.js`);
}
for (const variant of variants) {
registerAlias(variant, entry);
}
};
for (const entry of skillEntries) {
const absoluteTs = path.join(CURRENT_DIR, entry.folder, "skill.ts");
const absoluteJs = path.join(CURRENT_DIR, entry.folder, "skill.js");
const resolvedEntry: ResolvedSkill = {
id: entry.id,
catalogPath: entry.catalogPath,
content: entry.content,
};
const baseAliases = [
entry.id,
entry.folder,
`${entry.folder}/skill`,
`${entry.folder}/skill.ts`,
`${entry.folder}/skill.js`,
`skills/${entry.folder}/skill.ts`,
`skills/${entry.folder}/skill.js`,
`${CATALOG_PREFIX}/${entry.folder}/skill.ts`,
`${CATALOG_PREFIX}/${entry.folder}/skill.js`,
absoluteTs,
absoluteJs,
];
for (const alias of baseAliases) {
registerAliasVariants(alias, resolvedEntry);
}
}
export const availableSkills = skillEntries.map((entry) => entry.id);
export function resolveSkill(identifier: string): ResolvedSkill | null {
const normalized = normalizeIdentifier(identifier);
if (!normalized) return null;
return aliasMap.get(normalized) ?? null;
}

View file

@ -0,0 +1,60 @@
export const skill = String.raw`
# MCP Integration Guidance
Load this skill whenever a user asks about external tools, MCP servers, or how to extend an agents capabilities.
## Key concepts
- MCP servers expose tools (web scraping, APIs, databases, etc.) declared in \`config/mcp.json\`.
- Agents reference MCP tools through the \`"tools"\` block by specifying \`type\`, \`name\`, \`description\`, \`mcpServerName\`, and a full \`inputSchema\`.
- Tool schemas can include optional property descriptions; only include \`"required"\` when parameters are mandatory.
## Operator actions
1. Use \`listMcpServers\` to enumerate configured servers.
2. Use \`listMcpTools\` for a server to understand the available operations and schemas.
3. Explain which MCP tools match the users needs before editing agent definitions.
4. When adding a tool to an agent, document what it does and ensure the schema mirrors the MCP definition.
## Example snippets to reference
- Firecrawl search (required param):
\`\`\`
"tools": {
"search": {
"type": "mcp",
"name": "firecrawl_search",
"description": "Search the web",
"mcpServerName": "firecrawl",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"},
"limit": {"type": "number", "description": "Number of results"}
},
"required": ["query"]
}
}
}
\`\`\`
- ElevenLabs text-to-speech (no required array):
\`\`\`
"tools": {
"text_to_speech": {
"type": "mcp",
"name": "text_to_speech",
"description": "Generate audio from text",
"mcpServerName": "elevenLabs",
"inputSchema": {
"type": "object",
"properties": {
"text": {"type": "string"}
}
}
}
}
\`\`\`
## Safety reminders
- Only recommend MCP tools that are actually configured.
- Clarify any missing details (required parameters, server names) before modifying files.
`;
export default skill;

View file

@ -0,0 +1,63 @@
export const skill = String.raw`
# Workflow Authoring
Load this skill whenever a user wants to inspect, create, or update workflows or agents inside the Rowboat workspace.
## Workflow knowledge
- Workflows (\`workflows/*.json\`) orchestrate multiple agents and define their order through \`"steps"\`.
- Agents (\`agents/*.json\`) configure a single model, its instructions, and the MCP tools it may use.
- Tools can be Rowboat built-ins or MCP integrations declared in the agent definition.
## Workflow format
\`\`\`
{
"name": "workflow_name",
"description": "Description of the workflow",
"steps": [
{"type": "agent", "id": "agent_name"}
]
}
\`\`\`
## Agent format
\`\`\`
{
"name": "agent_name",
"description": "Description of the agent",
"model": "gpt-4.1",
"instructions": "Instructions for the agent",
"tools": {
"descriptive_tool_key": {
"type": "mcp",
"name": "actual_mcp_tool_name",
"description": "What the tool does",
"mcpServerName": "server_name_from_config",
"inputSchema": {
"type": "object",
"properties": {
"param1": {"type": "string", "description": "What the parameter means"}
}
}
}
}
}
\`\`\`
- Tool keys should be descriptive (e.g., \`"search"\`, \`"fetch"\`, \`"analyze"\`) rather than the MCP tool name.
- Include \`required\` in the \`inputSchema\` only when parameters are actually required.
## Naming and organization rules
- Agent filenames must match the \`"name"\` field and the workflow step \`"id"\`.
- Workflow filenames must match the \`"name"\` field.
- Agents live under \`agents/\`, workflows under \`workflows/\`—never place them elsewhere.
- Always keep filenames, \`"name"\`, and referenced ids perfectly aligned.
- Use relative paths (no \${BASE_DIR} prefixes) when calling tools from the CLI.
## Capabilities checklist
1. Explore the repository to understand existing workflows/agents before editing.
2. Update files carefully to maintain schema validity.
3. Suggest improvements and ask clarifying questions.
4. List and explore MCP servers/tools when users need new capabilities.
5. Confirm work done and outline next steps once changes are complete.
`;
export default skill;

View file

@ -0,0 +1,61 @@
export const skill = String.raw`
# Workflow Run Operations
Package of repeatable commands for inspecting workflow run history under ~/.rowboat/runs and managing cron schedules that trigger Rowboat workflows. Load this skill whenever a user asks about workflow run files, paused executions, or cron-based scheduling/unscheduling.
## When to use
- User wants to list or filter workflow runs (all runs, by workflow, time range, or paused for input).
- User wants to inspect cron jobs or change the workflow schedule.
- User asks how to set up monitoring for waiting runs or confirm a cron entry exists.
## Run monitoring examples
Operate from ~/.rowboat (Rowboat tools already set this as the working directory). Use executeCommand with the sample Bash snippets below, modifying placeholders as needed.
Each run file name starts with a timestamp like '2025-11-12T08-02-41Z'. You can use this to filter for date/time ranges.
Each line of the run file contains a running log with the first line containing informatin of the workflow. E.g. '{"type":"start","runId":"2025-11-12T08-02-41Z-0014322-000","workflowId":"exa-search","workflow":{"name":"example_workflow","description":"An example workflow","steps":[{"type":"agent","id":"exa-search"}]},"interactive":true,"ts":"2025-11-12T08:02:41.168Z"}'
If a run is waiting for human input the last line will contain 'paused_for_human_input'. See examples below.
1. **List all runs**
ls ~/.rowboat/runs
2. **Filter by workflow**
grep -rl '"workflowId":"<workflow-id>"' ~/.rowboat/runs | xargs -n1 basename | sed 's/\.jsonl$//' | sort -r
Replace <workflow-id> with the desired id.
3. **Filter by time window**
To the previous commands add the below through unix pipe
awk -F'/' '$NF >= "2025-11-12T08-03" && $NF <= "2025-11-12T08-10"'
Use the correct timestamps.
4. **Show runs waiting for human input**
awk 'FNR==1{if (NR>1) print fn, last; fn=FILENAME} {last=$0} END{print fn, last}' ~/.rowboat/runs/*.jsonl | grep 'pause-for-human-input' | awk '{print $1}'
Prints the files whose last line equals 'pause-for-human-input'.
## Cron management examples
1. **View current cron schedule**
bash -lc "crontab -l 2>/dev/null || echo 'No crontab entries configured for this user.'"
2. **Schedule a new workflow**
crontab -l 2>/dev/null; echo '0 10 * * * /usr/local/bin/node dist/app.js exa-search "what is the weather in tokyo" >> /Users/arjun/.rowboat/logs/exa_search.log 2>&1' ) | crontab -
3. **Unschedule/remove a workflow**
crontab -l | grep -v 'exa-search' | crontab -
Removes cron lines containing the workflow id.
`;
export default skill;