@tai42/studio-sdk 1.5.0 → 1.6.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.
- package/dist/components/tool-picker.d.ts +8 -1
- package/dist/components/tool-picker.d.ts.map +1 -1
- package/dist/components/tool-picker.js +23 -13
- package/dist/components/tool-picker.js.map +1 -1
- package/dist/hooks/useApi.d.ts +14 -1
- package/dist/hooks/useApi.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/tool-picker.tsx +34 -11
|
@@ -19,6 +19,13 @@ export interface ToolPickerProps {
|
|
|
19
19
|
readonly tagsByTool?: Readonly<Record<string, readonly string[]>>;
|
|
20
20
|
/** Tool names that are agent run tools; their option labels are suffixed " (agent)". */
|
|
21
21
|
readonly agentToolNames?: ReadonlySet<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Human display names keyed by raw tool name (from the tool-meta overlay). A
|
|
24
|
+
* mapped option's label reads `Display Name (raw_name)`; an unmapped name — or a
|
|
25
|
+
* mapping equal to the raw name — reads the bare raw name. The value `onChange`
|
|
26
|
+
* emits stays the raw name in every case.
|
|
27
|
+
*/
|
|
28
|
+
readonly displayNames?: Readonly<Record<string, string>>;
|
|
22
29
|
}
|
|
23
|
-
export declare function ToolPicker({ toolNames, value, onChange, disabled, placeholder, idPrefix, label, 'aria-label': ariaLabel, excludeNames, tagsByTool, agentToolNames, }: ToolPickerProps): import("react").JSX.Element;
|
|
30
|
+
export declare function ToolPicker({ toolNames, value, onChange, disabled, placeholder, idPrefix, label, 'aria-label': ariaLabel, excludeNames, tagsByTool, agentToolNames, displayNames, }: ToolPickerProps): import("react").JSX.Element;
|
|
24
31
|
//# sourceMappingURL=tool-picker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-picker.d.ts","sourceRoot":"","sources":["../../src/components/tool-picker.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool-picker.d.ts","sourceRoot":"","sources":["../../src/components/tool-picker.tsx"],"names":[],"mappings":"AAmCA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,sFAAsF;IACtF,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IAClE,wFAAwF;IACxF,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9C;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1D;AAyDD,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,WAA8B,EAC9B,QAAwB,EACxB,KAAK,EACL,YAAY,EAAE,SAAS,EACvB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,GACb,EAAE,eAAe,+BAgEjB"}
|
|
@@ -6,8 +6,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
* PRESENTATIONAL: the caller fetches the tool names (GET /api/tools) and owns the
|
|
7
7
|
* selected value; this component fetches nothing.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* passes
|
|
9
|
+
* Four optional extensions, each inert unless supplied; the preset create flow
|
|
10
|
+
* passes the first three and the multi-tool picker the first two:
|
|
11
11
|
* - `excludeNames` removes names from the options (e.g. a preset cannot be
|
|
12
12
|
* another preset's base, so the preset create flow excludes existing preset
|
|
13
13
|
* names). The server stays the authority — a slipped-through name is rejected
|
|
@@ -19,10 +19,15 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
19
19
|
* tool with " (agent)" (in grouped and flat renderings alike) — a purely visual
|
|
20
20
|
* honesty cue; the value stays the bare name and no option is excluded, since an
|
|
21
21
|
* agent run tool is a legal preset base for an authored agent.
|
|
22
|
+
* - `displayNames` (from the tool-meta overlay) overlays a human name onto the
|
|
23
|
+
* LABEL: a mapped option reads `Display Name (raw_name)`, an unmapped name (or a
|
|
24
|
+
* mapping equal to the raw name) reads the bare raw name. The value stays the raw
|
|
25
|
+
* name and grouping/filtering/exclusion key off raw names alone, so a display
|
|
26
|
+
* name is purely cosmetic.
|
|
22
27
|
*
|
|
23
|
-
* SAFETY: a tool name AND a
|
|
24
|
-
* TEXT through the DS `Select` (React escapes it) — never an HTML sink.
|
|
25
|
-
* a test.
|
|
28
|
+
* SAFETY: a tool name, a tag, AND a display name are server-supplied, so every one
|
|
29
|
+
* renders as TEXT through the DS `Select` (React escapes it) — never an HTML sink.
|
|
30
|
+
* Pinned by a test.
|
|
26
31
|
*/
|
|
27
32
|
import { useState } from 'react';
|
|
28
33
|
import { Field } from './field';
|
|
@@ -37,12 +42,17 @@ function groupFor(name, tagsByTool) {
|
|
|
37
42
|
const tags = [...(tagsByTool[name] ?? [])].sort((a, b) => a.localeCompare(b));
|
|
38
43
|
return tags[0] ?? UNTAGGED;
|
|
39
44
|
}
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The option label: `Display Name (raw)` when a distinct display name maps the
|
|
47
|
+
* name, else the bare name; either way suffixed " (agent)" for an agent run tool.
|
|
48
|
+
*/
|
|
49
|
+
function optionLabel(name, displayNames, agentToolNames) {
|
|
50
|
+
const display = displayNames?.[name];
|
|
51
|
+
const base = display !== undefined && display !== name ? `${display} (${name})` : name;
|
|
52
|
+
return agentToolNames?.has(name) === true ? `${base} (agent)` : base;
|
|
43
53
|
}
|
|
44
54
|
/** Build the grouped option clusters (sorted group labels, "Untagged" last). */
|
|
45
|
-
function buildGroups(names, tagsByTool, agentToolNames) {
|
|
55
|
+
function buildGroups(names, tagsByTool, displayNames, agentToolNames) {
|
|
46
56
|
const byGroup = new Map();
|
|
47
57
|
for (const name of names) {
|
|
48
58
|
const group = groupFor(name, tagsByTool);
|
|
@@ -62,11 +72,11 @@ function buildGroups(names, tagsByTool, agentToolNames) {
|
|
|
62
72
|
label,
|
|
63
73
|
options: groupNames.map((name) => ({
|
|
64
74
|
value: name,
|
|
65
|
-
label: optionLabel(name, agentToolNames),
|
|
75
|
+
label: optionLabel(name, displayNames, agentToolNames),
|
|
66
76
|
})),
|
|
67
77
|
}));
|
|
68
78
|
}
|
|
69
|
-
export function ToolPicker({ toolNames, value, onChange, disabled, placeholder = 'Select a tool…', idPrefix = 'tool-picker', label, 'aria-label': ariaLabel, excludeNames, tagsByTool, agentToolNames, }) {
|
|
79
|
+
export function ToolPicker({ toolNames, value, onChange, disabled, placeholder = 'Select a tool…', idPrefix = 'tool-picker', label, 'aria-label': ariaLabel, excludeNames, tagsByTool, agentToolNames, displayNames, }) {
|
|
70
80
|
const [tagFilter, setTagFilter] = useState(ALL_TAGS);
|
|
71
81
|
const excluded = new Set(excludeNames ?? []);
|
|
72
82
|
const available = toolNames.filter((name) => !excluded.has(name));
|
|
@@ -77,7 +87,7 @@ export function ToolPicker({ toolNames, value, onChange, disabled, placeholder =
|
|
|
77
87
|
const filtered = tagsByTool !== undefined && tagFilter !== ALL_TAGS
|
|
78
88
|
? available.filter((name) => (tagsByTool[name] ?? []).includes(tagFilter))
|
|
79
89
|
: available;
|
|
80
|
-
const toolSelect = tagsByTool !== undefined ? (_jsx(Select, { groups: buildGroups(filtered, tagsByTool, agentToolNames), value: value ?? '', onValueChange: onChange, placeholder: placeholder, "aria-label": ariaLabel, disabled: disabled })) : (_jsx(Select
|
|
90
|
+
const toolSelect = tagsByTool !== undefined ? (_jsx(Select, { groups: buildGroups(filtered, tagsByTool, displayNames, agentToolNames), value: value ?? '', onValueChange: onChange, placeholder: placeholder, "aria-label": ariaLabel, disabled: disabled })) : (_jsx(Select
|
|
81
91
|
// Keep Radix controlled even when the caller's value is null: `''` matches no
|
|
82
92
|
// item (placeholder still shows) and avoids the uncontrolled→controlled warning
|
|
83
93
|
// a subsequent selection would otherwise trigger.
|
|
@@ -87,7 +97,7 @@ export function ToolPicker({ toolNames, value, onChange, disabled, placeholder =
|
|
|
87
97
|
// a subsequent selection would otherwise trigger.
|
|
88
98
|
options: filtered.map((name) => ({
|
|
89
99
|
value: name,
|
|
90
|
-
label: optionLabel(name, agentToolNames),
|
|
100
|
+
label: optionLabel(name, displayNames, agentToolNames),
|
|
91
101
|
})), value: value ?? '', onValueChange: onChange, placeholder: placeholder, "aria-label": ariaLabel, disabled: disabled }));
|
|
92
102
|
return (_jsxs("div", { "data-testid": idPrefix, className: "tai-stack tai-stack-2", children: [tagsByTool !== undefined && allTags.length > 0 ? (_jsx(Field, { label: "Filter by tag", children: _jsx(Select, { options: [
|
|
93
103
|
{ value: ALL_TAGS, label: 'All tags' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-picker.js","sourceRoot":"","sources":["../../src/components/tool-picker.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"tool-picker.js","sourceRoot":"","sources":["../../src/components/tool-picker.tsx"],"names":[],"mappings":"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"}
|
package/dist/hooks/useApi.d.ts
CHANGED
|
@@ -873,6 +873,7 @@ export declare const ApiProvider: import("react").Provider<{
|
|
|
873
873
|
readonly readConversationTranscript: (query: import("@tai42/api-client").ConversationTranscriptQuery, signal?: AbortSignal) => Promise<{
|
|
874
874
|
items: {
|
|
875
875
|
created_at: number;
|
|
876
|
+
origin: "client" | "operator";
|
|
876
877
|
route_name: string;
|
|
877
878
|
door: "channel" | "api";
|
|
878
879
|
thread_id: string;
|
|
@@ -898,6 +899,18 @@ export declare const ApiProvider: import("react").Provider<{
|
|
|
898
899
|
next_page: number | null;
|
|
899
900
|
order: "asc" | "desc";
|
|
900
901
|
}>;
|
|
902
|
+
readonly sendConversationThreadMessage: (routeName: string, body: import("@tai42/api-client").ConversationThreadMessageBody) => Promise<{
|
|
903
|
+
thread_id: string;
|
|
904
|
+
message_id: string;
|
|
905
|
+
}>;
|
|
906
|
+
readonly getConversationThreadMode: (routeName: string, threadId: string, signal?: AbortSignal) => Promise<{
|
|
907
|
+
mode: "agent" | "manual";
|
|
908
|
+
source: "thread" | "route";
|
|
909
|
+
}>;
|
|
910
|
+
readonly setConversationThreadMode: (routeName: string, threadId: string, mode: import("@tai42/api-client").ConversationThreadMode) => Promise<{
|
|
911
|
+
mode: "agent" | "manual";
|
|
912
|
+
source: "thread" | "route";
|
|
913
|
+
}>;
|
|
901
914
|
readonly getWebEntryGate: (identity: string, signal?: AbortSignal) => Promise<{
|
|
902
915
|
enabled: boolean;
|
|
903
916
|
codes: {
|
|
@@ -1511,9 +1524,9 @@ export declare const ApiProvider: import("react").Provider<{
|
|
|
1511
1524
|
kind: string;
|
|
1512
1525
|
}[];
|
|
1513
1526
|
version: string;
|
|
1527
|
+
source: string;
|
|
1514
1528
|
ref: string;
|
|
1515
1529
|
latest: string | null;
|
|
1516
|
-
source: string;
|
|
1517
1530
|
installed_at: string;
|
|
1518
1531
|
update_available: boolean;
|
|
1519
1532
|
incompatible_newer: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useApi.d.ts","sourceRoot":"","sources":["../../src/hooks/useApi.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAInD,eAAO,MAAM,WAAW;;+
|
|
1
|
+
{"version":3,"file":"useApi.d.ts","sourceRoot":"","sources":["../../src/hooks/useApi.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tai42/studio-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "The Studio plugin contract, shared UI components, and hooks that every feature builds on.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "tai42 <oss@tai42.ai>",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@radix-ui/react-select": "^2.3.2",
|
|
90
90
|
"@radix-ui/react-tabs": "^1.1.16",
|
|
91
91
|
"@radix-ui/react-tooltip": "^1.2.11",
|
|
92
|
-
"@tai42/api-client": "1.
|
|
92
|
+
"@tai42/api-client": "1.6.0"
|
|
93
93
|
},
|
|
94
94
|
"scripts": {
|
|
95
95
|
"build": "tsc -b tsconfig.build.json && node scripts/copy-assets.mjs",
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* PRESENTATIONAL: the caller fetches the tool names (GET /api/tools) and owns the
|
|
6
6
|
* selected value; this component fetches nothing.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* passes
|
|
8
|
+
* Four optional extensions, each inert unless supplied; the preset create flow
|
|
9
|
+
* passes the first three and the multi-tool picker the first two:
|
|
10
10
|
* - `excludeNames` removes names from the options (e.g. a preset cannot be
|
|
11
11
|
* another preset's base, so the preset create flow excludes existing preset
|
|
12
12
|
* names). The server stays the authority — a slipped-through name is rejected
|
|
@@ -18,10 +18,15 @@
|
|
|
18
18
|
* tool with " (agent)" (in grouped and flat renderings alike) — a purely visual
|
|
19
19
|
* honesty cue; the value stays the bare name and no option is excluded, since an
|
|
20
20
|
* agent run tool is a legal preset base for an authored agent.
|
|
21
|
+
* - `displayNames` (from the tool-meta overlay) overlays a human name onto the
|
|
22
|
+
* LABEL: a mapped option reads `Display Name (raw_name)`, an unmapped name (or a
|
|
23
|
+
* mapping equal to the raw name) reads the bare raw name. The value stays the raw
|
|
24
|
+
* name and grouping/filtering/exclusion key off raw names alone, so a display
|
|
25
|
+
* name is purely cosmetic.
|
|
21
26
|
*
|
|
22
|
-
* SAFETY: a tool name AND a
|
|
23
|
-
* TEXT through the DS `Select` (React escapes it) — never an HTML sink.
|
|
24
|
-
* a test.
|
|
27
|
+
* SAFETY: a tool name, a tag, AND a display name are server-supplied, so every one
|
|
28
|
+
* renders as TEXT through the DS `Select` (React escapes it) — never an HTML sink.
|
|
29
|
+
* Pinned by a test.
|
|
25
30
|
*/
|
|
26
31
|
import { useState } from 'react';
|
|
27
32
|
|
|
@@ -49,6 +54,13 @@ export interface ToolPickerProps {
|
|
|
49
54
|
readonly tagsByTool?: Readonly<Record<string, readonly string[]>>;
|
|
50
55
|
/** Tool names that are agent run tools; their option labels are suffixed " (agent)". */
|
|
51
56
|
readonly agentToolNames?: ReadonlySet<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Human display names keyed by raw tool name (from the tool-meta overlay). A
|
|
59
|
+
* mapped option's label reads `Display Name (raw_name)`; an unmapped name — or a
|
|
60
|
+
* mapping equal to the raw name — reads the bare raw name. The value `onChange`
|
|
61
|
+
* emits stays the raw name in every case.
|
|
62
|
+
*/
|
|
63
|
+
readonly displayNames?: Readonly<Record<string, string>>;
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
const UNTAGGED = 'Untagged';
|
|
@@ -63,15 +75,25 @@ function groupFor(name: string, tagsByTool: Readonly<Record<string, readonly str
|
|
|
63
75
|
return tags[0] ?? UNTAGGED;
|
|
64
76
|
}
|
|
65
77
|
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
/**
|
|
79
|
+
* The option label: `Display Name (raw)` when a distinct display name maps the
|
|
80
|
+
* name, else the bare name; either way suffixed " (agent)" for an agent run tool.
|
|
81
|
+
*/
|
|
82
|
+
function optionLabel(
|
|
83
|
+
name: string,
|
|
84
|
+
displayNames: Readonly<Record<string, string>> | undefined,
|
|
85
|
+
agentToolNames: ReadonlySet<string> | undefined,
|
|
86
|
+
): string {
|
|
87
|
+
const display = displayNames?.[name];
|
|
88
|
+
const base = display !== undefined && display !== name ? `${display} (${name})` : name;
|
|
89
|
+
return agentToolNames?.has(name) === true ? `${base} (agent)` : base;
|
|
69
90
|
}
|
|
70
91
|
|
|
71
92
|
/** Build the grouped option clusters (sorted group labels, "Untagged" last). */
|
|
72
93
|
function buildGroups(
|
|
73
94
|
names: readonly string[],
|
|
74
95
|
tagsByTool: Readonly<Record<string, readonly string[]>>,
|
|
96
|
+
displayNames: Readonly<Record<string, string>> | undefined,
|
|
75
97
|
agentToolNames: ReadonlySet<string> | undefined,
|
|
76
98
|
): SelectGroup[] {
|
|
77
99
|
const byGroup = new Map<string, string[]>();
|
|
@@ -91,7 +113,7 @@ function buildGroups(
|
|
|
91
113
|
label,
|
|
92
114
|
options: groupNames.map((name) => ({
|
|
93
115
|
value: name,
|
|
94
|
-
label: optionLabel(name, agentToolNames),
|
|
116
|
+
label: optionLabel(name, displayNames, agentToolNames),
|
|
95
117
|
})),
|
|
96
118
|
}));
|
|
97
119
|
}
|
|
@@ -108,6 +130,7 @@ export function ToolPicker({
|
|
|
108
130
|
excludeNames,
|
|
109
131
|
tagsByTool,
|
|
110
132
|
agentToolNames,
|
|
133
|
+
displayNames,
|
|
111
134
|
}: ToolPickerProps) {
|
|
112
135
|
const [tagFilter, setTagFilter] = useState<string>(ALL_TAGS);
|
|
113
136
|
|
|
@@ -130,7 +153,7 @@ export function ToolPicker({
|
|
|
130
153
|
const toolSelect =
|
|
131
154
|
tagsByTool !== undefined ? (
|
|
132
155
|
<Select
|
|
133
|
-
groups={buildGroups(filtered, tagsByTool, agentToolNames)}
|
|
156
|
+
groups={buildGroups(filtered, tagsByTool, displayNames, agentToolNames)}
|
|
134
157
|
value={value ?? ''}
|
|
135
158
|
onValueChange={onChange}
|
|
136
159
|
placeholder={placeholder}
|
|
@@ -144,7 +167,7 @@ export function ToolPicker({
|
|
|
144
167
|
// a subsequent selection would otherwise trigger.
|
|
145
168
|
options={filtered.map((name) => ({
|
|
146
169
|
value: name,
|
|
147
|
-
label: optionLabel(name, agentToolNames),
|
|
170
|
+
label: optionLabel(name, displayNames, agentToolNames),
|
|
148
171
|
}))}
|
|
149
172
|
value={value ?? ''}
|
|
150
173
|
onValueChange={onChange}
|