nitrostack 1.0.72 → 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 +31 -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 +3 -2
- package/src/studio/app/chat/page.tsx +481 -105
- package/src/studio/app/health/page.tsx +1 -1
- package/src/studio/app/logs/page.tsx +2 -2
- package/src/studio/app/page.tsx +5 -5
- package/src/studio/app/prompts/page.tsx +2 -2
- package/src/studio/app/settings/page.tsx +3 -2
- package/src/studio/app/tools/page.tsx +3 -3
- package/src/studio/components/LogMessage.tsx +1 -1
- package/src/studio/components/MarkdownRenderer.tsx +245 -348
- package/src/studio/components/Sidebar.tsx +18 -3
- package/src/studio/components/VoiceOrbOverlay.tsx +12 -6
- package/src/studio/components/WidgetErrorBoundary.tsx +48 -0
- package/src/studio/components/WidgetRenderer.tsx +168 -215
- 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 +2 -2
- 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 +8 -11
- package/src/studio/lib/types.ts +228 -38
- package/src/studio/lib/widget-loader.ts +2 -2
- package/templates/typescript-oauth/src/modules/flights/flights.prompts.ts +19 -22
- package/dist/cli/build-widgets.mjs +0 -165
package/src/studio/lib/api.ts
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
// NitroStack Studio API Client
|
|
2
2
|
|
|
3
|
+
import type {
|
|
4
|
+
JsonValue,
|
|
5
|
+
ChatMessage,
|
|
6
|
+
PKCEParams,
|
|
7
|
+
ClientRegistration,
|
|
8
|
+
} from './types';
|
|
9
|
+
|
|
3
10
|
const API_BASE = typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000';
|
|
4
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Client registration metadata for OAuth
|
|
14
|
+
*/
|
|
15
|
+
interface ClientRegistrationMetadata {
|
|
16
|
+
client_name?: string;
|
|
17
|
+
redirect_uris: string[];
|
|
18
|
+
token_endpoint_auth_method?: string;
|
|
19
|
+
grant_types?: string[];
|
|
20
|
+
response_types?: string[];
|
|
21
|
+
[key: string]: JsonValue | undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
5
24
|
export class StudioAPI {
|
|
6
25
|
private baseUrl: string;
|
|
7
26
|
private initialized: boolean = false;
|
|
@@ -11,7 +30,7 @@ export class StudioAPI {
|
|
|
11
30
|
}
|
|
12
31
|
|
|
13
32
|
// Initialize MCP connection (call once on app start)
|
|
14
|
-
async initialize() {
|
|
33
|
+
async initialize(): Promise<void> {
|
|
15
34
|
if (this.initialized) return;
|
|
16
35
|
try {
|
|
17
36
|
await fetch(`${this.baseUrl}/api/init`, { method: 'POST' });
|
|
@@ -22,111 +41,111 @@ export class StudioAPI {
|
|
|
22
41
|
}
|
|
23
42
|
|
|
24
43
|
// Connection
|
|
25
|
-
async checkConnection() {
|
|
44
|
+
async checkConnection(): Promise<JsonValue> {
|
|
26
45
|
const response = await fetch(`${this.baseUrl}/api/health`);
|
|
27
|
-
return response.json()
|
|
46
|
+
return response.json() as Promise<JsonValue>;
|
|
28
47
|
}
|
|
29
48
|
|
|
30
49
|
// Tools
|
|
31
|
-
async listTools() {
|
|
50
|
+
async listTools(): Promise<JsonValue> {
|
|
32
51
|
const response = await fetch(`${this.baseUrl}/api/tools`);
|
|
33
|
-
return response.json()
|
|
52
|
+
return response.json() as Promise<JsonValue>;
|
|
34
53
|
}
|
|
35
54
|
|
|
36
|
-
async getTools() {
|
|
55
|
+
async getTools(): Promise<JsonValue> {
|
|
37
56
|
return this.listTools();
|
|
38
57
|
}
|
|
39
58
|
|
|
40
|
-
async callTool(name: string, args:
|
|
59
|
+
async callTool(name: string, args: JsonValue, jwtToken?: string, apiKey?: string): Promise<JsonValue> {
|
|
41
60
|
const response = await fetch(`${this.baseUrl}/api/tools/${name}/call`, {
|
|
42
61
|
method: 'POST',
|
|
43
62
|
headers: { 'Content-Type': 'application/json' },
|
|
44
63
|
body: JSON.stringify({ args, jwtToken, apiKey }),
|
|
45
64
|
});
|
|
46
|
-
return response.json()
|
|
65
|
+
return response.json() as Promise<JsonValue>;
|
|
47
66
|
}
|
|
48
67
|
|
|
49
68
|
// Resources
|
|
50
|
-
async getResources() {
|
|
69
|
+
async getResources(): Promise<JsonValue> {
|
|
51
70
|
const response = await fetch(`${this.baseUrl}/api/resources`);
|
|
52
|
-
return response.json()
|
|
71
|
+
return response.json() as Promise<JsonValue>;
|
|
53
72
|
}
|
|
54
73
|
|
|
55
|
-
async getResource(uri: string) {
|
|
74
|
+
async getResource(uri: string): Promise<JsonValue> {
|
|
56
75
|
const response = await fetch(`${this.baseUrl}/api/resources/${encodeURIComponent(uri)}`);
|
|
57
|
-
return response.json()
|
|
76
|
+
return response.json() as Promise<JsonValue>;
|
|
58
77
|
}
|
|
59
78
|
|
|
60
79
|
// Prompts
|
|
61
|
-
async getPrompts() {
|
|
80
|
+
async getPrompts(): Promise<JsonValue> {
|
|
62
81
|
const response = await fetch(`${this.baseUrl}/api/prompts`);
|
|
63
|
-
return response.json()
|
|
82
|
+
return response.json() as Promise<JsonValue>;
|
|
64
83
|
}
|
|
65
84
|
|
|
66
|
-
async executePrompt(name: string, args:
|
|
85
|
+
async executePrompt(name: string, args: Record<string, string>): Promise<JsonValue> {
|
|
67
86
|
const response = await fetch(`${this.baseUrl}/api/prompts/${name}`, {
|
|
68
87
|
method: 'POST',
|
|
69
88
|
headers: { 'Content-Type': 'application/json' },
|
|
70
89
|
body: JSON.stringify(args),
|
|
71
90
|
});
|
|
72
|
-
return response.json()
|
|
91
|
+
return response.json() as Promise<JsonValue>;
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
// Ping
|
|
76
|
-
async ping() {
|
|
95
|
+
async ping(): Promise<JsonValue> {
|
|
77
96
|
const response = await fetch(`${this.baseUrl}/api/ping`);
|
|
78
|
-
return response.json()
|
|
97
|
+
return response.json() as Promise<JsonValue>;
|
|
79
98
|
}
|
|
80
99
|
|
|
81
100
|
// Sampling
|
|
82
|
-
async sample(params: { prompt: string; maxTokens: number; model?: string }) {
|
|
101
|
+
async sample(params: { prompt: string; maxTokens: number; model?: string }): Promise<JsonValue> {
|
|
83
102
|
const response = await fetch(`${this.baseUrl}/api/sampling`, {
|
|
84
103
|
method: 'POST',
|
|
85
104
|
headers: { 'Content-Type': 'application/json' },
|
|
86
105
|
body: JSON.stringify(params),
|
|
87
106
|
});
|
|
88
|
-
return response.json()
|
|
107
|
+
return response.json() as Promise<JsonValue>;
|
|
89
108
|
}
|
|
90
109
|
|
|
91
110
|
// Roots
|
|
92
|
-
async getRoots() {
|
|
111
|
+
async getRoots(): Promise<JsonValue> {
|
|
93
112
|
const response = await fetch(`${this.baseUrl}/api/roots`);
|
|
94
|
-
return response.json()
|
|
113
|
+
return response.json() as Promise<JsonValue>;
|
|
95
114
|
}
|
|
96
115
|
|
|
97
116
|
// Chat
|
|
98
117
|
async chat(params: {
|
|
99
118
|
provider: string;
|
|
100
|
-
messages:
|
|
119
|
+
messages: ChatMessage[];
|
|
101
120
|
apiKey: string; // LLM API key (OpenAI/Gemini)
|
|
102
121
|
jwtToken?: string; // MCP server JWT token
|
|
103
122
|
mcpApiKey?: string; // MCP server API key
|
|
104
|
-
}) {
|
|
123
|
+
}): Promise<JsonValue> {
|
|
105
124
|
const response = await fetch(`${this.baseUrl}/api/chat`, {
|
|
106
125
|
method: 'POST',
|
|
107
126
|
headers: { 'Content-Type': 'application/json' },
|
|
108
127
|
body: JSON.stringify(params),
|
|
109
128
|
});
|
|
110
|
-
return response.json()
|
|
129
|
+
return response.json() as Promise<JsonValue>;
|
|
111
130
|
}
|
|
112
131
|
|
|
113
132
|
// Auth (OAuth 2.1)
|
|
114
|
-
async discoverAuth(url: string, type: 'resource' | 'auth-server') {
|
|
133
|
+
async discoverAuth(url: string, type: 'resource' | 'auth-server'): Promise<JsonValue> {
|
|
115
134
|
const response = await fetch(`${this.baseUrl}/api/auth/fetch-metadata`, {
|
|
116
135
|
method: 'POST',
|
|
117
136
|
headers: { 'Content-Type': 'application/json' },
|
|
118
137
|
body: JSON.stringify({ url, type }),
|
|
119
138
|
});
|
|
120
|
-
return response.json()
|
|
139
|
+
return response.json() as Promise<JsonValue>;
|
|
121
140
|
}
|
|
122
141
|
|
|
123
|
-
async registerClient(endpoint: string, metadata:
|
|
142
|
+
async registerClient(endpoint: string, metadata: ClientRegistrationMetadata): Promise<ClientRegistration> {
|
|
124
143
|
const response = await fetch(`${this.baseUrl}/api/auth/register-client`, {
|
|
125
144
|
method: 'POST',
|
|
126
145
|
headers: { 'Content-Type': 'application/json' },
|
|
127
146
|
body: JSON.stringify({ endpoint, metadata }),
|
|
128
147
|
});
|
|
129
|
-
return response.json()
|
|
148
|
+
return response.json() as Promise<ClientRegistration>;
|
|
130
149
|
}
|
|
131
150
|
|
|
132
151
|
async startOAuthFlow(params: {
|
|
@@ -135,30 +154,30 @@ export class StudioAPI {
|
|
|
135
154
|
redirectUri: string;
|
|
136
155
|
scope: string;
|
|
137
156
|
resource: string;
|
|
138
|
-
}) {
|
|
157
|
+
}): Promise<JsonValue> {
|
|
139
158
|
const response = await fetch(`${this.baseUrl}/api/auth/start-flow`, {
|
|
140
159
|
method: 'POST',
|
|
141
160
|
headers: { 'Content-Type': 'application/json' },
|
|
142
161
|
body: JSON.stringify(params),
|
|
143
162
|
});
|
|
144
|
-
return response.json()
|
|
163
|
+
return response.json() as Promise<JsonValue>;
|
|
145
164
|
}
|
|
146
165
|
|
|
147
166
|
async exchangeToken(params: {
|
|
148
167
|
code: string;
|
|
149
|
-
pkce:
|
|
168
|
+
pkce: PKCEParams;
|
|
150
169
|
tokenEndpoint: string;
|
|
151
170
|
clientId: string;
|
|
152
171
|
clientSecret?: string;
|
|
153
172
|
redirectUri: string;
|
|
154
173
|
resource: string;
|
|
155
|
-
}) {
|
|
174
|
+
}): Promise<JsonValue> {
|
|
156
175
|
const response = await fetch(`${this.baseUrl}/api/auth/exchange-token`, {
|
|
157
176
|
method: 'POST',
|
|
158
177
|
headers: { 'Content-Type': 'application/json' },
|
|
159
178
|
body: JSON.stringify(params),
|
|
160
179
|
});
|
|
161
|
-
return response.json()
|
|
180
|
+
return response.json() as Promise<JsonValue>;
|
|
162
181
|
}
|
|
163
182
|
|
|
164
183
|
async refreshToken(params: {
|
|
@@ -167,13 +186,13 @@ export class StudioAPI {
|
|
|
167
186
|
clientId: string;
|
|
168
187
|
clientSecret?: string;
|
|
169
188
|
resource: string;
|
|
170
|
-
}) {
|
|
189
|
+
}): Promise<JsonValue> {
|
|
171
190
|
const response = await fetch(`${this.baseUrl}/api/auth/refresh-token`, {
|
|
172
191
|
method: 'POST',
|
|
173
192
|
headers: { 'Content-Type': 'application/json' },
|
|
174
193
|
body: JSON.stringify(params),
|
|
175
194
|
});
|
|
176
|
-
return response.json()
|
|
195
|
+
return response.json() as Promise<JsonValue>;
|
|
177
196
|
}
|
|
178
197
|
|
|
179
198
|
async revokeToken(params: {
|
|
@@ -181,25 +200,25 @@ export class StudioAPI {
|
|
|
181
200
|
revocationEndpoint: string;
|
|
182
201
|
clientId: string;
|
|
183
202
|
clientSecret?: string;
|
|
184
|
-
}) {
|
|
203
|
+
}): Promise<JsonValue> {
|
|
185
204
|
const response = await fetch(`${this.baseUrl}/api/auth/revoke-token`, {
|
|
186
205
|
method: 'POST',
|
|
187
206
|
headers: { 'Content-Type': 'application/json' },
|
|
188
207
|
body: JSON.stringify(params),
|
|
189
208
|
});
|
|
190
|
-
return response.json()
|
|
209
|
+
return response.json() as Promise<JsonValue>;
|
|
191
210
|
}
|
|
192
211
|
|
|
193
212
|
// Health
|
|
194
|
-
async getHealth() {
|
|
213
|
+
async getHealth(): Promise<JsonValue> {
|
|
195
214
|
const response = await fetch(`${this.baseUrl}/api/health/checks`);
|
|
196
|
-
return response.json()
|
|
215
|
+
return response.json() as Promise<JsonValue>;
|
|
197
216
|
}
|
|
198
217
|
|
|
199
218
|
// Widget Examples
|
|
200
|
-
async getWidgetExamples() {
|
|
219
|
+
async getWidgetExamples(): Promise<JsonValue> {
|
|
201
220
|
const response = await fetch(`${this.baseUrl}/api/widget-examples`);
|
|
202
|
-
return response.json()
|
|
221
|
+
return response.json() as Promise<JsonValue>;
|
|
203
222
|
}
|
|
204
223
|
}
|
|
205
224
|
|
|
@@ -11,7 +11,7 @@ import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
|
11
11
|
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
12
12
|
|
|
13
13
|
// EventSource type that works in both browser and Node.js
|
|
14
|
-
type EventSourceType = typeof EventSource extends { prototype: infer T } ? T :
|
|
14
|
+
type EventSourceType = typeof EventSource extends { prototype: infer T } ? T : EventSource;
|
|
15
15
|
|
|
16
16
|
export interface HttpClientTransportOptions {
|
|
17
17
|
/**
|
|
@@ -47,7 +47,7 @@ export class HttpClientTransport implements Transport {
|
|
|
47
47
|
private closeHandler?: () => void;
|
|
48
48
|
private errorHandler?: (error: Error) => void;
|
|
49
49
|
private isConnected = false;
|
|
50
|
-
private EventSourceImpl:
|
|
50
|
+
private EventSourceImpl: typeof EventSource;
|
|
51
51
|
|
|
52
52
|
constructor(options: HttpClientTransportOptions) {
|
|
53
53
|
this.baseUrl = options.baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
@@ -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
|
|