nitrostack 1.0.71 → 1.0.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/api-key.js.map +1 -1
- package/dist/auth/client.js.map +1 -1
- package/dist/auth/index.d.ts +2 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +3 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/middleware.d.ts +1 -1
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js.map +1 -1
- package/dist/auth/secure-secret.d.ts +136 -0
- package/dist/auth/secure-secret.d.ts.map +1 -0
- package/dist/auth/secure-secret.js +182 -0
- package/dist/auth/secure-secret.js.map +1 -0
- package/dist/auth/server-metadata.d.ts.map +1 -1
- package/dist/auth/server-metadata.js.map +1 -1
- package/dist/auth/simple-jwt.d.ts +100 -14
- package/dist/auth/simple-jwt.d.ts.map +1 -1
- package/dist/auth/simple-jwt.js +19 -9
- package/dist/auth/simple-jwt.js.map +1 -1
- package/dist/auth/token-store.js +1 -1
- package/dist/auth/token-store.js.map +1 -1
- package/dist/auth/token-validation.js +1 -1
- package/dist/auth/token-validation.js.map +1 -1
- package/dist/cli/commands/build.js +1 -1
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/generate-types.js +12 -12
- package/dist/cli/commands/generate-types.js.map +1 -1
- package/dist/cli/commands/generate.d.ts +8 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +13 -12
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.js +1 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/upgrade.d.ts +10 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +221 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/app-decorator.d.ts +4 -3
- package/dist/core/app-decorator.d.ts.map +1 -1
- package/dist/core/app-decorator.js +67 -28
- package/dist/core/app-decorator.js.map +1 -1
- package/dist/core/builders.d.ts +19 -7
- package/dist/core/builders.d.ts.map +1 -1
- package/dist/core/builders.js +15 -8
- package/dist/core/builders.js.map +1 -1
- package/dist/core/component.d.ts +8 -8
- package/dist/core/component.d.ts.map +1 -1
- package/dist/core/component.js +3 -2
- package/dist/core/component.js.map +1 -1
- package/dist/core/config-module.d.ts +11 -4
- package/dist/core/config-module.d.ts.map +1 -1
- package/dist/core/config-module.js +1 -1
- package/dist/core/config-module.js.map +1 -1
- package/dist/core/decorators/cache.decorator.d.ts +9 -9
- package/dist/core/decorators/cache.decorator.d.ts.map +1 -1
- package/dist/core/decorators/cache.decorator.js +3 -3
- package/dist/core/decorators/cache.decorator.js.map +1 -1
- package/dist/core/decorators/health-check.decorator.d.ts +3 -3
- package/dist/core/decorators/health-check.decorator.d.ts.map +1 -1
- package/dist/core/decorators/health-check.decorator.js +2 -2
- package/dist/core/decorators/health-check.decorator.js.map +1 -1
- package/dist/core/decorators/rate-limit.decorator.d.ts +5 -4
- package/dist/core/decorators/rate-limit.decorator.d.ts.map +1 -1
- package/dist/core/decorators/rate-limit.decorator.js +3 -3
- package/dist/core/decorators/rate-limit.decorator.js.map +1 -1
- package/dist/core/decorators.d.ts +47 -29
- package/dist/core/decorators.d.ts.map +1 -1
- package/dist/core/decorators.js +9 -9
- package/dist/core/decorators.js.map +1 -1
- package/dist/core/di/container.d.ts +21 -4
- package/dist/core/di/container.d.ts.map +1 -1
- package/dist/core/di/container.js +11 -7
- package/dist/core/di/container.js.map +1 -1
- package/dist/core/di/injectable.decorator.d.ts +5 -3
- package/dist/core/di/injectable.decorator.d.ts.map +1 -1
- package/dist/core/di/injectable.decorator.js.map +1 -1
- package/dist/core/errors.d.ts +4 -4
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/events/event-emitter.d.ts +3 -3
- package/dist/core/events/event-emitter.d.ts.map +1 -1
- package/dist/core/events/event-emitter.js.map +1 -1
- package/dist/core/events/event.decorator.d.ts +5 -5
- package/dist/core/events/event.decorator.d.ts.map +1 -1
- package/dist/core/events/event.decorator.js +10 -6
- package/dist/core/events/event.decorator.js.map +1 -1
- package/dist/core/events/log-emitter.d.ts +7 -1
- package/dist/core/events/log-emitter.d.ts.map +1 -1
- package/dist/core/events/log-emitter.js.map +1 -1
- package/dist/core/filters/exception-filter.decorator.d.ts +5 -5
- package/dist/core/filters/exception-filter.decorator.d.ts.map +1 -1
- package/dist/core/filters/exception-filter.decorator.js +3 -3
- package/dist/core/filters/exception-filter.decorator.js.map +1 -1
- package/dist/core/filters/exception-filter.interface.d.ts +14 -5
- package/dist/core/filters/exception-filter.interface.d.ts.map +1 -1
- package/dist/core/guards/apikey.guard.d.ts +1 -1
- package/dist/core/guards/apikey.guard.d.ts.map +1 -1
- package/dist/core/guards/guard.interface.d.ts +1 -1
- package/dist/core/guards/guard.interface.d.ts.map +1 -1
- package/dist/core/guards/jwt.guard.d.ts +1 -1
- package/dist/core/guards/jwt.guard.d.ts.map +1 -1
- package/dist/core/guards/oauth.guard.d.ts +1 -1
- package/dist/core/guards/oauth.guard.d.ts.map +1 -1
- package/dist/core/guards/use-guards.decorator.d.ts +3 -3
- package/dist/core/guards/use-guards.decorator.d.ts.map +1 -1
- package/dist/core/guards/use-guards.decorator.js +1 -1
- package/dist/core/guards/use-guards.decorator.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/interceptors/interceptor.decorator.d.ts +4 -4
- package/dist/core/interceptors/interceptor.decorator.d.ts.map +1 -1
- package/dist/core/interceptors/interceptor.decorator.js +2 -2
- package/dist/core/interceptors/interceptor.decorator.js.map +1 -1
- package/dist/core/interceptors/interceptor.interface.d.ts +3 -3
- package/dist/core/interceptors/interceptor.interface.d.ts.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/core/middleware/middleware.decorator.d.ts +4 -4
- package/dist/core/middleware/middleware.decorator.d.ts.map +1 -1
- package/dist/core/middleware/middleware.decorator.js +2 -2
- package/dist/core/middleware/middleware.decorator.js.map +1 -1
- package/dist/core/middleware/middleware.interface.d.ts +3 -3
- package/dist/core/middleware/middleware.interface.d.ts.map +1 -1
- package/dist/core/module.d.ts +33 -14
- package/dist/core/module.d.ts.map +1 -1
- package/dist/core/module.js +11 -6
- package/dist/core/module.js.map +1 -1
- package/dist/core/oauth-module.d.ts +9 -3
- package/dist/core/oauth-module.d.ts.map +1 -1
- package/dist/core/oauth-module.js +4 -3
- package/dist/core/oauth-module.js.map +1 -1
- package/dist/core/pipes/pipe.decorator.d.ts +14 -5
- package/dist/core/pipes/pipe.decorator.d.ts.map +1 -1
- package/dist/core/pipes/pipe.decorator.js +2 -2
- package/dist/core/pipes/pipe.decorator.js.map +1 -1
- package/dist/core/pipes/pipe.interface.d.ts +9 -4
- package/dist/core/pipes/pipe.interface.d.ts.map +1 -1
- package/dist/core/prompt.d.ts +13 -4
- package/dist/core/prompt.d.ts.map +1 -1
- package/dist/core/prompt.js +2 -2
- package/dist/core/prompt.js.map +1 -1
- package/dist/core/resource.d.ts +7 -2
- package/dist/core/resource.d.ts.map +1 -1
- package/dist/core/resource.js +2 -2
- package/dist/core/resource.js.map +1 -1
- package/dist/core/server.d.ts +49 -3
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +61 -34
- package/dist/core/server.js.map +1 -1
- package/dist/core/tool.d.ts +44 -16
- package/dist/core/tool.d.ts.map +1 -1
- package/dist/core/tool.js +19 -6
- package/dist/core/tool.js.map +1 -1
- package/dist/core/transports/discovery-http-server.d.ts +7 -1
- package/dist/core/transports/discovery-http-server.d.ts.map +1 -1
- package/dist/core/transports/discovery-http-server.js.map +1 -1
- package/dist/core/transports/http-server.d.ts +2 -2
- package/dist/core/transports/http-server.d.ts.map +1 -1
- package/dist/core/transports/http-server.js +1 -1
- package/dist/core/transports/http-server.js.map +1 -1
- package/dist/core/transports/streamable-http.d.ts +4 -4
- package/dist/core/transports/streamable-http.d.ts.map +1 -1
- package/dist/core/transports/streamable-http.js +1 -1
- package/dist/core/transports/streamable-http.js.map +1 -1
- package/dist/core/types.d.ts +87 -15
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/widgets/widget-registry.d.ts +2 -2
- package/dist/core/widgets/widget-registry.d.ts.map +1 -1
- package/dist/core/widgets/widget-registry.js +1 -1
- package/dist/core/widgets/widget-registry.js.map +1 -1
- package/dist/testing/index.d.ts +44 -17
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5 -8
- package/dist/testing/index.js.map +1 -1
- package/dist/ui-next/index.d.ts +1 -1
- package/dist/ui-next/index.d.ts.map +1 -1
- package/dist/ui-next/index.js.map +1 -1
- package/dist/widgets/hooks/useWidgetSDK.d.ts +5 -5
- package/dist/widgets/runtime/WidgetLayout.js.map +1 -1
- package/dist/widgets/sdk.d.ts +5 -5
- package/dist/widgets/sdk.d.ts.map +1 -1
- package/dist/widgets/sdk.js.map +1 -1
- package/package.json +1 -1
- package/src/studio/app/api/auth/fetch-metadata/route.ts +3 -2
- package/src/studio/app/api/auth/register-client/route.ts +3 -2
- package/src/studio/app/api/chat/route.ts +33 -17
- package/src/studio/app/api/health/checks/route.ts +5 -4
- package/src/studio/app/api/init/route.ts +3 -2
- package/src/studio/app/api/ping/route.ts +3 -2
- package/src/studio/app/api/prompts/[name]/route.ts +4 -3
- package/src/studio/app/api/prompts/route.ts +3 -2
- package/src/studio/app/api/resources/[...uri]/route.ts +3 -2
- package/src/studio/app/api/resources/route.ts +3 -2
- package/src/studio/app/api/roots/route.ts +3 -2
- package/src/studio/app/api/sampling/route.ts +3 -2
- package/src/studio/app/api/tools/[name]/call/route.ts +3 -2
- package/src/studio/app/api/tools/route.ts +4 -3
- package/src/studio/app/api/widget-examples/route.ts +5 -4
- package/src/studio/app/auth/callback/page.tsx +9 -8
- package/src/studio/app/chat/page.tsx +1535 -468
- package/src/studio/app/chat/page.tsx.backup +1046 -187
- package/src/studio/app/globals.css +361 -191
- package/src/studio/app/health/page.tsx +73 -77
- package/src/studio/app/layout.tsx +9 -11
- package/src/studio/app/logs/page.tsx +31 -32
- package/src/studio/app/page.tsx +136 -232
- package/src/studio/app/prompts/page.tsx +115 -97
- package/src/studio/app/resources/page.tsx +115 -124
- package/src/studio/app/settings/page.tsx +1083 -127
- package/src/studio/app/tools/page.tsx +343 -0
- package/src/studio/components/EnlargeModal.tsx +76 -65
- package/src/studio/components/LogMessage.tsx +6 -6
- package/src/studio/components/MarkdownRenderer.tsx +246 -349
- package/src/studio/components/Sidebar.tsx +165 -210
- package/src/studio/components/SplashScreen.tsx +109 -0
- package/src/studio/components/ToolCard.tsx +50 -41
- package/src/studio/components/VoiceOrbOverlay.tsx +475 -0
- package/src/studio/components/WidgetErrorBoundary.tsx +48 -0
- package/src/studio/components/WidgetRenderer.tsx +169 -211
- package/src/studio/components/ops/OpsCanvas.tsx +748 -0
- package/src/studio/components/ops/OpsNodeDetailPanel.tsx +150 -0
- package/src/studio/components/ops/OpsSummaryBar.tsx +90 -0
- package/src/studio/components/ops/index.ts +5 -0
- package/src/studio/components/ops/nodes/BaseNode.tsx +65 -0
- package/src/studio/components/ops/nodes/LLMCallNode.tsx +34 -0
- package/src/studio/components/ops/nodes/LLMResponseNode.tsx +33 -0
- package/src/studio/components/ops/nodes/ToolCallNode.tsx +30 -0
- package/src/studio/components/ops/nodes/ToolResultNode.tsx +43 -0
- package/src/studio/components/ops/nodes/UserPromptNode.tsx +34 -0
- package/src/studio/components/ops/nodes/WidgetRenderNode.tsx +23 -0
- package/src/studio/components/ops/nodes/index.ts +8 -0
- package/src/studio/components/tools/ToolsCanvas.tsx +327 -0
- package/src/studio/lib/api.ts +61 -42
- package/src/studio/lib/http-client-transport.ts +2 -2
- package/src/studio/lib/llm-service.ts +126 -47
- package/src/studio/lib/mcp-client.ts +9 -6
- package/src/studio/lib/ops-store.ts +427 -0
- package/src/studio/lib/ops-tracker.ts +416 -0
- package/src/studio/lib/ops-types.ts +164 -0
- package/src/studio/lib/store.ts +23 -11
- package/src/studio/lib/types.ts +228 -38
- package/src/studio/lib/widget-loader.ts +2 -2
- package/src/studio/package-lock.json +3303 -0
- package/src/studio/package.json +3 -1
- package/src/studio/public/NitroStudio Isotype Color.png +0 -0
- package/src/studio/tailwind.config.ts +63 -17
- package/templates/typescript-oauth/src/modules/flights/flights.prompts.ts +19 -22
- package/dist/cli/build-widgets.mjs +0 -165
- package/src/studio/app/auth/page.tsx +0 -560
- package/src/studio/app/ping/page.tsx +0 -209
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// LLM Service for Studio
|
|
2
2
|
// Supports OpenAI and Gemini
|
|
3
3
|
|
|
4
|
+
import type { JsonValue, JsonObject } from './types';
|
|
5
|
+
|
|
4
6
|
export type LLMProvider = 'openai' | 'gemini';
|
|
5
7
|
|
|
6
8
|
export interface ChatMessage {
|
|
@@ -19,7 +21,7 @@ export interface ChatMessage {
|
|
|
19
21
|
export interface ToolCall {
|
|
20
22
|
id: string;
|
|
21
23
|
name: string;
|
|
22
|
-
arguments:
|
|
24
|
+
arguments: JsonValue;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export interface ChatResponse {
|
|
@@ -28,30 +30,108 @@ export interface ChatResponse {
|
|
|
28
30
|
finishReason?: string;
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Tool definition for LLM
|
|
35
|
+
*/
|
|
36
|
+
interface LLMTool {
|
|
37
|
+
name: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
inputSchema?: JsonObject;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* OpenAI message content part
|
|
44
|
+
*/
|
|
45
|
+
interface OpenAIContentPart {
|
|
46
|
+
type: 'text' | 'image_url';
|
|
47
|
+
text?: string;
|
|
48
|
+
image_url?: { url: string };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* OpenAI tool call from response
|
|
53
|
+
*/
|
|
54
|
+
interface OpenAIToolCall {
|
|
55
|
+
id: string;
|
|
56
|
+
type: 'function';
|
|
57
|
+
function: {
|
|
58
|
+
name: string;
|
|
59
|
+
arguments: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Gemini function call part
|
|
65
|
+
*/
|
|
66
|
+
interface GeminiFunctionPart {
|
|
67
|
+
functionCall?: {
|
|
68
|
+
name: string;
|
|
69
|
+
args: JsonObject;
|
|
70
|
+
};
|
|
71
|
+
functionResponse?: {
|
|
72
|
+
name: string;
|
|
73
|
+
response: { content: string };
|
|
74
|
+
};
|
|
75
|
+
text?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Gemini content entry
|
|
80
|
+
*/
|
|
81
|
+
interface GeminiContent {
|
|
82
|
+
role: 'user' | 'model' | 'function';
|
|
83
|
+
parts: GeminiFunctionPart[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Gemini parameter schema property
|
|
88
|
+
*/
|
|
89
|
+
interface GeminiParameterProperty {
|
|
90
|
+
type: string;
|
|
91
|
+
description: string;
|
|
92
|
+
enum?: JsonValue[];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gemini parameters schema
|
|
97
|
+
*/
|
|
98
|
+
interface GeminiParameters {
|
|
99
|
+
type: string;
|
|
100
|
+
properties: Record<string, GeminiParameterProperty>;
|
|
101
|
+
required: string[];
|
|
102
|
+
}
|
|
103
|
+
|
|
31
104
|
export class LLMService {
|
|
32
105
|
// System prompt to improve tool usage (especially for Gemini)
|
|
33
|
-
private getSystemPrompt(tools:
|
|
34
|
-
return `You are an intelligent AI assistant with access to ${tools.length} powerful tools. Your goal is to help users accomplish their tasks efficiently and
|
|
106
|
+
private getSystemPrompt(tools: LLMTool[]): string {
|
|
107
|
+
return `You are an intelligent AI assistant with access to ${tools.length} powerful tools. Your goal is to help users accomplish their tasks efficiently and accurately.
|
|
108
|
+
|
|
109
|
+
**CRITICAL: ONLY DO WHAT THE USER ASKS**
|
|
110
|
+
|
|
111
|
+
⚠️ **THE MOST IMPORTANT RULE**: Only perform the specific task the user requested. Do NOT assume additional steps or chain unrelated tools.
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
- "show me airports in london" → ONLY search airports in london. Do NOT search for flights.
|
|
115
|
+
- "search flights from A to B" → ONLY search those flights. Do NOT book them.
|
|
116
|
+
- "book this flight" → ONLY proceed with booking for the specified flight.
|
|
35
117
|
|
|
36
118
|
**CORE PRINCIPLES FOR TOOL USAGE:**
|
|
37
119
|
|
|
38
|
-
1. **
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
120
|
+
1. **Answer EXACTLY What Was Asked**:
|
|
121
|
+
- If user asks "show airports in X", only call search_airports for X
|
|
122
|
+
- If user asks "search flights", only search flights - don't book
|
|
123
|
+
- NEVER assume the user wants additional steps beyond their request
|
|
124
|
+
- Ask before doing more than requested
|
|
42
125
|
|
|
43
|
-
2. **
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
- Don't ask permission for each step in an obvious workflow
|
|
126
|
+
2. **Infer Context When Helpful** (but don't over-extend):
|
|
127
|
+
- Infer obvious location info (e.g., "Bangalore" → Karnataka, India)
|
|
128
|
+
- Use common sense defaults for required parameters
|
|
129
|
+
- But NEVER infer that user wants additional operations
|
|
48
130
|
|
|
49
131
|
3. **Maintain Context Awareness**:
|
|
50
132
|
- Remember information from previous tool calls in THIS conversation
|
|
51
133
|
- Extract and reuse data (IDs, names, values) from previous tool results
|
|
52
134
|
- Example: If browse_products returned products with IDs, use those IDs for add_to_cart
|
|
53
|
-
- Match user requests to previous data (e.g., "apple" → find product with name "Apple" → use its ID)
|
|
54
|
-
- Track state across the conversation (logged in status, product IDs, order IDs, etc.)
|
|
55
135
|
- NEVER ask for information you already have from a previous tool call
|
|
56
136
|
|
|
57
137
|
4. **Use Smart Defaults**:
|
|
@@ -59,25 +139,18 @@ export class LLMService {
|
|
|
59
139
|
- Common defaults: page=1, limit=10, sort=recent, etc.
|
|
60
140
|
- Only ask for clarification when truly ambiguous
|
|
61
141
|
|
|
62
|
-
5. **
|
|
63
|
-
- Don't ask for every detail - use inference and defaults
|
|
64
|
-
- Chain related operations seamlessly
|
|
65
|
-
- Provide concise summaries after multi-step operations
|
|
66
|
-
- Be conversational but efficient
|
|
67
|
-
|
|
68
|
-
6. **Handle Errors Gracefully**:
|
|
142
|
+
5. **Handle Errors Gracefully**:
|
|
69
143
|
- If authentication required, guide user to login
|
|
70
144
|
- If prerequisite missing, suggest the required step
|
|
71
145
|
- If operation fails, explain why and suggest alternatives
|
|
72
146
|
- Always provide a helpful next step
|
|
73
147
|
|
|
74
|
-
|
|
148
|
+
6. **Tool Call Best Practices**:
|
|
75
149
|
- Read tool descriptions carefully to understand their purpose
|
|
76
150
|
- Use exact parameter names as specified in the schema
|
|
77
151
|
- Pay attention to required vs optional parameters
|
|
78
152
|
- If a tool says "Requires authentication" - CALL IT ANYWAY! Auth is handled automatically
|
|
79
153
|
- Don't ask for credentials preemptively - only if a tool explicitly fails
|
|
80
|
-
- Look for examples in tool schemas for guidance
|
|
81
154
|
|
|
82
155
|
**AUTHENTICATION HANDLING:**
|
|
83
156
|
|
|
@@ -90,17 +163,23 @@ export class LLMService {
|
|
|
90
163
|
|
|
91
164
|
**EXAMPLES:**
|
|
92
165
|
|
|
166
|
+
**Stay Focused - Don't Over-Extend:**
|
|
167
|
+
✅ User: "show me airports in london" → Call search_airports("london") → Show results → STOP
|
|
168
|
+
❌ User: "show me airports in london" → search_airports → then search New York → then search flights (WRONG!)
|
|
169
|
+
|
|
170
|
+
✅ User: "search flights from NYC to LAX" → Call search_flights → Show results → STOP
|
|
171
|
+
❌ User: "search flights from NYC to LAX" → search → then automatically book (WRONG!)
|
|
172
|
+
|
|
93
173
|
**Authentication:**
|
|
94
174
|
User: "whoami" → Call whoami tool directly (don't ask for login)
|
|
95
175
|
User: "show my orders" → Call get_order_history directly (don't ask for login)
|
|
96
|
-
User: "what's in my cart" → Call view_cart directly (don't ask for login)
|
|
97
176
|
|
|
98
177
|
**Context Awareness:**
|
|
99
178
|
1. browse_products returns: [{id: "prod-3", name: "Apple", price: 0.99}, ...]
|
|
100
179
|
2. User: "add apple to cart" → Extract ID "prod-3" from previous result → Call add_to_cart({product_id: "prod-3", quantity: 1})
|
|
101
|
-
3. User: "add 2 more" → Remember prod-3 → Call add_to_cart({product_id: "prod-3", quantity: 2})
|
|
102
180
|
|
|
103
181
|
**NEVER do this:**
|
|
182
|
+
❌ User: "show airports" → Then automatically search flights (User didn't ask!)
|
|
104
183
|
❌ User: "add apple to cart" → "What is the product ID?" (You already have it!)
|
|
105
184
|
❌ User: "add to cart" → "Which product?" (Look at conversation context!)
|
|
106
185
|
|
|
@@ -140,7 +219,7 @@ User: "list all resources"
|
|
|
140
219
|
async chat(
|
|
141
220
|
provider: LLMProvider,
|
|
142
221
|
messages: ChatMessage[],
|
|
143
|
-
tools:
|
|
222
|
+
tools: LLMTool[],
|
|
144
223
|
apiKey: string
|
|
145
224
|
): Promise<ChatResponse> {
|
|
146
225
|
// Inject system prompt at the beginning if not already present
|
|
@@ -164,7 +243,7 @@ User: "list all resources"
|
|
|
164
243
|
|
|
165
244
|
private async chatOpenAI(
|
|
166
245
|
messages: ChatMessage[],
|
|
167
|
-
tools:
|
|
246
|
+
tools: LLMTool[],
|
|
168
247
|
apiKey: string
|
|
169
248
|
): Promise<ChatResponse> {
|
|
170
249
|
const formattedMessages = messages.map((msg) => {
|
|
@@ -194,7 +273,7 @@ User: "list all resources"
|
|
|
194
273
|
|
|
195
274
|
if (msg.role === 'user' && msg.file) {
|
|
196
275
|
// Handle file attachments for OpenAI
|
|
197
|
-
const contentParts:
|
|
276
|
+
const contentParts: OpenAIContentPart[] = [
|
|
198
277
|
{ type: 'text', text: msg.content || ' ' } // Ensure some text exists
|
|
199
278
|
];
|
|
200
279
|
|
|
@@ -247,9 +326,9 @@ User: "list all resources"
|
|
|
247
326
|
|
|
248
327
|
console.log('Formatted messages for OpenAI:', JSON.stringify(formattedMessages, null, 2));
|
|
249
328
|
|
|
250
|
-
const requestBody:
|
|
329
|
+
const requestBody: JsonObject = {
|
|
251
330
|
model: 'gpt-4-turbo-preview',
|
|
252
|
-
messages: formattedMessages,
|
|
331
|
+
messages: formattedMessages as JsonValue,
|
|
253
332
|
};
|
|
254
333
|
|
|
255
334
|
if (tools.length > 0) {
|
|
@@ -309,10 +388,10 @@ User: "list all resources"
|
|
|
309
388
|
};
|
|
310
389
|
|
|
311
390
|
if (choice.message.tool_calls) {
|
|
312
|
-
result.toolCalls = choice.message.tool_calls.map((tc
|
|
391
|
+
result.toolCalls = (choice.message.tool_calls as OpenAIToolCall[]).map((tc) => ({
|
|
313
392
|
id: tc.id,
|
|
314
393
|
name: tc.function?.name || '',
|
|
315
|
-
arguments: JSON.parse(tc.function?.arguments || '{}'),
|
|
394
|
+
arguments: JSON.parse(tc.function?.arguments || '{}') as JsonValue,
|
|
316
395
|
}));
|
|
317
396
|
result.message.toolCalls = result.toolCalls;
|
|
318
397
|
}
|
|
@@ -322,11 +401,11 @@ User: "list all resources"
|
|
|
322
401
|
|
|
323
402
|
private async chatGemini(
|
|
324
403
|
messages: ChatMessage[],
|
|
325
|
-
tools:
|
|
404
|
+
tools: LLMTool[],
|
|
326
405
|
apiKey: string
|
|
327
406
|
): Promise<ChatResponse> {
|
|
328
407
|
// Convert messages to Gemini format
|
|
329
|
-
const contents:
|
|
408
|
+
const contents: GeminiContent[] = [];
|
|
330
409
|
let systemInstruction = '';
|
|
331
410
|
|
|
332
411
|
// Group consecutive tool messages together for Gemini
|
|
@@ -342,7 +421,7 @@ User: "list all resources"
|
|
|
342
421
|
|
|
343
422
|
if (msg.role === 'tool') {
|
|
344
423
|
// Collect all consecutive tool messages and group them into ONE function response
|
|
345
|
-
const functionParts:
|
|
424
|
+
const functionParts: GeminiFunctionPart[] = [];
|
|
346
425
|
|
|
347
426
|
while (i < messages.length && messages[i].role === 'tool') {
|
|
348
427
|
const toolMsg = messages[i];
|
|
@@ -364,7 +443,7 @@ User: "list all resources"
|
|
|
364
443
|
});
|
|
365
444
|
} else if (msg.role === 'assistant' && msg.toolCalls && msg.toolCalls.length > 0) {
|
|
366
445
|
// Assistant message with tool calls
|
|
367
|
-
const parts:
|
|
446
|
+
const parts: GeminiFunctionPart[] = [];
|
|
368
447
|
|
|
369
448
|
if (msg.content) {
|
|
370
449
|
parts.push({ text: msg.content });
|
|
@@ -374,7 +453,7 @@ User: "list all resources"
|
|
|
374
453
|
parts.push({
|
|
375
454
|
functionCall: {
|
|
376
455
|
name: tc.name,
|
|
377
|
-
args: tc.arguments,
|
|
456
|
+
args: tc.arguments as JsonObject,
|
|
378
457
|
},
|
|
379
458
|
});
|
|
380
459
|
}
|
|
@@ -386,7 +465,7 @@ User: "list all resources"
|
|
|
386
465
|
i++;
|
|
387
466
|
} else {
|
|
388
467
|
// Regular user or assistant message
|
|
389
|
-
const parts:
|
|
468
|
+
const parts: GeminiFunctionPart[] = [];
|
|
390
469
|
|
|
391
470
|
if (msg.content) {
|
|
392
471
|
parts.push({ text: msg.content });
|
|
@@ -448,8 +527,8 @@ User: "list all resources"
|
|
|
448
527
|
// console.log('Formatted contents for Gemini:', JSON.stringify(contents, null, 2));
|
|
449
528
|
|
|
450
529
|
// Prepare request body
|
|
451
|
-
const requestBody:
|
|
452
|
-
contents,
|
|
530
|
+
const requestBody: JsonObject = {
|
|
531
|
+
contents: contents as JsonValue,
|
|
453
532
|
};
|
|
454
533
|
|
|
455
534
|
// Add system instruction if present
|
|
@@ -470,24 +549,24 @@ User: "list all resources"
|
|
|
470
549
|
delete cleanSchema.additionalProperties;
|
|
471
550
|
|
|
472
551
|
// Convert to Gemini's expected format
|
|
473
|
-
const parameters:
|
|
474
|
-
type: cleanSchema.type || 'OBJECT',
|
|
552
|
+
const parameters: GeminiParameters = {
|
|
553
|
+
type: (cleanSchema.type as string) || 'OBJECT',
|
|
475
554
|
properties: {},
|
|
476
|
-
required: cleanSchema.required || [],
|
|
555
|
+
required: (cleanSchema.required as string[]) || [],
|
|
477
556
|
};
|
|
478
557
|
|
|
479
558
|
// Convert properties
|
|
480
559
|
if (cleanSchema.properties) {
|
|
481
560
|
for (const [key, value] of Object.entries(cleanSchema.properties)) {
|
|
482
|
-
const prop
|
|
561
|
+
const prop = value as JsonObject;
|
|
483
562
|
parameters.properties[key] = {
|
|
484
|
-
type: this.convertTypeToGemini(prop.type),
|
|
485
|
-
description: prop.description || '',
|
|
563
|
+
type: this.convertTypeToGemini(prop.type as string | undefined),
|
|
564
|
+
description: (prop.description as string) || '',
|
|
486
565
|
};
|
|
487
566
|
|
|
488
567
|
// Handle enums
|
|
489
568
|
if (prop.enum) {
|
|
490
|
-
parameters.properties[key].enum = prop.enum;
|
|
569
|
+
parameters.properties[key].enum = prop.enum as JsonValue[];
|
|
491
570
|
}
|
|
492
571
|
}
|
|
493
572
|
}
|
|
@@ -116,7 +116,7 @@ export class McpClient {
|
|
|
116
116
|
// Start the HTTP transport (establish SSE connection)
|
|
117
117
|
await this.transport.start();
|
|
118
118
|
} else {
|
|
119
|
-
throw new Error(`Unknown transport type: ${(config as
|
|
119
|
+
throw new Error(`Unknown transport type: ${(config as McpClientConfig).type}`);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// Create client
|
|
@@ -198,7 +198,7 @@ export class McpClient {
|
|
|
198
198
|
return await this.client.listTools();
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
async callTool(name: string, args:
|
|
201
|
+
async callTool(name: string, args: Record<string, unknown>) {
|
|
202
202
|
if (!this.client) throw new Error('Not connected');
|
|
203
203
|
return await this.client.callTool({ name, arguments: args });
|
|
204
204
|
}
|
|
@@ -218,7 +218,7 @@ export class McpClient {
|
|
|
218
218
|
return await this.client.listPrompts();
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
async getPrompt(name: string, args:
|
|
221
|
+
async getPrompt(name: string, args: Record<string, string>) {
|
|
222
222
|
if (!this.client) throw new Error('Not connected');
|
|
223
223
|
return await this.client.getPrompt({ name, arguments: args });
|
|
224
224
|
}
|
|
@@ -233,13 +233,16 @@ export class McpClient {
|
|
|
233
233
|
return await this.client.listRoots();
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
async executeTool(name: string, args:
|
|
236
|
+
async executeTool(name: string, args: Record<string, unknown>) {
|
|
237
237
|
return await this.callTool(name, args);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
async createCompletion(params:
|
|
240
|
+
async createCompletion(params: {
|
|
241
|
+
ref: string;
|
|
242
|
+
argument: { name: string; value: string };
|
|
243
|
+
}) {
|
|
241
244
|
if (!this.client) throw new Error('Not connected');
|
|
242
|
-
return await this.client.
|
|
245
|
+
return await this.client.complete(params);
|
|
243
246
|
}
|
|
244
247
|
}
|
|
245
248
|
|