@serverless-dna/sop-agents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/dist/agent-discovery.d.ts +21 -0
- package/dist/agent-discovery.d.ts.map +1 -0
- package/dist/agent-discovery.js +97 -0
- package/dist/agent-discovery.js.map +1 -0
- package/dist/agents/discovery.d.ts +21 -0
- package/dist/agents/discovery.d.ts.map +1 -0
- package/dist/agents/discovery.js +97 -0
- package/dist/agents/discovery.js.map +1 -0
- package/dist/agents/sop-loader.d.ts +20 -0
- package/dist/agents/sop-loader.d.ts.map +1 -0
- package/dist/agents/sop-loader.js +150 -0
- package/dist/agents/sop-loader.js.map +1 -0
- package/dist/agents/tool-generator.d.ts +66 -0
- package/dist/agents/tool-generator.d.ts.map +1 -0
- package/dist/agents/tool-generator.js +171 -0
- package/dist/agents/tool-generator.js.map +1 -0
- package/dist/default-orchestrator.d.ts +7 -0
- package/dist/default-orchestrator.d.ts.map +1 -0
- package/dist/default-orchestrator.js +50 -0
- package/dist/default-orchestrator.js.map +1 -0
- package/dist/errors.d.ts +51 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +80 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +26 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +89 -0
- package/dist/logger.js.map +1 -0
- package/dist/model-factory.d.ts +36 -0
- package/dist/model-factory.d.ts.map +1 -0
- package/dist/model-factory.js +55 -0
- package/dist/model-factory.js.map +1 -0
- package/dist/orchestrator/default-orchestrator.d.ts +7 -0
- package/dist/orchestrator/default-orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/default-orchestrator.js +50 -0
- package/dist/orchestrator/default-orchestrator.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +47 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +276 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator.d.ts +50 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +281 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/sop-loader.d.ts +20 -0
- package/dist/sop-loader.d.ts.map +1 -0
- package/dist/sop-loader.js +150 -0
- package/dist/sop-loader.js.map +1 -0
- package/dist/tool-generator.d.ts +66 -0
- package/dist/tool-generator.d.ts.map +1 -0
- package/dist/tool-generator.js +171 -0
- package/dist/tool-generator.js.map +1 -0
- package/dist/types/errors.d.ts +51 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +80 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/types.d.ts +160 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +2 -0
- package/dist/types/types.js.map +1 -0
- package/dist/types.d.ts +157 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Serverless DNA
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# SOP Agents
|
|
2
|
+
|
|
3
|
+
**Multi-agent orchestration for [Strands Agents](https://github.com/strands-agents/sdk-python), defined in plain text. Write what your agents do. Write how they collaborate. Done.**
|
|
4
|
+
|
|
5
|
+
📖 Read the announcement: [Introducing Strands Agent SOPs](https://aws.amazon.com/blogs/opensource/introducing-strands-agent-sops-natural-language-workflows-for-ai-agents/) on the AWS Open Source Blog
|
|
6
|
+
|
|
7
|
+
```markdown
|
|
8
|
+
<!-- sops/researcher.md -->
|
|
9
|
+
---
|
|
10
|
+
name: researcher
|
|
11
|
+
description: Researches topics and gathers information
|
|
12
|
+
version: 1.0.0
|
|
13
|
+
type: agent
|
|
14
|
+
---
|
|
15
|
+
# Research Agent
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
You are a research specialist focused on gathering accurate information.
|
|
20
|
+
|
|
21
|
+
## Steps
|
|
22
|
+
|
|
23
|
+
### 1. Analyze the Topic
|
|
24
|
+
|
|
25
|
+
Understand what information is needed and identify reliable sources.
|
|
26
|
+
|
|
27
|
+
**Constraints:**
|
|
28
|
+
- You MUST use authoritative sources
|
|
29
|
+
- You SHOULD cross-reference multiple sources
|
|
30
|
+
|
|
31
|
+
### 2. Gather and Synthesize
|
|
32
|
+
|
|
33
|
+
Collect relevant information and organize it clearly.
|
|
34
|
+
|
|
35
|
+
**Constraints:**
|
|
36
|
+
- You MUST cite your sources
|
|
37
|
+
- You MUST distinguish facts from speculation
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
<!-- sops/writer.md -->
|
|
42
|
+
---
|
|
43
|
+
name: writer
|
|
44
|
+
description: Writes content based on research and requirements
|
|
45
|
+
version: 1.0.0
|
|
46
|
+
type: agent
|
|
47
|
+
---
|
|
48
|
+
# Writer Agent
|
|
49
|
+
|
|
50
|
+
## Overview
|
|
51
|
+
|
|
52
|
+
You are a skilled writer who transforms research into engaging content.
|
|
53
|
+
|
|
54
|
+
## Steps
|
|
55
|
+
|
|
56
|
+
### 1. Review the Input
|
|
57
|
+
|
|
58
|
+
Understand the research findings and target audience.
|
|
59
|
+
|
|
60
|
+
**Constraints:**
|
|
61
|
+
- You MUST NOT invent facts because the output must be grounded in provided research
|
|
62
|
+
- You SHOULD adapt tone to the target audience
|
|
63
|
+
|
|
64
|
+
### 2. Write and Polish
|
|
65
|
+
|
|
66
|
+
Create clear, engaging content from the source material.
|
|
67
|
+
|
|
68
|
+
**Constraints:**
|
|
69
|
+
- You MUST maintain factual accuracy
|
|
70
|
+
- You SHOULD use clear, accessible language
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// That's it. Now they work together automatically.
|
|
75
|
+
const orchestrator = await createOrchestrator({ directory: "./sops" });
|
|
76
|
+
|
|
77
|
+
const result = await orchestrator.invoke(
|
|
78
|
+
"Research quantum computing breakthroughs in 2025 and write a blog post about them"
|
|
79
|
+
);
|
|
80
|
+
// The orchestrator reads your request, calls researcher, passes results to writer,
|
|
81
|
+
// and returns the finished blog post.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
No glue code. No tool definitions. No agent-to-agent wiring. Just describe what each agent does, and the orchestrator figures out how to coordinate them.
|
|
85
|
+
|
|
86
|
+
## Why?
|
|
87
|
+
|
|
88
|
+
Building multi-agent systems usually means:
|
|
89
|
+
- Writing tool schemas and type definitions
|
|
90
|
+
- Manually wiring agents together
|
|
91
|
+
- Hardcoding orchestration logic
|
|
92
|
+
- Rebuilding when requirements change
|
|
93
|
+
|
|
94
|
+
With SOP Agents, you write markdown files. The library handles the rest.
|
|
95
|
+
|
|
96
|
+
**Model-driven orchestration** means the LLM decides how to coordinate agents at runtime—not you at build time. Traditional approaches lock you into predefined flows. Here, the orchestrator reasons about each request and picks the best path. Add a new agent? It's immediately available. Rephrase your request? The orchestrator adapts. No rewiring required.
|
|
97
|
+
|
|
98
|
+
## Install
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm install @serverless-dna/sop-agents
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Requires AWS credentials for Amazon Bedrock (the default model provider):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
aws login # or aws configure
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## How It Works
|
|
111
|
+
|
|
112
|
+
1. **You write SOPs** - Markdown files describing what each agent does
|
|
113
|
+
2. **Library generates tools** - Each SOP becomes a callable tool with typed inputs
|
|
114
|
+
3. **Orchestrator coordinates** - A master agent reads requests and delegates to the right agents
|
|
115
|
+
4. **Agents execute** - Each agent runs with its SOP as the system prompt
|
|
116
|
+
|
|
117
|
+
The orchestrator is itself an agent—defined the same way. It sees your request, looks at the available agent tools, and decides which to call and in what order. No flowcharts, no state machines—just LLM reasoning.
|
|
118
|
+
|
|
119
|
+
**Out of the box**, the library includes a default orchestrator that analyzes your request and selects the right agent(s) to handle it. One agent, multiple agents in sequence, or a back-and-forth—it figures out what's needed.
|
|
120
|
+
|
|
121
|
+
**Want more control?** Write your own orchestrator SOP:
|
|
122
|
+
|
|
123
|
+
```markdown
|
|
124
|
+
<!-- sops/orchestrator.md -->
|
|
125
|
+
---
|
|
126
|
+
name: orchestrator
|
|
127
|
+
description: Coordinates research and writing tasks
|
|
128
|
+
type: orchestrator
|
|
129
|
+
---
|
|
130
|
+
# Content Pipeline Orchestrator
|
|
131
|
+
|
|
132
|
+
You coordinate a content creation pipeline.
|
|
133
|
+
|
|
134
|
+
## Steps
|
|
135
|
+
|
|
136
|
+
1. Always start with the researcher to gather facts
|
|
137
|
+
2. Pass research findings to the writer
|
|
138
|
+
3. If the writer needs clarification, go back to the researcher
|
|
139
|
+
4. Review the final output for accuracy before returning
|
|
140
|
+
|
|
141
|
+
Never skip research. Never let the writer make up facts.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Plain English orchestration. Override the default when you need specific workflows.
|
|
145
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SOPDefinition } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Scans a directory for SOP files and builds an agent registry.
|
|
4
|
+
* Excludes orchestrator SOPs (type: orchestrator).
|
|
5
|
+
*
|
|
6
|
+
* @param directory - Path to scan (default: "./sops")
|
|
7
|
+
* @returns Map of agent name to SOPDefinition (excludes orchestrators)
|
|
8
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
9
|
+
*/
|
|
10
|
+
export declare function discoverAgents(directory?: string): Promise<Map<string, SOPDefinition>>;
|
|
11
|
+
/**
|
|
12
|
+
* Finds the orchestrator SOP in a directory.
|
|
13
|
+
* Returns the built-in default orchestrator if none is found.
|
|
14
|
+
*
|
|
15
|
+
* @param directory - Path to scan (default: "./sops")
|
|
16
|
+
* @returns The orchestrator SOPDefinition (user-defined or default)
|
|
17
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
18
|
+
* @throws MultipleOrchestratorsError if more than one orchestrator found
|
|
19
|
+
*/
|
|
20
|
+
export declare function findOrchestrator(directory?: string): Promise<SOPDefinition>;
|
|
21
|
+
//# sourceMappingURL=agent-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-discovery.d.ts","sourceRoot":"","sources":["../src/agent-discovery.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CACnC,SAAS,SAAW,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CA0CrC;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACrC,SAAS,SAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CA4CxB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { DEFAULT_ORCHESTRATOR } from "./default-orchestrator.js";
|
|
4
|
+
import { DirectoryNotFoundError, MultipleOrchestratorsError } from "./errors.js";
|
|
5
|
+
import { loadSOP } from "./sop-loader.js";
|
|
6
|
+
/**
|
|
7
|
+
* Scans a directory for SOP files and builds an agent registry.
|
|
8
|
+
* Excludes orchestrator SOPs (type: orchestrator).
|
|
9
|
+
*
|
|
10
|
+
* @param directory - Path to scan (default: "./sops")
|
|
11
|
+
* @returns Map of agent name to SOPDefinition (excludes orchestrators)
|
|
12
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
13
|
+
*/
|
|
14
|
+
export async function discoverAgents(directory = "./sops") {
|
|
15
|
+
// Check if directory exists
|
|
16
|
+
if (!fs.existsSync(directory)) {
|
|
17
|
+
throw new DirectoryNotFoundError(directory);
|
|
18
|
+
}
|
|
19
|
+
const stats = fs.statSync(directory);
|
|
20
|
+
if (!stats.isDirectory()) {
|
|
21
|
+
throw new DirectoryNotFoundError(directory);
|
|
22
|
+
}
|
|
23
|
+
// Find all .md files in the directory
|
|
24
|
+
const files = fs.readdirSync(directory);
|
|
25
|
+
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
26
|
+
// Log warning for empty directories
|
|
27
|
+
if (mdFiles.length === 0) {
|
|
28
|
+
console.warn(`Warning: No .md files found in directory: ${directory}`);
|
|
29
|
+
return new Map();
|
|
30
|
+
}
|
|
31
|
+
const registry = new Map();
|
|
32
|
+
// Load each file and filter out orchestrators
|
|
33
|
+
for (const file of mdFiles) {
|
|
34
|
+
const filepath = path.join(directory, file);
|
|
35
|
+
try {
|
|
36
|
+
const sop = await loadSOP(filepath);
|
|
37
|
+
// Filter out orchestrator SOPs
|
|
38
|
+
if (sop.type !== "orchestrator") {
|
|
39
|
+
registry.set(sop.name, sop);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Log error and continue processing other files
|
|
44
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
45
|
+
console.error(`Error loading SOP file ${filepath}: ${errorMessage}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return registry;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Finds the orchestrator SOP in a directory.
|
|
52
|
+
* Returns the built-in default orchestrator if none is found.
|
|
53
|
+
*
|
|
54
|
+
* @param directory - Path to scan (default: "./sops")
|
|
55
|
+
* @returns The orchestrator SOPDefinition (user-defined or default)
|
|
56
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
57
|
+
* @throws MultipleOrchestratorsError if more than one orchestrator found
|
|
58
|
+
*/
|
|
59
|
+
export async function findOrchestrator(directory = "./sops") {
|
|
60
|
+
// Check if directory exists
|
|
61
|
+
if (!fs.existsSync(directory)) {
|
|
62
|
+
throw new DirectoryNotFoundError(directory);
|
|
63
|
+
}
|
|
64
|
+
const stats = fs.statSync(directory);
|
|
65
|
+
if (!stats.isDirectory()) {
|
|
66
|
+
throw new DirectoryNotFoundError(directory);
|
|
67
|
+
}
|
|
68
|
+
// Find all .md files in the directory
|
|
69
|
+
const files = fs.readdirSync(directory);
|
|
70
|
+
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
71
|
+
const orchestrators = [];
|
|
72
|
+
const orchestratorFiles = [];
|
|
73
|
+
// Load each file and find orchestrators
|
|
74
|
+
for (const file of mdFiles) {
|
|
75
|
+
const filepath = path.join(directory, file);
|
|
76
|
+
try {
|
|
77
|
+
const sop = await loadSOP(filepath);
|
|
78
|
+
if (sop.type === "orchestrator") {
|
|
79
|
+
orchestrators.push(sop);
|
|
80
|
+
orchestratorFiles.push(filepath);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (_error) {
|
|
84
|
+
// Skip invalid files when searching for orchestrator
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Check for multiple orchestrators
|
|
88
|
+
if (orchestrators.length > 1) {
|
|
89
|
+
throw new MultipleOrchestratorsError(directory, orchestratorFiles);
|
|
90
|
+
}
|
|
91
|
+
// Return user-defined orchestrator or fall back to default
|
|
92
|
+
if (orchestrators.length === 1) {
|
|
93
|
+
return orchestrators[0];
|
|
94
|
+
}
|
|
95
|
+
return DEFAULT_ORCHESTRATOR;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=agent-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-discovery.js","sourceRoot":"","sources":["../src/agent-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SOPDefinition } from "../types/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Scans a directory for SOP files and builds an agent registry.
|
|
4
|
+
* Excludes orchestrator SOPs (type: orchestrator).
|
|
5
|
+
*
|
|
6
|
+
* @param directory - Path to scan (default: "./sops")
|
|
7
|
+
* @returns Map of agent name to SOPDefinition (excludes orchestrators)
|
|
8
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
9
|
+
*/
|
|
10
|
+
export declare function discoverAgents(directory?: string): Promise<Map<string, SOPDefinition>>;
|
|
11
|
+
/**
|
|
12
|
+
* Finds the orchestrator SOP in a directory.
|
|
13
|
+
* Returns the built-in default orchestrator if none is found.
|
|
14
|
+
*
|
|
15
|
+
* @param directory - Path to scan (default: "./sops")
|
|
16
|
+
* @returns The orchestrator SOPDefinition (user-defined or default)
|
|
17
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
18
|
+
* @throws MultipleOrchestratorsError if more than one orchestrator found
|
|
19
|
+
*/
|
|
20
|
+
export declare function findOrchestrator(directory?: string): Promise<SOPDefinition>;
|
|
21
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/agents/discovery.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CACnC,SAAS,SAAW,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CA0CrC;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACrC,SAAS,SAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CA4CxB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { DEFAULT_ORCHESTRATOR } from "../orchestrator/default-orchestrator.js";
|
|
4
|
+
import { DirectoryNotFoundError, MultipleOrchestratorsError, } from "../types/errors.js";
|
|
5
|
+
import { loadSOP } from "./sop-loader.js";
|
|
6
|
+
/**
|
|
7
|
+
* Scans a directory for SOP files and builds an agent registry.
|
|
8
|
+
* Excludes orchestrator SOPs (type: orchestrator).
|
|
9
|
+
*
|
|
10
|
+
* @param directory - Path to scan (default: "./sops")
|
|
11
|
+
* @returns Map of agent name to SOPDefinition (excludes orchestrators)
|
|
12
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
13
|
+
*/
|
|
14
|
+
export async function discoverAgents(directory = "./sops") {
|
|
15
|
+
// Check if directory exists
|
|
16
|
+
if (!fs.existsSync(directory)) {
|
|
17
|
+
throw new DirectoryNotFoundError(directory);
|
|
18
|
+
}
|
|
19
|
+
const stats = fs.statSync(directory);
|
|
20
|
+
if (!stats.isDirectory()) {
|
|
21
|
+
throw new DirectoryNotFoundError(directory);
|
|
22
|
+
}
|
|
23
|
+
// Find all .md files in the directory
|
|
24
|
+
const files = fs.readdirSync(directory);
|
|
25
|
+
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
26
|
+
// Log warning for empty directories
|
|
27
|
+
if (mdFiles.length === 0) {
|
|
28
|
+
console.warn(`Warning: No .md files found in directory: ${directory}`);
|
|
29
|
+
return new Map();
|
|
30
|
+
}
|
|
31
|
+
const registry = new Map();
|
|
32
|
+
// Load each file and filter out orchestrators
|
|
33
|
+
for (const file of mdFiles) {
|
|
34
|
+
const filepath = path.join(directory, file);
|
|
35
|
+
try {
|
|
36
|
+
const sop = await loadSOP(filepath);
|
|
37
|
+
// Filter out orchestrator SOPs
|
|
38
|
+
if (sop.type !== "orchestrator") {
|
|
39
|
+
registry.set(sop.name, sop);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Log error and continue processing other files
|
|
44
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
45
|
+
console.error(`Error loading SOP file ${filepath}: ${errorMessage}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return registry;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Finds the orchestrator SOP in a directory.
|
|
52
|
+
* Returns the built-in default orchestrator if none is found.
|
|
53
|
+
*
|
|
54
|
+
* @param directory - Path to scan (default: "./sops")
|
|
55
|
+
* @returns The orchestrator SOPDefinition (user-defined or default)
|
|
56
|
+
* @throws DirectoryNotFoundError if directory doesn't exist
|
|
57
|
+
* @throws MultipleOrchestratorsError if more than one orchestrator found
|
|
58
|
+
*/
|
|
59
|
+
export async function findOrchestrator(directory = "./sops") {
|
|
60
|
+
// Check if directory exists
|
|
61
|
+
if (!fs.existsSync(directory)) {
|
|
62
|
+
throw new DirectoryNotFoundError(directory);
|
|
63
|
+
}
|
|
64
|
+
const stats = fs.statSync(directory);
|
|
65
|
+
if (!stats.isDirectory()) {
|
|
66
|
+
throw new DirectoryNotFoundError(directory);
|
|
67
|
+
}
|
|
68
|
+
// Find all .md files in the directory
|
|
69
|
+
const files = fs.readdirSync(directory);
|
|
70
|
+
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
71
|
+
const orchestrators = [];
|
|
72
|
+
const orchestratorFiles = [];
|
|
73
|
+
// Load each file and find orchestrators
|
|
74
|
+
for (const file of mdFiles) {
|
|
75
|
+
const filepath = path.join(directory, file);
|
|
76
|
+
try {
|
|
77
|
+
const sop = await loadSOP(filepath);
|
|
78
|
+
if (sop.type === "orchestrator") {
|
|
79
|
+
orchestrators.push(sop);
|
|
80
|
+
orchestratorFiles.push(filepath);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (_error) {
|
|
84
|
+
// Skip invalid files when searching for orchestrator
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Check for multiple orchestrators
|
|
88
|
+
if (orchestrators.length > 1) {
|
|
89
|
+
throw new MultipleOrchestratorsError(directory, orchestratorFiles);
|
|
90
|
+
}
|
|
91
|
+
// Return user-defined orchestrator or fall back to default
|
|
92
|
+
if (orchestrators.length === 1) {
|
|
93
|
+
return orchestrators[0];
|
|
94
|
+
}
|
|
95
|
+
return DEFAULT_ORCHESTRATOR;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/agents/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { InputDef, SOPDefinition, SOPFrontmatter } from "../types/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Validates frontmatter data against the SOPFrontmatter schema
|
|
5
|
+
* @throws FrontmatterValidationError if validation fails
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateFrontmatter(data: unknown, filepath: string): SOPFrontmatter;
|
|
8
|
+
/**
|
|
9
|
+
* Generates a Zod schema from input definitions
|
|
10
|
+
* Always includes a required 'task' field
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateZodSchema(inputs?: Record<string, InputDef>): z.ZodObject<z.ZodRawShape>;
|
|
13
|
+
/**
|
|
14
|
+
* Loads and parses an SOP file
|
|
15
|
+
* @throws FileNotFoundError if file doesn't exist
|
|
16
|
+
* @throws FrontmatterParseError if YAML is malformed
|
|
17
|
+
* @throws FrontmatterValidationError if frontmatter validation fails
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadSOP(filepath: string): Promise<SOPDefinition>;
|
|
20
|
+
//# sourceMappingURL=sop-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sop-loader.d.ts","sourceRoot":"","sources":["../../src/agents/sop-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,OAAO,KAAK,EACX,QAAQ,EACR,aAAa,EACb,cAAc,EACd,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,GACd,cAAc,CA4EhB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAC/B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAoD5B;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA6CtE"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import matter from "gray-matter";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { FileNotFoundError, FrontmatterParseError, FrontmatterValidationError, } from "../types/errors.js";
|
|
6
|
+
/**
|
|
7
|
+
* Validates frontmatter data against the SOPFrontmatter schema
|
|
8
|
+
* @throws FrontmatterValidationError if validation fails
|
|
9
|
+
*/
|
|
10
|
+
export function validateFrontmatter(data, filepath) {
|
|
11
|
+
if (typeof data !== "object" || data === null) {
|
|
12
|
+
throw new FrontmatterValidationError(filepath, "frontmatter", "must be an object");
|
|
13
|
+
}
|
|
14
|
+
const obj = data;
|
|
15
|
+
// Validate required 'name' field
|
|
16
|
+
if (!("name" in obj) || obj.name === undefined || obj.name === null) {
|
|
17
|
+
throw new FrontmatterValidationError(filepath, "name", "is required but missing");
|
|
18
|
+
}
|
|
19
|
+
if (typeof obj.name !== "string" || obj.name.trim() === "") {
|
|
20
|
+
throw new FrontmatterValidationError(filepath, "name", "must be a non-empty string");
|
|
21
|
+
}
|
|
22
|
+
// Validate required 'description' field
|
|
23
|
+
if (!("description" in obj) ||
|
|
24
|
+
obj.description === undefined ||
|
|
25
|
+
obj.description === null) {
|
|
26
|
+
throw new FrontmatterValidationError(filepath, "description", "is required but missing");
|
|
27
|
+
}
|
|
28
|
+
if (typeof obj.description !== "string" || obj.description.trim() === "") {
|
|
29
|
+
throw new FrontmatterValidationError(filepath, "description", "must be a non-empty string");
|
|
30
|
+
}
|
|
31
|
+
// Validate 'type' field if present
|
|
32
|
+
if ("type" in obj && obj.type !== undefined) {
|
|
33
|
+
if (obj.type !== "agent" && obj.type !== "orchestrator") {
|
|
34
|
+
throw new FrontmatterValidationError(filepath, "type", 'must be either "agent" or "orchestrator"');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Validate optional fields
|
|
38
|
+
const version = typeof obj.version === "string" ? obj.version : undefined;
|
|
39
|
+
const tools = Array.isArray(obj.tools) ? obj.tools : undefined;
|
|
40
|
+
const inputs = typeof obj.inputs === "object" && obj.inputs !== null
|
|
41
|
+
? obj.inputs
|
|
42
|
+
: undefined;
|
|
43
|
+
const model = typeof obj.model === "string" ? obj.model : undefined;
|
|
44
|
+
return {
|
|
45
|
+
name: obj.name,
|
|
46
|
+
description: obj.description,
|
|
47
|
+
version,
|
|
48
|
+
tools,
|
|
49
|
+
inputs,
|
|
50
|
+
type: obj.type ?? "agent", // Default to "agent"
|
|
51
|
+
model,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generates a Zod schema from input definitions
|
|
56
|
+
* Always includes a required 'task' field
|
|
57
|
+
*/
|
|
58
|
+
export function generateZodSchema(inputs) {
|
|
59
|
+
const shape = {
|
|
60
|
+
task: z.string().describe("The specific task to perform"),
|
|
61
|
+
};
|
|
62
|
+
if (inputs) {
|
|
63
|
+
for (const [fieldName, inputDef] of Object.entries(inputs)) {
|
|
64
|
+
let fieldSchema;
|
|
65
|
+
// Map InputDef type to Zod type
|
|
66
|
+
switch (inputDef.type) {
|
|
67
|
+
case "string":
|
|
68
|
+
fieldSchema = z.string();
|
|
69
|
+
break;
|
|
70
|
+
case "number":
|
|
71
|
+
fieldSchema = z.number();
|
|
72
|
+
break;
|
|
73
|
+
case "boolean":
|
|
74
|
+
fieldSchema = z.boolean();
|
|
75
|
+
break;
|
|
76
|
+
case "enum":
|
|
77
|
+
if (inputDef.values && inputDef.values.length > 0) {
|
|
78
|
+
fieldSchema = z.enum(inputDef.values);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
fieldSchema = z.string();
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
case "list":
|
|
85
|
+
fieldSchema = z.array(z.string());
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
fieldSchema = z.string();
|
|
89
|
+
}
|
|
90
|
+
// Apply description
|
|
91
|
+
fieldSchema = fieldSchema.describe(inputDef.description);
|
|
92
|
+
// Apply default value if specified
|
|
93
|
+
if (inputDef.default !== undefined) {
|
|
94
|
+
fieldSchema = fieldSchema.default(inputDef.default);
|
|
95
|
+
}
|
|
96
|
+
// Apply optional if required is false
|
|
97
|
+
if (inputDef.required === false) {
|
|
98
|
+
fieldSchema = fieldSchema.optional();
|
|
99
|
+
}
|
|
100
|
+
shape[fieldName] = fieldSchema;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return z.object(shape);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Loads and parses an SOP file
|
|
107
|
+
* @throws FileNotFoundError if file doesn't exist
|
|
108
|
+
* @throws FrontmatterParseError if YAML is malformed
|
|
109
|
+
* @throws FrontmatterValidationError if frontmatter validation fails
|
|
110
|
+
*/
|
|
111
|
+
export async function loadSOP(filepath) {
|
|
112
|
+
// Check if file exists
|
|
113
|
+
if (!fs.existsSync(filepath)) {
|
|
114
|
+
throw new FileNotFoundError(filepath);
|
|
115
|
+
}
|
|
116
|
+
// Read file content
|
|
117
|
+
const content = fs.readFileSync(filepath, "utf-8");
|
|
118
|
+
// Parse with gray-matter
|
|
119
|
+
let parsed;
|
|
120
|
+
try {
|
|
121
|
+
parsed = matter(content);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
125
|
+
throw new FrontmatterParseError(filepath, errorMessage);
|
|
126
|
+
}
|
|
127
|
+
// Validate frontmatter
|
|
128
|
+
const frontmatter = validateFrontmatter(parsed.data, filepath);
|
|
129
|
+
// Check if name matches filename (log warning if not)
|
|
130
|
+
const filename = path.basename(filepath, ".md");
|
|
131
|
+
if (frontmatter.name !== filename) {
|
|
132
|
+
console.warn(`Warning: SOP name "${frontmatter.name}" does not match filename "${filename}" in ${filepath}`);
|
|
133
|
+
}
|
|
134
|
+
// Generate Zod schema from inputs
|
|
135
|
+
const zodSchema = generateZodSchema(frontmatter.inputs);
|
|
136
|
+
// Return complete SOPDefinition
|
|
137
|
+
return {
|
|
138
|
+
name: frontmatter.name,
|
|
139
|
+
description: frontmatter.description,
|
|
140
|
+
version: frontmatter.version ?? "1.0.0",
|
|
141
|
+
tools: frontmatter.tools ?? [],
|
|
142
|
+
inputs: frontmatter.inputs ?? {},
|
|
143
|
+
body: parsed.content.trim(),
|
|
144
|
+
filepath,
|
|
145
|
+
type: frontmatter.type ?? "agent",
|
|
146
|
+
zodSchema,
|
|
147
|
+
model: frontmatter.model,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=sop-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sop-loader.js","sourceRoot":"","sources":["../../src/agents/sop-loader.ts"],"names":[],"mappings":"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"}
|