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.
Files changed (36) hide show
  1. package/README.md +71 -2
  2. package/dist/agents/assistant-bedrock.yaml +20 -0
  3. package/dist/agents/assistant-openrouter.yaml +17 -0
  4. package/dist/agents/assistant.yaml +17 -0
  5. package/dist/agents/index.d.ts +24 -0
  6. package/dist/agents/index.d.ts.map +1 -0
  7. package/dist/agents/index.js +37 -0
  8. package/dist/index.d.ts +4 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +4 -0
  11. package/dist/primitives/llm.d.ts.map +1 -1
  12. package/dist/primitives/llm.js +4 -5
  13. package/dist/providers/index.d.ts +63 -0
  14. package/dist/providers/index.d.ts.map +1 -0
  15. package/dist/providers/index.js +115 -0
  16. package/dist/server/handler.d.ts +3 -0
  17. package/dist/server/handler.d.ts.map +1 -1
  18. package/dist/server/handler.js +39 -14
  19. package/dist/validation/index.d.ts +33 -0
  20. package/dist/validation/index.d.ts.map +1 -0
  21. package/dist/validation/index.js +74 -0
  22. package/docs/architecture/api-reference.md +56 -0
  23. package/docs/architecture/components.md +57 -1
  24. package/docs/architecture/core-workflows.md +31 -1
  25. package/docs/architecture/high-level-architecture.md +7 -2
  26. package/docs/architecture/source-tree.md +3 -1
  27. package/docs/architecture/tech-stack.md +1 -0
  28. package/package.json +8 -2
  29. package/src/agents/assistant-bedrock.yaml +20 -0
  30. package/src/agents/assistant-openrouter.yaml +17 -0
  31. package/src/agents/assistant.yaml +17 -0
  32. package/src/agents/index.ts +45 -0
  33. package/src/index.ts +13 -0
  34. package/src/primitives/llm.ts +5 -5
  35. package/src/providers/index.ts +143 -0
  36. 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
- ### 3. Set Environment Variable
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
+ [![Subscribe on Substack](https://img.shields.io/badge/Subscribe-Substack-orange?style=for-the-badge&logo=substack)](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
@@ -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;AAaH,OAAO,KAAK,EAAgC,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAI/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;AA0DD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,EAAE,gBA4E1B,CAAC"}
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"}
@@ -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
- // Initialize Google Generative AI provider
91
- const google = createGoogleGenerativeAI({
92
- apiKey: process.env.GEMINI_API_KEY,
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
+ });
@@ -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;AAK1C,MAAM,WAAW,oBAAoB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAsBxE,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAgDrF"}
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"}
@@ -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 relative to CWD (usually project root)
35
- const basePath = join(process.cwd(), agentsPath);
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"}