@kandleconsultinggroup/agent-seo 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/README.md +41 -0
- package/package.json +29 -0
- package/src/SEOAgent.js +57 -0
- package/src/dev.js +18 -0
- package/src/index.js +6 -0
- package/src/prompts/reviseBlog.js +14 -0
- package/src/prompts/writeBlog.js +26 -0
- package/src/utils/slugify.js +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# @kandle/agent-seo
|
|
2
|
+
|
|
3
|
+
SEO blog writing agent for Kandle.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @kandle/agent-seo @kandle/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
const { Kandle } = require("@kandle/core");
|
|
15
|
+
const seoAgent = require("@kandle/agent-seo");
|
|
16
|
+
|
|
17
|
+
const kandle = new Kandle({
|
|
18
|
+
agents: [seoAgent],
|
|
19
|
+
storage: /* your storage */,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const task = await kandle.createTask("seo", {
|
|
23
|
+
topic: "How AI is Transforming Business",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const { artifacts } = await kandle.runTask(task);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Configuration
|
|
30
|
+
|
|
31
|
+
Task input options:
|
|
32
|
+
|
|
33
|
+
- `topic` - Blog post topic (optional, has default)
|
|
34
|
+
- `keywords` - SEO keywords array (optional)
|
|
35
|
+
- `tone` - Writing tone (optional)
|
|
36
|
+
- `audience` - Target audience (optional)
|
|
37
|
+
- `length` - Target word count (optional)
|
|
38
|
+
|
|
39
|
+
## License
|
|
40
|
+
|
|
41
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kandleconsultinggroup/agent-seo",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SEO blog writing agent for Kandle",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "echo \"no tests yet\"",
|
|
9
|
+
"dev": "node src/dev.js"
|
|
10
|
+
},
|
|
11
|
+
"author": "Kandle Consulting Group",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/your-username/kandle.git",
|
|
16
|
+
"directory": "kandle-agent-seo"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"src",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@kandleconsultinggroup/core": "^0.1.0",
|
|
27
|
+
"dotenv": "^17.2.3"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/SEOAgent.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const { Agent, OpenAIClient } = require("@kandleconsultinggroup/core");
|
|
2
|
+
const writeBlogPrompt = require("./prompts/writeBlog");
|
|
3
|
+
const reviseBlogPrompt = require("./prompts/reviseBlog");
|
|
4
|
+
|
|
5
|
+
const openai = new OpenAIClient();
|
|
6
|
+
|
|
7
|
+
class SEOAgent extends Agent {
|
|
8
|
+
async execute(task) {
|
|
9
|
+
const {
|
|
10
|
+
topic = "How SMBs Can Use Cloud Software Effectively",
|
|
11
|
+
keywords = [],
|
|
12
|
+
tone = "professional and approachable",
|
|
13
|
+
audience = "small business owners",
|
|
14
|
+
length = 1200,
|
|
15
|
+
} = this.config;
|
|
16
|
+
|
|
17
|
+
const prompt = writeBlogPrompt({
|
|
18
|
+
topic,
|
|
19
|
+
keywords,
|
|
20
|
+
tone,
|
|
21
|
+
audience,
|
|
22
|
+
length,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const content = await openai.generate({ prompt, maxTokens: 2000 });
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
type: "blog_post",
|
|
30
|
+
content,
|
|
31
|
+
metadata: {
|
|
32
|
+
topic,
|
|
33
|
+
keywords,
|
|
34
|
+
wordTarget: length,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async revise(task, feedback) {
|
|
41
|
+
const originalArtifactContent = task.metadata?.originalContent;
|
|
42
|
+
|
|
43
|
+
const prompt = reviseBlogPrompt({
|
|
44
|
+
content: originalArtifactContent,
|
|
45
|
+
feedback,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const revisedContent = await openai.generate({ prompt, maxTokens: 2000 });
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
type: "blog_post",
|
|
52
|
+
content: revisedContent,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = SEOAgent;
|
package/src/dev.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { Kandle, MemoryAdapter } = require("@kandleconsultinggroup/core");
|
|
2
|
+
const seoAgent = require("@kandleconsultinggroup/agent-seo");
|
|
3
|
+
|
|
4
|
+
(async () => {
|
|
5
|
+
const kandle = new Kandle({
|
|
6
|
+
storage: new MemoryAdapter(),
|
|
7
|
+
agents: [seoAgent],
|
|
8
|
+
seo: {
|
|
9
|
+
keywords: ["cloud consulting", "SMB software"],
|
|
10
|
+
tone: "friendly and practical",
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const task = await kandle.createTask("seo", {});
|
|
15
|
+
const result = await kandle.runTask(task);
|
|
16
|
+
|
|
17
|
+
console.log(result.artifacts[0]);
|
|
18
|
+
})();
|
package/src/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = function reviseBlogPrompt({ content, feedback }) {
|
|
2
|
+
return `
|
|
3
|
+
You are revising an existing blog post.
|
|
4
|
+
|
|
5
|
+
Original content:
|
|
6
|
+
${content}
|
|
7
|
+
|
|
8
|
+
Revision feedback:
|
|
9
|
+
${feedback}
|
|
10
|
+
|
|
11
|
+
Revise the post accordingly while preserving structure and SEO quality.
|
|
12
|
+
Return ONLY the revised content.
|
|
13
|
+
`;
|
|
14
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module.exports = function writeBlogPrompt({
|
|
2
|
+
topic,
|
|
3
|
+
keywords,
|
|
4
|
+
tone,
|
|
5
|
+
audience,
|
|
6
|
+
length,
|
|
7
|
+
}) {
|
|
8
|
+
return `
|
|
9
|
+
You are an expert SEO content writer.
|
|
10
|
+
|
|
11
|
+
Write a long-form blog post with the following requirements:
|
|
12
|
+
- Topic: ${topic}
|
|
13
|
+
- Target keywords: ${keywords.join(", ")}
|
|
14
|
+
- Tone: ${tone}
|
|
15
|
+
- Audience: ${audience}
|
|
16
|
+
- Length: ${length} words
|
|
17
|
+
|
|
18
|
+
Structure the post with:
|
|
19
|
+
- Clear H1 title
|
|
20
|
+
- H2 and H3 subheadings
|
|
21
|
+
- Practical examples
|
|
22
|
+
- A short conclusion
|
|
23
|
+
|
|
24
|
+
Return ONLY the blog content.
|
|
25
|
+
`;
|
|
26
|
+
};
|
|
File without changes
|