@lleverage-ai/agent-sdk 0.0.2-alpha.6 → 0.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 (54) hide show
  1. package/README.md +81 -9
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +138 -20
  4. package/dist/agent.js.map +1 -1
  5. package/dist/hooks.d.ts +66 -0
  6. package/dist/hooks.d.ts.map +1 -1
  7. package/dist/hooks.js +63 -1
  8. package/dist/hooks.js.map +1 -1
  9. package/dist/index.d.ts +8 -4
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +7 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/mcp/manager.d.ts +16 -0
  14. package/dist/mcp/manager.d.ts.map +1 -1
  15. package/dist/mcp/manager.js +20 -0
  16. package/dist/mcp/manager.js.map +1 -1
  17. package/dist/prompt-builder/components.d.ts +149 -0
  18. package/dist/prompt-builder/components.d.ts.map +1 -0
  19. package/dist/prompt-builder/components.js +252 -0
  20. package/dist/prompt-builder/components.js.map +1 -0
  21. package/dist/prompt-builder/index.d.ts +248 -0
  22. package/dist/prompt-builder/index.d.ts.map +1 -0
  23. package/dist/prompt-builder/index.js +165 -0
  24. package/dist/prompt-builder/index.js.map +1 -0
  25. package/dist/skills/loader.d.ts +152 -0
  26. package/dist/skills/loader.d.ts.map +1 -0
  27. package/dist/skills/loader.js +411 -0
  28. package/dist/skills/loader.js.map +1 -0
  29. package/dist/testing/mock-agent.d.ts +2 -1
  30. package/dist/testing/mock-agent.d.ts.map +1 -1
  31. package/dist/tools/factory.d.ts +3 -3
  32. package/dist/tools/factory.d.ts.map +1 -1
  33. package/dist/tools/factory.js +1 -1
  34. package/dist/tools/factory.js.map +1 -1
  35. package/dist/tools/index.d.ts +2 -2
  36. package/dist/tools/index.d.ts.map +1 -1
  37. package/dist/tools/index.js +1 -1
  38. package/dist/tools/index.js.map +1 -1
  39. package/dist/tools/search.d.ts +11 -1
  40. package/dist/tools/search.d.ts.map +1 -1
  41. package/dist/tools/search.js +25 -10
  42. package/dist/tools/search.js.map +1 -1
  43. package/dist/tools/skills.d.ts +125 -84
  44. package/dist/tools/skills.d.ts.map +1 -1
  45. package/dist/tools/skills.js +16 -89
  46. package/dist/tools/skills.js.map +1 -1
  47. package/dist/tools.d.ts +5 -4
  48. package/dist/tools.d.ts.map +1 -1
  49. package/dist/tools.js +7 -4
  50. package/dist/tools.js.map +1 -1
  51. package/dist/types.d.ts +143 -45
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/types.js.map +1 -1
  54. package/package.json +1 -1
package/README.md CHANGED
@@ -126,8 +126,9 @@ const agent = createAgent({
126
126
 
127
127
  ### Skills
128
128
 
129
- Skills provide contextual instructions that guide agent behavior. They can bundle tool guidance, provide instructions-only, or enable progressive disclosure of tools.
129
+ Skills provide contextual instructions that guide agent behavior following the [Agent Skills specification](https://agentskills.io/specification). They support both programmatic (TypeScript) and file-based (SKILL.md) formats.
130
130
 
131
+ **Programmatic skills:**
131
132
  ```typescript
132
133
  import { defineSkill } from "@lleverage-ai/agent-sdk";
133
134
 
@@ -138,7 +139,7 @@ const dataPlugin = definePlugin({
138
139
  defineSkill({
139
140
  name: "data-exploration",
140
141
  description: "Query and visualize data",
141
- prompt: `You have access to data exploration tools.
142
+ instructions: `You have access to data exploration tools.
142
143
  Available tables: products, users, sales.
143
144
  Always use getSchema first to see column types.`,
144
145
  }),
@@ -146,24 +147,93 @@ Always use getSchema first to see column types.`,
146
147
  });
147
148
  ```
148
149
 
150
+ **File-based skills:**
151
+ ```typescript
152
+ import { loadSkillsFromDirectories } from "@lleverage-ai/agent-sdk";
153
+
154
+ // Load skills from SKILL.md files
155
+ const { skills } = await loadSkillsFromDirectories(["/path/to/skills"]);
156
+
157
+ // Agent auto-creates registry and skill tool
158
+ const agent = createAgent({ model, skills });
159
+ ```
160
+
161
+ See [Skills Documentation](./docs/skills.md) for complete details on the skills system and Agent Skills spec compliance.
162
+
163
+ ### Prompt Builder
164
+
165
+ Create dynamic, context-aware system prompts from composable components. Instead of static strings, prompts automatically include tools, skills, backend capabilities, and more.
166
+
167
+ **Using the default builder:**
168
+ ```typescript
169
+ const agent = createAgent({
170
+ model,
171
+ // No systemPrompt = uses default prompt builder
172
+ tools: { read, write, bash },
173
+ });
174
+ // Automatically generates:
175
+ // "You are a helpful AI assistant.
176
+ //
177
+ // # Available Tools
178
+ // - **read**: Read files
179
+ // - **write**: Write files
180
+ // - **bash**: Execute commands
181
+ //
182
+ // # Capabilities
183
+ // - Execute shell commands (bash)
184
+ // - Read and write files to the filesystem"
185
+ ```
186
+
187
+ **Customizing the prompt:**
188
+ ```typescript
189
+ import { createDefaultPromptBuilder } from "@lleverage-ai/agent-sdk";
190
+
191
+ const builder = createDefaultPromptBuilder()
192
+ .register({
193
+ name: "project-context",
194
+ priority: 95,
195
+ render: () => "You are working on a TypeScript project.",
196
+ });
197
+
198
+ const agent = createAgent({
199
+ model,
200
+ promptBuilder: builder,
201
+ tools,
202
+ });
203
+ ```
204
+
205
+ **Static prompts still work:**
206
+ ```typescript
207
+ const agent = createAgent({
208
+ model,
209
+ systemPrompt: "You are a helpful assistant.",
210
+ tools,
211
+ });
212
+ ```
213
+
214
+ See [Prompt Builder Documentation](./docs/prompt-builder.md) for complete details on dynamic prompts, components, and customization.
215
+
149
216
  ### Hooks
150
217
 
151
218
  Hooks allow you to observe and react to agent lifecycle events:
152
219
 
153
220
  ```typescript
221
+ import { createAgent, createToolHook } from "@lleverage-ai/agent-sdk";
222
+
154
223
  const agent = createAgent({
155
224
  model,
156
225
  hooks: {
226
+ // Simple observation hook (void return is fine)
157
227
  PreGenerate: [async ({ options }) => {
158
228
  console.log("Starting generation...");
159
- return {};
160
229
  }],
161
- PostToolUse: [{
162
- hooks: [async ({ tool_name, tool_response }) => {
230
+
231
+ // Use createToolHook helper for tool-specific hooks
232
+ PostToolUse: [
233
+ createToolHook(async ({ tool_name, tool_response }) => {
163
234
  console.log("Tool completed:", tool_name);
164
- return {};
165
- }],
166
- }],
235
+ }, { matcher: "search_*" }), // Only match tools starting with "search_"
236
+ ],
167
237
  },
168
238
  });
169
239
  ```
@@ -173,7 +243,7 @@ const agent = createAgent({
173
243
  - `PreToolUse`, `PostToolUse`, `PostToolUseFailure` — Tool execution lifecycle
174
244
  - `MCPConnectionFailed`, `MCPConnectionRestored` — MCP server connection lifecycle
175
245
 
176
- **Hook utilities:** `createRetryHooks`, `createRateLimitHooks`, `createLoggingHooks`, `createGuardrailsHooks`, `createSecretsFilterHooks`
246
+ **Hook utilities:** `createRetryHooks`, `createRateLimitHooks`, `createLoggingHooks`, `createGuardrailsHooks`, `createSecretsFilterHooks`, `createToolHook`
177
247
 
178
248
  ### Streaming
179
249
 
@@ -195,6 +265,8 @@ export async function POST(req: Request) {
195
265
 
196
266
  ## Documentation
197
267
 
268
+ - [Prompt Builder](./docs/prompt-builder.md) — Dynamic, context-aware system prompts
269
+ - [Skills System](./docs/skills.md) — Progressive disclosure with Agent Skills spec compliance
198
270
  - [Tool Loading Strategies](./docs/tool-loading.md) — Eager, lazy, and dynamic tool loading
199
271
  - [Security & Production](./docs/security.md) — Security policies, guardrails, and secrets filtering
200
272
  - [Subagents](./docs/subagents.md) — Task delegation and background tasks
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuDH,OAAO,KAAK,EACV,KAAK,EACL,YAAY,EA0Bb,MAAM,YAAY,CAAC;AA8lBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,KAAK,CAg/DxD"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0DH,OAAO,KAAK,EACV,KAAK,EACL,YAAY,EAyBb,MAAM,YAAY,CAAC;AA8lBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,KAAK,CAgoExD"}
package/dist/agent.js CHANGED
@@ -13,6 +13,7 @@ import { createRetryLoopState, handleGenerationError, invokePreGenerateHooks, no
13
13
  import { aggregatePermissionDecisions, extractUpdatedInput, extractUpdatedResult, invokeHooksWithTimeout, invokeMatchingHooks, } from "./hooks.js";
14
14
  import { MCPManager } from "./mcp/manager.js";
15
15
  import { applyMiddleware, mergeHooks, setupMiddleware } from "./middleware/index.js";
16
+ import { createDefaultPromptBuilder } from "./prompt-builder/components.js";
16
17
  import { ACCEPT_EDITS_BLOCKED_PATTERNS } from "./security/index.js";
17
18
  import { TaskManager } from "./task-manager.js";
18
19
  import { coreToolsToToolSet, createCoreTools, createSearchToolsTool, createTaskOutputTool, createTaskTool, } from "./tools/factory.js";
@@ -527,6 +528,16 @@ function isBackendFactory(value) {
527
528
  */
528
529
  export function createAgent(options) {
529
530
  const id = `agent-${++agentIdCounter}`;
531
+ // Validate mutually exclusive prompt options
532
+ if (options.systemPrompt !== undefined && options.promptBuilder) {
533
+ throw new Error("Cannot specify both systemPrompt and promptBuilder - they are mutually exclusive");
534
+ }
535
+ // Determine prompt mode
536
+ // - 'static': Use systemPrompt string directly
537
+ // - 'builder': Use PromptBuilder to generate dynamic prompts
538
+ const promptMode = options.systemPrompt !== undefined ? "static" : "builder";
539
+ // Get or create prompt builder
540
+ const promptBuilder = options.promptBuilder ?? (promptMode === "builder" ? createDefaultPromptBuilder() : undefined);
530
541
  // Process middleware to get hooks (middleware hooks come before explicit hooks)
531
542
  const middleware = options.middleware ?? [];
532
543
  const middlewareHooks = applyMiddleware(middleware);
@@ -562,6 +573,8 @@ export function createAgent(options) {
562
573
  // Initialize task manager for background task tracking
563
574
  const taskManager = new TaskManager();
564
575
  // Determine plugin loading mode
576
+ // Track whether it was explicitly set to distinguish from default
577
+ const explicitPluginLoading = options.pluginLoading !== undefined;
565
578
  const pluginLoadingMode = options.pluginLoading ?? "eager";
566
579
  const preloadPlugins = new Set(options.preloadPlugins ?? []);
567
580
  // Initialize tool registry for lazy/explicit loading modes
@@ -674,20 +687,21 @@ export function createAgent(options) {
674
687
  }
675
688
  }
676
689
  // Determine if we should use deferred loading based on tool search settings
677
- // Note: "auto" mode enables deferred loading when tool count exceeds threshold
690
+ // Note: Only activate deferred loading if explicitly requested, not based on auto threshold
691
+ // The auto threshold should only affect whether search_tools is created, not loading behavior
678
692
  if (toolSearchEnabled === "always") {
679
693
  deferredLoadingActive = true;
680
694
  }
681
- else if (toolSearchEnabled === "auto" && totalPluginToolCount > toolSearchThreshold) {
682
- deferredLoadingActive = true;
683
- }
695
+ // Removed: auto threshold no longer forces deferred loading
696
+ // The default eager loading should be respected
684
697
  // Auto-create core tools (unless user provides explicit tools)
685
- // Note: search_tools is created separately with proper configuration
698
+ // Note: search_tools is created separately below based on loading mode
686
699
  const { tools: autoCreatedCoreTools } = createCoreTools({
687
700
  backend: effectiveBackend,
688
701
  state,
689
702
  taskManager,
690
- mcpManager: deferredLoadingActive ? undefined : mcpManager, // Only pass if not deferred
703
+ // Don't pass mcpManager here - we create search_tools manually below
704
+ mcpManager: undefined,
691
705
  disabled: options.disabledCoreTools,
692
706
  skills,
693
707
  });
@@ -705,31 +719,64 @@ export function createAgent(options) {
705
719
  // getActiveToolSetWithStreaming() and are not registered here
706
720
  if (plugin.tools && typeof plugin.tools !== "function") {
707
721
  const shouldPreload = preloadPlugins.has(plugin.name);
708
- if (pluginLoadingMode === "lazy" && toolRegistry) {
722
+ // Priority order:
723
+ // 1. Explicit mode - don't register
724
+ // 2. Preload - always load immediately
725
+ // 3. Explicit eager - always load immediately
726
+ // 4. Lazy mode - register with tool registry
727
+ // 5. Deferred loading - register but don't load
728
+ // 6. Default eager - load immediately
729
+ if (pluginLoadingMode === "explicit") {
730
+ // Explicit mode: don't auto-register, user must do it manually
731
+ // Skip registration entirely
732
+ }
733
+ else if (shouldPreload) {
734
+ // Preloaded plugins: always load immediately, regardless of other settings
735
+ mcpManager.registerPluginTools(plugin.name, plugin.tools, {
736
+ autoLoad: true,
737
+ });
738
+ }
739
+ else if (explicitPluginLoading && pluginLoadingMode === "eager") {
740
+ // Explicit eager mode: always load immediately, regardless of toolSearch settings
741
+ mcpManager.registerPluginTools(plugin.name, plugin.tools, {
742
+ autoLoad: true,
743
+ });
744
+ }
745
+ else if (pluginLoadingMode === "lazy" && toolRegistry) {
709
746
  // Lazy mode: register with registry for on-demand loading
710
747
  toolRegistry.registerPlugin(plugin.name, plugin.tools);
711
748
  }
712
- else if (deferredLoadingActive && !shouldPreload) {
713
- // Deferred loading: register tools but don't load them initially
749
+ else if (deferredLoadingActive) {
750
+ // Deferred loading (auto threshold or always enabled): register tools but don't load them initially
714
751
  mcpManager.registerPluginTools(plugin.name, plugin.tools, {
715
752
  autoLoad: false,
716
753
  });
717
754
  }
718
- else if (pluginLoadingMode === "eager" || shouldPreload) {
719
- // Eager mode or preloaded: register and load immediately
755
+ else {
756
+ // Default eager mode: load immediately
720
757
  mcpManager.registerPluginTools(plugin.name, plugin.tools, {
721
758
  autoLoad: true,
722
759
  });
723
760
  }
724
- // explicit mode: don't register, user must do it manually
725
761
  }
726
762
  }
727
- // Create search_tools with load capability when deferred loading is active
728
- if (deferredLoadingActive && !options.disabledCoreTools?.includes("search_tools")) {
763
+ // Create search_tools for MCP tool discovery and/or plugin loading
764
+ // New behavior:
765
+ // - Create when auto threshold is exceeded (for lazy discovery)
766
+ // - Create when deferred loading is active (explicitly requested)
767
+ // - Create when external MCP servers exist (for MCP tool search)
768
+ // - Always auto-load tools when found (no manual load step)
769
+ const shouldCreateSearchToolsForAutoThreshold = toolSearchEnabled === "auto" && totalPluginToolCount > toolSearchThreshold;
770
+ const shouldCreateSearchTools = !options.disabledCoreTools?.includes("search_tools") &&
771
+ (deferredLoadingActive ||
772
+ shouldCreateSearchToolsForAutoThreshold ||
773
+ (mcpManager.hasExternalServers() && toolSearchEnabled !== "never"));
774
+ if (shouldCreateSearchTools) {
729
775
  coreTools.search_tools = createSearchToolsTool({
730
776
  manager: mcpManager,
731
777
  maxResults: toolSearchMaxResults,
732
- enableLoad: true,
778
+ enableLoad: true, // Always enable auto-loading
779
+ autoLoad: true, // NEW: Auto-load tools after searching
733
780
  onToolsLoaded: (toolNames) => {
734
781
  // Tools are now loaded in MCPManager and will be included in getActiveToolSet()
735
782
  // This callback can be used for logging/notifications
@@ -775,6 +822,62 @@ export function createAgent(options) {
775
822
  }
776
823
  return filtered;
777
824
  };
825
+ // Helper to build prompt context from current agent state
826
+ const buildPromptContext = (messages, threadId) => {
827
+ // Get filtered tools (respecting allowedTools/disallowedTools) so the prompt
828
+ // only advertises tools the agent will actually expose
829
+ const filteredTools = filterToolsByAllowed((() => {
830
+ const allTools = { ...coreTools };
831
+ Object.assign(allTools, mcpManager.getToolSet());
832
+ if (toolRegistry) {
833
+ Object.assign(allTools, toolRegistry.getLoadedTools());
834
+ }
835
+ return allTools;
836
+ })());
837
+ // Extract tool metadata for context
838
+ const toolsMetadata = Object.entries(filteredTools).map(([name, tool]) => ({
839
+ name,
840
+ description: tool.description ?? "",
841
+ }));
842
+ // Extract skills metadata from the skills array
843
+ const skillsMetadata = skills.map((skill) => ({
844
+ name: skill.name,
845
+ description: skill.description,
846
+ }));
847
+ // Extract plugins metadata
848
+ const pluginsMetadata = (options.plugins ?? []).map((plugin) => ({
849
+ name: plugin.name,
850
+ description: plugin.description ?? "",
851
+ }));
852
+ // Build backend info
853
+ const backendInfo = {
854
+ type: backend.constructor.name.toLowerCase().replace("backend", "") || "unknown",
855
+ hasExecuteCapability: hasExecuteCapability(backend),
856
+ rootDir: "rootDir" in backend ? backend.rootDir : undefined,
857
+ };
858
+ return {
859
+ tools: toolsMetadata.length > 0 ? toolsMetadata : undefined,
860
+ skills: skillsMetadata.length > 0 ? skillsMetadata : undefined,
861
+ plugins: pluginsMetadata.length > 0 ? pluginsMetadata : undefined,
862
+ backend: backendInfo,
863
+ state,
864
+ // Model ID extraction is not reliable across all LanguageModel types
865
+ // Users can access the full model via their custom context if needed
866
+ model: undefined,
867
+ maxSteps: options.maxSteps,
868
+ permissionMode,
869
+ currentMessages: messages,
870
+ threadId,
871
+ };
872
+ };
873
+ // Helper to get system prompt (either static or built from context)
874
+ const getSystemPrompt = (context) => {
875
+ if (promptMode === "static") {
876
+ return options.systemPrompt;
877
+ }
878
+ // Build prompt using prompt builder
879
+ return promptBuilder.build(context);
880
+ };
778
881
  // Helper to get current active tools (core + MCP + dynamically loaded from registry)
779
882
  const getActiveToolSet = (threadId) => {
780
883
  // Start with core tools
@@ -1151,8 +1254,11 @@ export function createAgent(options) {
1151
1254
  // Build initial params - use active tools (core + dynamically loaded + task)
1152
1255
  // Apply hooks AFTER adding task tool so task tool is also wrapped
1153
1256
  const activeTools = applyToolHooks(addTaskToolIfConfigured(getActiveToolSet(effectiveGenOptions.threadId)), effectiveGenOptions.threadId);
1257
+ // Build prompt context and generate system prompt
1258
+ const promptContext = buildPromptContext(messages, effectiveGenOptions.threadId);
1259
+ const systemPrompt = getSystemPrompt(promptContext);
1154
1260
  const initialParams = {
1155
- system: options.systemPrompt,
1261
+ system: systemPrompt,
1156
1262
  messages,
1157
1263
  tools: activeTools,
1158
1264
  maxTokens: effectiveGenOptions.maxTokens,
@@ -1418,8 +1524,11 @@ export function createAgent(options) {
1418
1524
  // Build initial params - use active tools (core + dynamically loaded + task)
1419
1525
  // Apply hooks AFTER adding task tool so task tool is also wrapped
1420
1526
  const activeTools = applyToolHooks(addTaskToolIfConfigured(getActiveToolSet(effectiveGenOptions.threadId)), effectiveGenOptions.threadId);
1527
+ // Build prompt context and generate system prompt
1528
+ const promptContext = buildPromptContext(messages, effectiveGenOptions.threadId);
1529
+ const systemPrompt = getSystemPrompt(promptContext);
1421
1530
  const initialParams = {
1422
- system: options.systemPrompt,
1531
+ system: systemPrompt,
1423
1532
  messages,
1424
1533
  tools: activeTools,
1425
1534
  maxTokens: effectiveGenOptions.maxTokens,
@@ -1576,8 +1685,11 @@ export function createAgent(options) {
1576
1685
  // Build initial params - use active tools (core + dynamically loaded + task)
1577
1686
  // Apply hooks AFTER adding task tool so task tool is also wrapped
1578
1687
  const activeTools = applyToolHooks(addTaskToolIfConfigured(getActiveToolSet(effectiveGenOptions.threadId)), effectiveGenOptions.threadId);
1688
+ // Build prompt context and generate system prompt
1689
+ const promptContext = buildPromptContext(messages, effectiveGenOptions.threadId);
1690
+ const systemPrompt = getSystemPrompt(promptContext);
1579
1691
  const initialParams = {
1580
- system: options.systemPrompt,
1692
+ system: systemPrompt,
1581
1693
  messages,
1582
1694
  tools: activeTools,
1583
1695
  maxTokens: effectiveGenOptions.maxTokens,
@@ -1707,8 +1819,11 @@ export function createAgent(options) {
1707
1819
  // Build initial params - use active tools (core + dynamically loaded + task)
1708
1820
  // Apply hooks AFTER adding task tool so task tool is also wrapped
1709
1821
  const activeTools = applyToolHooks(addTaskToolIfConfigured(getActiveToolSet(effectiveGenOptions.threadId)), effectiveGenOptions.threadId);
1822
+ // Build prompt context and generate system prompt
1823
+ const promptContext = buildPromptContext(messages, effectiveGenOptions.threadId);
1824
+ const systemPrompt = getSystemPrompt(promptContext);
1710
1825
  const initialParams = {
1711
- system: options.systemPrompt,
1826
+ system: systemPrompt,
1712
1827
  messages,
1713
1828
  tools: activeTools,
1714
1829
  maxTokens: effectiveGenOptions.maxTokens,
@@ -1856,9 +1971,12 @@ export function createAgent(options) {
1856
1971
  // Build tools with streaming context and task tool
1857
1972
  // Apply hooks AFTER adding task tool so task tool is also wrapped
1858
1973
  const streamingTools = applyToolHooks(addTaskToolIfConfigured(getActiveToolSetWithStreaming(streamingContext, effectiveGenOptions.threadId), streamingContext), effectiveGenOptions.threadId);
1974
+ // Build prompt context and generate system prompt
1975
+ const promptContext = buildPromptContext(messages, effectiveGenOptions.threadId);
1976
+ const systemPrompt = getSystemPrompt(promptContext);
1859
1977
  // Build initial params with streaming-aware tools
1860
1978
  const initialParams = {
1861
- system: options.systemPrompt,
1979
+ system: systemPrompt,
1862
1980
  messages,
1863
1981
  tools: streamingTools,
1864
1982
  maxTokens: effectiveGenOptions.maxTokens,