@loopstack/agent-examples 0.1.1

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 (53) hide show
  1. package/README.md +150 -0
  2. package/dist/agent-examples.module.d.ts +3 -0
  3. package/dist/agent-examples.module.d.ts.map +1 -0
  4. package/dist/agent-examples.module.js +52 -0
  5. package/dist/agent-examples.module.js.map +1 -0
  6. package/dist/index.d.ts +6 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +22 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/tools/calculator.tool.d.ts +15 -0
  11. package/dist/tools/calculator.tool.d.ts.map +1 -0
  12. package/dist/tools/calculator.tool.js +51 -0
  13. package/dist/tools/calculator.tool.js.map +1 -0
  14. package/dist/tools/index.d.ts +3 -0
  15. package/dist/tools/index.d.ts.map +1 -0
  16. package/dist/tools/index.js +19 -0
  17. package/dist/tools/index.js.map +1 -0
  18. package/dist/tools/weather-lookup.tool.d.ts +10 -0
  19. package/dist/tools/weather-lookup.tool.d.ts.map +1 -0
  20. package/dist/tools/weather-lookup.tool.js +36 -0
  21. package/dist/tools/weather-lookup.tool.js.map +1 -0
  22. package/dist/workflows/agent/agent-example.workflow.d.ts +9 -0
  23. package/dist/workflows/agent/agent-example.workflow.d.ts.map +1 -0
  24. package/dist/workflows/agent/agent-example.workflow.js +62 -0
  25. package/dist/workflows/agent/agent-example.workflow.js.map +1 -0
  26. package/dist/workflows/agent/templates/system.md +4 -0
  27. package/dist/workflows/code-agent/code-agent-example.workflow.d.ts +12 -0
  28. package/dist/workflows/code-agent/code-agent-example.workflow.d.ts.map +1 -0
  29. package/dist/workflows/code-agent/code-agent-example.workflow.js +75 -0
  30. package/dist/workflows/code-agent/code-agent-example.workflow.js.map +1 -0
  31. package/dist/workflows/custom-agent/custom-agent-example.workflow.d.ts +30 -0
  32. package/dist/workflows/custom-agent/custom-agent-example.workflow.d.ts.map +1 -0
  33. package/dist/workflows/custom-agent/custom-agent-example.workflow.js +165 -0
  34. package/dist/workflows/custom-agent/custom-agent-example.workflow.js.map +1 -0
  35. package/dist/workflows/custom-agent/templates/system.md +14 -0
  36. package/dist/workflows/custom-agent/templates/wrap-up.md +3 -0
  37. package/dist/workflows/mcp-linear/mcp-linear-example.workflow.d.ts +18 -0
  38. package/dist/workflows/mcp-linear/mcp-linear-example.workflow.d.ts.map +1 -0
  39. package/dist/workflows/mcp-linear/mcp-linear-example.workflow.js +65 -0
  40. package/dist/workflows/mcp-linear/mcp-linear-example.workflow.js.map +1 -0
  41. package/package.json +54 -0
  42. package/src/agent-examples.module.ts +40 -0
  43. package/src/index.ts +5 -0
  44. package/src/tools/calculator.tool.ts +47 -0
  45. package/src/tools/index.ts +2 -0
  46. package/src/tools/weather-lookup.tool.ts +29 -0
  47. package/src/workflows/agent/agent-example.workflow.ts +40 -0
  48. package/src/workflows/agent/templates/system.md +4 -0
  49. package/src/workflows/code-agent/code-agent-example.workflow.ts +56 -0
  50. package/src/workflows/custom-agent/custom-agent-example.workflow.ts +202 -0
  51. package/src/workflows/custom-agent/templates/system.md +14 -0
  52. package/src/workflows/custom-agent/templates/wrap-up.md +3 -0
  53. package/src/workflows/mcp-linear/mcp-linear-example.workflow.ts +52 -0
@@ -0,0 +1,30 @@
1
+ import { BaseWorkflow } from '@loopstack/common';
2
+ import type { TransitionInput } from '@loopstack/common';
3
+ import type { LlmDelegateResult, LlmGenerateTextResult } from '@loopstack/llm-provider-module';
4
+ import { LlmDelegateToolCallsTool, LlmGenerateTextTool, LlmUpdateToolResultTool } from '@loopstack/llm-provider-module';
5
+ interface CustomAgentState {
6
+ llmResult?: LlmGenerateTextResult;
7
+ delegateResult?: LlmDelegateResult;
8
+ turnCount: number;
9
+ }
10
+ export declare class CustomAgentExampleWorkflow extends BaseWorkflow {
11
+ private readonly llmGenerateText;
12
+ private readonly llmDelegateToolCalls;
13
+ private readonly llmUpdateToolResult;
14
+ constructor(llmGenerateText: LlmGenerateTextTool, llmDelegateToolCalls: LlmDelegateToolCallsTool, llmUpdateToolResult: LlmUpdateToolResultTool);
15
+ setup(_state: CustomAgentState): Promise<void>;
16
+ llmTurn(state: CustomAgentState): Promise<void>;
17
+ notifyOverBudget(_state: CustomAgentState): Promise<void>;
18
+ wrapUp(_state: CustomAgentState): Promise<void>;
19
+ executeToolCalls(state: CustomAgentState): Promise<void>;
20
+ toolResultReceived(state: CustomAgentState, input: TransitionInput): Promise<void>;
21
+ toolsComplete(_state: CustomAgentState): void;
22
+ respond(_state: CustomAgentState): void;
23
+ private hasBudget;
24
+ private isOverBudget;
25
+ private hasToolCalls;
26
+ private allToolsComplete;
27
+ private isEndTurn;
28
+ }
29
+ export {};
30
+ //# sourceMappingURL=custom-agent-example.workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-agent-example.workflow.d.ts","sourceRoot":"","sources":["../../../src/workflows/custom-agent/custom-agent-example.workflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAiD,MAAM,mBAAmB,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EAEnB,uBAAuB,EACxB,MAAM,gCAAgC,CAAC;AAIxC,UAAU,gBAAgB;IACxB,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAcD,qBAKa,0BAA2B,SAAQ,YAAY;IAExD,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAFnB,eAAe,EAAE,mBAAmB,EACpC,oBAAoB,EAAE,wBAAwB,EAC9C,mBAAmB,EAAE,uBAAuB;IAUzD,KAAK,CAAC,MAAM,EAAE,gBAAgB;IA0B9B,OAAO,CAAC,KAAK,EAAE,gBAAgB;IA2B/B,gBAAgB,CAAC,MAAM,EAAE,gBAAgB;IAezC,MAAM,CAAC,MAAM,EAAE,gBAAgB;IAoB/B,gBAAgB,CAAC,KAAK,EAAE,gBAAgB;IAcxC,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe;IAcxE,aAAa,CAAC,MAAM,EAAE,gBAAgB;IAStC,OAAO,CAAC,MAAM,EAAE,gBAAgB;IAGhC,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,SAAS;CAGlB"}
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CustomAgentExampleWorkflow = void 0;
13
+ const node_path_1 = require("node:path");
14
+ const common_1 = require("@loopstack/common");
15
+ const llm_provider_module_1 = require("@loopstack/llm-provider-module");
16
+ const MAX_TURNS = 2;
17
+ let CustomAgentExampleWorkflow = class CustomAgentExampleWorkflow extends common_1.BaseWorkflow {
18
+ llmGenerateText;
19
+ llmDelegateToolCalls;
20
+ llmUpdateToolResult;
21
+ constructor(llmGenerateText, llmDelegateToolCalls, llmUpdateToolResult) {
22
+ super();
23
+ this.llmGenerateText = llmGenerateText;
24
+ this.llmDelegateToolCalls = llmDelegateToolCalls;
25
+ this.llmUpdateToolResult = llmUpdateToolResult;
26
+ }
27
+ async setup(_state) {
28
+ await this.documentStore.save(common_1.MarkdownDocument, {
29
+ markdown: '# Custom Agent Example\n\n' +
30
+ `This agent has a budget of **${MAX_TURNS} tool-using turns**. ` +
31
+ 'Once the budget is hit, the workflow forces a final summary turn with no tools available.',
32
+ });
33
+ await this.documentStore.save(llm_provider_module_1.LlmMessageDocument, {
34
+ role: 'user',
35
+ text: 'I want to travel somewhere warm. Find me the first city of at least 25°C from this list, ' +
36
+ 'trying them one at a time in order: London, New York, Paris, Berlin, Tokyo. ' +
37
+ 'After each lookup, decide based on the temperature whether to keep searching.',
38
+ });
39
+ this.assignState({ turnCount: 0 });
40
+ }
41
+ async llmTurn(state) {
42
+ const result = await this.llmGenerateText.call({}, {
43
+ config: {
44
+ provider: 'claude',
45
+ system: this.render((0, node_path_1.join)(__dirname, 'templates', 'system.md')),
46
+ tools: ['weather_lookup', 'calculator'],
47
+ },
48
+ });
49
+ this.assignState({
50
+ turnCount: state.turnCount + 1,
51
+ llmResult: result.data,
52
+ });
53
+ }
54
+ async notifyOverBudget(_state) {
55
+ await this.documentStore.save(llm_provider_module_1.LlmMessageDocument, {
56
+ role: 'user',
57
+ text: `You have used your full turn budget of ${MAX_TURNS} tool-using turns and can no longer call tools. ` +
58
+ 'Summarise what you found so far in plain text and answer based on that.',
59
+ });
60
+ }
61
+ async wrapUp(_state) {
62
+ await this.llmGenerateText.call({}, {
63
+ config: {
64
+ provider: 'claude',
65
+ system: this.render((0, node_path_1.join)(__dirname, 'templates', 'wrap-up.md')),
66
+ tools: [],
67
+ },
68
+ });
69
+ }
70
+ async executeToolCalls(state) {
71
+ const result = await this.llmDelegateToolCalls.call({
72
+ message: state.llmResult.message,
73
+ callback: { transition: 'toolResultReceived' },
74
+ });
75
+ this.assignState({ delegateResult: result.data });
76
+ }
77
+ async toolResultReceived(state, input) {
78
+ const result = await this.llmUpdateToolResult.call({
79
+ delegateResult: state.delegateResult,
80
+ completedTool: input,
81
+ });
82
+ this.assignState({ delegateResult: result.data });
83
+ }
84
+ toolsComplete(_state) { }
85
+ respond(_state) { }
86
+ hasBudget(state) {
87
+ return state.turnCount < MAX_TURNS;
88
+ }
89
+ isOverBudget(state) {
90
+ return state.turnCount >= MAX_TURNS;
91
+ }
92
+ hasToolCalls(state) {
93
+ return state.llmResult?.message.stopReason === 'tool_use';
94
+ }
95
+ allToolsComplete(state) {
96
+ return !!state.delegateResult?.allCompleted;
97
+ }
98
+ isEndTurn(state) {
99
+ return state.llmResult?.message.stopReason === 'end_turn';
100
+ }
101
+ };
102
+ exports.CustomAgentExampleWorkflow = CustomAgentExampleWorkflow;
103
+ __decorate([
104
+ (0, common_1.Transition)({ to: 'ready' }),
105
+ __metadata("design:type", Function),
106
+ __metadata("design:paramtypes", [Object]),
107
+ __metadata("design:returntype", Promise)
108
+ ], CustomAgentExampleWorkflow.prototype, "setup", null);
109
+ __decorate([
110
+ (0, common_1.Transition)({ from: 'ready', to: 'prompt_executed', priority: 10 }),
111
+ (0, common_1.Guard)('hasBudget'),
112
+ __metadata("design:type", Function),
113
+ __metadata("design:paramtypes", [Object]),
114
+ __metadata("design:returntype", Promise)
115
+ ], CustomAgentExampleWorkflow.prototype, "llmTurn", null);
116
+ __decorate([
117
+ (0, common_1.Transition)({ from: 'ready', to: 'over_budget' }),
118
+ (0, common_1.Guard)('isOverBudget'),
119
+ __metadata("design:type", Function),
120
+ __metadata("design:paramtypes", [Object]),
121
+ __metadata("design:returntype", Promise)
122
+ ], CustomAgentExampleWorkflow.prototype, "notifyOverBudget", null);
123
+ __decorate([
124
+ (0, common_1.Transition)({ from: 'over_budget', to: 'end' }),
125
+ __metadata("design:type", Function),
126
+ __metadata("design:paramtypes", [Object]),
127
+ __metadata("design:returntype", Promise)
128
+ ], CustomAgentExampleWorkflow.prototype, "wrapUp", null);
129
+ __decorate([
130
+ (0, common_1.Transition)({ from: 'prompt_executed', to: 'awaiting_tools', priority: 10 }),
131
+ (0, common_1.Guard)('hasToolCalls'),
132
+ __metadata("design:type", Function),
133
+ __metadata("design:paramtypes", [Object]),
134
+ __metadata("design:returntype", Promise)
135
+ ], CustomAgentExampleWorkflow.prototype, "executeToolCalls", null);
136
+ __decorate([
137
+ (0, common_1.Transition)({ from: 'awaiting_tools', to: 'awaiting_tools', wait: true }),
138
+ __metadata("design:type", Function),
139
+ __metadata("design:paramtypes", [Object, Object]),
140
+ __metadata("design:returntype", Promise)
141
+ ], CustomAgentExampleWorkflow.prototype, "toolResultReceived", null);
142
+ __decorate([
143
+ (0, common_1.Transition)({ from: 'awaiting_tools', to: 'ready' }),
144
+ (0, common_1.Guard)('allToolsComplete'),
145
+ __metadata("design:type", Function),
146
+ __metadata("design:paramtypes", [Object]),
147
+ __metadata("design:returntype", void 0)
148
+ ], CustomAgentExampleWorkflow.prototype, "toolsComplete", null);
149
+ __decorate([
150
+ (0, common_1.Transition)({ from: 'prompt_executed', to: 'end' }),
151
+ (0, common_1.Guard)('isEndTurn'),
152
+ __metadata("design:type", Function),
153
+ __metadata("design:paramtypes", [Object]),
154
+ __metadata("design:returntype", void 0)
155
+ ], CustomAgentExampleWorkflow.prototype, "respond", null);
156
+ exports.CustomAgentExampleWorkflow = CustomAgentExampleWorkflow = __decorate([
157
+ (0, common_1.Workflow)({
158
+ title: 'Agent - Custom Agent Example',
159
+ description: 'A from-scratch agent loop with a deterministic turn budget. After N tool-using turns the workflow forces a wrap-up LLM call with a different system prompt and no tools — illustrating a control-flow shape the generic AgentWorkflow cannot express.',
160
+ }),
161
+ __metadata("design:paramtypes", [llm_provider_module_1.LlmGenerateTextTool,
162
+ llm_provider_module_1.LlmDelegateToolCallsTool,
163
+ llm_provider_module_1.LlmUpdateToolResultTool])
164
+ ], CustomAgentExampleWorkflow);
165
+ //# sourceMappingURL=custom-agent-example.workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-agent-example.workflow.js","sourceRoot":"","sources":["../../../src/workflows/custom-agent/custom-agent-example.workflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ You are a helpful assistant searching for a city that matches the user's criteria.
2
+
3
+ Available tools:
4
+
5
+ - `weather_lookup` — look up the current weather for a city
6
+ - `calculator` — perform a basic arithmetic calculation
7
+
8
+ How to work:
9
+
10
+ - Look up exactly ONE city per turn — never call `weather_lookup` for multiple cities in parallel.
11
+ - After each lookup, reason about the result before deciding whether to keep searching.
12
+ - Stop calling tools as soon as you have enough information to answer.
13
+
14
+ When you are done, answer in plain text without calling any more tools.
@@ -0,0 +1,3 @@
1
+ You have reached your turn budget and can no longer call tools.
2
+
3
+ Summarize what you have found so far for the user in plain text. If you did not finish gathering every data point, acknowledge that and answer based on what you have. Do not call any tools.
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ import { ChatAgentWorkflow } from '@loopstack/agent';
3
+ import { BaseWorkflow } from '@loopstack/common';
4
+ import type { RunContext } from '@loopstack/common';
5
+ import { McpCallTool, McpListToolsTool } from '@loopstack/mcp-module';
6
+ declare const McpLinearExampleArgsSchema: z.ZodObject<{
7
+ initialMessage: z.ZodDefault<z.ZodOptional<z.ZodString>>;
8
+ }, z.core.$strip>;
9
+ type McpLinearExampleArgs = z.infer<typeof McpLinearExampleArgsSchema>;
10
+ export declare class McpLinearExampleWorkflow extends BaseWorkflow<McpLinearExampleArgs> {
11
+ private readonly chatAgentWorkflow;
12
+ private readonly mcpListTools;
13
+ private readonly mcpCallTool;
14
+ constructor(chatAgentWorkflow: ChatAgentWorkflow, mcpListTools: McpListToolsTool, mcpCallTool: McpCallTool);
15
+ startChat(state: Record<string, unknown>, ctx: RunContext<McpLinearExampleArgs>): Promise<void>;
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=mcp-linear-example.workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-linear-example.workflow.d.ts","sourceRoot":"","sources":["../../../src/workflows/mcp-linear/mcp-linear-example.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAwB,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAItE,QAAA,MAAM,0BAA0B;;iBAQ9B,CAAC;AAEH,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEvE,qBAKa,wBAAyB,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAE5E,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFX,iBAAiB,EAAE,iBAAiB,EACpC,YAAY,EAAE,gBAAgB,EAC9B,WAAW,EAAE,WAAW;IAMrC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,oBAAoB,CAAC;CAgBtF"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.McpLinearExampleWorkflow = void 0;
13
+ const zod_1 = require("zod");
14
+ const agent_1 = require("@loopstack/agent");
15
+ const common_1 = require("@loopstack/common");
16
+ const mcp_module_1 = require("@loopstack/mcp-module");
17
+ const LINEAR_MCP_URL = 'https://mcp.linear.app/mcp';
18
+ const McpLinearExampleArgsSchema = zod_1.z.object({
19
+ initialMessage: zod_1.z
20
+ .string()
21
+ .optional()
22
+ .default('List the available Linear MCP tools, then fetch my active issues and summarize the top 5 by priority with assignee and status.')
23
+ .describe('Initial message shown to the agent.'),
24
+ });
25
+ let McpLinearExampleWorkflow = class McpLinearExampleWorkflow extends common_1.BaseWorkflow {
26
+ chatAgentWorkflow;
27
+ mcpListTools;
28
+ mcpCallTool;
29
+ constructor(chatAgentWorkflow, mcpListTools, mcpCallTool) {
30
+ super();
31
+ this.chatAgentWorkflow = chatAgentWorkflow;
32
+ this.mcpListTools = mcpListTools;
33
+ this.mcpCallTool = mcpCallTool;
34
+ }
35
+ async startChat(state, ctx) {
36
+ const systemPrompt = [
37
+ `You are a Linear assistant connected via MCP at ${LINEAR_MCP_URL} (transport: streamableHttp).`,
38
+ 'Use `mcpListTools` to discover the available Linear tools, then `mcpCallTool` to invoke them.',
39
+ `Always pass serverUrl="${LINEAR_MCP_URL}" and transport="streamableHttp".`,
40
+ ].join('\n');
41
+ await this.chatAgentWorkflow.run({
42
+ system: systemPrompt,
43
+ tools: ['mcp_list_tools', 'mcp_call'],
44
+ userMessage: ctx.args.initialMessage,
45
+ }, { show: 'inline', label: 'Linear Agent Chat' });
46
+ }
47
+ };
48
+ exports.McpLinearExampleWorkflow = McpLinearExampleWorkflow;
49
+ __decorate([
50
+ (0, common_1.Transition)({ to: 'chatting' }),
51
+ __metadata("design:type", Function),
52
+ __metadata("design:paramtypes", [Object, Object]),
53
+ __metadata("design:returntype", Promise)
54
+ ], McpLinearExampleWorkflow.prototype, "startChat", null);
55
+ exports.McpLinearExampleWorkflow = McpLinearExampleWorkflow = __decorate([
56
+ (0, common_1.Workflow)({
57
+ title: 'Agent - MCP Linear Example',
58
+ description: "Chat agent connected to Linear's hosted MCP server. Demonstrates MCP tool integration.",
59
+ schema: McpLinearExampleArgsSchema,
60
+ }),
61
+ __metadata("design:paramtypes", [agent_1.ChatAgentWorkflow,
62
+ mcp_module_1.McpListToolsTool,
63
+ mcp_module_1.McpCallTool])
64
+ ], McpLinearExampleWorkflow);
65
+ //# sourceMappingURL=mcp-linear-example.workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-linear-example.workflow.js","sourceRoot":"","sources":["../../../src/workflows/mcp-linear/mcp-linear-example.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6BAAwB;AACxB,4CAAqD;AACrD,8CAAuE;AAEvE,sDAAsE;AAEtE,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAEpD,MAAM,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,cAAc,EAAE,OAAC;SACd,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,OAAO,CACN,gIAAgI,CACjI;SACA,QAAQ,CAAC,qCAAqC,CAAC;CACnD,CAAC,CAAC;AASI,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,qBAAkC;IAE3D;IACA;IACA;IAHnB,YACmB,iBAAoC,EACpC,YAA8B,EAC9B,WAAwB;QAEzC,KAAK,EAAE,CAAC;QAJS,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,iBAAY,GAAZ,YAAY,CAAkB;QAC9B,gBAAW,GAAX,WAAW,CAAa;IAG3C,CAAC;IAGK,AAAN,KAAK,CAAC,SAAS,CAAC,KAA8B,EAAE,GAAqC;QACnF,MAAM,YAAY,GAAG;YACnB,mDAAmD,cAAc,+BAA+B;YAChG,+FAA+F;YAC/F,0BAA0B,cAAc,mCAAmC;SAC5E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAC9B;YACE,MAAM,EAAE,YAAY;YACpB,KAAK,EAAE,CAAC,gBAAgB,EAAE,UAAU,CAAC;YACrC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;SACrC,EACD,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAC/C,CAAC;IACJ,CAAC;CACF,CAAA;AA1BY,4DAAwB;AAU7B;IADL,IAAA,mBAAU,EAAC,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC;;;;yDAgB9B;mCAzBU,wBAAwB;IALpC,IAAA,iBAAQ,EAAC;QACR,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,wFAAwF;QACrG,MAAM,EAAE,0BAA0B;KACnC,CAAC;qCAGsC,yBAAiB;QACtB,6BAAgB;QACjB,wBAAW;GAJhC,wBAAwB,CA0BpC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@loopstack/agent-examples",
3
+ "displayName": "Loopstack Agent Examples",
4
+ "description": "Workflow examples for LLM agents in Loopstack — basic AgentWorkflow, code-exploration agent, MCP-connected agent, and a from-scratch custom agent loop with a deterministic turn budget.",
5
+ "keywords": [
6
+ "loopstack",
7
+ "example",
8
+ "agent",
9
+ "llm",
10
+ "claude",
11
+ "mcp",
12
+ "workflow"
13
+ ],
14
+ "version": "0.1.1",
15
+ "license": "MIT",
16
+ "author": {
17
+ "name": "Jakob Klippel",
18
+ "url": "https://www.linkedin.com/in/jakob-klippel/"
19
+ },
20
+ "main": "dist/index.js",
21
+ "types": "dist/index.d.ts",
22
+ "exports": {
23
+ ".": "./dist/index.js",
24
+ "./src/*": "./src/*"
25
+ },
26
+ "scripts": {
27
+ "build": "nest build",
28
+ "compile": "tsc --noEmit",
29
+ "format": "prettier --write .",
30
+ "lint": "eslint .",
31
+ "test": "vitest run --passWithNoTests",
32
+ "watch": "nest build --watch"
33
+ },
34
+ "dependencies": {
35
+ "@loopstack/agent": "*",
36
+ "@loopstack/claude-module": "*",
37
+ "@loopstack/code-agent": "*",
38
+ "@loopstack/common": "*",
39
+ "@loopstack/llm-provider-module": "*",
40
+ "@loopstack/mcp-module": "*",
41
+ "@loopstack/remote-client": "*",
42
+ "@nestjs/common": "^11.1.19",
43
+ "zod": "^4.3.6"
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "src"
48
+ ],
49
+ "devDependencies": {
50
+ "vitest": "^4.1.6",
51
+ "@swc/core": "^1.15.33",
52
+ "unplugin-swc": "^1.5.9"
53
+ }
54
+ }
@@ -0,0 +1,40 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { AgentModule } from '@loopstack/agent';
3
+ import { ClaudeModule } from '@loopstack/claude-module';
4
+ import { CodeAgentModule } from '@loopstack/code-agent';
5
+ import { StudioApp } from '@loopstack/common';
6
+ import { McpModule } from '@loopstack/mcp-module';
7
+ import { RemoteClientModule } from '@loopstack/remote-client';
8
+ import { CalculatorTool } from './tools/calculator.tool';
9
+ import { WeatherLookupTool } from './tools/weather-lookup.tool';
10
+ import { AgentExampleWorkflow } from './workflows/agent/agent-example.workflow';
11
+ import { CodeAgentExampleWorkflow } from './workflows/code-agent/code-agent-example.workflow';
12
+ import { CustomAgentExampleWorkflow } from './workflows/custom-agent/custom-agent-example.workflow';
13
+ import { McpLinearExampleWorkflow } from './workflows/mcp-linear/mcp-linear-example.workflow';
14
+
15
+ const WORKFLOWS = [
16
+ AgentExampleWorkflow,
17
+ CodeAgentExampleWorkflow,
18
+ McpLinearExampleWorkflow,
19
+ CustomAgentExampleWorkflow,
20
+ ];
21
+
22
+ @StudioApp({
23
+ title: 'Agent Examples',
24
+ workflows: WORKFLOWS,
25
+ })
26
+ @Module({
27
+ imports: [
28
+ AgentModule,
29
+ CodeAgentModule,
30
+ ClaudeModule,
31
+ McpModule.forRoot({
32
+ allowedHosts: ['mcp.linear.app'],
33
+ hostHeaderEnv: { 'mcp.linear.app': { Authorization: 'LINEAR_MCP_TOKEN' } },
34
+ }),
35
+ RemoteClientModule.forFeature({ slots: [{ id: 'sandbox', type: 'sandbox', title: 'Sandbox' }] }),
36
+ ],
37
+ providers: [CalculatorTool, WeatherLookupTool, ...WORKFLOWS],
38
+ exports: WORKFLOWS,
39
+ })
40
+ export class AgentExamplesModule {}
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './agent-examples.module';
2
+ export * from './workflows/agent/agent-example.workflow';
3
+ export * from './workflows/code-agent/code-agent-example.workflow';
4
+ export * from './workflows/mcp-linear/mcp-linear-example.workflow';
5
+ export * from './workflows/custom-agent/custom-agent-example.workflow';
@@ -0,0 +1,47 @@
1
+ import { z } from 'zod';
2
+ import { BaseTool, Tool, ToolEnvelope } from '@loopstack/common';
3
+ import type { RunContext } from '@loopstack/common';
4
+
5
+ export type CalculatorResult = string;
6
+
7
+ @Tool({
8
+ name: 'calculator',
9
+ description: 'Perform a basic arithmetic calculation. Supports add, subtract, multiply, divide.',
10
+ schema: z.object({
11
+ operation: z.enum(['add', 'subtract', 'multiply', 'divide']).describe('The arithmetic operation.'),
12
+ a: z.number().describe('First operand.'),
13
+ b: z.number().describe('Second operand.'),
14
+ }),
15
+ })
16
+ export class CalculatorTool extends BaseTool<{ operation: string; a: number; b: number }, object, CalculatorResult> {
17
+ protected async handle(
18
+ args: { operation: string; a: number; b: number },
19
+ _ctx: RunContext,
20
+ ): Promise<ToolEnvelope<CalculatorResult>> {
21
+ let result: number;
22
+
23
+ switch (args.operation) {
24
+ case 'add':
25
+ result = args.a + args.b;
26
+ break;
27
+ case 'subtract':
28
+ result = args.a - args.b;
29
+ break;
30
+ case 'multiply':
31
+ result = args.a * args.b;
32
+ break;
33
+ case 'divide':
34
+ if (args.b === 0) {
35
+ return { data: 'Error: Division by zero', error: 'Cannot divide by zero' };
36
+ }
37
+ result = args.a / args.b;
38
+ break;
39
+ default:
40
+ return { data: `Unknown operation: ${args.operation}`, error: 'Unsupported operation' };
41
+ }
42
+
43
+ return {
44
+ data: `${args.a} ${args.operation} ${args.b} = ${result}`,
45
+ };
46
+ }
47
+ }
@@ -0,0 +1,2 @@
1
+ export * from './weather-lookup.tool';
2
+ export * from './calculator.tool';
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { BaseTool, Tool, ToolEnvelope } from '@loopstack/common';
3
+
4
+ export type WeatherLookupResult = string;
5
+
6
+ @Tool({
7
+ name: 'weather_lookup',
8
+ description: 'Look up the current weather for a given city. Returns a simulated forecast.',
9
+ schema: z.object({
10
+ city: z.string().describe('The city name to look up weather for.'),
11
+ }),
12
+ })
13
+ export class WeatherLookupTool extends BaseTool<{ city: string }, object, WeatherLookupResult> {
14
+ protected async handle(args: { city: string }): Promise<ToolEnvelope<WeatherLookupResult>> {
15
+ // Simulated weather data for demonstration purposes
16
+ const forecasts: Record<string, string> = {
17
+ london: '14°C, cloudy with light rain',
18
+ tokyo: '22°C, sunny with clear skies',
19
+ 'new york': '18°C, partly cloudy',
20
+ };
21
+
22
+ const key = args.city.toLowerCase();
23
+ const weather = forecasts[key] ?? `21°C, pleasant conditions`;
24
+
25
+ return Promise.resolve({
26
+ data: `Weather in ${args.city}: ${weather}`,
27
+ });
28
+ }
29
+ }
@@ -0,0 +1,40 @@
1
+ import { join } from 'node:path';
2
+ import { type AgentResult, AgentResultSchema, AgentWorkflow } from '@loopstack/agent';
3
+ import { BaseWorkflow, Transition, type TransitionInput, Workflow } from '@loopstack/common';
4
+ import { LlmMessageDocument } from '@loopstack/llm-provider-module';
5
+
6
+ @Workflow({
7
+ title: 'Agent - Basic Agent Example',
8
+ description:
9
+ 'Launches a generic AgentWorkflow as a sub-workflow with weather and calculator tools. Recommended starting point.',
10
+ })
11
+ export class AgentExampleWorkflow extends BaseWorkflow {
12
+ constructor(private readonly agentWorkflow: AgentWorkflow) {
13
+ super();
14
+ }
15
+
16
+ @Transition({ to: 'running' })
17
+ async start() {
18
+ await this.agentWorkflow.run(
19
+ {
20
+ system: this.render(join(__dirname, 'templates', 'system.md')),
21
+ tools: ['weather_lookup', 'calculator'],
22
+ userMessage: "What's the weather in Tokyo? Also, what is 42 * 17?",
23
+ },
24
+ { callback: { transition: 'agentComplete' }, show: 'inline', label: 'Subagent' },
25
+ );
26
+ }
27
+
28
+ @Transition({
29
+ from: 'running',
30
+ to: 'end',
31
+ wait: true,
32
+ schema: AgentResultSchema,
33
+ })
34
+ async agentComplete(_state: Record<string, unknown>, input: TransitionInput<AgentResult>) {
35
+ await this.documentStore.save(LlmMessageDocument, {
36
+ role: 'assistant',
37
+ text: input.data.response,
38
+ });
39
+ }
40
+ }
@@ -0,0 +1,4 @@
1
+ You are a helpful assistant with access to a weather lookup tool and a calculator.
2
+ When the user asks about weather, use the weatherLookup tool.
3
+ When the user asks for calculations, use the calculator tool.
4
+ Provide a concise, helpful response summarizing the results.
@@ -0,0 +1,56 @@
1
+ import { type AgentResult, AgentResultSchema, AgentWorkflow } from '@loopstack/agent';
2
+ import { BaseWorkflow, MessageDocument, Transition, type TransitionInput, Workflow } from '@loopstack/common';
3
+ import { EnvironmentService } from '@loopstack/remote-client';
4
+
5
+ const EXPLORE_INSTRUCTIONS = `Find the entry-point module of this project and list the
6
+ top-level providers it registers. Return a short bulleted summary.`;
7
+
8
+ /**
9
+ * Code-exploration agent powered by `AgentWorkflow` with `glob`, `grep`, and `read`
10
+ * tools. These tools execute on a remote agent, so the workspace must have a
11
+ * `sandbox` environment connected and the remote agent must be reachable.
12
+ *
13
+ * Setup (see `agent-examples/README.md` → Code Agent for the full snippet):
14
+ */
15
+ @Workflow({
16
+ title: 'Agent - Code Agent Example',
17
+ description: 'Launches AgentWorkflow as a codebase-exploration agent with glob, grep, and read tools.',
18
+ })
19
+ export class CodeAgentExampleWorkflow extends BaseWorkflow {
20
+ constructor(
21
+ private readonly agentWorkflow: AgentWorkflow,
22
+ private readonly environments: EnvironmentService,
23
+ ) {
24
+ super();
25
+ }
26
+
27
+ @Transition({ to: 'verified' })
28
+ async verifyEnvironment(_state: Record<string, unknown>) {
29
+ await this.environments.assertReachable('sandbox');
30
+ }
31
+
32
+ @Transition({ from: 'verified', to: 'exploring' })
33
+ async startExploration(_state: Record<string, unknown>) {
34
+ await this.agentWorkflow.run(
35
+ {
36
+ system: 'You are a codebase exploration agent. Search and read source code to answer the question thoroughly.',
37
+ tools: ['glob', 'grep', 'read'],
38
+ userMessage: EXPLORE_INSTRUCTIONS,
39
+ },
40
+ { callback: { transition: 'exploreComplete' }, show: 'inline', label: 'Exploring codebase...' },
41
+ );
42
+ }
43
+
44
+ @Transition({
45
+ from: 'exploring',
46
+ to: 'end',
47
+ wait: true,
48
+ schema: AgentResultSchema,
49
+ })
50
+ async exploreComplete(_state: Record<string, unknown>, input: TransitionInput<AgentResult>) {
51
+ await this.documentStore.save(MessageDocument, {
52
+ role: 'assistant',
53
+ text: input.data.response,
54
+ });
55
+ }
56
+ }