substrai-lambdallm 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +64 -24
  2. package/dist/agents/agent.d.ts +57 -0
  3. package/dist/agents/agent.d.ts.map +1 -0
  4. package/dist/agents/agent.js +93 -0
  5. package/dist/agents/agent.js.map +1 -0
  6. package/dist/chains/chain.d.ts +51 -0
  7. package/dist/chains/chain.d.ts.map +1 -0
  8. package/dist/chains/chain.js +103 -0
  9. package/dist/chains/chain.js.map +1 -0
  10. package/dist/core/context.d.ts +34 -0
  11. package/dist/core/context.d.ts.map +1 -0
  12. package/dist/core/context.js +186 -0
  13. package/dist/core/context.js.map +1 -0
  14. package/dist/core/exceptions.d.ts +20 -0
  15. package/dist/core/exceptions.d.ts.map +1 -0
  16. package/dist/core/exceptions.js +43 -0
  17. package/dist/core/exceptions.js.map +1 -0
  18. package/dist/core/handler.d.ts +37 -0
  19. package/dist/core/handler.d.ts.map +1 -0
  20. package/dist/core/handler.js +74 -0
  21. package/dist/core/handler.js.map +1 -0
  22. package/dist/core/models.d.ts +34 -0
  23. package/dist/core/models.d.ts.map +1 -0
  24. package/dist/core/models.js +33 -0
  25. package/dist/core/models.js.map +1 -0
  26. package/dist/core/prompt.d.ts +29 -0
  27. package/dist/core/prompt.d.ts.map +1 -0
  28. package/dist/core/prompt.js +50 -0
  29. package/dist/core/prompt.js.map +1 -0
  30. package/dist/index.d.ts +19 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +37 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/middleware/base.d.ts +10 -0
  35. package/dist/middleware/base.d.ts.map +1 -0
  36. package/dist/middleware/base.js +17 -0
  37. package/dist/middleware/base.js.map +1 -0
  38. package/dist/state/session.d.ts +40 -0
  39. package/dist/state/session.d.ts.map +1 -0
  40. package/dist/state/session.js +52 -0
  41. package/dist/state/session.js.map +1 -0
  42. package/jest.config.js +6 -0
  43. package/package.json +26 -10
  44. package/src/agents/agent.ts +137 -0
  45. package/src/chains/chain.ts +145 -0
  46. package/src/core/context.ts +211 -0
  47. package/src/core/exceptions.ts +41 -0
  48. package/src/core/handler.ts +95 -0
  49. package/src/core/models.ts +47 -0
  50. package/src/core/prompt.ts +71 -0
  51. package/src/index.ts +25 -0
  52. package/src/middleware/base.ts +17 -0
  53. package/src/state/session.ts +73 -0
  54. package/tsconfig.json +27 -0
  55. package/index.d.ts +0 -24
  56. package/index.js +0 -57
package/README.md CHANGED
@@ -1,41 +1,83 @@
1
1
  # substrai-lambdallm
2
2
 
3
- **Serverless-native LLM orchestration framework for AWS Lambda.**
3
+ **Serverless-native LLM orchestration framework for AWS Lambda (TypeScript)**
4
4
 
5
- [![PyPI](https://badge.fury.io/py/substrai-lambdallm.svg)](https://pypi.org/project/substrai-lambdallm/)
5
+ [![npm](https://badge.fury.io/js/substrai-lambdallm.svg)](https://www.npmjs.com/package/substrai-lambdallm)
6
6
  [![GitHub](https://img.shields.io/github/stars/substrai/lambdallm)](https://github.com/substrai/lambdallm)
7
- [![Docs](https://img.shields.io/badge/docs-substrai.github.io-blue)](https://substrai.github.io/lambdallm)
8
7
 
9
- > **Note:** The primary implementation is in Python. TypeScript SDK coming soon.
10
-
11
- ## Install (Python)
8
+ ## Install
12
9
 
13
10
  ```bash
14
- pip install substrai-lambdallm[bedrock]
11
+ npm install substrai-lambdallm @aws-sdk/client-bedrock-runtime
15
12
  ```
16
13
 
17
14
  ## Quick Start
18
15
 
19
- ```python
20
- from lambdallm import handler, Prompt, Model
16
+ ```typescript
17
+ import { handler, Model } from 'substrai-lambdallm';
21
18
 
22
- @handler(model=Model.CLAUDE_3_HAIKU)
23
- def lambda_handler(event, context):
24
- result = context.invoke("Summarize: {text}", text=event["body"]["text"])
25
- return {"statusCode": 200, "body": result}
19
+ export const lambdaHandler = handler(
20
+ { model: Model.CLAUDE_3_HAIKU, maxRetries: 3 },
21
+ async (event, context) => {
22
+ const result = await context.invoke('Summarize: {text}', { text: event.body.text });
23
+ return { statusCode: 200, body: { result, cost: context.totalCost } };
24
+ }
25
+ );
26
26
  ```
27
27
 
28
28
  ## Features
29
29
 
30
- - < 5MB package (vs 400MB+ for LangChain)
31
- - Cold-start optimized (lazy imports, connection pooling)
32
- - DynamoDB-native state (conversation memory persists)
33
- - Multi-step chains with checkpoint/resume
34
- - AI Agents with tool sandboxing
35
- - Cost-aware model routing
36
- - One-command deploy
37
- - A/B testing for prompts
38
- - Full observability (X-Ray + CloudWatch)
30
+ - **< 50KB** package size
31
+ - **TypeScript-first** with full type safety
32
+ - **Bedrock provider** (Claude, Titan, Llama)
33
+ - **Retry with backoff** and fallback models
34
+ - **Prompt templates** with variable validation
35
+ - **Multi-step chains** with checkpoint/resume
36
+ - **AI Agents** with ReAct loop and tools
37
+ - **Session state** with sliding window memory
38
+ - **Cost tracking** per request
39
+
40
+ ## Chains
41
+
42
+ ```typescript
43
+ import { Chain, Step } from 'substrai-lambdallm';
44
+
45
+ const pipeline = new Chain({
46
+ name: 'analysis',
47
+ steps: [
48
+ new Step({ name: 'extract', prompt: 'Extract entities: {input}' }),
49
+ new Step({ name: 'classify', prompt: 'Classify: {extract.output}' }),
50
+ ],
51
+ timeoutStrategy: 'checkpoint',
52
+ });
53
+
54
+ const result = await pipeline.run(context, { input: 'document text' });
55
+ ```
56
+
57
+ ## Agents
58
+
59
+ ```typescript
60
+ import { Agent, Tool } from 'substrai-lambdallm';
61
+
62
+ const search = Tool({ description: 'Search docs' })(
63
+ (input: any) => `Results for ${input.query}`
64
+ );
65
+
66
+ const agent = new Agent({
67
+ name: 'researcher',
68
+ systemPrompt: 'You are a research assistant.',
69
+ tools: [search],
70
+ maxIterations: 5,
71
+ });
72
+
73
+ const result = await agent.run('What is LambdaLLM?', context);
74
+ ```
75
+
76
+ ## Also Available in Python
77
+
78
+ ```bash
79
+ pip install substrai-lambdallm[bedrock]
80
+ ```
39
81
 
40
82
  ## Links
41
83
 
@@ -46,5 +88,3 @@ def lambda_handler(event, context):
46
88
  ## Author
47
89
 
48
90
  **Gaurav Kumar Sinha** — Founder, [SubstrAI](https://github.com/substrai)
49
-
50
- Email: gaurav@substrai.dev
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Agent and Tool system for LambdaLLM.
3
+ */
4
+ import { LambdaLLMContext } from '../core/context';
5
+ export interface ToolDefinition {
6
+ name: string;
7
+ description: string;
8
+ parameters: Array<{
9
+ name: string;
10
+ type: string;
11
+ description: string;
12
+ required: boolean;
13
+ }>;
14
+ func: (...args: any[]) => any;
15
+ }
16
+ /**
17
+ * Decorator-like function to define a tool.
18
+ */
19
+ export declare function Tool(options: {
20
+ description: string;
21
+ name?: string;
22
+ }): (func: Function) => ToolDefinition;
23
+ export interface AgentResult {
24
+ answer: string;
25
+ status: 'completed' | 'max_iterations' | 'timeout' | 'cost_limit';
26
+ totalIterations: number;
27
+ totalToolCalls: number;
28
+ totalCostUsd: number;
29
+ totalLatencyMs: number;
30
+ steps: Array<{
31
+ thought: string;
32
+ toolName?: string;
33
+ toolOutput?: string;
34
+ isFinal: boolean;
35
+ }>;
36
+ }
37
+ export interface AgentOptions {
38
+ name: string;
39
+ systemPrompt: string;
40
+ tools: ToolDefinition[];
41
+ maxIterations?: number;
42
+ timeoutBuffer?: number;
43
+ maxCostUsd?: number;
44
+ }
45
+ export declare class Agent {
46
+ name: string;
47
+ systemPrompt: string;
48
+ tools: ToolDefinition[];
49
+ maxIterations: number;
50
+ timeoutBuffer: number;
51
+ maxCostUsd?: number;
52
+ constructor(options: AgentOptions);
53
+ run(query: string, context: LambdaLLMContext): Promise<AgentResult>;
54
+ private parseDecision;
55
+ private buildResult;
56
+ }
57
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/agents/agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1F,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,IACjD,MAAM,QAAQ,KAAG,cAAc,CAQjD;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,GAAG,gBAAgB,GAAG,SAAS,GAAG,YAAY,CAAC;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC7F;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,KAAK;IACT,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,YAAY;IAS3B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;IA+CzE,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,WAAW;CAYpB"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /**
3
+ * Agent and Tool system for LambdaLLM.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Agent = void 0;
7
+ exports.Tool = Tool;
8
+ /**
9
+ * Decorator-like function to define a tool.
10
+ */
11
+ function Tool(options) {
12
+ return function (func) {
13
+ return {
14
+ name: options.name || func.name,
15
+ description: options.description,
16
+ parameters: [],
17
+ func: func,
18
+ };
19
+ };
20
+ }
21
+ class Agent {
22
+ constructor(options) {
23
+ this.name = options.name;
24
+ this.systemPrompt = options.systemPrompt;
25
+ this.tools = options.tools;
26
+ this.maxIterations = options.maxIterations || 10;
27
+ this.timeoutBuffer = options.timeoutBuffer || 30;
28
+ this.maxCostUsd = options.maxCostUsd;
29
+ }
30
+ async run(query, context) {
31
+ const startTime = Date.now();
32
+ const steps = [];
33
+ let toolCalls = 0;
34
+ const toolDescriptions = this.tools.map(t => `- ${t.name}: ${t.description}`).join('\n');
35
+ const systemContent = `${this.systemPrompt}\n\nTools available:\n${toolDescriptions}\n\nRespond with JSON: {"thought": "...", "tool_name": "...", "tool_input": {...}} or {"thought": "...", "final_answer": "..."}`;
36
+ let messages = `System: ${systemContent}\n\nUser: ${query}\n\nAssistant:`;
37
+ for (let i = 0; i < this.maxIterations; i++) {
38
+ if (context.remainingTimeMs < this.timeoutBuffer * 1000) {
39
+ return this.buildResult(steps, 'timeout', startTime, toolCalls, context.totalCost, 'Approaching timeout.');
40
+ }
41
+ if (this.maxCostUsd && context.totalCost >= this.maxCostUsd) {
42
+ return this.buildResult(steps, 'cost_limit', startTime, toolCalls, context.totalCost, 'Cost limit reached.');
43
+ }
44
+ const response = await context.invoke(messages);
45
+ const decision = this.parseDecision(response);
46
+ if (decision.final_answer) {
47
+ steps.push({ thought: decision.thought || '', isFinal: true });
48
+ return this.buildResult(steps, 'completed', startTime, toolCalls, context.totalCost, decision.final_answer);
49
+ }
50
+ if (decision.tool_name) {
51
+ const tool = this.tools.find(t => t.name === decision.tool_name);
52
+ let toolOutput = 'Tool not found';
53
+ if (tool) {
54
+ try {
55
+ toolOutput = String(tool.func(decision.tool_input || {}));
56
+ toolCalls++;
57
+ }
58
+ catch (e) {
59
+ toolOutput = `Error: ${e.message}`;
60
+ }
61
+ }
62
+ steps.push({ thought: decision.thought || '', toolName: decision.tool_name, toolOutput, isFinal: false });
63
+ messages += `\n${response}\nUser: Tool '${decision.tool_name}' returned: ${toolOutput}\nContinue.\nAssistant:`;
64
+ }
65
+ }
66
+ return this.buildResult(steps, 'max_iterations', startTime, toolCalls, context.totalCost, 'Max iterations reached.');
67
+ }
68
+ parseDecision(response) {
69
+ try {
70
+ if (response.trim().startsWith('{'))
71
+ return JSON.parse(response.trim());
72
+ if (response.includes('```json')) {
73
+ const json = response.split('```json')[1].split('```')[0];
74
+ return JSON.parse(json.trim());
75
+ }
76
+ return { thought: 'Direct response', final_answer: response };
77
+ }
78
+ catch {
79
+ return { thought: 'Could not parse', final_answer: response };
80
+ }
81
+ }
82
+ buildResult(steps, status, startTime, toolCalls, cost, answer) {
83
+ return {
84
+ answer, status, steps,
85
+ totalIterations: steps.length,
86
+ totalToolCalls: toolCalls,
87
+ totalCostUsd: cost,
88
+ totalLatencyMs: Date.now() - startTime,
89
+ };
90
+ }
91
+ }
92
+ exports.Agent = Agent;
93
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agents/agent.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAeH,oBASC;AAZD;;GAEG;AACH,SAAgB,IAAI,CAAC,OAA+C;IAClE,OAAO,UAAU,IAAc;QAC7B,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;YAC/B,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE,EAAE;YACd,IAAI,EAAE,IAAW;SAClB,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAqBD,MAAa,KAAK;IAQhB,YAAY,OAAqB;QAC/B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAa,EAAE,OAAyB;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAyB,EAAE,CAAC;QACvC,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzF,MAAM,aAAa,GAAG,GAAG,IAAI,CAAC,YAAY,yBAAyB,gBAAgB,iIAAiI,CAAC;QAErN,IAAI,QAAQ,GAAG,WAAW,aAAa,aAAa,KAAK,gBAAgB,CAAC;QAE1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,EAAE,CAAC;gBACxD,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;YAC7G,CAAC;YAED,IAAI,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;YAC/G,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAE9C,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC/D,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC9G,CAAC;YAED,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC;gBACjE,IAAI,UAAU,GAAG,gBAAgB,CAAC;gBAClC,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,CAAC;wBACH,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;wBAC1D,SAAS,EAAE,CAAC;oBACd,CAAC;oBAAC,OAAO,CAAM,EAAE,CAAC;wBAChB,UAAU,GAAG,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;oBACrC,CAAC;gBACH,CAAC;gBAED,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC1G,QAAQ,IAAI,KAAK,QAAQ,iBAAiB,QAAQ,CAAC,SAAS,eAAe,UAAU,yBAAyB,CAAC;YACjH,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAC;IACvH,CAAC;IAEO,aAAa,CAAC,QAAgB;QACpC,IAAI,CAAC;YACH,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACxE,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;QAChE,CAAC;IACH,CAAC;IAEO,WAAW,CACjB,KAA2B,EAAE,MAA6B,EAC1D,SAAiB,EAAE,SAAiB,EAAE,IAAY,EAAE,MAAc;QAElE,OAAO;YACL,MAAM,EAAE,MAAM,EAAE,KAAK;YACrB,eAAe,EAAE,KAAK,CAAC,MAAM;YAC7B,cAAc,EAAE,SAAS;YACzB,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACvC,CAAC;IACJ,CAAC;CACF;AAzFD,sBAyFC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Multi-step chain pipeline for LambdaLLM.
3
+ */
4
+ import { LambdaLLMContext } from '../core/context';
5
+ export interface StepOptions {
6
+ name: string;
7
+ prompt?: string;
8
+ func?: (outputs: Record<string, any>) => any;
9
+ condition?: (outputs: Record<string, any>) => boolean;
10
+ }
11
+ export declare class Step {
12
+ name: string;
13
+ prompt?: string;
14
+ func?: (outputs: Record<string, any>) => any;
15
+ condition?: (outputs: Record<string, any>) => boolean;
16
+ constructor(options: StepOptions);
17
+ get isLlmStep(): boolean;
18
+ get isTransformStep(): boolean;
19
+ }
20
+ export interface ChainResult {
21
+ chainName: string;
22
+ status: 'completed' | 'checkpointed' | 'failed' | 'truncated';
23
+ steps: Array<{
24
+ name: string;
25
+ output: any;
26
+ costUsd: number;
27
+ latencyMs: number;
28
+ skipped: boolean;
29
+ }>;
30
+ finalOutput: any;
31
+ totalCostUsd: number;
32
+ totalLatencyMs: number;
33
+ completedSteps: number;
34
+ checkpoint?: any;
35
+ }
36
+ export interface ChainOptions {
37
+ name: string;
38
+ steps: Step[];
39
+ timeoutStrategy?: 'fail-fast' | 'checkpoint' | 'truncate';
40
+ maxTotalCost?: number;
41
+ }
42
+ export declare class Chain {
43
+ name: string;
44
+ steps: Step[];
45
+ timeoutStrategy: string;
46
+ maxTotalCost?: number;
47
+ constructor(options: ChainOptions);
48
+ run(context: LambdaLLMContext, variables: Record<string, any>): Promise<ChainResult>;
49
+ private resolveVariables;
50
+ }
51
+ //# sourceMappingURL=chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../../src/chains/chain.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;CACvD;AAED,qBAAa,IAAI;IACR,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;gBAEjD,OAAO,EAAE,WAAW;IAUhC,IAAI,SAAS,IAAI,OAAO,CAA0B;IAClD,IAAI,eAAe,IAAI,OAAO,CAAwB;CACvD;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC9D,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClG,WAAW,EAAE,GAAG,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,eAAe,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,KAAK;IACT,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,YAAY;IAQ3B,GAAG,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAyE1F,OAAO,CAAC,gBAAgB;CAKzB"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ /**
3
+ * Multi-step chain pipeline for LambdaLLM.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Chain = exports.Step = void 0;
7
+ class Step {
8
+ constructor(options) {
9
+ if (!options.prompt && !options.func) {
10
+ throw new Error(`Step '${options.name}' must have either prompt or func`);
11
+ }
12
+ this.name = options.name;
13
+ this.prompt = options.prompt;
14
+ this.func = options.func;
15
+ this.condition = options.condition;
16
+ }
17
+ get isLlmStep() { return !!this.prompt; }
18
+ get isTransformStep() { return !!this.func; }
19
+ }
20
+ exports.Step = Step;
21
+ class Chain {
22
+ constructor(options) {
23
+ if (!options.steps.length)
24
+ throw new Error('Chain must have at least one step');
25
+ this.name = options.name;
26
+ this.steps = options.steps;
27
+ this.timeoutStrategy = options.timeoutStrategy || 'fail-fast';
28
+ this.maxTotalCost = options.maxTotalCost;
29
+ }
30
+ async run(context, variables) {
31
+ const startTime = Date.now();
32
+ const outputs = { ...variables };
33
+ const stepResults = [];
34
+ let totalCost = 0;
35
+ for (let i = 0; i < this.steps.length; i++) {
36
+ const step = this.steps[i];
37
+ // Check timeout
38
+ if (this.timeoutStrategy === 'checkpoint' && context.shouldCheckpoint) {
39
+ return {
40
+ chainName: this.name, status: 'checkpointed', steps: stepResults,
41
+ finalOutput: stepResults[stepResults.length - 1]?.output,
42
+ totalCostUsd: totalCost, totalLatencyMs: Date.now() - startTime,
43
+ completedSteps: stepResults.filter(s => !s.skipped).length,
44
+ checkpoint: { nextStepIndex: i, outputs },
45
+ };
46
+ }
47
+ // Check cost
48
+ if (this.maxTotalCost && totalCost >= this.maxTotalCost) {
49
+ return {
50
+ chainName: this.name, status: 'truncated', steps: stepResults,
51
+ finalOutput: stepResults[stepResults.length - 1]?.output,
52
+ totalCostUsd: totalCost, totalLatencyMs: Date.now() - startTime,
53
+ completedSteps: stepResults.filter(s => !s.skipped).length,
54
+ };
55
+ }
56
+ // Check condition
57
+ if (step.condition && !step.condition(outputs)) {
58
+ stepResults.push({ name: step.name, output: null, costUsd: 0, latencyMs: 0, skipped: true });
59
+ continue;
60
+ }
61
+ const stepStart = Date.now();
62
+ try {
63
+ let output;
64
+ if (step.isLlmStep) {
65
+ const resolved = this.resolveVariables(step.prompt, outputs);
66
+ output = await context.invoke(resolved);
67
+ }
68
+ else if (step.func) {
69
+ output = step.func(outputs);
70
+ }
71
+ const stepCost = context.totalCost - totalCost;
72
+ totalCost = context.totalCost;
73
+ outputs[step.name] = output;
74
+ outputs[`${step.name}.output`] = output;
75
+ stepResults.push({
76
+ name: step.name, output, costUsd: stepCost,
77
+ latencyMs: Date.now() - stepStart, skipped: false,
78
+ });
79
+ }
80
+ catch (e) {
81
+ stepResults.push({ name: step.name, output: null, costUsd: 0, latencyMs: Date.now() - stepStart, skipped: false });
82
+ return {
83
+ chainName: this.name, status: 'failed', steps: stepResults,
84
+ finalOutput: null, totalCostUsd: totalCost, totalLatencyMs: Date.now() - startTime,
85
+ completedSteps: stepResults.filter(s => !s.skipped).length,
86
+ };
87
+ }
88
+ }
89
+ return {
90
+ chainName: this.name, status: 'completed', steps: stepResults,
91
+ finalOutput: stepResults[stepResults.length - 1]?.output,
92
+ totalCostUsd: totalCost, totalLatencyMs: Date.now() - startTime,
93
+ completedSteps: stepResults.filter(s => !s.skipped).length,
94
+ };
95
+ }
96
+ resolveVariables(template, outputs) {
97
+ return template.replace(/\{([a-zA-Z_][a-zA-Z0-9_.]*)\}/g, (_, key) => {
98
+ return key in outputs ? String(outputs[key]) : `{${key}}`;
99
+ });
100
+ }
101
+ }
102
+ exports.Chain = Chain;
103
+ //# sourceMappingURL=chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../../src/chains/chain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * LambdaLLM Context - passed to handler functions.
3
+ */
4
+ import { ModelConfig } from './models';
5
+ export declare class LambdaLLMContext {
6
+ model: ModelConfig;
7
+ timeoutBuffer: number;
8
+ maxRetries: number;
9
+ fallbackModel?: ModelConfig;
10
+ private lambdaContext;
11
+ private _totalCost;
12
+ private _invocationCount;
13
+ private _provider;
14
+ constructor(options: {
15
+ model: ModelConfig;
16
+ timeoutBuffer?: number;
17
+ maxRetries?: number;
18
+ fallbackModel?: ModelConfig;
19
+ lambdaContext?: any;
20
+ });
21
+ get remainingTimeMs(): number;
22
+ get shouldCheckpoint(): boolean;
23
+ get totalCost(): number;
24
+ get invocationCount(): number;
25
+ invoke(prompt: string, variables?: Record<string, any>): Promise<string>;
26
+ invokeStructured(prompt: string, variables?: Record<string, any>): Promise<any>;
27
+ getRawClient(service?: string): any;
28
+ private formatPrompt;
29
+ private invokeWithRetry;
30
+ private callProvider;
31
+ private buildRequestBody;
32
+ private parseResponse;
33
+ }
34
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAgC,MAAM,UAAU,CAAC;AAGrE,qBAAa,gBAAgB;IACpB,KAAK,EAAE,WAAW,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,WAAW,CAAC;IACnC,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,SAAS,CAAa;gBAElB,OAAO,EAAE;QACnB,KAAK,EAAE,WAAW,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,WAAW,CAAC;QAC5B,aAAa,CAAC,EAAE,GAAG,CAAC;KACrB;IAQD,IAAI,eAAe,IAAI,MAAM,CAK5B;IAED,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAEK,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAcxE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAoBrF,YAAY,CAAC,OAAO,SAAoB,GAAG,GAAG;IAU9C,OAAO,CAAC,YAAY;YAQN,eAAe;YA0Bf,YAAY;IAiC1B,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,aAAa;CAsBtB"}