lemma-sdk 0.2.32 → 0.2.33
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/README.md +133 -49
- package/dist/browser/lemma-client.js +23 -8
- package/dist/namespaces/desks.d.ts +5 -2
- package/dist/namespaces/desks.js +5 -2
- package/dist/namespaces/files.d.ts +11 -0
- package/dist/namespaces/files.js +12 -0
- package/dist/openapi_client/models/DeskBundleUploadRequest.d.ts +1 -1
- package/dist/openapi_client/services/DesksService.d.ts +4 -4
- package/dist/openapi_client/services/DesksService.js +6 -6
- package/dist/openapi_client/services/PublicDesksService.d.ts +2 -2
- package/dist/openapi_client/services/PublicDesksService.js +3 -3
- package/dist/react/index.d.ts +10 -0
- package/dist/react/index.js +5 -0
- package/dist/react/useAssistantController.js +82 -37
- package/dist/react/useAssistantRuntime.js +8 -4
- package/dist/react/useAssistantSession.js +44 -2
- package/dist/react/useConversationMessages.js +19 -2
- package/dist/react/useFile.d.ts +18 -0
- package/dist/react/useFile.js +58 -0
- package/dist/react/useFilePreview.d.ts +23 -0
- package/dist/react/useFilePreview.js +76 -0
- package/dist/react/useFileSearch.d.ts +26 -0
- package/dist/react/useFileSearch.js +64 -0
- package/dist/react/useFileTree.d.ts +21 -0
- package/dist/react/useFileTree.js +59 -0
- package/dist/react/useFiles.d.ts +29 -0
- package/dist/react/useFiles.js +90 -0
- package/dist/react/useRecords.js +8 -5
- package/dist/types.d.ts +6 -1
- package/package.json +2 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { normalizeError, resolvePodClient } from "./utils.js";
|
|
3
|
+
export function useFileSearch({ client, podId, query = "", enabled = true, autoLoad = true, minQueryLength = 1, limit = 10, searchMethod, }) {
|
|
4
|
+
const [response, setResponse] = useState(null);
|
|
5
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const trimmedQuery = query.trim();
|
|
8
|
+
const reset = useCallback(() => {
|
|
9
|
+
setResponse(null);
|
|
10
|
+
setError(null);
|
|
11
|
+
setIsLoading(false);
|
|
12
|
+
}, []);
|
|
13
|
+
const search = useCallback(async (overrides = {}, signal) => {
|
|
14
|
+
const nextQuery = (overrides.query ?? trimmedQuery).trim();
|
|
15
|
+
if (!enabled || nextQuery.length < minQueryLength) {
|
|
16
|
+
reset();
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
setIsLoading(true);
|
|
20
|
+
setError(null);
|
|
21
|
+
try {
|
|
22
|
+
const scopedClient = resolvePodClient(client, podId);
|
|
23
|
+
const nextResponse = await scopedClient.files.search(nextQuery, {
|
|
24
|
+
limit: overrides.limit ?? limit,
|
|
25
|
+
searchMethod: overrides.searchMethod ?? searchMethod,
|
|
26
|
+
});
|
|
27
|
+
if (signal?.aborted)
|
|
28
|
+
return null;
|
|
29
|
+
setResponse(nextResponse);
|
|
30
|
+
return nextResponse;
|
|
31
|
+
}
|
|
32
|
+
catch (searchError) {
|
|
33
|
+
if (signal?.aborted)
|
|
34
|
+
return null;
|
|
35
|
+
setError(normalizeError(searchError, "Failed to search files."));
|
|
36
|
+
setResponse(null);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
if (!signal?.aborted)
|
|
41
|
+
setIsLoading(false);
|
|
42
|
+
}
|
|
43
|
+
}, [client, enabled, limit, minQueryLength, podId, reset, searchMethod, trimmedQuery]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!enabled || !autoLoad)
|
|
46
|
+
return;
|
|
47
|
+
if (trimmedQuery.length < minQueryLength) {
|
|
48
|
+
reset();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
void search({}, controller.signal);
|
|
53
|
+
return () => controller.abort();
|
|
54
|
+
}, [autoLoad, enabled, minQueryLength, reset, search, trimmedQuery]);
|
|
55
|
+
return useMemo(() => ({
|
|
56
|
+
response,
|
|
57
|
+
results: response?.results ?? [],
|
|
58
|
+
totalResults: response?.total_results ?? 0,
|
|
59
|
+
isLoading,
|
|
60
|
+
error,
|
|
61
|
+
search,
|
|
62
|
+
reset,
|
|
63
|
+
}), [error, isLoading, reset, response, search]);
|
|
64
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LemmaClient } from "../client.js";
|
|
2
|
+
import type { DirectoryTreeNode, DirectoryTreeResponse } from "../types.js";
|
|
3
|
+
export interface UseFileTreeOptions {
|
|
4
|
+
client: LemmaClient;
|
|
5
|
+
podId?: string;
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
autoLoad?: boolean;
|
|
8
|
+
rootPath?: string;
|
|
9
|
+
filesPerDirectory?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface UseFileTreeResult {
|
|
12
|
+
tree: DirectoryTreeNode | null;
|
|
13
|
+
response: DirectoryTreeResponse | null;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
error: Error | null;
|
|
16
|
+
refresh: (overrides?: {
|
|
17
|
+
rootPath?: string;
|
|
18
|
+
filesPerDirectory?: number;
|
|
19
|
+
}) => Promise<DirectoryTreeResponse | null>;
|
|
20
|
+
}
|
|
21
|
+
export declare function useFileTree({ client, podId, enabled, autoLoad, rootPath, filesPerDirectory, }: UseFileTreeOptions): UseFileTreeResult;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { normalizeError, resolvePodClient } from "./utils.js";
|
|
3
|
+
export function useFileTree({ client, podId, enabled = true, autoLoad = true, rootPath = "/", filesPerDirectory = 3, }) {
|
|
4
|
+
const [response, setResponse] = useState(null);
|
|
5
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const refresh = useCallback(async (overrides = {}, signal) => {
|
|
8
|
+
if (!enabled) {
|
|
9
|
+
setResponse(null);
|
|
10
|
+
setError(null);
|
|
11
|
+
setIsLoading(false);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
setIsLoading(true);
|
|
15
|
+
setError(null);
|
|
16
|
+
try {
|
|
17
|
+
const scopedClient = resolvePodClient(client, podId);
|
|
18
|
+
const nextResponse = await scopedClient.files.tree({
|
|
19
|
+
rootPath: overrides.rootPath ?? rootPath,
|
|
20
|
+
filesPerDirectory: overrides.filesPerDirectory ?? filesPerDirectory,
|
|
21
|
+
});
|
|
22
|
+
if (signal?.aborted)
|
|
23
|
+
return null;
|
|
24
|
+
setResponse(nextResponse);
|
|
25
|
+
return nextResponse;
|
|
26
|
+
}
|
|
27
|
+
catch (refreshError) {
|
|
28
|
+
if (signal?.aborted)
|
|
29
|
+
return null;
|
|
30
|
+
setError(normalizeError(refreshError, "Failed to load file tree."));
|
|
31
|
+
setResponse(null);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
if (!signal?.aborted)
|
|
36
|
+
setIsLoading(false);
|
|
37
|
+
}
|
|
38
|
+
}, [client, enabled, filesPerDirectory, podId, rootPath]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!enabled) {
|
|
41
|
+
setResponse(null);
|
|
42
|
+
setError(null);
|
|
43
|
+
setIsLoading(false);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!autoLoad)
|
|
47
|
+
return;
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
void refresh({}, controller.signal);
|
|
50
|
+
return () => controller.abort();
|
|
51
|
+
}, [autoLoad, enabled, refresh]);
|
|
52
|
+
return useMemo(() => ({
|
|
53
|
+
tree: response?.tree ?? null,
|
|
54
|
+
response,
|
|
55
|
+
isLoading,
|
|
56
|
+
error,
|
|
57
|
+
refresh,
|
|
58
|
+
}), [error, isLoading, refresh, response]);
|
|
59
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { LemmaClient } from "../client.js";
|
|
2
|
+
import type { FileResponse } from "../types.js";
|
|
3
|
+
export interface UseFilesOptions {
|
|
4
|
+
client: LemmaClient;
|
|
5
|
+
podId?: string;
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
autoLoad?: boolean;
|
|
8
|
+
limit?: number;
|
|
9
|
+
pageToken?: string;
|
|
10
|
+
directoryPath?: string;
|
|
11
|
+
parentId?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface UseFilesResult {
|
|
14
|
+
files: FileResponse[];
|
|
15
|
+
nextPageToken: string | null;
|
|
16
|
+
isLoading: boolean;
|
|
17
|
+
isLoadingMore: boolean;
|
|
18
|
+
error: Error | null;
|
|
19
|
+
refresh: (overrides?: {
|
|
20
|
+
limit?: number;
|
|
21
|
+
pageToken?: string;
|
|
22
|
+
directoryPath?: string;
|
|
23
|
+
parentId?: string;
|
|
24
|
+
}) => Promise<FileResponse[]>;
|
|
25
|
+
loadMore: (overrides?: {
|
|
26
|
+
limit?: number;
|
|
27
|
+
}) => Promise<FileResponse[]>;
|
|
28
|
+
}
|
|
29
|
+
export declare function useFiles({ client, podId, enabled, autoLoad, limit, pageToken, directoryPath, parentId, }: UseFilesOptions): UseFilesResult;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { normalizeError, resolvePodClient } from "./utils.js";
|
|
3
|
+
export function useFiles({ client, podId, enabled = true, autoLoad = true, limit = 100, pageToken, directoryPath = "/", parentId, }) {
|
|
4
|
+
const [files, setFiles] = useState([]);
|
|
5
|
+
const [nextPageToken, setNextPageToken] = useState(null);
|
|
6
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
7
|
+
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const refresh = useCallback(async (overrides = {}, signal) => {
|
|
10
|
+
if (!enabled)
|
|
11
|
+
return [];
|
|
12
|
+
setIsLoading(true);
|
|
13
|
+
setError(null);
|
|
14
|
+
try {
|
|
15
|
+
const scopedClient = resolvePodClient(client, podId);
|
|
16
|
+
const response = await scopedClient.files.list({
|
|
17
|
+
limit: overrides.limit ?? limit,
|
|
18
|
+
pageToken: overrides.pageToken ?? pageToken,
|
|
19
|
+
directoryPath: overrides.directoryPath ?? directoryPath,
|
|
20
|
+
parentId: overrides.parentId ?? parentId,
|
|
21
|
+
});
|
|
22
|
+
if (signal?.aborted)
|
|
23
|
+
return [];
|
|
24
|
+
const nextFiles = response.items ?? [];
|
|
25
|
+
setFiles(nextFiles);
|
|
26
|
+
setNextPageToken(response.next_page_token ?? null);
|
|
27
|
+
return nextFiles;
|
|
28
|
+
}
|
|
29
|
+
catch (refreshError) {
|
|
30
|
+
if (signal?.aborted)
|
|
31
|
+
return [];
|
|
32
|
+
setError(normalizeError(refreshError, "Failed to load files."));
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
if (!signal?.aborted)
|
|
37
|
+
setIsLoading(false);
|
|
38
|
+
}
|
|
39
|
+
}, [client, directoryPath, enabled, limit, pageToken, parentId, podId]);
|
|
40
|
+
const loadMore = useCallback(async (overrides = {}) => {
|
|
41
|
+
if (!enabled || !nextPageToken || isLoading || isLoadingMore)
|
|
42
|
+
return [];
|
|
43
|
+
setIsLoadingMore(true);
|
|
44
|
+
setError(null);
|
|
45
|
+
try {
|
|
46
|
+
const scopedClient = resolvePodClient(client, podId);
|
|
47
|
+
const response = await scopedClient.files.list({
|
|
48
|
+
limit: overrides.limit ?? limit,
|
|
49
|
+
pageToken: nextPageToken,
|
|
50
|
+
directoryPath,
|
|
51
|
+
parentId,
|
|
52
|
+
});
|
|
53
|
+
const moreFiles = response.items ?? [];
|
|
54
|
+
setFiles((previous) => [...previous, ...moreFiles]);
|
|
55
|
+
setNextPageToken(response.next_page_token ?? null);
|
|
56
|
+
return moreFiles;
|
|
57
|
+
}
|
|
58
|
+
catch (loadError) {
|
|
59
|
+
setError(normalizeError(loadError, "Failed to load more files."));
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
setIsLoadingMore(false);
|
|
64
|
+
}
|
|
65
|
+
}, [client, directoryPath, enabled, isLoading, isLoadingMore, limit, nextPageToken, parentId, podId]);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (!enabled) {
|
|
68
|
+
setFiles([]);
|
|
69
|
+
setNextPageToken(null);
|
|
70
|
+
setError(null);
|
|
71
|
+
setIsLoading(false);
|
|
72
|
+
setIsLoadingMore(false);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!autoLoad)
|
|
76
|
+
return;
|
|
77
|
+
const controller = new AbortController();
|
|
78
|
+
void refresh({}, controller.signal);
|
|
79
|
+
return () => controller.abort();
|
|
80
|
+
}, [autoLoad, enabled, refresh]);
|
|
81
|
+
return useMemo(() => ({
|
|
82
|
+
files,
|
|
83
|
+
nextPageToken,
|
|
84
|
+
isLoading,
|
|
85
|
+
isLoadingMore,
|
|
86
|
+
error,
|
|
87
|
+
refresh,
|
|
88
|
+
loadMore,
|
|
89
|
+
}), [error, files, isLoading, isLoadingMore, loadMore, nextPageToken, refresh]);
|
|
90
|
+
}
|
package/dist/react/useRecords.js
CHANGED
|
@@ -72,7 +72,10 @@ export function useRecords({ client, podId, tableName, filters, sort, limit = 20
|
|
|
72
72
|
trimmedTableName,
|
|
73
73
|
]);
|
|
74
74
|
const loadMore = useCallback(async (overrides = {}) => {
|
|
75
|
-
|
|
75
|
+
const loadedCount = records.length;
|
|
76
|
+
const canLoadWithCursor = Boolean(nextPageToken);
|
|
77
|
+
const canLoadWithOffset = loadedCount < total;
|
|
78
|
+
if (!isEnabled || isLoading || isLoadingMore || (!canLoadWithCursor && !canLoadWithOffset)) {
|
|
76
79
|
return [];
|
|
77
80
|
}
|
|
78
81
|
setIsLoadingMore(true);
|
|
@@ -83,15 +86,15 @@ export function useRecords({ client, podId, tableName, filters, sort, limit = 20
|
|
|
83
86
|
filters: stableFilters,
|
|
84
87
|
sort: stableSort,
|
|
85
88
|
limit: overrides.limit ?? limit,
|
|
86
|
-
pageToken: nextPageToken,
|
|
87
|
-
offset: overrides.offset,
|
|
89
|
+
pageToken: overrides.pageToken ?? nextPageToken ?? undefined,
|
|
90
|
+
offset: overrides.offset ?? (nextPageToken ? undefined : (offset ?? 0) + loadedCount),
|
|
88
91
|
sortBy: overrides.sortBy ?? sortBy,
|
|
89
92
|
order: overrides.order ?? order,
|
|
90
93
|
params: overrides.params ?? stableParams,
|
|
91
94
|
});
|
|
92
95
|
const moreRecords = (response.items ?? []);
|
|
93
96
|
setRecords((previous) => [...previous, ...moreRecords]);
|
|
94
|
-
setTotal(response.total ??
|
|
97
|
+
setTotal(response.total ?? loadedCount + moreRecords.length);
|
|
95
98
|
setNextPageToken(response.next_page_token ?? null);
|
|
96
99
|
return moreRecords;
|
|
97
100
|
}
|
|
@@ -103,7 +106,7 @@ export function useRecords({ client, podId, tableName, filters, sort, limit = 20
|
|
|
103
106
|
finally {
|
|
104
107
|
setIsLoadingMore(false);
|
|
105
108
|
}
|
|
106
|
-
}, [client, isEnabled, isLoading, isLoadingMore, limit, nextPageToken, offset, order, podId, records.length, sortBy, stableFilters, stableParams, stableSort, trimmedTableName]);
|
|
109
|
+
}, [client, isEnabled, isLoading, isLoadingMore, limit, nextPageToken, offset, order, podId, records.length, sortBy, stableFilters, stableParams, stableSort, total, trimmedTableName]);
|
|
107
110
|
useEffect(() => {
|
|
108
111
|
if (!isEnabled) {
|
|
109
112
|
setRecords([]);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentResponse, AssistantResponse, AvailableModels, ColumnSchema, ConversationMessageResponse, ConversationResponse, CreateAgentRequest, CreateAssistantRequest, CreateTaskRequest, DatastoreQueryResponse, FlowRunEntity, FlowResponse, FunctionRunResponse, IconUploadResponse, OrganizationInvitationResponse, OrganizationMemberResponse, OrganizationResponse, PodConfigResponse, PodJoinRequestCreateResponse, PodMemberResponse, PodResponse, TableResponse, TaskMessageResponse, TaskResponse, UpdateAgentRequest, UpdateAssistantRequest, UserResponse } from "./openapi_client/index.js";
|
|
1
|
+
import type { AgentResponse, AssistantResponse, AvailableModels, ColumnSchema, ConversationMessageResponse, ConversationResponse, CreateAgentRequest, CreateAssistantRequest, CreateTaskRequest, DatastoreQueryResponse, DirectoryTreeNode, DirectoryTreeResponse, FileResponse, FileSearchResponse, FileSearchResultSchema, FlowRunEntity, FlowResponse, FunctionRunResponse, IconUploadResponse, OrganizationInvitationResponse, OrganizationMemberResponse, OrganizationResponse, PodConfigResponse, PodJoinRequestCreateResponse, PodMemberResponse, PodResponse, TableResponse, TaskMessageResponse, TaskResponse, UpdateAgentRequest, UpdateAssistantRequest, UserResponse } from "./openapi_client/index.js";
|
|
2
2
|
/** Public ergonomic types. */
|
|
3
3
|
export interface PageResult<T> {
|
|
4
4
|
items: T[];
|
|
@@ -55,6 +55,11 @@ export type Workflow = FlowResponse;
|
|
|
55
55
|
export type Table = TableResponse;
|
|
56
56
|
export type TableColumn = ColumnSchema;
|
|
57
57
|
export type DatastoreQueryResult = DatastoreQueryResponse;
|
|
58
|
+
export type DatastoreFile = FileResponse;
|
|
59
|
+
export type DatastoreFileSearchResponse = FileSearchResponse;
|
|
60
|
+
export type DatastoreFileSearchResult = FileSearchResultSchema;
|
|
61
|
+
export type DatastoreDirectoryTree = DirectoryTreeResponse;
|
|
62
|
+
export type DatastoreDirectoryTreeNode = DirectoryTreeNode;
|
|
58
63
|
export type Pod = PodResponse;
|
|
59
64
|
export type PodConfig = PodConfigResponse;
|
|
60
65
|
export type PodMember = PodMemberResponse;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lemma-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.33",
|
|
4
4
|
"description": "Official TypeScript SDK for Lemma pod-scoped APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"build:bundle": "tsc -p tsconfig.bundle.json && node ./scripts/build_browser_bundle.mjs",
|
|
46
46
|
"clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true, maxRetries: 10, retryDelay: 100 })\"",
|
|
47
47
|
"registry:build": "shadcn build ./registry.json -o ./public/r",
|
|
48
|
+
"registry:check": "npm run registry:build && node ./scripts/check_registry_blocks.mjs",
|
|
48
49
|
"prepublishOnly": "npm run build",
|
|
49
50
|
"release:check": "npm run build && npm_config_cache=.npm-cache npm pack --dry-run"
|
|
50
51
|
},
|