@tai42/api-client 3.0.0 → 5.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.
- package/dist/client.d.ts +77 -38
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -2
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +355 -413
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +82 -29
- package/dist/schemas.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +42 -3
- package/src/index.ts +6 -0
- package/src/schemas.ts +90 -31
package/src/client.ts
CHANGED
|
@@ -213,12 +213,14 @@ export interface ValidatePresetBody {
|
|
|
213
213
|
* untouched — there is no full-row replace, so a display-name+tags editor sends
|
|
214
214
|
* ONLY those two keys with no risk to `folder_id`/`hidden`. At least one field must
|
|
215
215
|
* be present. A blank/whitespace-only `display_name` is rejected by the API (422) —
|
|
216
|
-
* callers map an emptied label to `null`, never `""`.
|
|
216
|
+
* callers map an emptied label to `null`, never `""`. A present `badges` array
|
|
217
|
+
* replaces the whole overlay set (INFORMATIONAL labels, never an enforced gate).
|
|
217
218
|
*/
|
|
218
219
|
export interface ToolMetaPatch {
|
|
219
220
|
readonly display_name?: string | null;
|
|
220
221
|
readonly folder_id?: string | null;
|
|
221
222
|
readonly tags?: readonly string[];
|
|
223
|
+
readonly badges?: readonly string[];
|
|
222
224
|
readonly hidden?: boolean | null;
|
|
223
225
|
}
|
|
224
226
|
|
|
@@ -234,11 +236,23 @@ export interface StorageUploadBody {
|
|
|
234
236
|
readonly content_base64?: string;
|
|
235
237
|
}
|
|
236
238
|
|
|
239
|
+
/**
|
|
240
|
+
* The thread-list filter set (GET `/api/conversations/{route}/threads` query
|
|
241
|
+
* params, alongside `page`/`pageSize`). `status` narrows to threads whose newest
|
|
242
|
+
* record sits in one delivery state; `address` is a SUBSTRING match over the
|
|
243
|
+
* client address. Both omitted when undefined — an unfiltered listing.
|
|
244
|
+
*/
|
|
245
|
+
export interface ConversationThreadFilters {
|
|
246
|
+
readonly status?: s.ConversationDeliveryStatus;
|
|
247
|
+
readonly address?: string;
|
|
248
|
+
}
|
|
249
|
+
|
|
237
250
|
/**
|
|
238
251
|
* One transcript read (GET `/api/conversations/{route}/transcript` query params).
|
|
239
252
|
* `order` is not a default the caller may skip: `asc` reads the thread from its
|
|
240
253
|
* beginning and `desc` from its newest end, and which one a screen wants is a
|
|
241
|
-
* decision that screen must make.
|
|
254
|
+
* decision that screen must make. `q` narrows the page to records whose text
|
|
255
|
+
* matches it (a SUBSTRING), omitted for an unfiltered read.
|
|
242
256
|
*/
|
|
243
257
|
export interface ConversationTranscriptQuery {
|
|
244
258
|
readonly routeName: string;
|
|
@@ -246,6 +260,20 @@ export interface ConversationTranscriptQuery {
|
|
|
246
260
|
readonly page: number;
|
|
247
261
|
readonly pageSize: number;
|
|
248
262
|
readonly order: s.TranscriptOrder;
|
|
263
|
+
readonly q?: string;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* A route-scoped message search (GET
|
|
268
|
+
* `/api/conversations/{route}/messages/search` query params). `q` is the required
|
|
269
|
+
* needle — a substring over record text, across every thread on the route; `page`
|
|
270
|
+
* is supplied per-request by the infinite query.
|
|
271
|
+
*/
|
|
272
|
+
export interface ConversationMessageSearchQuery {
|
|
273
|
+
readonly routeName: string;
|
|
274
|
+
readonly q: string;
|
|
275
|
+
readonly page: number;
|
|
276
|
+
readonly pageSize: number;
|
|
249
277
|
}
|
|
250
278
|
|
|
251
279
|
/**
|
|
@@ -790,11 +818,12 @@ export function createApiClient(config: ApiConfig) {
|
|
|
790
818
|
routeName: string,
|
|
791
819
|
page: number,
|
|
792
820
|
pageSize: number,
|
|
821
|
+
filters: ConversationThreadFilters = {},
|
|
793
822
|
signal?: AbortSignal,
|
|
794
823
|
) =>
|
|
795
824
|
req(`/api/conversations/${encodeSegment(routeName)}/threads`, s.conversationThreadsPage, {
|
|
796
825
|
signal,
|
|
797
|
-
query: { page, pageSize },
|
|
826
|
+
query: { page, pageSize, status: filters.status, address: filters.address },
|
|
798
827
|
}),
|
|
799
828
|
// One thread's transcript, caller-scoped, read in the asked-for direction.
|
|
800
829
|
// The `thread_id` rides the QUERY STRING, never the path: it embeds the api
|
|
@@ -813,9 +842,19 @@ export function createApiClient(config: ApiConfig) {
|
|
|
813
842
|
page: query.page,
|
|
814
843
|
pageSize: query.pageSize,
|
|
815
844
|
order: query.order,
|
|
845
|
+
q: query.q,
|
|
816
846
|
},
|
|
817
847
|
},
|
|
818
848
|
),
|
|
849
|
+
// Search every record on a route by text, across threads, newest first. The
|
|
850
|
+
// needle rides the QUERY (`q`); paging is the infinite query's own window. The
|
|
851
|
+
// page's `truncated` flag says the match set outran the door's scan cap.
|
|
852
|
+
searchConversationMessages: (query: ConversationMessageSearchQuery, signal?: AbortSignal) =>
|
|
853
|
+
req(
|
|
854
|
+
`/api/conversations/${encodeSegment(query.routeName)}/messages/search`,
|
|
855
|
+
s.conversationMessageSearchPage,
|
|
856
|
+
{ signal, query: { q: query.q, page: query.page, pageSize: query.pageSize } },
|
|
857
|
+
),
|
|
819
858
|
// Send a human message into a thread. The `thread_id` rides the BODY (a POST,
|
|
820
859
|
// never a path segment) — same encode-once reasoning as the transcript read.
|
|
821
860
|
sendConversationThreadMessage: (routeName: string, body: ConversationThreadMessageBody) =>
|
package/src/index.ts
CHANGED
|
@@ -25,7 +25,9 @@ export type {
|
|
|
25
25
|
ValidatePresetBody,
|
|
26
26
|
ToolMetaPatch,
|
|
27
27
|
StorageUploadBody,
|
|
28
|
+
ConversationThreadFilters,
|
|
28
29
|
ConversationTranscriptQuery,
|
|
30
|
+
ConversationMessageSearchQuery,
|
|
29
31
|
ConversationThreadMessageBody,
|
|
30
32
|
MetricsQuery,
|
|
31
33
|
RunsQuery,
|
|
@@ -128,6 +130,7 @@ export type {
|
|
|
128
130
|
ConversationRecordOrigin,
|
|
129
131
|
TranscriptOrder,
|
|
130
132
|
ConversationTranscriptPage,
|
|
133
|
+
ConversationMessageSearchPage,
|
|
131
134
|
ConversationThreadMode,
|
|
132
135
|
ConversationThreadModeState,
|
|
133
136
|
ConversationThreadMessageSent,
|
|
@@ -183,6 +186,9 @@ export type {
|
|
|
183
186
|
RunSpan,
|
|
184
187
|
RunTrace,
|
|
185
188
|
MarketplaceItem,
|
|
189
|
+
MarketplaceDelivery,
|
|
190
|
+
MarketplaceSource,
|
|
191
|
+
MarketplaceRequiredEnvVar,
|
|
186
192
|
MarketplaceRouteDecl,
|
|
187
193
|
MarketplaceRoutesDecl,
|
|
188
194
|
MarketplaceSearchKind,
|
package/src/schemas.ts
CHANGED
|
@@ -58,10 +58,15 @@ export type ToolMediaResult = z.infer<typeof toolMediaResult>;
|
|
|
58
58
|
* FastMCP `meta` under `tai42/hidden`; a tool that never declared it is not hidden).
|
|
59
59
|
* The tool_meta overlay's tri-state override is merged on top client-side; this read
|
|
60
60
|
* exposes only the declaration.
|
|
61
|
+
*
|
|
62
|
+
* `badges` are the tool's plugin-DECLARED capability labels — purely INFORMATIONAL
|
|
63
|
+
* (e.g. `network`, `filesystem`), never a gate the server enforces. The overlay's
|
|
64
|
+
* own badges are merged on top client-side; this read exposes only the declaration.
|
|
61
65
|
*/
|
|
62
66
|
export const toolTagEntry = z.object({
|
|
63
67
|
name: z.string(),
|
|
64
68
|
tags: z.array(z.string()),
|
|
69
|
+
badges: z.array(z.string()),
|
|
65
70
|
hidden: z.boolean(),
|
|
66
71
|
});
|
|
67
72
|
export const toolTags = z.array(toolTagEntry);
|
|
@@ -238,7 +243,9 @@ export type FolderRecord = z.infer<typeof folderRecord>;
|
|
|
238
243
|
* The organizational overlay for one tool, keyed by `tool_name`. `display_name`
|
|
239
244
|
* overrides the rendered label (`display_name ?? name`); `folder_id` places the tool
|
|
240
245
|
* in a folder (`null` = unfiled); `tags` is the user's editable categorization,
|
|
241
|
-
* merged with the tool's read-only native tags by the UI; `
|
|
246
|
+
* merged with the tool's read-only native tags by the UI; `badges` is the operator's
|
|
247
|
+
* editable capability-label overlay, merged with the tool's read-only plugin-declared
|
|
248
|
+
* badges by the UI (INFORMATIONAL, never an enforced gate); `hidden` is TRI-STATE —
|
|
242
249
|
* `null` = defer to the plugin declaration, `true` = force hidden, `false` = force
|
|
243
250
|
* visible. A drift throws `ApiSchemaError`.
|
|
244
251
|
*/
|
|
@@ -247,6 +254,7 @@ export const toolMetaRecord = z.object({
|
|
|
247
254
|
display_name: z.string().nullable(),
|
|
248
255
|
folder_id: z.string().nullable(),
|
|
249
256
|
tags: z.array(z.string()),
|
|
257
|
+
badges: z.array(z.string()),
|
|
250
258
|
hidden: z.boolean().nullable(),
|
|
251
259
|
});
|
|
252
260
|
export type ToolMetaRecord = z.infer<typeof toolMetaRecord>;
|
|
@@ -750,7 +758,10 @@ export const providerView = z.object({
|
|
|
750
758
|
id: z.string(),
|
|
751
759
|
display_name: z.string(),
|
|
752
760
|
description: z.string(),
|
|
753
|
-
|
|
761
|
+
// Required and a real URL: the contract's `ProviderDescriptor.icon_url` runs
|
|
762
|
+
// `check_web_url(schemes=("https",))`, which rejects an empty/relative value, so
|
|
763
|
+
// an empty or malformed one here is drift and fails the parse loudly.
|
|
764
|
+
icon_url: z.string().url(),
|
|
754
765
|
kind: z.enum(['oauth', 'none']),
|
|
755
766
|
origin: z.enum(['system', 'community']),
|
|
756
767
|
category: z.string(),
|
|
@@ -1056,12 +1067,18 @@ export const conversationThread = z.object({
|
|
|
1056
1067
|
});
|
|
1057
1068
|
export type ConversationThread = z.infer<typeof conversationThread>;
|
|
1058
1069
|
|
|
1059
|
-
/**
|
|
1070
|
+
/**
|
|
1071
|
+
* The page window every conversation read door carries; `next_page` is null on the
|
|
1072
|
+
* last page. `truncated` is TRUE when the door had more matches than it would scan
|
|
1073
|
+
* or return under its filter/search cap — the UI must surface that LOUDLY, never a
|
|
1074
|
+
* silent cut — and false whenever the window is exhaustive.
|
|
1075
|
+
*/
|
|
1060
1076
|
const conversationPageWindow = {
|
|
1061
1077
|
total: z.number(),
|
|
1062
1078
|
page: z.number(),
|
|
1063
1079
|
page_size: z.number(),
|
|
1064
1080
|
next_page: z.number().nullable(),
|
|
1081
|
+
truncated: z.boolean(),
|
|
1065
1082
|
};
|
|
1066
1083
|
|
|
1067
1084
|
export const conversationThreadsPage = z.object({
|
|
@@ -1117,6 +1134,19 @@ export const conversationTranscriptPage = z.object({
|
|
|
1117
1134
|
});
|
|
1118
1135
|
export type ConversationTranscriptPage = z.infer<typeof conversationTranscriptPage>;
|
|
1119
1136
|
|
|
1137
|
+
/**
|
|
1138
|
+
* A route-scoped message search (`GET /api/conversations/{route}/messages/search?q`):
|
|
1139
|
+
* every record on the route whose text matches `q`, across threads, newest first.
|
|
1140
|
+
* The record shape is the transcript's exactly, so a hit renders with the same
|
|
1141
|
+
* projection. `truncated` says the match set outran the door's scan cap — surfaced
|
|
1142
|
+
* loudly, never a silent cut.
|
|
1143
|
+
*/
|
|
1144
|
+
export const conversationMessageSearchPage = z.object({
|
|
1145
|
+
items: z.array(conversationMessage),
|
|
1146
|
+
...conversationPageWindow,
|
|
1147
|
+
});
|
|
1148
|
+
export type ConversationMessageSearchPage = z.infer<typeof conversationMessageSearchPage>;
|
|
1149
|
+
|
|
1120
1150
|
/**
|
|
1121
1151
|
* Who answers a thread's incoming messages: `agent` lets the flow reply on its
|
|
1122
1152
|
* own; `manual` holds the flow back so a human answers. `source` says whether the
|
|
@@ -1866,6 +1896,31 @@ export type RunTrace = z.infer<typeof runTrace>;
|
|
|
1866
1896
|
export const routeMethod = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
|
|
1867
1897
|
export type RouteMethod = z.infer<typeof routeMethod>;
|
|
1868
1898
|
|
|
1899
|
+
/**
|
|
1900
|
+
* How the plugin is delivered, derived server-side from whether its spec names a
|
|
1901
|
+
* package: `package` is pip-installed, `descriptor` (marketplace `source` `spec`)
|
|
1902
|
+
* installs nothing but the manifest entry. A CLOSED enum, so a wire value the
|
|
1903
|
+
* server does not derive fails loudly as drift.
|
|
1904
|
+
*/
|
|
1905
|
+
export const marketplaceDelivery = z.enum(['package', 'descriptor']);
|
|
1906
|
+
export type MarketplaceDelivery = z.infer<typeof marketplaceDelivery>;
|
|
1907
|
+
|
|
1908
|
+
/**
|
|
1909
|
+
* The install-provenance vocabulary a listing/version resolves from: a pip index
|
|
1910
|
+
* (`pypi`), a git tag (`github`), or a descriptor yml (`spec`). CLOSED, so a wire
|
|
1911
|
+
* value outside it fails as drift.
|
|
1912
|
+
*/
|
|
1913
|
+
export const marketplaceSource = z.enum(['pypi', 'github', 'spec']);
|
|
1914
|
+
export type MarketplaceSource = z.infer<typeof marketplaceSource>;
|
|
1915
|
+
|
|
1916
|
+
/**
|
|
1917
|
+
* One env var an item requires before install: its `name` and whether its value is
|
|
1918
|
+
* a `secret` (an OAuth client secret is; a client id or a plain marker var is not).
|
|
1919
|
+
* The install dialog seeds each toggle from `secret` and collects the missing ones.
|
|
1920
|
+
*/
|
|
1921
|
+
export const marketplaceRequiredEnvVar = z.object({ name: z.string(), secret: z.boolean() });
|
|
1922
|
+
export type MarketplaceRequiredEnvVar = z.infer<typeof marketplaceRequiredEnvVar>;
|
|
1923
|
+
|
|
1869
1924
|
/**
|
|
1870
1925
|
* One HTTP route an item declares in its `tai-plugin.yml`: a `path` relative to
|
|
1871
1926
|
* the item's mount base, the `methods` it answers, and whether it is served
|
|
@@ -1894,6 +1949,12 @@ export type MarketplaceRoutesDecl = z.infer<typeof marketplaceRoutesDecl>;
|
|
|
1894
1949
|
* (tool / agent / extension / …), name, description, free-form tags, and the
|
|
1895
1950
|
* logical group it belongs to (`null` when ungrouped). `routes` is present only
|
|
1896
1951
|
* on a route-carrying item (a router or channel); absent/null on every other.
|
|
1952
|
+
* `required_env` is the env vars the item needs before install — but the REGISTRY's
|
|
1953
|
+
* plugin-detail body does NOT carry it per item: required-env is server-computed
|
|
1954
|
+
* (`required_env_for_spec`) and rides the install PREVIEW, never the listing detail,
|
|
1955
|
+
* so the registry OMITS it here and it parses as `undefined`. Optional (not
|
|
1956
|
+
* defaulted) so the type mirrors the wire; the authority the install dialog collects
|
|
1957
|
+
* from is the preview's `required_env`/`missing_env`, never this field.
|
|
1897
1958
|
*/
|
|
1898
1959
|
export const marketplaceItem = z.object({
|
|
1899
1960
|
kind: z.string(),
|
|
@@ -1902,6 +1963,7 @@ export const marketplaceItem = z.object({
|
|
|
1902
1963
|
tags: z.array(z.string()),
|
|
1903
1964
|
group: z.string().nullable(),
|
|
1904
1965
|
routes: marketplaceRoutesDecl.nullish(),
|
|
1966
|
+
required_env: z.array(marketplaceRequiredEnvVar).optional(),
|
|
1905
1967
|
});
|
|
1906
1968
|
export type MarketplaceItem = z.infer<typeof marketplaceItem>;
|
|
1907
1969
|
|
|
@@ -1943,7 +2005,8 @@ export const marketplaceSearchRow = z.object({
|
|
|
1943
2005
|
name: z.string(),
|
|
1944
2006
|
display_name: z.string().nullable(),
|
|
1945
2007
|
icon_url: z.string().nullable(),
|
|
1946
|
-
|
|
2008
|
+
// Null for a descriptor listing (`source` `spec`): it names no package.
|
|
2009
|
+
package: z.string().nullable(),
|
|
1947
2010
|
description: z.string(),
|
|
1948
2011
|
categories: z.array(z.string()),
|
|
1949
2012
|
tags: z.array(z.string()),
|
|
@@ -1987,35 +2050,16 @@ export const marketplaceVersion = z.object({
|
|
|
1987
2050
|
export type MarketplaceVersion = z.infer<typeof marketplaceVersion>;
|
|
1988
2051
|
|
|
1989
2052
|
/**
|
|
1990
|
-
* The listing's latest published version as embedded in its detail: the version
|
|
1991
|
-
* the
|
|
1992
|
-
*
|
|
1993
|
-
*
|
|
1994
|
-
*
|
|
1995
|
-
*
|
|
1996
|
-
*
|
|
1997
|
-
* `spec` as an unknown key). Nullable + optional: a listing with nothing published
|
|
1998
|
-
* carries no spec.
|
|
2053
|
+
* The listing's latest published version as embedded in its detail: the version
|
|
2054
|
+
* (with the `marketplaceVersion` lifecycle fields) and the items it contains. The
|
|
2055
|
+
* registry's detail body carries NO per-version `delivery` field — delivery is
|
|
2056
|
+
* server-computed from whether the spec names a package, and the detail surface
|
|
2057
|
+
* derives it from the listing's `package` (null ⇒ `descriptor`, else `package`).
|
|
2058
|
+
* Env to collect comes from the install preview (`required_env` / `missing_env`),
|
|
2059
|
+
* never from these items.
|
|
1999
2060
|
*/
|
|
2000
2061
|
export const marketplaceLatestVersion = marketplaceVersion.extend({
|
|
2001
2062
|
items: z.array(marketplaceItem),
|
|
2002
|
-
spec: z
|
|
2003
|
-
.object({
|
|
2004
|
-
provides: z.array(
|
|
2005
|
-
z
|
|
2006
|
-
.object({
|
|
2007
|
-
kind: z.string(),
|
|
2008
|
-
name: z.string(),
|
|
2009
|
-
mcp: z
|
|
2010
|
-
.object({ env: z.record(z.string(), z.string()).nullish() })
|
|
2011
|
-
.passthrough()
|
|
2012
|
-
.nullish(),
|
|
2013
|
-
})
|
|
2014
|
-
.passthrough(),
|
|
2015
|
-
),
|
|
2016
|
-
})
|
|
2017
|
-
.passthrough()
|
|
2018
|
-
.nullish(),
|
|
2019
2063
|
});
|
|
2020
2064
|
export type MarketplaceLatestVersion = z.infer<typeof marketplaceLatestVersion>;
|
|
2021
2065
|
|
|
@@ -2043,7 +2087,11 @@ export const marketplacePluginDetail = z.object({
|
|
|
2043
2087
|
name: z.string(),
|
|
2044
2088
|
display_name: z.string().nullable(),
|
|
2045
2089
|
icon_url: z.string().nullable(),
|
|
2046
|
-
|
|
2090
|
+
// Null for a descriptor listing (`source` `spec`): it names no package.
|
|
2091
|
+
package: z.string().nullable(),
|
|
2092
|
+
// The install-provenance vocabulary (`pypi` / `github` / `spec`). Nullish: an
|
|
2093
|
+
// older registry omits it, and a listing with nothing published carries none.
|
|
2094
|
+
source: marketplaceSource.nullish(),
|
|
2047
2095
|
description: z.string(),
|
|
2048
2096
|
readme_md: z.string().nullable(),
|
|
2049
2097
|
license: z.string().nullable(),
|
|
@@ -2095,6 +2143,9 @@ export const marketplaceInstalledPlugin = z
|
|
|
2095
2143
|
ref: z.string(),
|
|
2096
2144
|
version: z.string(),
|
|
2097
2145
|
source: z.string(),
|
|
2146
|
+
// How the row was delivered: `package` for a pip-installed plugin, `descriptor`
|
|
2147
|
+
// for a descriptor-only plugin whose stored spec names no package.
|
|
2148
|
+
delivery: marketplaceDelivery,
|
|
2098
2149
|
installed_at: z.string(),
|
|
2099
2150
|
latest: z.string().nullable(),
|
|
2100
2151
|
update_available: z.boolean(),
|
|
@@ -2248,6 +2299,11 @@ export type MarketplacePreviewPublicRoute = z.infer<typeof marketplacePreviewPub
|
|
|
2248
2299
|
* live registry, the public routes requiring acceptance, and whether acceptance
|
|
2249
2300
|
* is required at all. `new_public_routes` narrows to rows not already approved
|
|
2250
2301
|
* (the update case); on a fresh install it equals `public_routes`.
|
|
2302
|
+
*
|
|
2303
|
+
* `required_env` is every env var the spec requires with its derived secret-ness;
|
|
2304
|
+
* `missing_env` is the bare names not already present in the env store union
|
|
2305
|
+
* process env (server-computed — the ONE authority the dialog collects), and
|
|
2306
|
+
* `delivery` is the one word the surface shows (`package` / `descriptor`).
|
|
2251
2307
|
*/
|
|
2252
2308
|
export const marketplaceInstallPreview = z.object({
|
|
2253
2309
|
ref: z.string(),
|
|
@@ -2257,6 +2313,9 @@ export const marketplaceInstallPreview = z.object({
|
|
|
2257
2313
|
public_routes: z.array(marketplacePreviewPublicRoute),
|
|
2258
2314
|
new_public_routes: z.array(marketplacePreviewPublicRoute),
|
|
2259
2315
|
requires_public_acceptance: z.boolean(),
|
|
2316
|
+
required_env: z.array(marketplaceRequiredEnvVar),
|
|
2317
|
+
missing_env: z.array(z.string()),
|
|
2318
|
+
delivery: marketplaceDelivery,
|
|
2260
2319
|
});
|
|
2261
2320
|
export type MarketplaceInstallPreview = z.infer<typeof marketplaceInstallPreview>;
|
|
2262
2321
|
|