@gradio/core 0.27.0 → 0.27.2
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/CHANGELOG.md +21 -0
- package/dist/src/Blocks.svelte +12 -21
- package/dist/src/Blocks.svelte.d.ts +11 -9
- package/dist/src/Embed.svelte.d.ts +4 -2
- package/dist/src/Login.svelte.d.ts +2 -0
- package/dist/src/MountComponents.svelte.d.ts +3 -1
- package/dist/src/Render.svelte +12 -13
- package/dist/src/Render.svelte.d.ts +3 -1
- package/dist/src/RenderComponent.svelte +3 -6
- package/dist/src/RenderComponent.svelte.d.ts +2 -0
- package/dist/src/api_docs/ApiBanner.svelte.d.ts +3 -1
- package/dist/src/api_docs/ApiDocs.svelte +28 -18
- package/dist/src/api_docs/ApiDocs.svelte.d.ts +3 -1
- package/dist/src/api_docs/ApiRecorder.svelte.d.ts +3 -1
- package/dist/src/api_docs/CodeSnippet.svelte +40 -40
- package/dist/src/api_docs/CodeSnippet.svelte.d.ts +4 -1
- package/dist/src/api_docs/CopyButton.svelte.d.ts +2 -0
- package/dist/src/api_docs/EndpointDetail.svelte +23 -1
- package/dist/src/api_docs/EndpointDetail.svelte.d.ts +5 -2
- package/dist/src/api_docs/InputPayload.svelte.d.ts +2 -0
- package/dist/src/api_docs/InstallSnippet.svelte.d.ts +2 -0
- package/dist/src/api_docs/MCPSnippet.svelte +89 -44
- package/dist/src/api_docs/MCPSnippet.svelte.d.ts +7 -2
- package/dist/src/api_docs/NoApi.svelte.d.ts +2 -0
- package/dist/src/api_docs/ParametersSnippet.svelte.d.ts +2 -0
- package/dist/src/api_docs/RecordingSnippet.svelte.d.ts +4 -2
- package/dist/src/api_docs/ResponseSnippet.svelte.d.ts +2 -0
- package/dist/src/api_docs/Settings.svelte.d.ts +4 -2
- package/dist/src/api_docs/SettingsBanner.svelte.d.ts +2 -0
- package/dist/src/api_docs/TryButton.svelte.d.ts +2 -0
- package/dist/src/api_docs/img/clear.svelte.d.ts +2 -0
- package/dist/src/api_docs/utils.d.ts +2 -0
- package/dist/src/api_docs/utils.js +14 -0
- package/dist/src/stories/I18nMultiLanguageTestComponent.svelte.d.ts +3 -3
- package/dist/src/stories/I18nTestSetup.svelte +1 -2
- package/dist/src/stories/I18nTestSetup.svelte.d.ts +3 -1
- package/package.json +31 -31
- package/src/api_docs/ApiDocs.svelte +24 -3
- package/src/api_docs/CodeSnippet.svelte +38 -36
- package/src/api_docs/EndpointDetail.svelte +24 -1
- package/src/api_docs/MCPSnippet.svelte +68 -17
- package/src/api_docs/utils.ts +14 -0
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
export let username: string | null;
|
|
23
23
|
export let current_language: "python" | "javascript" | "bash";
|
|
24
24
|
export let api_description: string | null = null;
|
|
25
|
+
export let analytics: Record<string, any>;
|
|
25
26
|
|
|
26
27
|
let python_code: HTMLElement;
|
|
27
28
|
let js_code: HTMLElement;
|
|
@@ -44,6 +45,7 @@
|
|
|
44
45
|
<EndpointDetail
|
|
45
46
|
api_name={dependency.api_name}
|
|
46
47
|
description={api_description}
|
|
48
|
+
{analytics}
|
|
47
49
|
/>
|
|
48
50
|
{#if current_language === "python"}
|
|
49
51
|
<Block>
|
|
@@ -56,13 +58,13 @@
|
|
|
56
58
|
class="highlight">import</span
|
|
57
59
|
> Client{#if has_file_path}, handle_file{/if}
|
|
58
60
|
|
|
59
|
-
client = Client(<span class="token string">"{space_id || root}"</span
|
|
61
|
+
client = Client(<span class="token string">"{space_id || root}"</span
|
|
60
62
|
>{#if username !== null}, auth=("{username}", **password**){/if})
|
|
61
|
-
result = client.<span class="highlight">predict</span
|
|
63
|
+
result = client.<span class="highlight">predict</span
|
|
62
64
|
>(<!--
|
|
63
|
-
-->{#each endpoint_parameters as { python_type, example_input, parameter_name, parameter_has_default, parameter_default }, i}<!--
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
-->{#each endpoint_parameters as { python_type, example_input, parameter_name, parameter_has_default, parameter_default }, i}<!--
|
|
66
|
+
-->
|
|
67
|
+
{parameter_name
|
|
66
68
|
? parameter_name + "="
|
|
67
69
|
: ""}<span
|
|
68
70
|
>{represent_value(
|
|
@@ -72,11 +74,11 @@ result = client.<span class="highlight">predict</span
|
|
|
72
74
|
)}</span
|
|
73
75
|
>,{/each}<!--
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
)
|
|
79
|
-
<span class="highlight">print</span>(result)</pre>
|
|
77
|
+
-->
|
|
78
|
+
api_name=<span class="api-name">"/{dependency.api_name}"</span><!--
|
|
79
|
+
-->
|
|
80
|
+
)
|
|
81
|
+
<span class="highlight">print</span>(result)</pre>
|
|
80
82
|
</div>
|
|
81
83
|
</code>
|
|
82
84
|
</Block>
|
|
@@ -88,44 +90,44 @@ result = client.<span class="highlight">predict</span
|
|
|
88
90
|
</div>
|
|
89
91
|
<div bind:this={js_code}>
|
|
90
92
|
<pre>import { Client } from "@gradio/client";
|
|
91
|
-
{#each blob_examples as { component, example_input }, i}<!--
|
|
92
|
-
-->
|
|
93
|
-
const response_{i} = await fetch("{example_input.url}");
|
|
94
|
-
const example{component} = await response_{i}.blob();
|
|
93
|
+
{#each blob_examples as { component, example_input }, i}<!--
|
|
94
|
+
-->
|
|
95
|
+
const response_{i} = await fetch("{example_input.url}");
|
|
96
|
+
const example{component} = await response_{i}.blob();
|
|
95
97
|
{/each}<!--
|
|
96
|
-
-->
|
|
97
|
-
const client = await Client.connect(<span class="token string"
|
|
98
|
+
-->
|
|
99
|
+
const client = await Client.connect(<span class="token string"
|
|
98
100
|
>"{space_id || root}"</span
|
|
99
101
|
>{#if username !== null}, {auth: ["{username}", **password**]}{/if});
|
|
100
|
-
const result = await client.predict(<span class="api-name"
|
|
102
|
+
const result = await client.predict(<span class="api-name"
|
|
101
103
|
>"/{dependency.api_name}"</span
|
|
102
104
|
>, { <!--
|
|
103
|
-
-->{#each endpoint_parameters as { label, parameter_name, type, python_type, component, example_input, serializer }, i}<!--
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
-->{#each endpoint_parameters as { label, parameter_name, type, python_type, component, example_input, serializer }, i}<!--
|
|
106
|
+
-->{#if blob_components.includes(component)}<!--
|
|
107
|
+
-->
|
|
108
|
+
<span
|
|
107
109
|
class="example-inputs"
|
|
108
110
|
>{parameter_name}: example{component}</span
|
|
109
111
|
>, <!--
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
--><span class="desc"><!--
|
|
113
|
+
--></span
|
|
112
114
|
><!--
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
-->{:else}<!--
|
|
116
|
+
-->
|
|
117
|
+
<span class="example-inputs"
|
|
116
118
|
>{parameter_name}: {represent_value(
|
|
117
119
|
example_input,
|
|
118
120
|
python_type.type,
|
|
119
121
|
"js"
|
|
120
122
|
)}</span
|
|
121
123
|
>, <!--
|
|
122
|
-
--><!--
|
|
123
|
-
-->{/if}
|
|
124
|
+
--><!--
|
|
125
|
+
-->{/if}
|
|
124
126
|
{/each}
|
|
125
|
-
});
|
|
127
|
+
});
|
|
126
128
|
|
|
127
|
-
console.log(result.data);
|
|
128
|
-
</pre>
|
|
129
|
+
console.log(result.data);
|
|
130
|
+
</pre>
|
|
129
131
|
</div>
|
|
130
132
|
</code>
|
|
131
133
|
</Block>
|
|
@@ -138,18 +140,18 @@ console.log(result.data);
|
|
|
138
140
|
|
|
139
141
|
<div bind:this={bash_post_code}>
|
|
140
142
|
<pre>curl -X POST {normalised_root}{normalised_api_prefix}/call/{dependency.api_name} -s -H "Content-Type: application/json" -d '{"{"}
|
|
141
|
-
|
|
143
|
+
"data": [{#each endpoint_parameters as { label, parameter_name, type, python_type, component, example_input, serializer }, i}
|
|
142
144
|
<!--
|
|
143
|
-
-->{represent_value(
|
|
145
|
+
-->{represent_value(
|
|
144
146
|
example_input,
|
|
145
147
|
python_type.type,
|
|
146
148
|
"bash"
|
|
147
149
|
)}{#if i < endpoint_parameters.length - 1},
|
|
148
150
|
{/if}
|
|
149
151
|
{/each}
|
|
150
|
-
]{"}"}' \
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
]{"}"}' \
|
|
153
|
+
| awk -F'"' '{"{"} print $4{"}"}' \
|
|
154
|
+
| read EVENT_ID; curl -N {normalised_root}{normalised_api_prefix}/call/{dependency.api_name}/$EVENT_ID</pre>
|
|
153
155
|
</div>
|
|
154
156
|
</code>
|
|
155
157
|
</Block>
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
export let api_name: string | null = null;
|
|
3
3
|
export let description: string | null = null;
|
|
4
|
+
export let analytics: Record<string, any>;
|
|
5
|
+
import { format_latency, get_color_from_success_rate } from "./utils";
|
|
6
|
+
|
|
7
|
+
const success_rate = api_name ? analytics[api_name]?.success_rate : 0;
|
|
8
|
+
const color = get_color_from_success_rate(success_rate);
|
|
4
9
|
</script>
|
|
5
10
|
|
|
6
11
|
<h3>
|
|
7
12
|
API name:
|
|
8
13
|
<span class="post">{"/" + api_name}</span>
|
|
9
14
|
<span class="desc">{description}</span>
|
|
15
|
+
{#if analytics && api_name && analytics[api_name]}
|
|
16
|
+
<span class="analytics">
|
|
17
|
+
Total requests: {analytics[api_name].total_requests} (<span style={color}
|
|
18
|
+
>{Math.round(success_rate * 100)}%</span
|
|
19
|
+
>
|
|
20
|
+
successful) | p50/p90/p99:
|
|
21
|
+
{format_latency(analytics[api_name].process_time_percentiles["50th"])}
|
|
22
|
+
/
|
|
23
|
+
{format_latency(analytics[api_name].process_time_percentiles["90th"])}
|
|
24
|
+
/
|
|
25
|
+
{format_latency(analytics[api_name].process_time_percentiles["99th"])}
|
|
26
|
+
</span>
|
|
27
|
+
{/if}
|
|
10
28
|
</h3>
|
|
11
29
|
|
|
12
30
|
<style>
|
|
@@ -28,8 +46,13 @@
|
|
|
28
46
|
font-weight: var(--weight-semibold);
|
|
29
47
|
}
|
|
30
48
|
|
|
31
|
-
.
|
|
49
|
+
.analytics {
|
|
32
50
|
color: var(--body-text-color-subdued);
|
|
51
|
+
margin-top: var(--size-1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.desc {
|
|
55
|
+
color: var(--body-text-color);
|
|
33
56
|
font-size: var(--text-lg);
|
|
34
57
|
margin-top: var(--size-1);
|
|
35
58
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Block } from "@gradio/atoms";
|
|
3
3
|
import CopyButton from "./CopyButton.svelte";
|
|
4
|
+
import { Tool, Prompt, Resource } from "@gradio/icons";
|
|
5
|
+
import { format_latency, get_color_from_success_rate } from "./utils";
|
|
4
6
|
|
|
5
7
|
export let mcp_server_active: boolean;
|
|
6
8
|
export let mcp_server_url: string;
|
|
@@ -12,6 +14,7 @@
|
|
|
12
14
|
export let mcp_json_stdio: any;
|
|
13
15
|
export let file_data_present: boolean;
|
|
14
16
|
export let mcp_docs: string;
|
|
17
|
+
export let analytics: Record<string, any>;
|
|
15
18
|
|
|
16
19
|
interface ToolParameter {
|
|
17
20
|
title?: string;
|
|
@@ -29,6 +32,7 @@
|
|
|
29
32
|
meta: {
|
|
30
33
|
mcp_type: "tool" | "resource" | "prompt";
|
|
31
34
|
file_data_present: boolean;
|
|
35
|
+
endpoint_name: string;
|
|
32
36
|
};
|
|
33
37
|
}
|
|
34
38
|
|
|
@@ -42,10 +46,10 @@
|
|
|
42
46
|
["stdio", "STDIO"]
|
|
43
47
|
] as const;
|
|
44
48
|
|
|
45
|
-
const
|
|
46
|
-
tool:
|
|
47
|
-
resource:
|
|
48
|
-
prompt:
|
|
49
|
+
const tool_type_icons: Record<Tool["meta"]["mcp_type"], typeof Tool> = {
|
|
50
|
+
tool: Tool,
|
|
51
|
+
resource: Resource,
|
|
52
|
+
prompt: Prompt
|
|
49
53
|
};
|
|
50
54
|
|
|
51
55
|
$: display_url =
|
|
@@ -145,11 +149,15 @@
|
|
|
145
149
|
{/if}
|
|
146
150
|
|
|
147
151
|
<div class="tool-selection">
|
|
148
|
-
<strong
|
|
149
|
-
|
|
150
|
-
(
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
<strong>
|
|
153
|
+
{all_tools.length > 0 ? all_tools.length : tools.length} Available MCP Tools
|
|
154
|
+
(<span style="display: inline-block; vertical-align: sub;"><Tool /></span
|
|
155
|
+
>), Resources (<span style="display: inline-block; vertical-align: sub;"
|
|
156
|
+
><Resource /></span
|
|
157
|
+
>), and Prompts (<span style="display: inline-block; vertical-align: sub;"
|
|
158
|
+
><Prompt /></span
|
|
159
|
+
>)
|
|
160
|
+
</strong>
|
|
153
161
|
{#if all_tools.length > 0}
|
|
154
162
|
<div class="tool-selection-controls">
|
|
155
163
|
<button
|
|
@@ -173,6 +181,9 @@
|
|
|
173
181
|
</div>
|
|
174
182
|
<div class="mcp-tools">
|
|
175
183
|
{#each all_tools.length > 0 ? all_tools : tools as tool}
|
|
184
|
+
{@const success_rate =
|
|
185
|
+
analytics[tool.meta.endpoint_name]?.success_rate || 0}
|
|
186
|
+
{@const color = get_color_from_success_rate(success_rate)}
|
|
176
187
|
<div class="tool-item">
|
|
177
188
|
<div class="tool-header-wrapper">
|
|
178
189
|
{#if all_tools.length > 0}
|
|
@@ -199,17 +210,53 @@
|
|
|
199
210
|
class="tool-header"
|
|
200
211
|
on:click={() => (tool.expanded = !tool.expanded)}
|
|
201
212
|
>
|
|
202
|
-
<span
|
|
203
|
-
|
|
204
|
-
|
|
213
|
+
<span style="display: inline-block">
|
|
214
|
+
<span
|
|
215
|
+
style="display: inline-block; padding-right: 6px; vertical-align: sub"
|
|
205
216
|
>
|
|
217
|
+
{#if tool_type_icons[tool.meta.mcp_type]}
|
|
218
|
+
{@const Icon = tool_type_icons[tool.meta.mcp_type]}
|
|
219
|
+
<Icon />
|
|
220
|
+
{/if}
|
|
221
|
+
</span>
|
|
222
|
+
<span class="tool-name">{tool.name}</span>
|
|
206
223
|
|
|
207
|
-
<span class="tool-description"
|
|
208
|
-
|
|
224
|
+
<span class="tool-description">
|
|
225
|
+
{tool.description
|
|
209
226
|
? tool.description
|
|
210
|
-
: "⚠︎ No description provided in function docstring"}
|
|
211
|
-
|
|
212
|
-
|
|
227
|
+
: "⚠︎ No description provided in function docstring"}
|
|
228
|
+
</span>
|
|
229
|
+
{#if analytics[tool.meta.endpoint_name]}
|
|
230
|
+
<span
|
|
231
|
+
class="tool-analytics"
|
|
232
|
+
style="color: var(--body-text-color-subdued); margin-left: 1em;"
|
|
233
|
+
>
|
|
234
|
+
Total requests: {analytics[tool.meta.endpoint_name]
|
|
235
|
+
.total_requests}
|
|
236
|
+
<span style={color}
|
|
237
|
+
>({Math.round(success_rate * 100)}% successful)</span
|
|
238
|
+
>
|
|
239
|
+
| p50/p90/p99:
|
|
240
|
+
{format_latency(
|
|
241
|
+
analytics[tool.meta.endpoint_name].process_time_percentiles[
|
|
242
|
+
"50th"
|
|
243
|
+
]
|
|
244
|
+
)}
|
|
245
|
+
/
|
|
246
|
+
{format_latency(
|
|
247
|
+
analytics[tool.meta.endpoint_name].process_time_percentiles[
|
|
248
|
+
"90th"
|
|
249
|
+
]
|
|
250
|
+
)}
|
|
251
|
+
/
|
|
252
|
+
{format_latency(
|
|
253
|
+
analytics[tool.meta.endpoint_name].process_time_percentiles[
|
|
254
|
+
"99th"
|
|
255
|
+
]
|
|
256
|
+
)}
|
|
257
|
+
</span>
|
|
258
|
+
{/if}
|
|
259
|
+
</span>
|
|
213
260
|
<span class="tool-arrow">{tool.expanded ? "▼" : "▶"}</span>
|
|
214
261
|
</button>
|
|
215
262
|
</div>
|
|
@@ -333,6 +380,10 @@
|
|
|
333
380
|
{/if}
|
|
334
381
|
|
|
335
382
|
<style>
|
|
383
|
+
.tool-analytics {
|
|
384
|
+
font-size: 0.95em;
|
|
385
|
+
color: var(--body-text-color-subdued);
|
|
386
|
+
}
|
|
336
387
|
.transport-selection {
|
|
337
388
|
margin-bottom: var(--size-4);
|
|
338
389
|
}
|
package/src/api_docs/utils.ts
CHANGED
|
@@ -141,3 +141,17 @@ function stringify_except_file_function(obj: any): string {
|
|
|
141
141
|
const regexNone = /"UNQUOTEDNone"/g;
|
|
142
142
|
return jsonString.replace(regexNone, "None");
|
|
143
143
|
}
|
|
144
|
+
|
|
145
|
+
export function format_latency(val: number): string {
|
|
146
|
+
if (val < 1) return `${Math.round(val * 1000)} ms`;
|
|
147
|
+
return `${val.toFixed(2)} s`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function get_color_from_success_rate(success_rate: number): string {
|
|
151
|
+
if (success_rate > 0.9) {
|
|
152
|
+
return "color: green;";
|
|
153
|
+
} else if (success_rate > 0.1) {
|
|
154
|
+
return "color: orange;";
|
|
155
|
+
}
|
|
156
|
+
return "color: red;";
|
|
157
|
+
}
|