@crewx/sdk 0.8.0-rc.58
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 +201 -0
- package/README.md +1022 -0
- package/dist/adapters/MastraToolAdapter.d.ts +9 -0
- package/dist/adapters/MastraToolAdapter.js +66 -0
- package/dist/adapters/MastraToolAdapter.js.map +1 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +8 -0
- package/dist/api/index.js.map +1 -0
- package/dist/boxing/box-storage.interface.d.ts +13 -0
- package/dist/boxing/box-storage.interface.js +3 -0
- package/dist/boxing/box-storage.interface.js.map +1 -0
- package/dist/boxing/box.service.d.ts +15 -0
- package/dist/boxing/box.service.js +70 -0
- package/dist/boxing/box.service.js.map +1 -0
- package/dist/boxing/box.types.d.ts +86 -0
- package/dist/boxing/box.types.js +3 -0
- package/dist/boxing/box.types.js.map +1 -0
- package/dist/boxing/context-builder.d.ts +8 -0
- package/dist/boxing/context-builder.js +76 -0
- package/dist/boxing/context-builder.js.map +1 -0
- package/dist/boxing/index.d.ts +6 -0
- package/dist/boxing/index.js +11 -0
- package/dist/boxing/index.js.map +1 -0
- package/dist/boxing/tokenizer.d.ts +3 -0
- package/dist/boxing/tokenizer.js +11 -0
- package/dist/boxing/tokenizer.js.map +1 -0
- package/dist/config/api-provider-parser.d.ts +58 -0
- package/dist/config/api-provider-parser.js +212 -0
- package/dist/config/api-provider-parser.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.js +20 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/log.config.d.ts +7 -0
- package/dist/config/log.config.js +20 -0
- package/dist/config/log.config.js.map +1 -0
- package/dist/config/pricing.d.ts +10 -0
- package/dist/config/pricing.js +44 -0
- package/dist/config/pricing.js.map +1 -0
- package/dist/config/timeout.config.d.ts +14 -0
- package/dist/config/timeout.config.js +34 -0
- package/dist/config/timeout.config.js.map +1 -0
- package/dist/config/yaml-loader.d.ts +8 -0
- package/dist/config/yaml-loader.js +155 -0
- package/dist/config/yaml-loader.js.map +1 -0
- package/dist/constants/index.d.ts +4 -0
- package/dist/constants/index.js +8 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +18 -0
- package/dist/constants.js.map +1 -0
- package/dist/conversation/conversation-config.d.ts +9 -0
- package/dist/conversation/conversation-config.js +22 -0
- package/dist/conversation/conversation-config.js.map +1 -0
- package/dist/conversation/conversation-history.interface.d.ts +36 -0
- package/dist/conversation/conversation-history.interface.js +3 -0
- package/dist/conversation/conversation-history.interface.js.map +1 -0
- package/dist/conversation/conversation-storage.service.d.ts +16 -0
- package/dist/conversation/conversation-storage.service.js +213 -0
- package/dist/conversation/conversation-storage.service.js.map +1 -0
- package/dist/conversation/index.d.ts +3 -0
- package/dist/conversation/index.js +20 -0
- package/dist/conversation/index.js.map +1 -0
- package/dist/core/agent/agent-factory.d.ts +37 -0
- package/dist/core/agent/agent-factory.js +68 -0
- package/dist/core/agent/agent-factory.js.map +1 -0
- package/dist/core/agent/agent-runtime.d.ts +52 -0
- package/dist/core/agent/agent-runtime.js +206 -0
- package/dist/core/agent/agent-runtime.js.map +1 -0
- package/dist/core/agent/event-bus.d.ts +44 -0
- package/dist/core/agent/event-bus.js +43 -0
- package/dist/core/agent/event-bus.js.map +1 -0
- package/dist/core/agent/index.d.ts +3 -0
- package/dist/core/agent/index.js +13 -0
- package/dist/core/agent/index.js.map +1 -0
- package/dist/core/env-defaults.d.ts +1 -0
- package/dist/core/env-defaults.js +7 -0
- package/dist/core/env-defaults.js.map +1 -0
- package/dist/core/parallel/helpers.d.ts +27 -0
- package/dist/core/parallel/helpers.js +252 -0
- package/dist/core/parallel/helpers.js.map +1 -0
- package/dist/core/parallel/index.d.ts +4 -0
- package/dist/core/parallel/index.js +11 -0
- package/dist/core/parallel/index.js.map +1 -0
- package/dist/core/parallel/parallel-runner.d.ts +16 -0
- package/dist/core/parallel/parallel-runner.js +230 -0
- package/dist/core/parallel/parallel-runner.js.map +1 -0
- package/dist/core/parallel/types.d.ts +41 -0
- package/dist/core/parallel/types.js +3 -0
- package/dist/core/parallel/types.js.map +1 -0
- package/dist/core/providers/MastraAPIProvider.d.ts +31 -0
- package/dist/core/providers/MastraAPIProvider.js +365 -0
- package/dist/core/providers/MastraAPIProvider.js.map +1 -0
- package/dist/core/providers/ai-provider.interface.d.ts +78 -0
- package/dist/core/providers/ai-provider.interface.js +23 -0
- package/dist/core/providers/ai-provider.interface.js.map +1 -0
- package/dist/core/providers/base-ai.provider.d.ts +80 -0
- package/dist/core/providers/base-ai.provider.js +1183 -0
- package/dist/core/providers/base-ai.provider.js.map +1 -0
- package/dist/core/providers/base-ai.types.d.ts +26 -0
- package/dist/core/providers/base-ai.types.js +3 -0
- package/dist/core/providers/base-ai.types.js.map +1 -0
- package/dist/core/providers/claude.provider.d.ts +19 -0
- package/dist/core/providers/claude.provider.js +170 -0
- package/dist/core/providers/claude.provider.js.map +1 -0
- package/dist/core/providers/codex.provider.d.ts +21 -0
- package/dist/core/providers/codex.provider.js +134 -0
- package/dist/core/providers/codex.provider.js.map +1 -0
- package/dist/core/providers/copilot.provider.d.ts +24 -0
- package/dist/core/providers/copilot.provider.js +146 -0
- package/dist/core/providers/copilot.provider.js.map +1 -0
- package/dist/core/providers/dynamic-provider.factory.d.ts +74 -0
- package/dist/core/providers/dynamic-provider.factory.js +643 -0
- package/dist/core/providers/dynamic-provider.factory.js.map +1 -0
- package/dist/core/providers/gemini.provider.d.ts +16 -0
- package/dist/core/providers/gemini.provider.js +101 -0
- package/dist/core/providers/gemini.provider.js.map +1 -0
- package/dist/core/providers/index.d.ts +8 -0
- package/dist/core/providers/index.js +20 -0
- package/dist/core/providers/index.js.map +1 -0
- package/dist/core/providers/mock.provider.d.ts +13 -0
- package/dist/core/providers/mock.provider.js +55 -0
- package/dist/core/providers/mock.provider.js.map +1 -0
- package/dist/core/providers/provider-factory.d.ts +3 -0
- package/dist/core/providers/provider-factory.js +65 -0
- package/dist/core/providers/provider-factory.js.map +1 -0
- package/dist/core/providers/tool-call.types.d.ts +39 -0
- package/dist/core/providers/tool-call.types.js +3 -0
- package/dist/core/providers/tool-call.types.js.map +1 -0
- package/dist/core/remote/index.d.ts +3 -0
- package/dist/core/remote/index.js +20 -0
- package/dist/core/remote/index.js.map +1 -0
- package/dist/core/remote/remote-agent-manager.d.ts +24 -0
- package/dist/core/remote/remote-agent-manager.js +195 -0
- package/dist/core/remote/remote-agent-manager.js.map +1 -0
- package/dist/core/remote/remote-transport.d.ts +15 -0
- package/dist/core/remote/remote-transport.js +70 -0
- package/dist/core/remote/remote-transport.js.map +1 -0
- package/dist/core/remote/types.d.ts +79 -0
- package/dist/core/remote/types.js +3 -0
- package/dist/core/remote/types.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +133 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.js +6 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/knowledge/DocumentManager.d.ts +4 -0
- package/dist/knowledge/DocumentManager.js +119 -0
- package/dist/knowledge/DocumentManager.js.map +1 -0
- package/dist/knowledge/index.d.ts +1 -0
- package/dist/knowledge/index.js +18 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/parsers/agent-call.util.d.ts +3 -0
- package/dist/parsers/agent-call.util.js +17 -0
- package/dist/parsers/agent-call.util.js.map +1 -0
- package/dist/parsers/claude.parser.d.ts +2 -0
- package/dist/parsers/claude.parser.js +46 -0
- package/dist/parsers/claude.parser.js.map +1 -0
- package/dist/parsers/codex.parser.d.ts +2 -0
- package/dist/parsers/codex.parser.js +89 -0
- package/dist/parsers/codex.parser.js.map +1 -0
- package/dist/parsers/copilot.parser.d.ts +2 -0
- package/dist/parsers/copilot.parser.js +58 -0
- package/dist/parsers/copilot.parser.js.map +1 -0
- package/dist/parsers/gemini.parser.d.ts +2 -0
- package/dist/parsers/gemini.parser.js +36 -0
- package/dist/parsers/gemini.parser.js.map +1 -0
- package/dist/parsers/index.d.ts +7 -0
- package/dist/parsers/index.js +45 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/schema/skills-parser.d.ts +8 -0
- package/dist/schema/skills-parser.js +438 -0
- package/dist/schema/skills-parser.js.map +1 -0
- package/dist/schema/skills.types.d.ts +158 -0
- package/dist/schema/skills.types.js +41 -0
- package/dist/schema/skills.types.js.map +1 -0
- package/dist/schemas/api-provider.schema.d.ts +432 -0
- package/dist/schemas/api-provider.schema.js +50 -0
- package/dist/schemas/api-provider.schema.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +19 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/layout-loader.service.d.ts +18 -0
- package/dist/services/layout-loader.service.js +271 -0
- package/dist/services/layout-loader.service.js.map +1 -0
- package/dist/services/layout-renderer.service.d.ts +34 -0
- package/dist/services/layout-renderer.service.js +325 -0
- package/dist/services/layout-renderer.service.js.map +1 -0
- package/dist/services/props-validator.service.d.ts +29 -0
- package/dist/services/props-validator.service.js +332 -0
- package/dist/services/props-validator.service.js.map +1 -0
- package/dist/skills/adapter/claude-skill-adapter.d.ts +11 -0
- package/dist/skills/adapter/claude-skill-adapter.js +222 -0
- package/dist/skills/adapter/claude-skill-adapter.js.map +1 -0
- package/dist/skills/index.d.ts +6 -0
- package/dist/skills/index.js +31 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/runtime/progressive-loader.d.ts +27 -0
- package/dist/skills/runtime/progressive-loader.js +186 -0
- package/dist/skills/runtime/progressive-loader.js.map +1 -0
- package/dist/skills/runtime/runtime-requirements-validator.d.ts +23 -0
- package/dist/skills/runtime/runtime-requirements-validator.js +248 -0
- package/dist/skills/runtime/runtime-requirements-validator.js.map +1 -0
- package/dist/skills/runtime/skill-runtime.service.d.ts +42 -0
- package/dist/skills/runtime/skill-runtime.service.js +434 -0
- package/dist/skills/runtime/skill-runtime.service.js.map +1 -0
- package/dist/tools/file-system.service.d.ts +10 -0
- package/dist/tools/file-system.service.js +33 -0
- package/dist/tools/file-system.service.js.map +1 -0
- package/dist/tools/find.tool.d.ts +85 -0
- package/dist/tools/find.tool.js +139 -0
- package/dist/tools/find.tool.js.map +1 -0
- package/dist/tools/glob.tool.d.ts +100 -0
- package/dist/tools/glob.tool.js +153 -0
- package/dist/tools/glob.tool.js.map +1 -0
- package/dist/tools/grep.tool.d.ts +30 -0
- package/dist/tools/grep.tool.js +137 -0
- package/dist/tools/grep.tool.js.map +1 -0
- package/dist/tools/index.d.ts +12 -0
- package/dist/tools/index.js +40 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/ls.tool.d.ts +24 -0
- package/dist/tools/ls.tool.js +94 -0
- package/dist/tools/ls.tool.js.map +1 -0
- package/dist/tools/read-file.tool.d.ts +30 -0
- package/dist/tools/read-file.tool.js +69 -0
- package/dist/tools/read-file.tool.js.map +1 -0
- package/dist/tools/replace.tool.d.ts +36 -0
- package/dist/tools/replace.tool.js +68 -0
- package/dist/tools/replace.tool.js.map +1 -0
- package/dist/tools/run-shell-command.tool.d.ts +24 -0
- package/dist/tools/run-shell-command.tool.js +64 -0
- package/dist/tools/run-shell-command.tool.js.map +1 -0
- package/dist/tools/tree.tool.d.ts +24 -0
- package/dist/tools/tree.tool.js +109 -0
- package/dist/tools/tree.tool.js.map +1 -0
- package/dist/tools/types.d.ts +42 -0
- package/dist/tools/types.js +13 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/utils/file-utils.d.ts +5 -0
- package/dist/tools/utils/file-utils.js +221 -0
- package/dist/tools/utils/file-utils.js.map +1 -0
- package/dist/tools/write-file.tool.d.ts +24 -0
- package/dist/tools/write-file.tool.js +55 -0
- package/dist/tools/write-file.tool.js.map +1 -0
- package/dist/types/agent.types.d.ts +134 -0
- package/dist/types/agent.types.js +16 -0
- package/dist/types/agent.types.js.map +1 -0
- package/dist/types/api-provider.types.d.ts +85 -0
- package/dist/types/api-provider.types.js +65 -0
- package/dist/types/api-provider.types.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/layout.types.d.ts +115 -0
- package/dist/types/layout.types.js +22 -0
- package/dist/types/layout.types.js.map +1 -0
- package/dist/types/provider.types.d.ts +12 -0
- package/dist/types/provider.types.js +3 -0
- package/dist/types/provider.types.js.map +1 -0
- package/dist/types/skill-runtime.types.d.ts +244 -0
- package/dist/types/skill-runtime.types.js +44 -0
- package/dist/types/skill-runtime.types.js.map +1 -0
- package/dist/types/structured-payload.types.d.ts +46 -0
- package/dist/types/structured-payload.types.js +65 -0
- package/dist/types/structured-payload.types.js.map +1 -0
- package/dist/types/task-log.types.d.ts +14 -0
- package/dist/types/task-log.types.js +3 -0
- package/dist/types/task-log.types.js.map +1 -0
- package/dist/types/template.types.d.ts +38 -0
- package/dist/types/template.types.js +3 -0
- package/dist/types/template.types.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/api-provider-normalizer.d.ts +16 -0
- package/dist/utils/api-provider-normalizer.js +135 -0
- package/dist/utils/api-provider-normalizer.js.map +1 -0
- package/dist/utils/base-message-formatter.d.ts +32 -0
- package/dist/utils/base-message-formatter.js +170 -0
- package/dist/utils/base-message-formatter.js.map +1 -0
- package/dist/utils/error-utils.d.ts +3 -0
- package/dist/utils/error-utils.js +27 -0
- package/dist/utils/error-utils.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/math-utils.d.ts +3 -0
- package/dist/utils/math-utils.js +10 -0
- package/dist/utils/math-utils.js.map +1 -0
- package/dist/utils/mention-parser.d.ts +18 -0
- package/dist/utils/mention-parser.js +136 -0
- package/dist/utils/mention-parser.js.map +1 -0
- package/dist/utils/string-utils.d.ts +1 -0
- package/dist/utils/string-utils.js +10 -0
- package/dist/utils/string-utils.js.map +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +20 -0
- package/dist/utils.js.map +1 -0
- package/package.json +134 -0
- package/schema/api-provider-config.json +138 -0
- package/schema/crewx-config.json +224 -0
- package/schema/skills-config.json +306 -0
package/README.md
ADDED
|
@@ -0,0 +1,1022 @@
|
|
|
1
|
+
# SowonAI CrewX SDK
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
4
|
+
[](https://www.npmjs.com/package/@sowonai/crewx-sdk)
|
|
5
|
+
|
|
6
|
+
Core SDK for building custom AI agent integrations and tools on top of SowonAI CrewX.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
The CrewX SDK provides the foundational interfaces, types, and utilities for building AI agent systems. It's designed to be framework-agnostic and extensible, allowing you to:
|
|
11
|
+
|
|
12
|
+
- Build custom AI provider integrations
|
|
13
|
+
- Implement conversation history management
|
|
14
|
+
- Create knowledge base utilities
|
|
15
|
+
- Develop agent orchestration systems
|
|
16
|
+
- Integrate with existing applications
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @sowonai/crewx-sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For peer dependencies (if using NestJS):
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @nestjs/common @nestjs/core reflect-metadata rxjs
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Basic Usage with createCrewxAgent (NEW)
|
|
33
|
+
|
|
34
|
+
The SDK provides a high-level `createCrewxAgent` factory function for simplified agent creation:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { createCrewxAgent } from '@sowonai/crewx-sdk';
|
|
38
|
+
|
|
39
|
+
// Create an agent with configuration
|
|
40
|
+
const { agent, onEvent } = await createCrewxAgent({
|
|
41
|
+
provider: {
|
|
42
|
+
namespace: 'cli',
|
|
43
|
+
id: 'codex',
|
|
44
|
+
apiKey: process.env.CODEX_TOKEN,
|
|
45
|
+
},
|
|
46
|
+
enableCallStack: true,
|
|
47
|
+
defaultAgentId: 'my-agent',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Subscribe to agent events
|
|
51
|
+
onEvent('callStackUpdated', (stack) => {
|
|
52
|
+
console.log('Call stack:', stack.map(f => `${f.depth}: ${f.agentId}`));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
onEvent('agentStarted', ({ agentId, mode }) => {
|
|
56
|
+
console.log(`Agent ${agentId} started in ${mode} mode`);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Execute a query (read-only)
|
|
60
|
+
const queryResult = await agent.query({
|
|
61
|
+
prompt: 'What is the current status?',
|
|
62
|
+
context: 'Project: CrewX',
|
|
63
|
+
messages: [
|
|
64
|
+
{
|
|
65
|
+
id: 'msg-1',
|
|
66
|
+
text: 'Previous message',
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
isAssistant: false,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
console.log(queryResult.content);
|
|
74
|
+
|
|
75
|
+
// Execute an action (write mode)
|
|
76
|
+
const executeResult = await agent.execute({
|
|
77
|
+
prompt: 'Create a summary document',
|
|
78
|
+
context: 'Project root: /path/to/project',
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
console.log(executeResult.content);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Using Utilities
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import {
|
|
88
|
+
MentionParser,
|
|
89
|
+
loadAvailableAgents,
|
|
90
|
+
type AgentConfig,
|
|
91
|
+
type AIProvider
|
|
92
|
+
} from '@sowonai/crewx-sdk';
|
|
93
|
+
|
|
94
|
+
// Parse agent mentions from user input
|
|
95
|
+
const parser = new MentionParser();
|
|
96
|
+
const parsed = parser.parse('@claude analyze this code');
|
|
97
|
+
|
|
98
|
+
console.log(parsed.mentions); // ['claude']
|
|
99
|
+
console.log(parsed.cleanedPrompt); // 'analyze this code'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Working with Conversation History
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import {
|
|
106
|
+
type ConversationMessage,
|
|
107
|
+
type ConversationThread,
|
|
108
|
+
type IConversationHistoryProvider,
|
|
109
|
+
getConversationConfig
|
|
110
|
+
} from '@sowonai/crewx-sdk';
|
|
111
|
+
|
|
112
|
+
// Implement custom conversation storage
|
|
113
|
+
class MyConversationProvider implements IConversationHistoryProvider {
|
|
114
|
+
async fetchHistory(options) {
|
|
115
|
+
// Fetch from your database
|
|
116
|
+
return {
|
|
117
|
+
messages: [],
|
|
118
|
+
metadata: { platform: 'my-platform' }
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async saveMessage(message, threadId) {
|
|
123
|
+
// Save to your database
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ... other methods
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Using Document Manager
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { DocumentManager } from '@sowonai/crewx-sdk';
|
|
134
|
+
|
|
135
|
+
const docManager = new DocumentManager();
|
|
136
|
+
|
|
137
|
+
// Load markdown documents
|
|
138
|
+
await docManager.loadDocument('./docs/api.md', 'markdown');
|
|
139
|
+
|
|
140
|
+
// Get document content
|
|
141
|
+
const content = docManager.getDocument('./docs/api.md');
|
|
142
|
+
console.log(content);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## API Reference
|
|
146
|
+
|
|
147
|
+
### Core Interfaces
|
|
148
|
+
|
|
149
|
+
#### AIProvider
|
|
150
|
+
|
|
151
|
+
The fundamental interface for all AI providers:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
interface AIProvider {
|
|
155
|
+
respond(
|
|
156
|
+
prompt: string,
|
|
157
|
+
options?: AIQueryOptions
|
|
158
|
+
): Promise<AIResponse>;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
interface AIQueryOptions {
|
|
162
|
+
messages?: ConversationMessage[];
|
|
163
|
+
pipedContext?: string;
|
|
164
|
+
model?: string;
|
|
165
|
+
// ... other options
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface AIResponse {
|
|
169
|
+
content: string;
|
|
170
|
+
metadata?: Record<string, unknown>;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### IConversationHistoryProvider
|
|
175
|
+
|
|
176
|
+
Interface for conversation storage implementations:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
interface IConversationHistoryProvider {
|
|
180
|
+
fetchHistory(options: FetchHistoryOptions): Promise<ConversationThread>;
|
|
181
|
+
saveMessage(message: ConversationMessage, threadId: string): Promise<void>;
|
|
182
|
+
createThread(threadId: string, metadata?: Record<string, unknown>): Promise<void>;
|
|
183
|
+
listThreads(): Promise<Array<{ id: string; updatedAt: Date }>>;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Configuration
|
|
188
|
+
|
|
189
|
+
#### TimeoutConfig
|
|
190
|
+
|
|
191
|
+
Manage timeout settings for AI operations:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { getTimeoutConfig, getDefaultTimeoutConfig } from '@sowonai/crewx-sdk';
|
|
195
|
+
|
|
196
|
+
// Get timeout configuration
|
|
197
|
+
const timeout = getTimeoutConfig();
|
|
198
|
+
|
|
199
|
+
// Use default timeouts
|
|
200
|
+
const defaults = getDefaultTimeoutConfig();
|
|
201
|
+
console.log(defaults.default); // 120000ms
|
|
202
|
+
console.log(defaults.query); // 60000ms
|
|
203
|
+
console.log(defaults.execute); // 300000ms
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### ConversationConfig
|
|
207
|
+
|
|
208
|
+
Configure conversation behavior:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import { getConversationConfig, DEFAULT_CONVERSATION_CONFIG } from '@sowonai/crewx-sdk';
|
|
212
|
+
|
|
213
|
+
const config = getConversationConfig();
|
|
214
|
+
// Or use defaults
|
|
215
|
+
console.log(DEFAULT_CONVERSATION_CONFIG);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Utilities
|
|
219
|
+
|
|
220
|
+
#### MentionParser
|
|
221
|
+
|
|
222
|
+
Parse agent mentions from text:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
import { MentionParser, type ParsedMentions } from '@sowonai/crewx-sdk';
|
|
226
|
+
|
|
227
|
+
const parser = new MentionParser();
|
|
228
|
+
|
|
229
|
+
// Parse single mention
|
|
230
|
+
const result = parser.parse('@claude help me');
|
|
231
|
+
// result.mentions: ['claude']
|
|
232
|
+
// result.cleanedPrompt: 'help me'
|
|
233
|
+
|
|
234
|
+
// Parse multiple mentions
|
|
235
|
+
const multi = parser.parse('@claude @gemini compare approaches');
|
|
236
|
+
// multi.mentions: ['claude', 'gemini']
|
|
237
|
+
|
|
238
|
+
// Override model
|
|
239
|
+
const withModel = parser.parse('@claude:opus analyze');
|
|
240
|
+
// Model override detected
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### Error Utilities
|
|
244
|
+
|
|
245
|
+
Handle errors consistently:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { getErrorMessage, getErrorStack, isError } from '@sowonai/crewx-sdk';
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
// ... operation
|
|
252
|
+
} catch (err) {
|
|
253
|
+
if (isError(err)) {
|
|
254
|
+
console.error(getErrorMessage(err));
|
|
255
|
+
console.error(getErrorStack(err));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Agent Factory API
|
|
261
|
+
|
|
262
|
+
#### createCrewxAgent
|
|
263
|
+
|
|
264
|
+
Create and configure an agent with event support:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import {
|
|
268
|
+
createCrewxAgent,
|
|
269
|
+
type CrewxAgentConfig,
|
|
270
|
+
type CrewxAgent,
|
|
271
|
+
type AgentQueryRequest,
|
|
272
|
+
type AgentExecuteRequest,
|
|
273
|
+
type CallStackFrame
|
|
274
|
+
} from '@sowonai/crewx-sdk';
|
|
275
|
+
|
|
276
|
+
// Configuration interface
|
|
277
|
+
interface CrewxAgentConfig {
|
|
278
|
+
provider?: {
|
|
279
|
+
namespace: string;
|
|
280
|
+
id: string;
|
|
281
|
+
apiKey?: string;
|
|
282
|
+
model?: string;
|
|
283
|
+
};
|
|
284
|
+
knowledgeBase?: {
|
|
285
|
+
path?: string;
|
|
286
|
+
sources?: string[];
|
|
287
|
+
};
|
|
288
|
+
enableCallStack?: boolean;
|
|
289
|
+
defaultAgentId?: string;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Create agent
|
|
293
|
+
const { agent, onEvent, eventBus } = await createCrewxAgent({
|
|
294
|
+
provider: { namespace: 'cli', id: 'codex' },
|
|
295
|
+
enableCallStack: true,
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Agent interface
|
|
299
|
+
agent.query(request: AgentQueryRequest): Promise<AgentResult>
|
|
300
|
+
agent.execute(request: AgentExecuteRequest): Promise<AgentResult>
|
|
301
|
+
agent.getCallStack(): CallStackFrame[]
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
#### Event System
|
|
305
|
+
|
|
306
|
+
The event system supports lifecycle and call stack tracking:
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
// Subscribe to events
|
|
310
|
+
const unsubscribe = onEvent('eventName', (payload) => {
|
|
311
|
+
console.log('Event:', payload);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Supported events:
|
|
315
|
+
// - 'callStackUpdated': CallStackFrame[]
|
|
316
|
+
// - 'agentStarted': { agentId: string, mode: 'query' | 'execute' }
|
|
317
|
+
// - 'agentCompleted': { agentId: string, success: boolean }
|
|
318
|
+
// - 'toolCallStarted': { toolName: string, args: any }
|
|
319
|
+
// - 'toolCallCompleted': { toolName: string, result: any }
|
|
320
|
+
|
|
321
|
+
// Unsubscribe when done
|
|
322
|
+
unsubscribe();
|
|
323
|
+
|
|
324
|
+
// Direct event bus access for advanced usage
|
|
325
|
+
eventBus.emit('customEvent', { data: 'value' });
|
|
326
|
+
eventBus.listenerCount('eventName');
|
|
327
|
+
eventBus.clear(); // Remove all listeners
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Types
|
|
331
|
+
|
|
332
|
+
#### Agent Types
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import type {
|
|
336
|
+
AgentConfig,
|
|
337
|
+
AgentsConfig,
|
|
338
|
+
AgentInfo,
|
|
339
|
+
AgentQueryOptions,
|
|
340
|
+
AgentResponse,
|
|
341
|
+
RemoteAgentConfigInput,
|
|
342
|
+
RemoteAgentInfo
|
|
343
|
+
} from '@sowonai/crewx-sdk';
|
|
344
|
+
|
|
345
|
+
import { ExecutionMode, SecurityLevel } from '@sowonai/crewx-sdk';
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Provider Development
|
|
349
|
+
|
|
350
|
+
### Creating a Custom Provider
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import { AIProvider, AIQueryOptions, AIResponse } from '@sowonai/crewx-sdk';
|
|
354
|
+
|
|
355
|
+
export class MyCustomProvider implements AIProvider {
|
|
356
|
+
async respond(
|
|
357
|
+
prompt: string,
|
|
358
|
+
options?: AIQueryOptions
|
|
359
|
+
): Promise<AIResponse> {
|
|
360
|
+
// Implement your AI provider logic
|
|
361
|
+
const result = await this.callMyAI(prompt, options);
|
|
362
|
+
|
|
363
|
+
return {
|
|
364
|
+
content: result.text,
|
|
365
|
+
metadata: {
|
|
366
|
+
model: result.model,
|
|
367
|
+
tokens: result.usage
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
private async callMyAI(prompt: string, options?: AIQueryOptions) {
|
|
373
|
+
// Your implementation
|
|
374
|
+
return {
|
|
375
|
+
text: 'Response from my AI',
|
|
376
|
+
model: 'my-model-v1',
|
|
377
|
+
usage: { total: 100 }
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Implementing Conversation Storage
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import {
|
|
387
|
+
IConversationHistoryProvider,
|
|
388
|
+
ConversationMessage,
|
|
389
|
+
ConversationThread,
|
|
390
|
+
FetchHistoryOptions
|
|
391
|
+
} from '@sowonai/crewx-sdk';
|
|
392
|
+
|
|
393
|
+
export class DatabaseConversationProvider implements IConversationHistoryProvider {
|
|
394
|
+
constructor(private db: MyDatabase) {}
|
|
395
|
+
|
|
396
|
+
async fetchHistory(options: FetchHistoryOptions): Promise<ConversationThread> {
|
|
397
|
+
const messages = await this.db.query(
|
|
398
|
+
'SELECT * FROM messages WHERE thread_id = ?',
|
|
399
|
+
[options.threadId]
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
return {
|
|
403
|
+
messages: messages.map(this.toMessage),
|
|
404
|
+
metadata: { platform: 'database' }
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async saveMessage(message: ConversationMessage, threadId: string): Promise<void> {
|
|
409
|
+
await this.db.insert('messages', {
|
|
410
|
+
thread_id: threadId,
|
|
411
|
+
...message
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
async createThread(threadId: string, metadata?: Record<string, unknown>): Promise<void> {
|
|
416
|
+
await this.db.insert('threads', { id: threadId, metadata });
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
async listThreads() {
|
|
420
|
+
return await this.db.query('SELECT id, updated_at FROM threads');
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
private toMessage(row: any): ConversationMessage {
|
|
424
|
+
return {
|
|
425
|
+
id: row.id,
|
|
426
|
+
userId: row.user_id,
|
|
427
|
+
text: row.text,
|
|
428
|
+
timestamp: row.created_at,
|
|
429
|
+
isAssistant: row.is_assistant,
|
|
430
|
+
metadata: row.metadata
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## Shared SDK/CLI Integration
|
|
437
|
+
|
|
438
|
+
The SDK provides reusable components that were previously CLI-only. These abstractions enable custom platform integrations while maintaining consistency.
|
|
439
|
+
|
|
440
|
+
### Message Formatting (Phase 1)
|
|
441
|
+
|
|
442
|
+
The SDK provides a flexible message formatting system that supports multiple platforms (Slack, Terminal, API, etc.) and allows custom formatters.
|
|
443
|
+
|
|
444
|
+
#### Platform-Specific Formatters
|
|
445
|
+
|
|
446
|
+
**Terminal Formatter (Built-in)**
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
import { BaseMessageFormatter, type StructuredMessage } from '@sowonai/crewx-sdk';
|
|
450
|
+
|
|
451
|
+
const formatter = new BaseMessageFormatter();
|
|
452
|
+
|
|
453
|
+
// Format messages for terminal display
|
|
454
|
+
const history = formatter.formatHistory(messages, {
|
|
455
|
+
includeUserId: true,
|
|
456
|
+
includeTimestamp: true,
|
|
457
|
+
timestampFormat: 'iso', // 'iso' | 'relative' | 'unix'
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
console.log(history);
|
|
461
|
+
// Output:
|
|
462
|
+
// [2025-10-17T10:00:00Z] user123: Hello!
|
|
463
|
+
// [2025-10-17T10:00:05Z] assistant: How can I help?
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
**Slack Formatter (Built-in)**
|
|
467
|
+
|
|
468
|
+
For Slack bot integrations, use the Slack-specific formatter that handles threading, mentions, and rich formatting:
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
import { SlackMessageFormatter } from '@sowonai/crewx-sdk';
|
|
472
|
+
|
|
473
|
+
const slackFormatter = new SlackMessageFormatter();
|
|
474
|
+
|
|
475
|
+
// Format for Slack with rich text support
|
|
476
|
+
const formatted = slackFormatter.formatForSlack(messages, {
|
|
477
|
+
includeTimestamp: true,
|
|
478
|
+
useThreading: true,
|
|
479
|
+
preserveMentions: true,
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
// Format agent response with Slack-specific blocks
|
|
483
|
+
const response = slackFormatter.formatAgentResponse({
|
|
484
|
+
content: 'Task completed successfully!',
|
|
485
|
+
agentId: 'backend',
|
|
486
|
+
metadata: { status: 'success' }
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Send to Slack
|
|
490
|
+
await slackClient.chat.postMessage({
|
|
491
|
+
channel: channelId,
|
|
492
|
+
blocks: response.blocks,
|
|
493
|
+
thread_ts: threadId,
|
|
494
|
+
});
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**API/JSON Formatter**
|
|
498
|
+
|
|
499
|
+
For API responses or structured data:
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
import {
|
|
503
|
+
BaseMessageFormatter,
|
|
504
|
+
type StructuredMessage,
|
|
505
|
+
type ConversationMetadata
|
|
506
|
+
} from '@sowonai/crewx-sdk';
|
|
507
|
+
|
|
508
|
+
class APIFormatter extends BaseMessageFormatter {
|
|
509
|
+
formatForAPI(messages: StructuredMessage[]): {
|
|
510
|
+
messages: Array<{
|
|
511
|
+
id: string;
|
|
512
|
+
author: { id: string; isBot: boolean };
|
|
513
|
+
content: string;
|
|
514
|
+
timestamp: string;
|
|
515
|
+
metadata?: Record<string, unknown>;
|
|
516
|
+
}>;
|
|
517
|
+
meta: ConversationMetadata;
|
|
518
|
+
} {
|
|
519
|
+
return {
|
|
520
|
+
messages: messages.map(msg => ({
|
|
521
|
+
id: msg.id,
|
|
522
|
+
author: {
|
|
523
|
+
id: msg.userId || 'unknown',
|
|
524
|
+
isBot: msg.isAssistant || false,
|
|
525
|
+
},
|
|
526
|
+
content: msg.text,
|
|
527
|
+
timestamp: msg.timestamp,
|
|
528
|
+
metadata: msg.metadata,
|
|
529
|
+
})),
|
|
530
|
+
meta: {
|
|
531
|
+
platform: 'api',
|
|
532
|
+
totalMessages: messages.length,
|
|
533
|
+
generatedAt: new Date().toISOString(),
|
|
534
|
+
},
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const apiFormatter = new APIFormatter();
|
|
540
|
+
const response = apiFormatter.formatForAPI(messages);
|
|
541
|
+
|
|
542
|
+
// Return as JSON API response
|
|
543
|
+
res.json(response);
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
#### Custom Formatter Extension
|
|
547
|
+
|
|
548
|
+
Create your own formatter for custom platforms:
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
551
|
+
import {
|
|
552
|
+
BaseMessageFormatter,
|
|
553
|
+
StructuredMessage,
|
|
554
|
+
FormatterOptions
|
|
555
|
+
} from '@sowonai/crewx-sdk';
|
|
556
|
+
|
|
557
|
+
class DiscordFormatter extends BaseMessageFormatter {
|
|
558
|
+
formatMessage(msg: StructuredMessage, options: FormatterOptions): string {
|
|
559
|
+
const timestamp = options.includeTimestamp
|
|
560
|
+
? `<t:${Math.floor(new Date(msg.timestamp).getTime() / 1000)}:R> `
|
|
561
|
+
: '';
|
|
562
|
+
|
|
563
|
+
const author = msg.isAssistant ? '🤖 **Bot**' : `👤 **${msg.userId}**`;
|
|
564
|
+
|
|
565
|
+
return `${timestamp}${author}: ${msg.text}`;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
formatForDiscordEmbed(
|
|
569
|
+
message: string,
|
|
570
|
+
options: { color?: number; title?: string }
|
|
571
|
+
) {
|
|
572
|
+
return {
|
|
573
|
+
embeds: [{
|
|
574
|
+
title: options.title || 'Agent Response',
|
|
575
|
+
description: message,
|
|
576
|
+
color: options.color || 0x5865F2,
|
|
577
|
+
timestamp: new Date().toISOString(),
|
|
578
|
+
}],
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const discordFormatter = new DiscordFormatter();
|
|
584
|
+
const embed = discordFormatter.formatForDiscordEmbed(
|
|
585
|
+
'Analysis complete!',
|
|
586
|
+
{ title: 'Backend Agent', color: 0x00FF00 }
|
|
587
|
+
);
|
|
588
|
+
|
|
589
|
+
await discordChannel.send(embed);
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
#### Metadata Handling
|
|
593
|
+
|
|
594
|
+
The formatter system supports rich metadata for enhanced context:
|
|
595
|
+
|
|
596
|
+
```typescript
|
|
597
|
+
import {
|
|
598
|
+
BaseMessageFormatter,
|
|
599
|
+
type StructuredMessage,
|
|
600
|
+
type ConversationMetadata
|
|
601
|
+
} from '@sowonai/crewx-sdk';
|
|
602
|
+
|
|
603
|
+
const messages: StructuredMessage[] = [
|
|
604
|
+
{
|
|
605
|
+
id: 'msg-1',
|
|
606
|
+
userId: 'user123',
|
|
607
|
+
text: 'What is the status?',
|
|
608
|
+
timestamp: new Date().toISOString(),
|
|
609
|
+
isAssistant: false,
|
|
610
|
+
metadata: {
|
|
611
|
+
platform: 'slack',
|
|
612
|
+
channelId: 'C123456',
|
|
613
|
+
threadTs: '1234567890.123456',
|
|
614
|
+
userAgent: 'SlackBot/1.0',
|
|
615
|
+
},
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
id: 'msg-2',
|
|
619
|
+
userId: 'backend-agent',
|
|
620
|
+
text: 'All systems operational.',
|
|
621
|
+
timestamp: new Date().toISOString(),
|
|
622
|
+
isAssistant: true,
|
|
623
|
+
metadata: {
|
|
624
|
+
agentId: 'backend',
|
|
625
|
+
model: 'claude-3-5-sonnet',
|
|
626
|
+
processingTime: 1234,
|
|
627
|
+
tokenUsage: { input: 50, output: 100 },
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
];
|
|
631
|
+
|
|
632
|
+
const formatter = new BaseMessageFormatter();
|
|
633
|
+
|
|
634
|
+
// Format with metadata extraction
|
|
635
|
+
const formatted = formatter.formatHistory(messages, {
|
|
636
|
+
includeUserId: true,
|
|
637
|
+
includeTimestamp: true,
|
|
638
|
+
extractMetadata: true,
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
// Access metadata
|
|
642
|
+
messages.forEach(msg => {
|
|
643
|
+
if (msg.metadata?.tokenUsage) {
|
|
644
|
+
console.log(`Tokens used: ${msg.metadata.tokenUsage.input + msg.metadata.tokenUsage.output}`);
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
#### Migration Guide for Existing Formatter Users
|
|
650
|
+
|
|
651
|
+
If you're migrating from the CLI's internal formatter to the SDK formatter:
|
|
652
|
+
|
|
653
|
+
**Before (CLI internal)**
|
|
654
|
+
```typescript
|
|
655
|
+
// This was CLI-only code
|
|
656
|
+
import { MessageFormatter } from '../cli/src/utils/message-formatter';
|
|
657
|
+
|
|
658
|
+
const formatter = new MessageFormatter();
|
|
659
|
+
const result = formatter.format(messages);
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
**After (SDK)**
|
|
663
|
+
```typescript
|
|
664
|
+
// Now use SDK's BaseMessageFormatter
|
|
665
|
+
import { BaseMessageFormatter } from '@sowonai/crewx-sdk';
|
|
666
|
+
|
|
667
|
+
const formatter = new BaseMessageFormatter();
|
|
668
|
+
const result = formatter.formatHistory(messages, {
|
|
669
|
+
includeUserId: true,
|
|
670
|
+
includeTimestamp: true,
|
|
671
|
+
});
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**Key Changes:**
|
|
675
|
+
1. Import from `@sowonai/crewx-sdk` instead of CLI internals
|
|
676
|
+
2. Use `formatHistory()` method instead of `format()`
|
|
677
|
+
3. Options are now explicitly passed as second parameter
|
|
678
|
+
4. Metadata handling is built-in with `extractMetadata` option
|
|
679
|
+
|
|
680
|
+
**Slack Migration**
|
|
681
|
+
```typescript
|
|
682
|
+
// Before (CLI)
|
|
683
|
+
import { SlackFormatter } from '../cli/src/slack/formatter';
|
|
684
|
+
|
|
685
|
+
// After (SDK)
|
|
686
|
+
import { SlackMessageFormatter } from '@sowonai/crewx-sdk';
|
|
687
|
+
|
|
688
|
+
const formatter = new SlackMessageFormatter();
|
|
689
|
+
// Same API, now available in SDK
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
#### CLI Developer Guide: Adding Slack Formatting
|
|
693
|
+
|
|
694
|
+
If you're building a CLI tool and want to add Slack formatting support:
|
|
695
|
+
|
|
696
|
+
**Step 1: Install SDK**
|
|
697
|
+
```bash
|
|
698
|
+
npm install @sowonai/crewx-sdk
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
**Step 2: Import Slack Formatter**
|
|
702
|
+
```typescript
|
|
703
|
+
import { SlackMessageFormatter } from '@sowonai/crewx-sdk';
|
|
704
|
+
import { WebClient } from '@slack/web-api';
|
|
705
|
+
|
|
706
|
+
const slackClient = new WebClient(process.env.SLACK_BOT_TOKEN);
|
|
707
|
+
const formatter = new SlackMessageFormatter();
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
**Step 3: Format Messages for Slack**
|
|
711
|
+
```typescript
|
|
712
|
+
async function sendToSlack(
|
|
713
|
+
channelId: string,
|
|
714
|
+
content: string,
|
|
715
|
+
threadTs?: string
|
|
716
|
+
) {
|
|
717
|
+
// Format using SDK formatter
|
|
718
|
+
const formatted = formatter.formatAgentResponse({
|
|
719
|
+
content,
|
|
720
|
+
agentId: 'my-cli-agent',
|
|
721
|
+
metadata: {
|
|
722
|
+
source: 'cli',
|
|
723
|
+
timestamp: new Date().toISOString(),
|
|
724
|
+
},
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
// Send to Slack
|
|
728
|
+
await slackClient.chat.postMessage({
|
|
729
|
+
channel: channelId,
|
|
730
|
+
text: content, // Fallback text
|
|
731
|
+
blocks: formatted.blocks,
|
|
732
|
+
thread_ts: threadTs,
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
**Step 4: Handle Conversation History**
|
|
738
|
+
```typescript
|
|
739
|
+
import {
|
|
740
|
+
SlackMessageFormatter,
|
|
741
|
+
type StructuredMessage
|
|
742
|
+
} from '@sowonai/crewx-sdk';
|
|
743
|
+
|
|
744
|
+
async function formatSlackThread(threadTs: string) {
|
|
745
|
+
// Fetch Slack thread
|
|
746
|
+
const thread = await slackClient.conversations.replies({
|
|
747
|
+
channel: channelId,
|
|
748
|
+
ts: threadTs,
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
// Convert to StructuredMessage format
|
|
752
|
+
const messages: StructuredMessage[] = thread.messages.map(msg => ({
|
|
753
|
+
id: msg.ts,
|
|
754
|
+
userId: msg.user || 'bot',
|
|
755
|
+
text: msg.text || '',
|
|
756
|
+
timestamp: new Date(parseFloat(msg.ts) * 1000).toISOString(),
|
|
757
|
+
isAssistant: !!msg.bot_id,
|
|
758
|
+
metadata: {
|
|
759
|
+
platform: 'slack',
|
|
760
|
+
threadTs: msg.thread_ts,
|
|
761
|
+
},
|
|
762
|
+
}));
|
|
763
|
+
|
|
764
|
+
// Format for display or processing
|
|
765
|
+
const formatter = new SlackMessageFormatter();
|
|
766
|
+
const formatted = formatter.formatHistory(messages, {
|
|
767
|
+
includeTimestamp: true,
|
|
768
|
+
useThreading: true,
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
return formatted;
|
|
772
|
+
}
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
**Step 5: Error Handling**
|
|
776
|
+
```typescript
|
|
777
|
+
try {
|
|
778
|
+
await sendToSlack(channelId, 'Task completed!', threadTs);
|
|
779
|
+
} catch (error) {
|
|
780
|
+
// Format error for Slack
|
|
781
|
+
const errorMessage = formatter.formatAgentResponse({
|
|
782
|
+
content: `❌ Error: ${error.message}`,
|
|
783
|
+
agentId: 'cli-agent',
|
|
784
|
+
metadata: { status: 'error' },
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
await slackClient.chat.postMessage({
|
|
788
|
+
channel: channelId,
|
|
789
|
+
blocks: errorMessage.blocks,
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### AI Providers (Phase 2)
|
|
795
|
+
|
|
796
|
+
Use built-in providers or create custom ones:
|
|
797
|
+
|
|
798
|
+
```typescript
|
|
799
|
+
import {
|
|
800
|
+
BaseAIProvider,
|
|
801
|
+
ClaudeProvider,
|
|
802
|
+
GeminiProvider,
|
|
803
|
+
CopilotProvider,
|
|
804
|
+
CodexProvider,
|
|
805
|
+
type LoggerLike,
|
|
806
|
+
type BaseAIProviderOptions
|
|
807
|
+
} from '@sowonai/crewx-sdk';
|
|
808
|
+
|
|
809
|
+
// Use built-in provider
|
|
810
|
+
const claude = new ClaudeProvider({
|
|
811
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
812
|
+
logger: console,
|
|
813
|
+
enableToolUse: true,
|
|
814
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
// Custom provider
|
|
818
|
+
class MyProvider extends BaseAIProvider {
|
|
819
|
+
constructor(options: BaseAIProviderOptions) {
|
|
820
|
+
super(options);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
async query(prompt: string, options: AIQueryOptions): Promise<AIResponse> {
|
|
824
|
+
// Custom implementation
|
|
825
|
+
return { content: 'Response', metadata: {} };
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
### Remote Agent Management (Phase 3)
|
|
831
|
+
|
|
832
|
+
Manage remote agent communications:
|
|
833
|
+
|
|
834
|
+
```typescript
|
|
835
|
+
import {
|
|
836
|
+
RemoteAgentManager,
|
|
837
|
+
FetchRemoteTransport,
|
|
838
|
+
MockRemoteTransport,
|
|
839
|
+
type RemoteAgentConfig
|
|
840
|
+
} from '@sowonai/crewx-sdk';
|
|
841
|
+
|
|
842
|
+
// Production transport
|
|
843
|
+
const transport = new FetchRemoteTransport({
|
|
844
|
+
timeout: 30000,
|
|
845
|
+
headers: { 'Authorization': `Bearer ${token}` },
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
// Testing transport
|
|
849
|
+
const mockTransport = new MockRemoteTransport({
|
|
850
|
+
'agent-1': { content: 'Mocked response', success: true },
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
const manager = new RemoteAgentManager({
|
|
854
|
+
transport,
|
|
855
|
+
enableLogging: true,
|
|
856
|
+
logger: console,
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
// Load remote agent
|
|
860
|
+
await manager.loadAgent({
|
|
861
|
+
id: 'backend',
|
|
862
|
+
url: 'https://api.example.com/agent',
|
|
863
|
+
apiKey: process.env.REMOTE_API_KEY,
|
|
864
|
+
tools: ['search', 'analyze'],
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
// Query remote agent
|
|
868
|
+
const result = await manager.queryAgent('backend', 'Analyze codebase');
|
|
869
|
+
console.log(result.content);
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
## Advanced Usage
|
|
873
|
+
|
|
874
|
+
### Using Internal APIs
|
|
875
|
+
|
|
876
|
+
Some internal APIs are available for advanced use cases:
|
|
877
|
+
|
|
878
|
+
```typescript
|
|
879
|
+
import { /* internal exports */ } from '@sowonai/crewx-sdk/internal';
|
|
880
|
+
|
|
881
|
+
// Note: Internal APIs may change between minor versions
|
|
882
|
+
// Use at your own risk
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
### Integration with NestJS
|
|
886
|
+
|
|
887
|
+
The SDK works seamlessly with NestJS:
|
|
888
|
+
|
|
889
|
+
```typescript
|
|
890
|
+
import { Injectable } from '@nestjs/common';
|
|
891
|
+
import { DocumentManager } from '@sowonai/crewx-sdk';
|
|
892
|
+
|
|
893
|
+
@Injectable()
|
|
894
|
+
export class MyService {
|
|
895
|
+
constructor(private readonly docManager: DocumentManager) {}
|
|
896
|
+
|
|
897
|
+
async loadDocs() {
|
|
898
|
+
await this.docManager.loadDocument('./docs/api.md', 'markdown');
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
## Constants
|
|
904
|
+
|
|
905
|
+
```typescript
|
|
906
|
+
import {
|
|
907
|
+
SERVER_NAME,
|
|
908
|
+
PREFIX_TOOL_NAME,
|
|
909
|
+
DEFAULT_MAX_FILE_SIZE,
|
|
910
|
+
DEFAULT_MAX_FILES
|
|
911
|
+
} from '@sowonai/crewx-sdk';
|
|
912
|
+
|
|
913
|
+
console.log(SERVER_NAME); // 'crewx'
|
|
914
|
+
console.log(PREFIX_TOOL_NAME); // 'crewx_'
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
## Package Exports
|
|
918
|
+
|
|
919
|
+
The SDK provides the following export paths:
|
|
920
|
+
|
|
921
|
+
- `@sowonai/crewx-sdk` - Main public API
|
|
922
|
+
- `@sowonai/crewx-sdk/internal` - Internal utilities (use with caution)
|
|
923
|
+
- `@sowonai/crewx-sdk/package.json` - Package metadata
|
|
924
|
+
|
|
925
|
+
## TypeScript
|
|
926
|
+
|
|
927
|
+
The SDK is written in TypeScript and includes full type definitions. No additional `@types` packages are needed.
|
|
928
|
+
|
|
929
|
+
```typescript
|
|
930
|
+
import type { AIProvider, AgentConfig } from '@sowonai/crewx-sdk';
|
|
931
|
+
|
|
932
|
+
// Full type safety
|
|
933
|
+
const config: AgentConfig = {
|
|
934
|
+
id: 'my-agent',
|
|
935
|
+
provider: 'cli/claude',
|
|
936
|
+
// ... TypeScript will guide you
|
|
937
|
+
};
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
## Testing
|
|
941
|
+
|
|
942
|
+
```bash
|
|
943
|
+
# Run unit tests
|
|
944
|
+
npm test
|
|
945
|
+
|
|
946
|
+
# Run tests in watch mode
|
|
947
|
+
npm run test:watch
|
|
948
|
+
|
|
949
|
+
# Run tests with UI
|
|
950
|
+
npm run test:ui
|
|
951
|
+
|
|
952
|
+
# Run tests with coverage
|
|
953
|
+
npm run test:coverage
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
## Building
|
|
957
|
+
|
|
958
|
+
```bash
|
|
959
|
+
# Build the package
|
|
960
|
+
npm run build
|
|
961
|
+
|
|
962
|
+
# Output: dist/
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
## Contributing
|
|
966
|
+
|
|
967
|
+
Contributions to the SDK require signing our [Contributor License Agreement (CLA)](../../docs/CLA.md).
|
|
968
|
+
|
|
969
|
+
Please follow these steps:
|
|
970
|
+
|
|
971
|
+
1. Fork the repository
|
|
972
|
+
2. Create a feature branch
|
|
973
|
+
3. Make your changes
|
|
974
|
+
4. Add tests for new functionality
|
|
975
|
+
5. Run `npm test` and `npm run build`
|
|
976
|
+
6. Submit a pull request
|
|
977
|
+
|
|
978
|
+
## License
|
|
979
|
+
|
|
980
|
+
Apache-2.0 License - See [LICENSE](./LICENSE) for details.
|
|
981
|
+
|
|
982
|
+
## Context Integration
|
|
983
|
+
|
|
984
|
+
The SDK provides `TemplateContext` and `AgentMetadata` exports for dynamic template processing:
|
|
985
|
+
|
|
986
|
+
```typescript
|
|
987
|
+
import { TemplateContext, AgentMetadata } from '@sowonai/crewx-sdk';
|
|
988
|
+
|
|
989
|
+
// Use TemplateContext for dynamic prompts
|
|
990
|
+
const context: TemplateContext = {
|
|
991
|
+
env: process.env,
|
|
992
|
+
agent: {
|
|
993
|
+
id: 'claude',
|
|
994
|
+
name: 'Claude Assistant',
|
|
995
|
+
provider: 'cli/claude',
|
|
996
|
+
model: 'claude-3-5-sonnet'
|
|
997
|
+
},
|
|
998
|
+
agentMetadata: {
|
|
999
|
+
specialties: ['code-analysis', 'architecture'],
|
|
1000
|
+
capabilities: ['file-operations', 'web-search'],
|
|
1001
|
+
description: 'Advanced reasoning and analysis specialist'
|
|
1002
|
+
},
|
|
1003
|
+
mode: 'query',
|
|
1004
|
+
platform: 'cli'
|
|
1005
|
+
};
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
For detailed usage, see [Template Variables Guide](../../docs/template-variables.md).
|
|
1009
|
+
|
|
1010
|
+
## Support
|
|
1011
|
+
|
|
1012
|
+
- [GitHub Issues](https://github.com/sowonlabs/crewx/issues)
|
|
1013
|
+
- [Documentation](../../docs/)
|
|
1014
|
+
- [Main README](../../README.md)
|
|
1015
|
+
|
|
1016
|
+
## Related Packages
|
|
1017
|
+
|
|
1018
|
+
- [`crewx`](../cli/README.md) - Full-featured CLI tool built on this SDK
|
|
1019
|
+
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
Built by [SowonLabs](https://github.com/sowonlabs)
|