@gradio/core 1.0.0-dev.3 → 1.0.0

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.
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import type { ComponentMeta, Dependency } from "../types";
2
+ import type { ComponentMeta, Dependency, Payload } from "../types";
3
3
  import CopyButton from "./CopyButton.svelte";
4
4
  import { represent_value, is_potentially_nested_file_data } from "./utils";
5
5
  import { Block } from "@gradio/atoms";
@@ -24,6 +24,7 @@
24
24
  export let api_description: string | null = null;
25
25
  export let analytics: Record<string, any>;
26
26
  export let markdown_code_snippets: Record<string, Record<string, string>>;
27
+ export let last_api_call: Payload | null = null;
27
28
 
28
29
  let python_code: HTMLElement;
29
30
  let js_code: HTMLElement;
@@ -41,6 +42,27 @@
41
42
  $: normalised_api_prefix = api_prefix ? api_prefix : "/";
42
43
  $: normalised_root = root.replace(/\/$/, "");
43
44
 
45
+ $: is_most_recently_used = last_api_call?.fn_index === dependency.id;
46
+
47
+ $: actual_data =
48
+ is_most_recently_used && last_api_call?.data
49
+ ? last_api_call.data.filter((d) => typeof d !== "undefined")
50
+ : null;
51
+
52
+ function getParameterValue(param: any, index: number): any {
53
+ if (
54
+ is_most_recently_used &&
55
+ actual_data &&
56
+ actual_data[index] !== undefined
57
+ ) {
58
+ return actual_data[index];
59
+ }
60
+ return param.parameter_has_default !== undefined &&
61
+ param.parameter_has_default
62
+ ? param.parameter_default
63
+ : param.example_input;
64
+ }
65
+
44
66
  $: markdown_code_snippets[
45
67
  dependency.api_name as keyof typeof markdown_code_snippets
46
68
  ] = {
@@ -55,6 +77,8 @@
55
77
  api_name={dependency.api_name}
56
78
  description={api_description}
57
79
  {analytics}
80
+ {last_api_call}
81
+ dependency_id={dependency.id}
58
82
  />
59
83
  <div class:hidden={current_language !== "python"}>
60
84
  <Block>
@@ -71,14 +95,16 @@ client = Client(<span class="token string">"{space_id || root}"</span
71
95
  >{#if username !== null}, auth=("{username}", **password**){/if})
72
96
  result = client.<span class="highlight">predict</span
73
97
  >(<!--
74
- -->{#each endpoint_parameters as { python_type, example_input, parameter_name, parameter_has_default, parameter_default }, i}<!--
98
+ -->{#each endpoint_parameters as param, i}<!--
75
99
  -->
76
- {parameter_name
77
- ? parameter_name + "="
100
+ {param.parameter_name
101
+ ? param.parameter_name + "="
78
102
  : ""}<span
103
+ class:recent-value={is_most_recently_used &&
104
+ actual_data?.[i] !== undefined}
79
105
  >{represent_value(
80
- parameter_has_default ? parameter_default : example_input,
81
- python_type.type,
106
+ getParameterValue(param, i),
107
+ param.python_type.type,
82
108
  "py"
83
109
  )}</span
84
110
  >,{/each}<!--
@@ -112,22 +138,26 @@ result = client.<span class="highlight">predict</span
112
138
  const result = await client.predict(<span class="api-name"
113
139
  >"/{dependency.api_name}"</span
114
140
  >, &lbrace; <!--
115
- -->{#each endpoint_parameters as { label, parameter_name, type, python_type, component, example_input, serializer }, i}<!--
116
- -->{#if blob_components.includes(component)}<!--
141
+ -->{#each endpoint_parameters as param, i}<!--
142
+ -->{#if blob_components.includes(param.component)}<!--
117
143
  -->
118
144
  <span
119
145
  class="example-inputs"
120
- >{parameter_name}: example{component}</span
146
+ >{param.parameter_name}: example{param.component}</span
121
147
  >, <!--
122
148
  --><span class="desc"><!--
123
149
  --></span
124
150
  ><!--
125
151
  -->{:else}<!--
126
152
  -->
127
- <span class="example-inputs"
128
- >{parameter_name}: {represent_value(
129
- example_input,
130
- python_type.type,
153
+ <span
154
+ class="example-inputs {is_most_recently_used &&
155
+ actual_data?.[i] !== undefined
156
+ ? 'recent-value'
157
+ : ''}"
158
+ >{param.parameter_name}: {represent_value(
159
+ getParameterValue(param, i),
160
+ param.python_type.type,
131
161
  "js"
132
162
  )}</span
133
163
  >, <!--
@@ -151,13 +181,18 @@ result = client.<span class="highlight">predict</span
151
181
 
152
182
  <div bind:this={bash_post_code}>
153
183
  <pre>curl -X POST {normalised_root}{normalised_api_prefix}/call/{dependency.api_name} -s -H "Content-Type: application/json" -d '{"{"}
154
- "data": [{#each endpoint_parameters as { label, parameter_name, type, python_type, component, example_input, serializer }, i}
184
+ "data": [{#each endpoint_parameters as param, i}
155
185
  <!--
156
- -->{represent_value(
157
- example_input,
158
- python_type.type,
159
- "bash"
160
- )}{#if i < endpoint_parameters.length - 1},
186
+ --><span
187
+ class={is_most_recently_used && actual_data?.[i] !== undefined
188
+ ? "recent-value"
189
+ : ""}
190
+ >{represent_value(
191
+ getParameterValue(param, i),
192
+ param.python_type.type,
193
+ "bash"
194
+ )}</span
195
+ >{#if i < endpoint_parameters.length - 1},
161
196
  {/if}
162
197
  {/each}
163
198
  ]{"}"}' \
@@ -211,6 +246,15 @@ result = client.<span class="highlight">predict</span
211
246
  color: var(--color-accent);
212
247
  }
213
248
 
249
+ .recent-value {
250
+ color: #fd7b00;
251
+ background: #fff4e6;
252
+ border: 1px solid #ffd9b3;
253
+ border-radius: var(--radius-sm);
254
+ padding: 1px 4px;
255
+ font-weight: var(--weight-medium);
256
+ }
257
+
214
258
  .hidden {
215
259
  display: none;
216
260
  }
@@ -1,30 +1,45 @@
1
1
  <script lang="ts">
2
+ import type { Payload } from "../types";
2
3
  export let api_name: string | null = null;
3
4
  export let description: string | null = null;
4
5
  export let analytics: Record<string, any>;
6
+ export let last_api_call: Payload | null = null;
7
+ export let dependency_id: number | null = null;
5
8
  import { format_latency, get_color_from_success_rate } from "./utils";
9
+ import PercentileChart from "./PercentileChart.svelte";
6
10
 
7
11
  const success_rate = api_name ? analytics[api_name]?.success_rate : 0;
8
12
  const color = get_color_from_success_rate(success_rate);
13
+ $: is_most_recently_used = last_api_call?.fn_index === dependency_id;
9
14
  </script>
10
15
 
11
16
  <h3>
12
17
  API name:
13
18
  <span class="post">{"/" + api_name}</span>
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) &nbsp;|&nbsp; 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}
19
+ <span class="desc">
20
+ {description}
21
+ {#if analytics && api_name && analytics[api_name]}
22
+ {@const endpoint_analytics = analytics[api_name]}
23
+ {@const p50 = endpoint_analytics.process_time_percentiles["50th"]}
24
+ {@const p90 = endpoint_analytics.process_time_percentiles["90th"]}
25
+ {@const p99 = endpoint_analytics.process_time_percentiles["99th"]}
26
+ <span class="analytics-inline">
27
+ <span class="analytics-content">
28
+ <span class="analytics-text-wrapper">
29
+ {endpoint_analytics.total_requests} requests ({Math.round(
30
+ success_rate * 100
31
+ )}% successful, p50: {format_latency(p50)})
32
+ </span>
33
+ <div class="analytics-tooltip">
34
+ <PercentileChart {p50} {p90} {p99} />
35
+ </div>
36
+ </span>
37
+ {#if is_most_recently_used}
38
+ <span class="most-recently-used">Most recently used</span>
39
+ {/if}
40
+ </span>
41
+ {/if}
42
+ </span>
28
43
  </h3>
29
44
 
30
45
  <style>
@@ -46,14 +61,55 @@
46
61
  font-weight: var(--weight-semibold);
47
62
  }
48
63
 
49
- .analytics {
64
+ .analytics-inline {
65
+ display: inline-flex;
66
+ align-items: center;
67
+ gap: var(--size-2);
68
+ margin-left: var(--size-2);
50
69
  color: var(--body-text-color-subdued);
51
- margin-top: var(--size-1);
70
+ }
71
+
72
+ .analytics-content {
73
+ position: relative;
74
+ display: inline-block;
75
+ }
76
+
77
+ .analytics-text-wrapper {
78
+ cursor: help;
79
+ }
80
+
81
+ .analytics-tooltip {
82
+ position: absolute;
83
+ bottom: 100%;
84
+ left: 50%;
85
+ transform: translateX(-50%);
86
+ margin-bottom: var(--size-2);
87
+ opacity: 0;
88
+ pointer-events: none;
89
+ transition: opacity 0.2s ease;
90
+ z-index: 1000;
91
+ }
92
+
93
+ .analytics-content:hover .analytics-tooltip {
94
+ opacity: 1;
95
+ pointer-events: auto;
96
+ }
97
+
98
+ .most-recently-used {
99
+ display: inline-block;
100
+ color: #fd7b00;
101
+ background: #fff4e6;
102
+ border: 1px solid #ffd9b3;
103
+ border-radius: var(--radius-sm);
104
+ padding: var(--size-1) var(--size-2);
105
+ font-size: var(--text-sm);
106
+ font-weight: var(--weight-medium);
107
+ white-space: nowrap;
52
108
  }
53
109
 
54
110
  .desc {
55
111
  color: var(--body-text-color);
56
112
  font-size: var(--text-lg);
57
- margin-top: var(--size-1);
113
+ margin-left: var(--size-2);
58
114
  }
59
115
  </style>
@@ -3,9 +3,11 @@
3
3
  import CopyButton from "./CopyButton.svelte";
4
4
  import { Tool, Prompt, Resource } from "@gradio/icons";
5
5
  import { format_latency, get_color_from_success_rate } from "./utils";
6
+ import PercentileChart from "./PercentileChart.svelte";
6
7
 
7
8
  export let mcp_server_active: boolean;
8
9
  export let mcp_server_url_streamable: string;
10
+ export let root: string;
9
11
  export let tools: Tool[];
10
12
  export let all_tools: Tool[] = [];
11
13
  export let selected_tools: Set<string> = new Set();
@@ -69,7 +71,7 @@
69
71
  "gradio[mcp]",
70
72
  "gradio",
71
73
  "upload-mcp",
72
- mcp_server_url_streamable,
74
+ root,
73
75
  "<UPLOAD_DIRECTORY>"
74
76
  ]
75
77
  };
@@ -218,34 +220,19 @@
218
220
  : "⚠︎ No description provided in function docstring"}
219
221
  </span>
220
222
  {#if analytics[tool.meta.endpoint_name]}
221
- <span
222
- class="tool-analytics"
223
- style="color: var(--body-text-color-subdued); margin-left: 1em;"
224
- >
225
- Total requests: {analytics[tool.meta.endpoint_name]
226
- .total_requests}
227
- <span style={color}
228
- >({Math.round(success_rate * 100)}% successful)</span
223
+ {@const endpoint_analytics = analytics[tool.meta.endpoint_name]}
224
+ {@const p50 =
225
+ endpoint_analytics.process_time_percentiles["50th"]}
226
+ <div class="tool-analytics-wrapper" style="margin-left: 1em;">
227
+ <span
228
+ class="tool-analytics"
229
+ style="color: var(--body-text-color-subdued);"
229
230
  >
230
- &nbsp;|&nbsp; p50/p90/p99:
231
- {format_latency(
232
- analytics[tool.meta.endpoint_name].process_time_percentiles[
233
- "50th"
234
- ]
235
- )}
236
- /
237
- {format_latency(
238
- analytics[tool.meta.endpoint_name].process_time_percentiles[
239
- "90th"
240
- ]
241
- )}
242
- /
243
- {format_latency(
244
- analytics[tool.meta.endpoint_name].process_time_percentiles[
245
- "99th"
246
- ]
247
- )}
248
- </span>
231
+ {endpoint_analytics.total_requests} requests ({Math.round(
232
+ success_rate * 100
233
+ )}% successful, p50: {format_latency(p50)})
234
+ </span>
235
+ </div>
249
236
  {/if}
250
237
  </span>
251
238
  <span class="tool-arrow">{tool.expanded ? "▼" : "▶"}</span>
@@ -354,10 +341,16 @@
354
341
  {/if}
355
342
 
356
343
  <style>
344
+ .tool-analytics-wrapper {
345
+ position: relative;
346
+ display: inline-block;
347
+ }
348
+
357
349
  .tool-analytics {
358
350
  font-size: 0.95em;
359
351
  color: var(--body-text-color-subdued);
360
352
  }
353
+
361
354
  .transport-selection {
362
355
  margin-bottom: var(--size-4);
363
356
  }
@@ -0,0 +1,125 @@
1
+ <script lang="ts">
2
+ import { format_latency } from "./utils";
3
+
4
+ export let p50: number;
5
+ export let p90: number;
6
+ export let p99: number;
7
+
8
+ $: max_latency = Math.max(p50, p90, p99);
9
+ </script>
10
+
11
+ <div class="tooltip-chart">
12
+ <div class="tooltip-arrow"></div>
13
+ <div class="chart-bars">
14
+ <div class="chart-bar-container">
15
+ <div class="chart-bar-label">p50</div>
16
+ <div class="chart-bar-wrapper">
17
+ <div
18
+ class="chart-bar"
19
+ style="width: {(p50 / max_latency) * 100}%"
20
+ ></div>
21
+ </div>
22
+ <div class="chart-bar-value">{format_latency(p50)}</div>
23
+ </div>
24
+ <div class="chart-bar-container">
25
+ <div class="chart-bar-label">p90</div>
26
+ <div class="chart-bar-wrapper">
27
+ <div
28
+ class="chart-bar"
29
+ style="width: {(p90 / max_latency) * 100}%"
30
+ ></div>
31
+ </div>
32
+ <div class="chart-bar-value">{format_latency(p90)}</div>
33
+ </div>
34
+ <div class="chart-bar-container">
35
+ <div class="chart-bar-label">p99</div>
36
+ <div class="chart-bar-wrapper">
37
+ <div
38
+ class="chart-bar"
39
+ style="width: {(p99 / max_latency) * 100}%"
40
+ ></div>
41
+ </div>
42
+ <div class="chart-bar-value">{format_latency(p99)}</div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+
47
+ <style>
48
+ .tooltip-chart {
49
+ background: var(--background-fill-primary);
50
+ border: 1px solid var(--border-color-primary);
51
+ border-radius: var(--radius-md);
52
+ padding: var(--size-3);
53
+ box-shadow: var(--shadow-drop-lg);
54
+ min-width: 200px;
55
+ position: relative;
56
+ }
57
+
58
+ .tooltip-arrow {
59
+ position: absolute;
60
+ bottom: -8px;
61
+ left: 50%;
62
+ transform: translateX(-50%);
63
+ width: 0;
64
+ height: 0;
65
+ border-left: 8px solid transparent;
66
+ border-right: 8px solid transparent;
67
+ border-top: 8px solid var(--border-color-primary);
68
+ }
69
+
70
+ .tooltip-arrow::after {
71
+ content: "";
72
+ position: absolute;
73
+ bottom: 1px;
74
+ left: 50%;
75
+ transform: translateX(-50%);
76
+ width: 0;
77
+ height: 0;
78
+ border-left: 7px solid transparent;
79
+ border-right: 7px solid transparent;
80
+ border-top: 7px solid var(--background-fill-primary);
81
+ }
82
+
83
+ .chart-bars {
84
+ display: flex;
85
+ flex-direction: column;
86
+ gap: var(--size-2);
87
+ }
88
+
89
+ .chart-bar-container {
90
+ display: flex;
91
+ align-items: center;
92
+ gap: var(--size-2);
93
+ }
94
+
95
+ .chart-bar-label {
96
+ font-size: var(--text-sm);
97
+ font-weight: var(--weight-semibold);
98
+ color: var(--body-text-color);
99
+ min-width: 30px;
100
+ }
101
+
102
+ .chart-bar-wrapper {
103
+ flex: 1;
104
+ height: 16px;
105
+ background: var(--background-fill-secondary);
106
+ border-radius: var(--radius-sm);
107
+ overflow: hidden;
108
+ position: relative;
109
+ }
110
+
111
+ .chart-bar {
112
+ height: 100%;
113
+ background: var(--color-accent);
114
+ border-radius: var(--radius-sm);
115
+ transition: width 0.3s ease;
116
+ }
117
+
118
+ .chart-bar-value {
119
+ font-size: var(--text-sm);
120
+ color: var(--body-text-color);
121
+ min-width: 50px;
122
+ text-align: right;
123
+ font-family: var(--font-mono);
124
+ }
125
+ </style>