Merge branch origin/copilot/add-codex-digest-agent into main
This commit is contained in:
84
base-agent.template.json
Normal file
84
base-agent.template.json
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./schemas/agent-spec.schema.json",
|
||||||
|
"description": "Base template for creating new Lucidia agents. Copy and customize for your agent.",
|
||||||
|
"template": {
|
||||||
|
"id": "{{agent-id}}",
|
||||||
|
"name": "{{Agent Display Name}}",
|
||||||
|
"role": "{{role: interpreter | sentinel | documenter | validator | orchestrator}}",
|
||||||
|
"source": "bot/{{agent-name}}.js",
|
||||||
|
"traits": [
|
||||||
|
"{{trait-1}}",
|
||||||
|
"{{trait-2}}"
|
||||||
|
],
|
||||||
|
"inputs": ["{{input-type-1}}", "{{input-type-2}}"],
|
||||||
|
"outputs": ["{{output-type-1}}", "{{output-type-2}}"],
|
||||||
|
"triggers": ["{{trigger-type::value}}"],
|
||||||
|
"inherits_from": "{{base-agent-type or null}}"
|
||||||
|
},
|
||||||
|
"available_roles": [
|
||||||
|
{
|
||||||
|
"role": "interpreter",
|
||||||
|
"description": "Processes and interprets data, generates summaries and insights",
|
||||||
|
"base_template": "base-interpreter-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "sentinel",
|
||||||
|
"description": "Monitors for specific events and triggers alerts",
|
||||||
|
"base_template": "base-sentinel-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "documenter",
|
||||||
|
"description": "Creates and maintains documentation from project data",
|
||||||
|
"base_template": "base-documenter-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "validator",
|
||||||
|
"description": "Validates code quality, tests, and compliance",
|
||||||
|
"base_template": "base-validator-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "orchestrator",
|
||||||
|
"description": "Coordinates other agents and manages workflows",
|
||||||
|
"base_template": "base-orchestrator-agent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"available_trigger_types": [
|
||||||
|
{
|
||||||
|
"type": "cron",
|
||||||
|
"syntax": "cron::{schedule}",
|
||||||
|
"examples": ["cron::weekly", "cron::daily", "cron::hourly", "cron::0 9 * * 1"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"syntax": "command::{command text}",
|
||||||
|
"examples": ["command::summarize agent performance", "command::generate docs"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "reaction",
|
||||||
|
"syntax": "reaction::{emoji}",
|
||||||
|
"examples": ["reaction::🛟", "reaction::❌", "reaction::✅"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "event",
|
||||||
|
"syntax": "event::{github_event}",
|
||||||
|
"examples": ["event::pr_merged", "event::issue_created", "event::test_complete"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "alert",
|
||||||
|
"syntax": "alert::{agent-id}",
|
||||||
|
"examples": ["alert::guardian-agent", "alert::qa-agent"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"common_traits": [
|
||||||
|
"executive-tone",
|
||||||
|
"emoji-native",
|
||||||
|
"math-ratio-logic",
|
||||||
|
"markdown-output",
|
||||||
|
"verbose-logging",
|
||||||
|
"alert-driven",
|
||||||
|
"test-aware",
|
||||||
|
"coverage-focused",
|
||||||
|
"strategic-planning",
|
||||||
|
"changelog-aware"
|
||||||
|
]
|
||||||
|
}
|
||||||
136
bot/digest.js
Normal file
136
bot/digest.js
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
// bot/digest.js
|
||||||
|
// Codex Digest Agent - interprets emoji digests and weekly stats
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Codex Digest Agent
|
||||||
|
* Role: Interpreter
|
||||||
|
* Traits: executive-tone, emoji-native, math-ratio-logic, markdown-output
|
||||||
|
*/
|
||||||
|
class CodexDigestAgent {
|
||||||
|
constructor() {
|
||||||
|
this.agentId = "codex-digest-agent";
|
||||||
|
this.role = "interpreter";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process emoji digest input and generate markdown summary
|
||||||
|
* @param {Object} input - Input containing emoji-digest and weekly-stats
|
||||||
|
* @returns {Object} - Output containing markdown-summary and action-recommendations
|
||||||
|
*/
|
||||||
|
process(input) {
|
||||||
|
const { emojiDigest = {}, weeklyStats = {} } = input;
|
||||||
|
|
||||||
|
const summary = this.generateMarkdownSummary(emojiDigest, weeklyStats);
|
||||||
|
const recommendations = this.generateActionRecommendations(weeklyStats);
|
||||||
|
|
||||||
|
return {
|
||||||
|
markdownSummary: summary,
|
||||||
|
actionRecommendations: recommendations,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a markdown summary from the emoji digest
|
||||||
|
* @param {Object} emojiDigest - Emoji status mappings
|
||||||
|
* @param {Object} weeklyStats - Weekly statistics
|
||||||
|
* @returns {string} - Markdown formatted summary
|
||||||
|
*/
|
||||||
|
generateMarkdownSummary(emojiDigest, weeklyStats) {
|
||||||
|
const lines = [
|
||||||
|
"# 📊 Weekly Codex Digest Report",
|
||||||
|
"",
|
||||||
|
"## Status Overview",
|
||||||
|
"",
|
||||||
|
];
|
||||||
|
|
||||||
|
// Process emoji digest
|
||||||
|
if (Object.keys(emojiDigest).length > 0) {
|
||||||
|
lines.push("| Emoji | Status | Count |");
|
||||||
|
lines.push("|-------|--------|-------|");
|
||||||
|
for (const [emoji, data] of Object.entries(emojiDigest)) {
|
||||||
|
const status = data.status || "Unknown";
|
||||||
|
const count = data.count || 0;
|
||||||
|
lines.push(`| ${emoji} | ${status} | ${count} |`);
|
||||||
|
}
|
||||||
|
lines.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process weekly stats
|
||||||
|
if (Object.keys(weeklyStats).length > 0) {
|
||||||
|
lines.push("## 📈 Weekly Statistics");
|
||||||
|
lines.push("");
|
||||||
|
for (const [key, value] of Object.entries(weeklyStats)) {
|
||||||
|
lines.push(`- **${key}**: ${value}`);
|
||||||
|
}
|
||||||
|
lines.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push(`*Generated by ${this.agentId} at ${new Date().toISOString()}*`);
|
||||||
|
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate action recommendations based on stats
|
||||||
|
* @param {Object} weeklyStats - Weekly statistics
|
||||||
|
* @returns {Array<string>} - List of recommended actions
|
||||||
|
*/
|
||||||
|
generateActionRecommendations(weeklyStats) {
|
||||||
|
const recommendations = [];
|
||||||
|
|
||||||
|
const escalations = weeklyStats.escalations || 0;
|
||||||
|
const blocked = weeklyStats.blocked || 0;
|
||||||
|
const completionRate = weeklyStats.completionRate || 0;
|
||||||
|
|
||||||
|
if (escalations > 10) {
|
||||||
|
recommendations.push("🚨 High escalation count detected. Trigger planner-agent for resource reallocation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blocked > 5) {
|
||||||
|
recommendations.push("⚠️ Multiple blocked items. Review blockers with team leads.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completionRate < 70) {
|
||||||
|
recommendations.push("📉 Completion rate below target. Consider sprint capacity adjustment.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recommendations.length === 0) {
|
||||||
|
recommendations.push("✅ All metrics within healthy ranges. Continue current workflow.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return recommendations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export for use in other modules
|
||||||
|
module.exports = { CodexDigestAgent };
|
||||||
|
|
||||||
|
// CLI execution
|
||||||
|
if (require.main === module) {
|
||||||
|
console.log("🤖 Codex Digest Agent Activated");
|
||||||
|
|
||||||
|
const agent = new CodexDigestAgent();
|
||||||
|
|
||||||
|
// Example input for testing
|
||||||
|
const sampleInput = {
|
||||||
|
emojiDigest: {
|
||||||
|
"✅": { status: "Done", count: 15 },
|
||||||
|
"🟡": { status: "In Progress", count: 8 },
|
||||||
|
"❌": { status: "Blocked", count: 2 },
|
||||||
|
"🛟": { status: "Escalation", count: 3 },
|
||||||
|
},
|
||||||
|
weeklyStats: {
|
||||||
|
totalTasks: 30,
|
||||||
|
completed: 15,
|
||||||
|
inProgress: 8,
|
||||||
|
blocked: 2,
|
||||||
|
escalations: 3,
|
||||||
|
completionRate: 50,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = agent.process(sampleInput);
|
||||||
|
console.log(result.markdownSummary);
|
||||||
|
console.log("\n📋 Recommendations:");
|
||||||
|
result.actionRecommendations.forEach((rec) => console.log(` ${rec}`));
|
||||||
|
}
|
||||||
135
docs/agent-registry.md
Normal file
135
docs/agent-registry.md
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# 🤖 Lucidia Agent Registry
|
||||||
|
|
||||||
|
The Lucidia Agent Registry (`lucidia.agent-spec.json`) defines all agents available in the BlackRoad OS orchestration system.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Agents are runnable processes that can be triggered by:
|
||||||
|
- **Cron schedules** (e.g., `cron::weekly`)
|
||||||
|
- **Commands** (e.g., `command::summarize agent performance`)
|
||||||
|
- **Reactions** (e.g., `reaction::🛟`)
|
||||||
|
- **Events** (e.g., `event::pr_merged`)
|
||||||
|
- **Alerts from other agents** (e.g., `alert::guardian-agent`)
|
||||||
|
|
||||||
|
## Registered Agents
|
||||||
|
|
||||||
|
### 🧠 Codex Digest Agent
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| **ID** | `codex-digest-agent` |
|
||||||
|
| **Role** | Interpreter |
|
||||||
|
| **Source** | `bot/digest.js` |
|
||||||
|
| **Triggers** | `cron::weekly`, `command::summarize agent performance` |
|
||||||
|
|
||||||
|
**Traits:** executive-tone, emoji-native, math-ratio-logic, markdown-output
|
||||||
|
|
||||||
|
**Inputs:** emoji-digest, weekly-stats
|
||||||
|
|
||||||
|
**Outputs:** markdown-summary, action-recommendations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🛡️ Guardian Agent
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| **ID** | `guardian-agent` |
|
||||||
|
| **Role** | Sentinel |
|
||||||
|
| **Source** | `bot/guardian.js` |
|
||||||
|
| **Triggers** | `reaction::🛟`, `reaction::❌` |
|
||||||
|
|
||||||
|
**Traits:** alert-driven, emoji-native, escalation-handler
|
||||||
|
|
||||||
|
**Alerts:** planner-agent
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 📝 Scribe Agent
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| **ID** | `scribe-agent` |
|
||||||
|
| **Role** | Documenter |
|
||||||
|
| **Source** | `bot/scribe.js` |
|
||||||
|
| **Triggers** | `event::pr_merged`, `command::generate docs` |
|
||||||
|
|
||||||
|
**Traits:** verbose-logging, markdown-output, changelog-aware
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ✅ QA Agent
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| **ID** | `qa-agent` |
|
||||||
|
| **Role** | Validator |
|
||||||
|
| **Source** | `bot/qa.js` |
|
||||||
|
| **Triggers** | `event::test_complete`, `cron::daily` |
|
||||||
|
|
||||||
|
**Traits:** test-aware, coverage-focused, regression-detector
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 📋 Planner Agent
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| **ID** | `planner-agent` |
|
||||||
|
| **Role** | Orchestrator |
|
||||||
|
| **Source** | `bot/planner.js` |
|
||||||
|
| **Triggers** | `alert::guardian-agent`, `cron::hourly`, `command::replan` |
|
||||||
|
|
||||||
|
**Traits:** strategic-planning, priority-aware, resource-optimizer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Creating New Agents
|
||||||
|
|
||||||
|
Use the `base-agent.template.json` as a starting point for new agents:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "my-new-agent",
|
||||||
|
"name": "My New Agent",
|
||||||
|
"role": "interpreter",
|
||||||
|
"source": "bot/my-new-agent.js",
|
||||||
|
"traits": ["trait-1", "trait-2"],
|
||||||
|
"inputs": ["input-type"],
|
||||||
|
"outputs": ["output-type"],
|
||||||
|
"triggers": ["cron::daily"],
|
||||||
|
"inherits_from": "base-interpreter-agent"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Agent Roles
|
||||||
|
|
||||||
|
| Role | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| **interpreter** | Processes and interprets data, generates summaries |
|
||||||
|
| **sentinel** | Monitors for specific events and triggers alerts |
|
||||||
|
| **documenter** | Creates and maintains documentation |
|
||||||
|
| **validator** | Validates code quality, tests, and compliance |
|
||||||
|
| **orchestrator** | Coordinates other agents and manages workflows |
|
||||||
|
|
||||||
|
## Orchestration Flows
|
||||||
|
|
||||||
|
Agents can be chained together using orchestration flows:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
if escalations > 10:
|
||||||
|
trigger: codex-digest-agent
|
||||||
|
then: planner-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration
|
||||||
|
|
||||||
|
The registry integrates with:
|
||||||
|
- ✅ GitHub Actions via reaction triggers
|
||||||
|
- ✅ Lucidia Prism Console for visualization
|
||||||
|
- ✅ RoadChain smart triggers for deployment
|
||||||
|
- ✅ Emoji Bot Config (`emoji-bot-config.yml`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Powered by BlackRoad OS 🖤🛣️*
|
||||||
82
lucidia.agent-spec.json
Normal file
82
lucidia.agent-spec.json
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./schemas/agent-spec.schema.json",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"agents": [
|
||||||
|
{
|
||||||
|
"id": "codex-digest-agent",
|
||||||
|
"name": "Codex Digest Agent",
|
||||||
|
"role": "interpreter",
|
||||||
|
"source": "bot/digest.js",
|
||||||
|
"traits": [
|
||||||
|
"executive-tone",
|
||||||
|
"emoji-native",
|
||||||
|
"math-ratio-logic",
|
||||||
|
"markdown-output"
|
||||||
|
],
|
||||||
|
"inputs": ["emoji-digest", "weekly-stats"],
|
||||||
|
"outputs": ["markdown-summary", "action-recommendations"],
|
||||||
|
"triggers": ["cron::weekly", "command::summarize agent performance"],
|
||||||
|
"inherits_from": "base-interpreter-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "guardian-agent",
|
||||||
|
"name": "Guardian Agent",
|
||||||
|
"role": "sentinel",
|
||||||
|
"source": "bot/guardian.js",
|
||||||
|
"traits": [
|
||||||
|
"alert-driven",
|
||||||
|
"emoji-native",
|
||||||
|
"escalation-handler"
|
||||||
|
],
|
||||||
|
"inputs": ["escalation-events", "reaction-triggers"],
|
||||||
|
"outputs": ["alert-notifications", "status-updates"],
|
||||||
|
"triggers": ["reaction::🛟", "reaction::❌"],
|
||||||
|
"alerts": ["planner-agent"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "scribe-agent",
|
||||||
|
"name": "Scribe Agent",
|
||||||
|
"role": "documenter",
|
||||||
|
"source": "bot/scribe.js",
|
||||||
|
"traits": [
|
||||||
|
"verbose-logging",
|
||||||
|
"markdown-output",
|
||||||
|
"changelog-aware"
|
||||||
|
],
|
||||||
|
"inputs": ["commit-history", "pr-metadata"],
|
||||||
|
"outputs": ["documentation", "changelog-entries"],
|
||||||
|
"triggers": ["event::pr_merged", "command::generate docs"],
|
||||||
|
"inherits_from": "base-documenter-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "qa-agent",
|
||||||
|
"name": "QA Agent",
|
||||||
|
"role": "validator",
|
||||||
|
"source": "bot/qa.js",
|
||||||
|
"traits": [
|
||||||
|
"test-aware",
|
||||||
|
"coverage-focused",
|
||||||
|
"regression-detector"
|
||||||
|
],
|
||||||
|
"inputs": ["test-results", "coverage-reports"],
|
||||||
|
"outputs": ["test-summaries", "regression-alerts"],
|
||||||
|
"triggers": ["event::test_complete", "cron::daily"],
|
||||||
|
"inherits_from": "base-validator-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "planner-agent",
|
||||||
|
"name": "Planner Agent",
|
||||||
|
"role": "orchestrator",
|
||||||
|
"source": "bot/planner.js",
|
||||||
|
"traits": [
|
||||||
|
"strategic-planning",
|
||||||
|
"priority-aware",
|
||||||
|
"resource-optimizer"
|
||||||
|
],
|
||||||
|
"inputs": ["agent-alerts", "project-status", "escalations"],
|
||||||
|
"outputs": ["task-assignments", "priority-updates", "workflow-triggers"],
|
||||||
|
"triggers": ["alert::guardian-agent", "cron::hourly", "command::replan"],
|
||||||
|
"inherits_from": "base-orchestrator-agent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
76
tests/agentSpec.test.ts
Normal file
76
tests/agentSpec.test.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
describe("lucidia.agent-spec.json", () => {
|
||||||
|
const specPath = path.resolve(__dirname, "../lucidia.agent-spec.json");
|
||||||
|
const spec = JSON.parse(fs.readFileSync(specPath, "utf-8"));
|
||||||
|
|
||||||
|
it("should have a valid version", () => {
|
||||||
|
expect(spec.version).toBe("1.0.0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should have an agents array", () => {
|
||||||
|
expect(Array.isArray(spec.agents)).toBe(true);
|
||||||
|
expect(spec.agents.length).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should include codex-digest-agent", () => {
|
||||||
|
const codexAgent = spec.agents.find((a: any) => a.id === "codex-digest-agent");
|
||||||
|
expect(codexAgent).toBeDefined();
|
||||||
|
expect(codexAgent.role).toBe("interpreter");
|
||||||
|
expect(codexAgent.source).toBe("bot/digest.js");
|
||||||
|
expect(codexAgent.traits).toContain("emoji-native");
|
||||||
|
expect(codexAgent.triggers).toContain("cron::weekly");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should include guardian-agent", () => {
|
||||||
|
const guardianAgent = spec.agents.find((a: any) => a.id === "guardian-agent");
|
||||||
|
expect(guardianAgent).toBeDefined();
|
||||||
|
expect(guardianAgent.role).toBe("sentinel");
|
||||||
|
expect(guardianAgent.triggers).toContain("reaction::🛟");
|
||||||
|
expect(guardianAgent.alerts).toContain("planner-agent");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should include planner-agent referenced by guardian-agent", () => {
|
||||||
|
const plannerAgent = spec.agents.find((a: any) => a.id === "planner-agent");
|
||||||
|
expect(plannerAgent).toBeDefined();
|
||||||
|
expect(plannerAgent.role).toBe("orchestrator");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("all agents should have required fields", () => {
|
||||||
|
spec.agents.forEach((agent: any) => {
|
||||||
|
expect(agent.id).toBeDefined();
|
||||||
|
expect(agent.role).toBeDefined();
|
||||||
|
expect(agent.triggers).toBeDefined();
|
||||||
|
expect(Array.isArray(agent.triggers)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("base-agent.template.json", () => {
|
||||||
|
const templatePath = path.resolve(__dirname, "../base-agent.template.json");
|
||||||
|
const template = JSON.parse(fs.readFileSync(templatePath, "utf-8"));
|
||||||
|
|
||||||
|
it("should have a template object", () => {
|
||||||
|
expect(template.template).toBeDefined();
|
||||||
|
expect(template.template.id).toBeDefined();
|
||||||
|
expect(template.template.role).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should have available roles", () => {
|
||||||
|
expect(Array.isArray(template.available_roles)).toBe(true);
|
||||||
|
const roleNames = template.available_roles.map((r: any) => r.role);
|
||||||
|
expect(roleNames).toContain("interpreter");
|
||||||
|
expect(roleNames).toContain("sentinel");
|
||||||
|
expect(roleNames).toContain("orchestrator");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should have trigger types documentation", () => {
|
||||||
|
expect(Array.isArray(template.available_trigger_types)).toBe(true);
|
||||||
|
const triggerTypes = template.available_trigger_types.map((t: any) => t.type);
|
||||||
|
expect(triggerTypes).toContain("cron");
|
||||||
|
expect(triggerTypes).toContain("reaction");
|
||||||
|
expect(triggerTypes).toContain("command");
|
||||||
|
});
|
||||||
|
});
|
||||||
66
tests/digestAgent.test.ts
Normal file
66
tests/digestAgent.test.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
|
||||||
|
const { CodexDigestAgent } = require("../bot/digest.js");
|
||||||
|
|
||||||
|
describe("CodexDigestAgent", () => {
|
||||||
|
it("should create an agent with correct id and role", () => {
|
||||||
|
const agent = new CodexDigestAgent();
|
||||||
|
expect(agent.agentId).toBe("codex-digest-agent");
|
||||||
|
expect(agent.role).toBe("interpreter");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate markdown summary from emoji digest", () => {
|
||||||
|
const agent = new CodexDigestAgent();
|
||||||
|
const input = {
|
||||||
|
emojiDigest: {
|
||||||
|
"✅": { status: "Done", count: 10 },
|
||||||
|
"🟡": { status: "In Progress", count: 5 },
|
||||||
|
},
|
||||||
|
weeklyStats: {
|
||||||
|
totalTasks: 15,
|
||||||
|
completed: 10,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = agent.process(input);
|
||||||
|
|
||||||
|
expect(result.markdownSummary).toContain("# 📊 Weekly Codex Digest Report");
|
||||||
|
expect(result.markdownSummary).toContain("✅");
|
||||||
|
expect(result.markdownSummary).toContain("Done");
|
||||||
|
expect(result.markdownSummary).toContain("10");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate action recommendations for high escalations", () => {
|
||||||
|
const agent = new CodexDigestAgent();
|
||||||
|
const input = {
|
||||||
|
emojiDigest: {},
|
||||||
|
weeklyStats: {
|
||||||
|
escalations: 15,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = agent.process(input);
|
||||||
|
|
||||||
|
expect(result.actionRecommendations).toContain(
|
||||||
|
"🚨 High escalation count detected. Trigger planner-agent for resource reallocation."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate healthy status when metrics are good", () => {
|
||||||
|
const agent = new CodexDigestAgent();
|
||||||
|
const input = {
|
||||||
|
emojiDigest: {},
|
||||||
|
weeklyStats: {
|
||||||
|
escalations: 0,
|
||||||
|
blocked: 0,
|
||||||
|
completionRate: 85,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = agent.process(input);
|
||||||
|
|
||||||
|
expect(result.actionRecommendations).toContain(
|
||||||
|
"✅ All metrics within healthy ranges. Continue current workflow."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user