beddel 1.0.1 → 1.0.3
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 +71 -2
- package/dist/agents/assistant-bedrock.yaml +20 -0
- package/dist/agents/assistant-openrouter.yaml +17 -0
- package/dist/agents/assistant.yaml +17 -0
- package/dist/agents/index.d.ts +24 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +37 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/primitives/llm.d.ts.map +1 -1
- package/dist/primitives/llm.js +4 -5
- package/dist/providers/index.d.ts +63 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +115 -0
- package/dist/server/handler.d.ts +3 -0
- package/dist/server/handler.d.ts.map +1 -1
- package/dist/server/handler.js +39 -14
- package/dist/validation/index.d.ts +33 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +74 -0
- package/docs/architecture/api-reference.md +56 -0
- package/docs/architecture/components.md +57 -1
- package/docs/architecture/core-workflows.md +31 -1
- package/docs/architecture/high-level-architecture.md +7 -2
- package/docs/architecture/source-tree.md +3 -1
- package/docs/architecture/tech-stack.md +1 -0
- package/package.json +8 -2
- package/src/agents/assistant-bedrock.yaml +20 -0
- package/src/agents/assistant-openrouter.yaml +17 -0
- package/src/agents/assistant.yaml +17 -0
- package/src/agents/index.ts +45 -0
- package/src/index.ts +13 -0
- package/src/primitives/llm.ts +5 -5
- package/src/providers/index.ts +143 -0
- package/src/server/handler.ts +50 -17
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
- 🔌 **Extensible Primitives** — Register custom step types, tools, and callbacks
|
|
15
15
|
- 🔒 **Security First** — YAML parsing with `FAILSAFE_SCHEMA` prevents code execution
|
|
16
16
|
- 📦 **Bundle Separation** — Three entry points for server, client, and full API access
|
|
17
|
+
- 🌐 **Multi-Provider** — Built-in support for Google Gemini, Amazon Bedrock, and OpenRouter (400+ models)
|
|
17
18
|
|
|
18
19
|
## Installation
|
|
19
20
|
|
|
@@ -40,6 +41,8 @@ export const POST = createBeddelHandler({
|
|
|
40
41
|
|
|
41
42
|
### 2. Create YAML Agent
|
|
42
43
|
|
|
44
|
+
#### Example 1: Google Gemini (Default Provider)
|
|
45
|
+
|
|
43
46
|
```yaml
|
|
44
47
|
# src/agents/assistant.yaml
|
|
45
48
|
metadata:
|
|
@@ -50,16 +53,47 @@ workflow:
|
|
|
50
53
|
- id: "chat-interaction"
|
|
51
54
|
type: "llm"
|
|
52
55
|
config:
|
|
56
|
+
provider: "google"
|
|
53
57
|
model: "gemini-2.0-flash-exp"
|
|
54
58
|
stream: true
|
|
55
59
|
system: "You are a helpful assistant."
|
|
56
60
|
messages: "$input.messages"
|
|
57
61
|
```
|
|
58
62
|
|
|
59
|
-
|
|
63
|
+
#### Example 2: Amazon Bedrock (Llama 3.2)
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
# src/agents/assistant-bedrock.yaml
|
|
67
|
+
metadata:
|
|
68
|
+
name: "Bedrock Assistant"
|
|
69
|
+
version: "1.0.0"
|
|
70
|
+
description: "Simple assistant using Llama 3.2 1B (lightweight)"
|
|
71
|
+
|
|
72
|
+
workflow:
|
|
73
|
+
- id: "chat"
|
|
74
|
+
type: "llm"
|
|
75
|
+
config:
|
|
76
|
+
provider: "bedrock"
|
|
77
|
+
model: "us.meta.llama3-2-1b-instruct-v1:0"
|
|
78
|
+
stream: true
|
|
79
|
+
system: |
|
|
80
|
+
You are a helpful, friendly assistant. Be concise and direct.
|
|
81
|
+
Answer in the same language the user writes to you.
|
|
82
|
+
messages: "$input.messages"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 3. Set Environment Variables
|
|
60
86
|
|
|
61
87
|
```bash
|
|
88
|
+
# For Google Gemini
|
|
62
89
|
GEMINI_API_KEY=your_api_key_here
|
|
90
|
+
|
|
91
|
+
# For Amazon Bedrock
|
|
92
|
+
AWS_REGION=us-east-1
|
|
93
|
+
AWS_BEARER_TOKEN_BEDROCK=your_bedrock_api_key
|
|
94
|
+
# Or use standard AWS credentials:
|
|
95
|
+
# AWS_ACCESS_KEY_ID=your_access_key
|
|
96
|
+
# AWS_SECRET_ACCESS_KEY=your_secret_key
|
|
63
97
|
```
|
|
64
98
|
|
|
65
99
|
### 4. Use with React (useChat)
|
|
@@ -71,7 +105,7 @@ import { useChat } from '@ai-sdk/react';
|
|
|
71
105
|
export default function Chat() {
|
|
72
106
|
const { messages, input, handleInputChange, handleSubmit } = useChat({
|
|
73
107
|
api: '/api/beddel/chat',
|
|
74
|
-
body: { agentId: 'assistant' },
|
|
108
|
+
body: { agentId: 'assistant' }, // or 'assistant-bedrock'
|
|
75
109
|
});
|
|
76
110
|
|
|
77
111
|
return (
|
|
@@ -88,6 +122,35 @@ export default function Chat() {
|
|
|
88
122
|
}
|
|
89
123
|
```
|
|
90
124
|
|
|
125
|
+
## Built-in Providers
|
|
126
|
+
|
|
127
|
+
| Provider | Environment Variables | Default Model |
|
|
128
|
+
|----------|----------------------|---------------|
|
|
129
|
+
| `google` | `GEMINI_API_KEY` | `gemini-1.5-flash` |
|
|
130
|
+
| `bedrock` | `AWS_REGION`, `AWS_BEARER_TOKEN_BEDROCK` (or AWS credentials) | `anthropic.claude-3-haiku-20240307-v1:0` |
|
|
131
|
+
| `openrouter` | `OPENROUTER_API_KEY` | `qwen/qwen3-14b:free` |
|
|
132
|
+
|
|
133
|
+
> **Note:** The Bedrock provider requires `AWS_REGION` to be set (defaults to `us-east-1` if not provided).
|
|
134
|
+
|
|
135
|
+
### Example: OpenRouter (400+ Models)
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
# src/agents/assistant-openrouter.yaml
|
|
139
|
+
metadata:
|
|
140
|
+
name: "OpenRouter Assistant"
|
|
141
|
+
version: "1.0.0"
|
|
142
|
+
|
|
143
|
+
workflow:
|
|
144
|
+
- id: "chat"
|
|
145
|
+
type: "llm"
|
|
146
|
+
config:
|
|
147
|
+
provider: "openrouter"
|
|
148
|
+
model: "qwen/qwen3-14b:free" # or any model from openrouter.ai/models
|
|
149
|
+
stream: true
|
|
150
|
+
system: "You are a helpful assistant."
|
|
151
|
+
messages: "$input.messages"
|
|
152
|
+
```
|
|
153
|
+
|
|
91
154
|
## Entry Points
|
|
92
155
|
|
|
93
156
|
| Import Path | Purpose | Environment |
|
|
@@ -188,6 +251,8 @@ Beddel is fully compatible with Vercel AI SDK v6:
|
|
|
188
251
|
| Runtime | Node.js / Edge | 20+ |
|
|
189
252
|
| AI Core | `ai` | 6.x |
|
|
190
253
|
| AI Provider | `@ai-sdk/google` | 3.x |
|
|
254
|
+
| AI Provider | `@ai-sdk/amazon-bedrock` | 4.x |
|
|
255
|
+
| AI Provider | `@ai-sdk/openai` | 1.x |
|
|
191
256
|
| Validation | `zod` | 3.x |
|
|
192
257
|
| YAML Parser | `js-yaml` | 4.x |
|
|
193
258
|
|
|
@@ -200,6 +265,10 @@ Detailed documentation is available in [`docs/`](./docs/):
|
|
|
200
265
|
- [Core Workflows](./docs/architecture/core-workflows.md)
|
|
201
266
|
- [High-Level Architecture](./docs/architecture/high-level-architecture.md)
|
|
202
267
|
|
|
268
|
+
## Newsletter
|
|
269
|
+
|
|
270
|
+
[](https://beddelprotocol.substack.com/subscribe)
|
|
271
|
+
|
|
203
272
|
## License
|
|
204
273
|
|
|
205
274
|
[MIT](LICENSE)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Built-in Bedrock Assistant
|
|
2
|
+
# Uses Meta Llama 3.2 1B - lightweight and cheap model on Bedrock
|
|
3
|
+
|
|
4
|
+
metadata:
|
|
5
|
+
name: "Bedrock Assistant"
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
description: "Simple assistant using Llama 3.2 1B (lightweight)"
|
|
8
|
+
builtin: true
|
|
9
|
+
|
|
10
|
+
workflow:
|
|
11
|
+
- id: "chat"
|
|
12
|
+
type: "llm"
|
|
13
|
+
config:
|
|
14
|
+
provider: "bedrock"
|
|
15
|
+
model: "us.meta.llama3-2-1b-instruct-v1:0"
|
|
16
|
+
stream: true
|
|
17
|
+
system: |
|
|
18
|
+
You are a helpful, friendly assistant. Be concise and direct.
|
|
19
|
+
Answer in the same language the user writes to you.
|
|
20
|
+
messages: "$input.messages"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Built-in OpenRouter Assistant
|
|
2
|
+
# Uses OpenRouter for access to 400+ models
|
|
3
|
+
|
|
4
|
+
metadata:
|
|
5
|
+
name: "OpenRouter Assistant"
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
builtin: true
|
|
8
|
+
|
|
9
|
+
workflow:
|
|
10
|
+
- id: "chat-interaction"
|
|
11
|
+
type: "llm"
|
|
12
|
+
config:
|
|
13
|
+
provider: "openrouter"
|
|
14
|
+
model: "qwen/qwen3-coder:free"
|
|
15
|
+
stream: true
|
|
16
|
+
system: "You are a helpful assistant."
|
|
17
|
+
messages: "$input.messages"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Built-in Streaming Assistant
|
|
2
|
+
# Uses Google Gemini for fast, streaming responses
|
|
3
|
+
|
|
4
|
+
metadata:
|
|
5
|
+
name: "Streaming Assistant"
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
builtin: true
|
|
8
|
+
|
|
9
|
+
workflow:
|
|
10
|
+
- id: "chat-interaction"
|
|
11
|
+
type: "llm"
|
|
12
|
+
config:
|
|
13
|
+
provider: "google"
|
|
14
|
+
model: "gemini-2.0-flash-exp"
|
|
15
|
+
stream: true
|
|
16
|
+
system: "You are a helpful assistant."
|
|
17
|
+
messages: "$input.messages"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Agents Registry
|
|
3
|
+
*
|
|
4
|
+
* Lists all agents bundled with the beddel package.
|
|
5
|
+
* These are available automatically without user configuration.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* List of built-in agent IDs available in the package
|
|
9
|
+
*/
|
|
10
|
+
export declare const BUILTIN_AGENTS: readonly ["assistant", "assistant-bedrock", "assistant-openrouter"];
|
|
11
|
+
export type BuiltinAgentId = typeof BUILTIN_AGENTS[number];
|
|
12
|
+
/**
|
|
13
|
+
* Get the absolute path to the built-in agents directory
|
|
14
|
+
*/
|
|
15
|
+
export declare function getBuiltinAgentsPath(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Check if an agent ID is a built-in agent
|
|
18
|
+
*/
|
|
19
|
+
export declare function isBuiltinAgent(agentId: string): agentId is BuiltinAgentId;
|
|
20
|
+
/**
|
|
21
|
+
* Get the full path to a built-in agent YAML file
|
|
22
|
+
*/
|
|
23
|
+
export declare function getBuiltinAgentPath(agentId: BuiltinAgentId): string;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;GAEG;AACH,eAAO,MAAM,cAAc,qEAIjB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAE3D;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,cAAc,CAEzE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAEnE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Agents Registry
|
|
3
|
+
*
|
|
4
|
+
* Lists all agents bundled with the beddel package.
|
|
5
|
+
* These are available automatically without user configuration.
|
|
6
|
+
*/
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import { dirname, join } from 'path';
|
|
9
|
+
// Get the directory where built-in agents are located
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
/**
|
|
13
|
+
* List of built-in agent IDs available in the package
|
|
14
|
+
*/
|
|
15
|
+
export const BUILTIN_AGENTS = [
|
|
16
|
+
'assistant',
|
|
17
|
+
'assistant-bedrock',
|
|
18
|
+
'assistant-openrouter',
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Get the absolute path to the built-in agents directory
|
|
22
|
+
*/
|
|
23
|
+
export function getBuiltinAgentsPath() {
|
|
24
|
+
return __dirname;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if an agent ID is a built-in agent
|
|
28
|
+
*/
|
|
29
|
+
export function isBuiltinAgent(agentId) {
|
|
30
|
+
return BUILTIN_AGENTS.includes(agentId);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the full path to a built-in agent YAML file
|
|
34
|
+
*/
|
|
35
|
+
export function getBuiltinAgentPath(agentId) {
|
|
36
|
+
return join(__dirname, `${agentId}.yaml`);
|
|
37
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,5 +14,9 @@ export { createBeddelHandler } from './server/handler';
|
|
|
14
14
|
export { handlerRegistry, registerPrimitive } from './primitives';
|
|
15
15
|
export { toolRegistry, registerTool } from './tools';
|
|
16
16
|
export type { ToolImplementation } from './tools';
|
|
17
|
+
export { providerRegistry, registerProvider, createModel } from './providers';
|
|
18
|
+
export type { ProviderImplementation, ProviderConfig } from './providers';
|
|
19
|
+
export { BUILTIN_AGENTS, getBuiltinAgentsPath, getBuiltinAgentPath, isBuiltinAgent } from './agents';
|
|
20
|
+
export type { BuiltinAgentId } from './agents';
|
|
17
21
|
export type { ParsedYaml, WorkflowStep, StepConfig, YamlMetadata, ExecutionContext, PrimitiveHandler, } from './types';
|
|
18
22
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAIvD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGlD,YAAY,EACR,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAIvD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EACH,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACjB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG/C,YAAY,EACR,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,3 +16,7 @@ export { createBeddelHandler } from './server/handler';
|
|
|
16
16
|
export { handlerRegistry, registerPrimitive } from './primitives';
|
|
17
17
|
// Tools registry (for custom tool registration)
|
|
18
18
|
export { toolRegistry, registerTool } from './tools';
|
|
19
|
+
// Providers registry (for custom LLM provider registration)
|
|
20
|
+
export { providerRegistry, registerProvider, createModel } from './providers';
|
|
21
|
+
// Built-in agents registry
|
|
22
|
+
export { BUILTIN_AGENTS, getBuiltinAgentsPath, getBuiltinAgentPath, isBuiltinAgent } from './agents';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/primitives/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/primitives/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,OAAO,KAAK,EAAgC,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAK/E;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAM,CAAC;AAE/D;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI,CAKzE;AA2DD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,EAAE,gBA2E1B,CAAC"}
|
package/dist/primitives/llm.js
CHANGED
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
* - convertToModelMessages() bridges this gap automatically
|
|
17
17
|
*/
|
|
18
18
|
import { streamText, generateText, dynamicTool, stepCountIs, convertToModelMessages, } from 'ai';
|
|
19
|
-
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
20
19
|
import { toolRegistry } from '../tools';
|
|
21
20
|
import { resolveVariables } from '../core/variable-resolver';
|
|
21
|
+
import { createModel } from '../providers';
|
|
22
22
|
/**
|
|
23
23
|
* Registry for consumer-registered callbacks.
|
|
24
24
|
* Populated by the application using Beddel.
|
|
@@ -87,11 +87,10 @@ function mapTools(toolDefinitions) {
|
|
|
87
87
|
*/
|
|
88
88
|
export const llmPrimitive = async (config, context) => {
|
|
89
89
|
const llmConfig = config;
|
|
90
|
-
//
|
|
91
|
-
const
|
|
92
|
-
|
|
90
|
+
// Create model from provider registry (defaults to 'google')
|
|
91
|
+
const model = createModel(llmConfig.provider || 'google', {
|
|
92
|
+
model: llmConfig.model || 'gemini-1.5-flash',
|
|
93
93
|
});
|
|
94
|
-
const model = google(llmConfig.model || 'gemini-1.5-flash');
|
|
95
94
|
// Resolve messages from context (e.g., $input.messages)
|
|
96
95
|
// AI SDK v6: Frontend sends UIMessage[], we convert to ModelMessage[]
|
|
97
96
|
const rawMessages = resolveVariables(llmConfig.messages, context);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Beddel Protocol - Provider Registry
|
|
3
|
+
*
|
|
4
|
+
* This registry maps provider names to their implementations.
|
|
5
|
+
* Following Expansion Pack Pattern from BMAD-METHOD™ for extensibility.
|
|
6
|
+
* See: https://github.com/bmadcode/bmad-method
|
|
7
|
+
*
|
|
8
|
+
* Server-only: Providers may use Node.js APIs and external services.
|
|
9
|
+
*/
|
|
10
|
+
import type { LanguageModel } from 'ai';
|
|
11
|
+
/**
|
|
12
|
+
* Configuration passed to provider's createModel method.
|
|
13
|
+
*/
|
|
14
|
+
export interface ProviderConfig {
|
|
15
|
+
model: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Provider implementation interface.
|
|
20
|
+
* Each provider must implement createModel to return an AI SDK LanguageModel.
|
|
21
|
+
*/
|
|
22
|
+
export interface ProviderImplementation {
|
|
23
|
+
createModel: (config: ProviderConfig) => LanguageModel;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Registry of provider implementations keyed by provider name.
|
|
27
|
+
*
|
|
28
|
+
* Built-in Providers:
|
|
29
|
+
* - 'google': Google Gemini via @ai-sdk/google
|
|
30
|
+
* - 'bedrock': Amazon Bedrock via @ai-sdk/amazon-bedrock
|
|
31
|
+
*/
|
|
32
|
+
export declare const providerRegistry: Record<string, ProviderImplementation>;
|
|
33
|
+
/**
|
|
34
|
+
* Register a custom provider implementation in the registry.
|
|
35
|
+
* Allows consumers to extend Beddel with additional LLM providers.
|
|
36
|
+
*
|
|
37
|
+
* @param name - Provider identifier (e.g., 'openai', 'anthropic')
|
|
38
|
+
* @param implementation - ProviderImplementation with createModel method
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* import { registerProvider } from 'beddel';
|
|
42
|
+
*
|
|
43
|
+
* registerProvider('openai', {
|
|
44
|
+
* createModel: (config) => {
|
|
45
|
+
* const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
46
|
+
* return openai(config.model || 'gpt-4');
|
|
47
|
+
* },
|
|
48
|
+
* });
|
|
49
|
+
*/
|
|
50
|
+
export declare function registerProvider(name: string, implementation: ProviderImplementation): void;
|
|
51
|
+
/**
|
|
52
|
+
* Create a LanguageModel instance from a registered provider.
|
|
53
|
+
*
|
|
54
|
+
* @param provider - Provider name (must be registered in providerRegistry)
|
|
55
|
+
* @param config - Configuration including model name and provider-specific options
|
|
56
|
+
* @returns LanguageModel instance from the AI SDK
|
|
57
|
+
* @throws Error if provider is not found, listing available providers
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* const model = createModel('google', { model: 'gemini-1.5-flash' });
|
|
61
|
+
*/
|
|
62
|
+
export declare function createModel(provider: string, config: ProviderConfig): LanguageModel;
|
|
63
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAKxC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,aAAa,CAAC;CAC1D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAM,CAAC;AAE3E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,sBAAsB,GACvC,IAAI,CAKN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,aAAa,CAOnF"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Beddel Protocol - Provider Registry
|
|
3
|
+
*
|
|
4
|
+
* This registry maps provider names to their implementations.
|
|
5
|
+
* Following Expansion Pack Pattern from BMAD-METHOD™ for extensibility.
|
|
6
|
+
* See: https://github.com/bmadcode/bmad-method
|
|
7
|
+
*
|
|
8
|
+
* Server-only: Providers may use Node.js APIs and external services.
|
|
9
|
+
*/
|
|
10
|
+
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
11
|
+
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
|
|
12
|
+
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
|
|
13
|
+
/**
|
|
14
|
+
* Registry of provider implementations keyed by provider name.
|
|
15
|
+
*
|
|
16
|
+
* Built-in Providers:
|
|
17
|
+
* - 'google': Google Gemini via @ai-sdk/google
|
|
18
|
+
* - 'bedrock': Amazon Bedrock via @ai-sdk/amazon-bedrock
|
|
19
|
+
*/
|
|
20
|
+
export const providerRegistry = {};
|
|
21
|
+
/**
|
|
22
|
+
* Register a custom provider implementation in the registry.
|
|
23
|
+
* Allows consumers to extend Beddel with additional LLM providers.
|
|
24
|
+
*
|
|
25
|
+
* @param name - Provider identifier (e.g., 'openai', 'anthropic')
|
|
26
|
+
* @param implementation - ProviderImplementation with createModel method
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* import { registerProvider } from 'beddel';
|
|
30
|
+
*
|
|
31
|
+
* registerProvider('openai', {
|
|
32
|
+
* createModel: (config) => {
|
|
33
|
+
* const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
34
|
+
* return openai(config.model || 'gpt-4');
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
*/
|
|
38
|
+
export function registerProvider(name, implementation) {
|
|
39
|
+
if (providerRegistry[name]) {
|
|
40
|
+
console.warn(`[Beddel] Provider '${name}' already registered, overwriting.`);
|
|
41
|
+
}
|
|
42
|
+
providerRegistry[name] = implementation;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a LanguageModel instance from a registered provider.
|
|
46
|
+
*
|
|
47
|
+
* @param provider - Provider name (must be registered in providerRegistry)
|
|
48
|
+
* @param config - Configuration including model name and provider-specific options
|
|
49
|
+
* @returns LanguageModel instance from the AI SDK
|
|
50
|
+
* @throws Error if provider is not found, listing available providers
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* const model = createModel('google', { model: 'gemini-1.5-flash' });
|
|
54
|
+
*/
|
|
55
|
+
export function createModel(provider, config) {
|
|
56
|
+
const impl = providerRegistry[provider];
|
|
57
|
+
if (!impl) {
|
|
58
|
+
const available = Object.keys(providerRegistry).join(', ') || 'none';
|
|
59
|
+
throw new Error(`Unknown provider: '${provider}'. Available: ${available}`);
|
|
60
|
+
}
|
|
61
|
+
return impl.createModel(config);
|
|
62
|
+
}
|
|
63
|
+
// =============================================================================
|
|
64
|
+
// Built-in Providers
|
|
65
|
+
// =============================================================================
|
|
66
|
+
/**
|
|
67
|
+
* Google Gemini Provider (Built-in)
|
|
68
|
+
*
|
|
69
|
+
* Uses @ai-sdk/google with GEMINI_API_KEY environment variable.
|
|
70
|
+
* Default model: gemini-1.5-flash
|
|
71
|
+
*
|
|
72
|
+
* Requirements: 1.2, 4.1
|
|
73
|
+
*/
|
|
74
|
+
registerProvider('google', {
|
|
75
|
+
createModel: (config) => {
|
|
76
|
+
const google = createGoogleGenerativeAI({
|
|
77
|
+
apiKey: process.env.GEMINI_API_KEY,
|
|
78
|
+
});
|
|
79
|
+
return google(config.model || 'gemini-1.5-flash');
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* Amazon Bedrock Provider (Built-in)
|
|
84
|
+
*
|
|
85
|
+
* Uses @ai-sdk/amazon-bedrock with AWS_BEARER_TOKEN_BEDROCK environment variable.
|
|
86
|
+
* Region is configured via AWS_REGION env var or defaults to 'us-east-1'.
|
|
87
|
+
* Default model: anthropic.claude-3-haiku-20240307-v1:0
|
|
88
|
+
*
|
|
89
|
+
* Requirements: 1.3, 4.2
|
|
90
|
+
*/
|
|
91
|
+
registerProvider('bedrock', {
|
|
92
|
+
createModel: (config) => {
|
|
93
|
+
const bedrock = createAmazonBedrock({
|
|
94
|
+
region: process.env.AWS_REGION || 'us-east-1',
|
|
95
|
+
});
|
|
96
|
+
return bedrock(config.model || 'anthropic.claude-3-haiku-20240307-v1:0');
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* OpenRouter Provider (Built-in)
|
|
101
|
+
*
|
|
102
|
+
* Uses @openrouter/ai-sdk-provider for access to 400+ models.
|
|
103
|
+
* Requires OPENROUTER_API_KEY environment variable.
|
|
104
|
+
* Default model: qwen/qwen3-coder:free (free tier)
|
|
105
|
+
*
|
|
106
|
+
* Requirements: 1.4, 4.3
|
|
107
|
+
*/
|
|
108
|
+
registerProvider('openrouter', {
|
|
109
|
+
createModel: (config) => {
|
|
110
|
+
const openrouter = createOpenRouter({
|
|
111
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
112
|
+
});
|
|
113
|
+
return openrouter(config.model || 'qwen/qwen3-coder:free');
|
|
114
|
+
},
|
|
115
|
+
});
|
package/dist/server/handler.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { NextRequest } from 'next/server';
|
|
2
2
|
export interface BeddelHandlerOptions {
|
|
3
|
+
/** Path to user-defined agents (relative to CWD). Default: 'src/agents' */
|
|
3
4
|
agentsPath?: string;
|
|
5
|
+
/** Disable built-in agents bundled with the package. Default: false */
|
|
6
|
+
disableBuiltinAgents?: boolean;
|
|
4
7
|
}
|
|
5
8
|
export type BeddelHandler = (request: NextRequest) => Promise<Response>;
|
|
6
9
|
export declare function createBeddelHandler(options?: BeddelHandlerOptions): BeddelHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/server/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/server/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C,MAAM,WAAW,oBAAoB;IACjC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAwDxE,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA0CrF"}
|
package/dist/server/handler.js
CHANGED
|
@@ -1,25 +1,56 @@
|
|
|
1
1
|
import { loadYaml } from '../core/parser';
|
|
2
2
|
import { WorkflowExecutor } from '../core/workflow';
|
|
3
3
|
import { join, normalize } from 'path';
|
|
4
|
+
import { access } from 'fs/promises';
|
|
5
|
+
import { getBuiltinAgentsPath } from '../agents';
|
|
4
6
|
/**
|
|
5
7
|
* Validate agentId to prevent path traversal attacks.
|
|
6
8
|
* Only allows alphanumeric characters, hyphens, and underscores.
|
|
7
|
-
*
|
|
8
|
-
* @param agentId - The agent identifier from request
|
|
9
|
-
* @returns true if valid, false otherwise
|
|
10
9
|
*/
|
|
11
10
|
function isValidAgentId(agentId) {
|
|
12
|
-
// Must be non-empty string
|
|
13
11
|
if (typeof agentId !== 'string' || agentId.length === 0) {
|
|
14
12
|
return false;
|
|
15
13
|
}
|
|
16
|
-
// Only allow safe characters: alphanumeric, hyphen, underscore
|
|
17
|
-
// No dots, slashes, or other path characters
|
|
18
14
|
const safePattern = /^[a-zA-Z0-9_-]+$/;
|
|
19
15
|
return safePattern.test(agentId);
|
|
20
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if a file exists at the given path
|
|
19
|
+
*/
|
|
20
|
+
async function fileExists(path) {
|
|
21
|
+
try {
|
|
22
|
+
await access(path);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve agent path with fallback chain:
|
|
31
|
+
* 1. User agents (agentsPath) - allows override
|
|
32
|
+
* 2. Built-in agents (package) - fallback
|
|
33
|
+
*/
|
|
34
|
+
async function resolveAgentPath(agentId, userAgentsPath, disableBuiltinAgents) {
|
|
35
|
+
// 1. First: try user agents (allows override of built-in)
|
|
36
|
+
const basePath = join(process.cwd(), userAgentsPath);
|
|
37
|
+
const userPath = normalize(join(basePath, `${agentId}.yaml`));
|
|
38
|
+
// Security: ensure resolved path is within user agents directory
|
|
39
|
+
if (userPath.startsWith(basePath) && await fileExists(userPath)) {
|
|
40
|
+
return userPath;
|
|
41
|
+
}
|
|
42
|
+
// 2. Fallback: built-in agents from package
|
|
43
|
+
if (!disableBuiltinAgents) {
|
|
44
|
+
const builtinPath = join(getBuiltinAgentsPath(), `${agentId}.yaml`);
|
|
45
|
+
if (await fileExists(builtinPath)) {
|
|
46
|
+
return builtinPath;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Agent not found: ${agentId}`);
|
|
50
|
+
}
|
|
21
51
|
export function createBeddelHandler(options = {}) {
|
|
22
52
|
const agentsPath = options.agentsPath || 'src/agents';
|
|
53
|
+
const disableBuiltinAgents = options.disableBuiltinAgents || false;
|
|
23
54
|
return async function POST(request) {
|
|
24
55
|
try {
|
|
25
56
|
const body = await request.json();
|
|
@@ -31,16 +62,10 @@ export function createBeddelHandler(options = {}) {
|
|
|
31
62
|
if (!isValidAgentId(agentId)) {
|
|
32
63
|
return Response.json({ error: 'Invalid agentId: only alphanumeric characters, hyphens, and underscores allowed' }, { status: 400 });
|
|
33
64
|
}
|
|
34
|
-
// Resolve path
|
|
35
|
-
const
|
|
36
|
-
const fullPath = normalize(join(basePath, `${agentId}.yaml`));
|
|
37
|
-
// Double-check: ensure resolved path is within agents directory
|
|
38
|
-
if (!fullPath.startsWith(basePath)) {
|
|
39
|
-
return Response.json({ error: 'Invalid agentId' }, { status: 400 });
|
|
40
|
-
}
|
|
65
|
+
// Resolve agent path with fallback chain
|
|
66
|
+
const fullPath = await resolveAgentPath(agentId, agentsPath, disableBuiltinAgents);
|
|
41
67
|
const yaml = await loadYaml(fullPath);
|
|
42
68
|
const executor = new WorkflowExecutor(yaml);
|
|
43
|
-
// Pass the entire body (minus agentId) as input ($input)
|
|
44
69
|
const result = await executor.execute(input);
|
|
45
70
|
if (result instanceof Response) {
|
|
46
71
|
return result;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Beddel Protocol - Validation Module
|
|
3
|
+
* Schema validation using Zod with stream/output constraint enforcement
|
|
4
|
+
*/
|
|
5
|
+
import { ZodSchema } from 'zod';
|
|
6
|
+
import type { SchemaSpec, ParsedYaml } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Validation error with detailed issue list
|
|
9
|
+
*/
|
|
10
|
+
export declare class ValidationError extends Error {
|
|
11
|
+
details: string[];
|
|
12
|
+
constructor(message: string, details: string[]);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Convert SchemaSpec to Zod schema
|
|
16
|
+
*/
|
|
17
|
+
export declare function schemaSpecToZod(spec: SchemaSpec): ZodSchema;
|
|
18
|
+
/**
|
|
19
|
+
* Validate data against SchemaSpec
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateSchema(spec: SchemaSpec, data: unknown): {
|
|
22
|
+
success: true;
|
|
23
|
+
data: unknown;
|
|
24
|
+
} | {
|
|
25
|
+
success: false;
|
|
26
|
+
error: ValidationError;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Validate YAML structure for stream/output constraint
|
|
30
|
+
* @throws ValidationError if stream: true AND output schema is defined
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateYamlConstraints(yaml: ParsedYaml): void;
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAK,SAAS,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEvD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACF,OAAO,EAAE,MAAM,EAAE;gBAAzC,OAAO,EAAE,MAAM,EAAS,OAAO,EAAE,MAAM,EAAE;CAIxD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAqB3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,OAAO,GACd;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAa/E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAiB9D"}
|