@lark-apaas/client-toolkit 1.2.10-alpha.35 → 1.2.10-alpha.36

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.
Files changed (36) hide show
  1. package/lib/apis/tools/generateImage.d.ts +1 -0
  2. package/lib/apis/tools/generateImage.js +1 -0
  3. package/lib/apis/tools/generateTextStream.d.ts +1 -0
  4. package/lib/apis/tools/generateTextStream.js +1 -0
  5. package/lib/components/AppContainer/index.js +5 -32
  6. package/lib/components/AppContainer/safety.js +2 -5
  7. package/lib/components/AppContainer/utils/getLarkUser.js +2 -4
  8. package/lib/components/AppContainer/utils/observable.js +1 -7
  9. package/lib/components/theme/index.d.ts +0 -1
  10. package/lib/components/theme/index.js +0 -1
  11. package/lib/components/theme/util.d.ts +0 -2
  12. package/lib/components/theme/util.js +0 -108
  13. package/lib/hooks/useLogout.js +17 -2
  14. package/lib/index.js +0 -7
  15. package/lib/integrations/dataloom.js +1 -1
  16. package/lib/integrations/generateImage.d.ts +1 -0
  17. package/lib/integrations/generateImage.js +47 -0
  18. package/lib/integrations/generateTextStream.d.ts +21 -0
  19. package/lib/integrations/generateTextStream.js +98 -0
  20. package/lib/integrations/services/DepartmentService.js +2 -3
  21. package/lib/integrations/services/UserProfileService.js +2 -3
  22. package/lib/integrations/services/UserService.js +3 -4
  23. package/lib/runtime/index.d.ts +1 -0
  24. package/lib/runtime/index.js +1 -0
  25. package/lib/runtime/react-devtools-hook.d.ts +19 -0
  26. package/lib/runtime/react-devtools-hook.js +20 -0
  27. package/lib/utils/getAppId.d.ts +4 -2
  28. package/lib/utils/getAppId.js +9 -2
  29. package/lib/utils/getInitialInfo.js +2 -4
  30. package/lib/utils/getUserProfile.js +12 -4
  31. package/lib/utils/scopedStorage.js +1 -1
  32. package/package.json +5 -5
  33. package/lib/components/theme/ui-config.d.ts +0 -1
  34. package/lib/components/theme/ui-config.js +0 -2
  35. package/lib/utils/apiPath.d.ts +0 -5
  36. package/lib/utils/apiPath.js +0 -5
@@ -0,0 +1 @@
1
+ export * from '../../integrations/generateImage';
@@ -0,0 +1 @@
1
+ export * from "../../integrations/generateImage.js";
@@ -0,0 +1 @@
1
+ export * from '../../integrations/generateTextStream';
@@ -0,0 +1 @@
1
+ export * from "../../integrations/generateTextStream.js";
@@ -4,16 +4,13 @@ import { ConfigProvider } from "antd";
4
4
  import { MiaodaInspector } from "@lark-apaas/miaoda-inspector";
5
5
  import zh_CN from "antd/locale/zh_CN";
6
6
  import IframeBridge from "./IframeBridge.js";
7
- import { defaultUIConfig } from "../theme/ui-config.js";
8
7
  import { Toaster } from "./sonner.js";
9
8
  import { PageHoc } from "./PageHoc.js";
10
- import { findValueByPixel, generateTailwindRadiusToken, themeColorTokenMap, themeMetaOptions } from "../theme/index.js";
11
9
  import { reportTeaEvent } from "./utils/tea.js";
12
10
  import { useAppInfo } from "../../hooks/index.js";
13
11
  import { TrackKey } from "../../types/tea.js";
14
12
  import safety from "./safety.js";
15
13
  import { getAppId } from "../../utils/getAppId.js";
16
- import { isNewPathEnabled } from "../../utils/apiPath.js";
17
14
  import QueryProvider from "../QueryProvider/index.js";
18
15
  import { AuthProvider } from "@lark-apaas/auth-sdk";
19
16
  import "../../runtime/index.js";
@@ -28,19 +25,8 @@ const readCssVarColor = (varName, fallback)=>{
28
25
  }
29
26
  };
30
27
  const App = (props)=>{
31
- const { themeMeta = {}, enableAuth } = props;
28
+ const { enableAuth } = props;
32
29
  useAppInfo();
33
- const { rem } = findValueByPixel(themeMetaOptions.themeRadius, themeMeta.borderRadius) || {
34
- rem: '0.625'
35
- };
36
- const radiusToken = generateTailwindRadiusToken(Number(rem));
37
- const themeToken = {
38
- ...defaultUIConfig,
39
- common: {
40
- ...defaultUIConfig.common,
41
- borderRadius: radiusToken
42
- }
43
- };
44
30
  useEffect(()=>{
45
31
  if (isMiaodaPreview) fetch(`${location.origin}/ai/api/feida_preview/csrf`).then(()=>{
46
32
  setTimeout(()=>{
@@ -53,31 +39,19 @@ const App = (props)=>{
53
39
  if ('production' === process.env.NODE_ENV) reportTeaEvent({
54
40
  trackKey: TrackKey.VIEW,
55
41
  trackParams: {
56
- artifact_uid: getAppId(),
42
+ artifact_uid: getAppId(window.location.pathname),
57
43
  agent_id: 'agent_miaoda',
58
44
  url: window.location.href
59
45
  }
60
46
  });
61
47
  }, []);
62
- const appId = getAppId();
63
- const permissionApiUrl = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/permissions/roles` : `/spark/app/${appId}/runtime/api/v1/permissions/roles`;
64
48
  return /*#__PURE__*/ jsxs(AuthProvider, {
65
49
  config: {
66
- enable: enableAuth,
67
- permissionApi: {
68
- url: permissionApiUrl
69
- }
50
+ enable: enableAuth
70
51
  },
71
52
  children: [
72
53
  /*#__PURE__*/ jsx(Toaster, {}),
73
- 'production' !== process.env.NODE_ENV && /*#__PURE__*/ jsx(MiaodaInspector, {
74
- theme: {
75
- themeMetaOptions: themeMetaOptions,
76
- themeColorTokenMap: themeColorTokenMap,
77
- themeToken
78
- },
79
- cwd: process.env.CWD || ''
80
- }),
54
+ 'production' !== process.env.NODE_ENV && /*#__PURE__*/ jsx(MiaodaInspector, {}),
81
55
  'production' !== process.env.NODE_ENV && /*#__PURE__*/ jsx(IframeBridge, {}),
82
56
  /*#__PURE__*/ jsx(PageHoc, {
83
57
  children: props.children
@@ -86,7 +60,7 @@ const App = (props)=>{
86
60
  });
87
61
  };
88
62
  const AppContainer_AppContainer = (props)=>{
89
- const { children, ...rest } = props;
63
+ const { children } = props;
90
64
  const [cssColors, setCssColors] = useState(()=>({
91
65
  background: readCssVarColor('--background'),
92
66
  destructive: readCssVarColor('--destructive'),
@@ -214,7 +188,6 @@ const AppContainer_AppContainer = (props)=>{
214
188
  }
215
189
  },
216
190
  children: /*#__PURE__*/ jsx(App, {
217
- themeMeta: props.themeMeta,
218
191
  enableAuth: props.enableAuth,
219
192
  children: children
220
193
  })
@@ -3,12 +3,11 @@ import { useEffect, useRef, useState } from "react";
3
3
  import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
4
4
  import { getCsrfToken } from "../../utils/getCsrfToken.js";
5
5
  import { getAppId } from "../../utils/getAppId.js";
6
- import { isNewPathEnabled } from "../../utils/apiPath.js";
7
6
  import { useIsMobile } from "../../hooks/index.js";
8
7
  import { X } from "lucide-react";
9
8
  import { Sheet, SheetContent, SheetTrigger } from "../ui/drawer.js";
10
9
  const Component = ()=>{
11
- const HasClosedKey = `miaoda-creatByMiaoda-has-closed-${getAppId()}`;
10
+ const HasClosedKey = `miaoda-creatByMiaoda-has-closed-${getAppId(window.location.pathname)}`;
12
11
  const [visible, setVisible] = useState(!window.localStorage?.getItem(HasClosedKey));
13
12
  const [open, setOpen] = useState(false);
14
13
  const isMobile = useIsMobile();
@@ -16,9 +15,7 @@ const Component = ()=>{
16
15
  const [isInternetVisible, setIsInternetVisible] = useState(false);
17
16
  const timeoutRef = useRef(null);
18
17
  useEffect(()=>{
19
- const appId = getAppId();
20
- const tenantInfoUrl = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/tenant_info` : `/spark/b/${appId}/tenant_info`;
21
- fetch(tenantInfoUrl, {
18
+ fetch(`/spark/b/${getAppId(window.location.pathname)}/tenant_info`, {
22
19
  headers: {
23
20
  'X-Suda-Csrf-Token': getCsrfToken()
24
21
  }
@@ -1,15 +1,13 @@
1
1
  import { getAppId } from "../../../utils/getAppId.js";
2
2
  import { getCsrfToken } from "../../../utils/getCsrfToken.js";
3
- import { isNewPathEnabled } from "../../../utils/apiPath.js";
4
3
  async function getLarkUserInfo() {
5
- const appId = getAppId();
4
+ const appId = getAppId(window.location.pathname);
6
5
  if (!appId) return {
7
6
  code: 1,
8
7
  msg: 'appId is required',
9
8
  data: {}
10
9
  };
11
- const url = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/lark/user_info` : `/spark/b/${appId}/lark/user_info`;
12
- const response = await fetch(url, {
10
+ const response = await fetch(`/spark/b/${appId}/lark/user_info`, {
13
11
  headers: {
14
12
  'X-Suda-Csrf-Token': getCsrfToken()
15
13
  }
@@ -1,17 +1,11 @@
1
1
  import { AppEnv, observable } from "@lark-apaas/observable-web";
2
- import { isNewPathEnabled } from "../../../utils/apiPath.js";
3
2
  const initObservable = ()=>{
4
3
  try {
5
4
  const appId = window.appId;
6
5
  observable.start({
7
6
  serviceName: "app",
8
7
  env: 'development' === process.env.NODE_ENV ? AppEnv.Dev : AppEnv.Prod,
9
- collectorUrl: isNewPathEnabled() ? {
10
- log: `/app/${appId}/__runtime__/api/v1/observability/logs/collect`,
11
- trace: `/app/${appId}/__runtime__/api/v1/observability/traces/collect`,
12
- metric: `/app/${appId}/__runtime__/api/v1/observability/metrics/collect`,
13
- time: `/app/${appId}/__runtime__/api/v1/observability/current_server_timestamp`
14
- } : {
8
+ collectorUrl: {
15
9
  log: `/spark/app/${appId}/runtime/api/v1/observability/logs/collect`,
16
10
  trace: `/spark/app/${appId}/runtime/api/v1/observability/traces/collect`,
17
11
  metric: `/spark/app/${appId}/runtime/api/v1/observability/metrics/collect`,
@@ -1,3 +1,2 @@
1
1
  export * from './constants';
2
2
  export * from './util';
3
- export * from './ui-config';
@@ -1,3 +1,2 @@
1
1
  export * from "./constants.js";
2
2
  export * from "./util.js";
3
- export * from "./ui-config.js";
@@ -1,5 +1,4 @@
1
1
  import { ITheme } from "../../types";
2
- import { UIComponentConfig } from "./ui-config";
3
2
  export interface IBaseThemeProviderProps {
4
3
  defaultTheme?: ITheme;
5
4
  themeMeta?: Partial<IThemeTokenMeta>;
@@ -18,4 +17,3 @@ export interface IThemeTokenMeta {
18
17
  */
19
18
  spacing: number;
20
19
  }
21
- export declare const generateTailwindRadiusToken: (radiusRemValue: number) => UIComponentConfig;
@@ -1,108 +0,0 @@
1
- const generateTailwindRadiusToken = (radiusRemValue)=>{
2
- try {
3
- const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
4
- const radiusPx = radiusRemValue * rootFontSize;
5
- const tempElement = document.createElement('div');
6
- tempElement.style.position = 'absolute';
7
- tempElement.style.visibility = 'hidden';
8
- document.body.appendChild(tempElement);
9
- tempElement.style.borderRadius = `${radiusPx}px`;
10
- const computed = getComputedStyle(tempElement).borderRadius;
11
- document.body.removeChild(tempElement);
12
- if (computed && 'auto' !== computed && 'initial' !== computed) return {
13
- type: 'select',
14
- options: [
15
- {
16
- value: 'rounded-none',
17
- label: 'none(0px)',
18
- rawValue: '0'
19
- },
20
- {
21
- value: 'rounded-sm',
22
- label: `sm (${Math.max(0, radiusPx - 4)}px)`,
23
- rawValue: `${Math.max(0, radiusPx - 4)}`
24
- },
25
- {
26
- value: 'rounded',
27
- label: 's (4px)',
28
- rawValue: '4'
29
- },
30
- {
31
- value: 'rounded-md',
32
- label: `m (${Math.max(0, radiusPx - 2)}px)`,
33
- rawValue: `${Math.max(0, radiusPx - 2)}`
34
- },
35
- {
36
- value: 'rounded-lg',
37
- label: `l (${radiusPx}px)`,
38
- rawValue: `${radiusPx}`
39
- },
40
- {
41
- value: 'rounded-xl',
42
- label: `xl (${radiusPx + 4}px)`,
43
- rawValue: `${radiusPx + 4}`
44
- },
45
- {
46
- value: 'rounded-2xl',
47
- label: '2xl (16px)',
48
- rawValue: '16'
49
- },
50
- {
51
- value: 'rounded-full',
52
- label: 'Full',
53
- rawValue: '9999'
54
- }
55
- ]
56
- };
57
- throw new Error('Browser calculation validation failed');
58
- } catch (error) {
59
- console.warn('Failed to get computed values from browser, falling back to default calculation:', error);
60
- const radiusPx = 16 * radiusRemValue;
61
- return {
62
- type: 'select',
63
- options: [
64
- {
65
- value: 'rounded-none',
66
- label: 'none(0px)',
67
- rawValue: '0'
68
- },
69
- {
70
- value: 'rounded-sm',
71
- label: `sm (${Math.max(0, radiusPx - 4)}px)`,
72
- rawValue: `${Math.max(0, radiusPx - 4)}`
73
- },
74
- {
75
- value: 'rounded',
76
- label: 's (4px)',
77
- rawValue: '4'
78
- },
79
- {
80
- value: 'rounded-md',
81
- label: `m (${Math.max(0, radiusPx - 2)}px)`,
82
- rawValue: `${Math.max(0, radiusPx - 2)}`
83
- },
84
- {
85
- value: 'rounded-lg',
86
- label: `l (${radiusPx}px)`,
87
- rawValue: `${radiusPx}`
88
- },
89
- {
90
- value: 'rounded-xl',
91
- label: `xl (${radiusPx + 4}px)`,
92
- rawValue: `${radiusPx + 4}`
93
- },
94
- {
95
- value: 'rounded-2xl',
96
- label: '2xl (16px)',
97
- rawValue: '16'
98
- },
99
- {
100
- value: 'rounded-full',
101
- label: 'Full',
102
- rawValue: '9999'
103
- }
104
- ]
105
- };
106
- }
107
- };
108
- export { generateTailwindRadiusToken };
@@ -1,13 +1,28 @@
1
1
  import { useState } from "react";
2
2
  import { getDataloom } from "../integrations/dataloom.js";
3
+ import { isSparkRuntime } from "../utils/utils.js";
3
4
  function useLogout() {
4
5
  const [isLoading, setIsLoading] = useState(false);
5
6
  async function handlerLogout() {
6
7
  if ('production' !== process.env.NODE_ENV) return void console.log('只有生产环境才执行登出');
8
+ if (isSparkRuntime()) {
9
+ setIsLoading(true);
10
+ try {
11
+ const dataloom = await getDataloom();
12
+ await dataloom.service.session.signOut();
13
+ } catch (error) {
14
+ console.error('登出失败', error);
15
+ } finally{
16
+ setIsLoading(false);
17
+ }
18
+ return;
19
+ }
7
20
  setIsLoading(true);
8
21
  try {
9
- const dataloom = await getDataloom();
10
- await dataloom.service.session.signOut();
22
+ await fetch('/ai/api/ui/page/logout', {
23
+ method: 'GET'
24
+ });
25
+ window.location.reload();
11
26
  } catch (error) {
12
27
  console.error('登出失败', error);
13
28
  } finally{
package/lib/index.js CHANGED
@@ -1,17 +1,10 @@
1
1
  import { createClient } from "@lark-apaas/client-capability";
2
2
  import { normalizeBasePath } from "./utils/utils.js";
3
- import { getAppId } from "./utils/getAppId.js";
4
- import { isNewPathEnabled } from "./utils/apiPath.js";
5
3
  import { logger } from "./logger/index.js";
6
4
  import { showToast } from "./components/ui/toast.js";
7
5
  import { version } from "../package.json";
8
- const _appId = getAppId();
9
- const _acquireUploadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_upload_url` : "/af/api/v1/studio/plugins/tmp_files/acquire_upload_url";
10
- const _acquireDownloadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_download_url` : "/af/api/v1/studio/plugins/tmp_files/acquire_download_url";
11
6
  const capabilityClient = createClient({
12
7
  baseURL: normalizeBasePath(process.env.CLIENT_BASE_PATH),
13
- acquireUploadUrl: _acquireUploadUrl,
14
- acquireDownloadUrl: _acquireDownloadUrl,
15
8
  fetchOptions: {
16
9
  headers: {
17
10
  'X-Suda-Csrf-Token': window.csrfToken ?? ''
@@ -7,7 +7,7 @@ const createDataLoomClient = (url, pat)=>{
7
7
  baseUrl: '',
8
8
  workspace: ''
9
9
  };
10
- const appId = getAppId();
10
+ const appId = getAppId(window.location.pathname);
11
11
  return createClient(baseUrl, pat, workspace, {
12
12
  global: {
13
13
  enableDataloomLog: 'production' !== process.env.NODE_ENV,
@@ -0,0 +1 @@
1
+ export declare function generateImage(prompt: string, size?: string, headers?: Record<string, string>): Promise<any>;
@@ -0,0 +1,47 @@
1
+ import { getAppId } from "../utils/getAppId.js";
2
+ import { getCsrfToken } from "../utils/getCsrfToken.js";
3
+ import { getEnvPath } from "../utils/getEnvPath.js";
4
+ import { isSparkRuntime } from "../utils/utils.js";
5
+ async function generateImage(prompt, size = '1024x1024', headers = {}) {
6
+ const appId = getAppId(window.location.pathname);
7
+ if (!appId) return {
8
+ code: 1,
9
+ msg: 'appId is required',
10
+ data: {}
11
+ };
12
+ const defaultHeaders = {
13
+ 'Content-Type': 'application/json'
14
+ };
15
+ const mergedHeaders = {
16
+ ...defaultHeaders,
17
+ ...headers,
18
+ 'X-Kunlun-Token': window.token,
19
+ 'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
20
+ 'x-lgw-csrf-token': window.lgw_csrf_token,
21
+ ...window.CSRF_HEADERS || {}
22
+ };
23
+ if (isSparkRuntime()) {
24
+ mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
25
+ const response = await fetch(`${window.location.origin}/spark/b/${appId}/text2image`, {
26
+ method: 'POST',
27
+ headers: mergedHeaders,
28
+ credentials: 'include',
29
+ body: JSON.stringify({
30
+ prompt,
31
+ size
32
+ })
33
+ });
34
+ return await response.json();
35
+ }
36
+ const response = await fetch(`${window.location.origin}/ai/api/${getEnvPath()}/v1/apps/${appId}/text2image`, {
37
+ method: 'POST',
38
+ headers: mergedHeaders,
39
+ credentials: 'include',
40
+ body: JSON.stringify({
41
+ prompt,
42
+ size
43
+ })
44
+ });
45
+ return await response.json();
46
+ }
47
+ export { generateImage };
@@ -0,0 +1,21 @@
1
+ interface GenerateTextOptions {
2
+ text: string;
3
+ thinking_type?: 'enabled' | 'disabled';
4
+ headers?: Record<string, string>;
5
+ }
6
+ interface GenerateTextResult {
7
+ content: string;
8
+ reasoning_content: string;
9
+ success: boolean;
10
+ error?: string;
11
+ }
12
+ /**
13
+ * 文生文 - 流式版本
14
+ * 支持实时接收生成内容的回调
15
+ */
16
+ export declare function generateTextStream(options: GenerateTextOptions, onChunk?: (chunk: {
17
+ content: string;
18
+ reasoning_content: string;
19
+ finished: boolean;
20
+ }) => void): Promise<GenerateTextResult>;
21
+ export {};
@@ -0,0 +1,98 @@
1
+ import { getAppId } from "../utils/getAppId.js";
2
+ import { getCsrfToken } from "../utils/getCsrfToken.js";
3
+ import { getEnvPath } from "../utils/getEnvPath.js";
4
+ import { isSparkRuntime } from "../utils/utils.js";
5
+ async function generateTextStream(options, onChunk) {
6
+ const { text, thinking_type = 'disabled', headers = {} } = options;
7
+ const appId = getAppId(window.location.pathname);
8
+ if (!appId) return {
9
+ content: '',
10
+ reasoning_content: '',
11
+ success: false,
12
+ error: 'appId is required'
13
+ };
14
+ try {
15
+ const mergedHeaders = {
16
+ 'Content-Type': 'application/json',
17
+ ...headers,
18
+ 'X-Kunlun-Token': window.token,
19
+ 'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
20
+ 'x-lgw-csrf-token': window.lgw_csrf_token,
21
+ ...window.CSRF_HEADERS || {}
22
+ };
23
+ let response;
24
+ if (isSparkRuntime()) {
25
+ mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
26
+ response = await fetch(`${window.location.origin}/spark/b/${appId}/text/generate`, {
27
+ method: 'POST',
28
+ headers: mergedHeaders,
29
+ credentials: 'include',
30
+ body: JSON.stringify({
31
+ text,
32
+ thinking_type
33
+ })
34
+ });
35
+ } else response = await fetch(`${window.location.origin}/ai/api/${getEnvPath()}/v1/apps/${appId}/text/generate`, {
36
+ method: 'POST',
37
+ headers: mergedHeaders,
38
+ credentials: 'include',
39
+ body: JSON.stringify({
40
+ text,
41
+ thinking_type
42
+ })
43
+ });
44
+ if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
45
+ const reader = response.body?.getReader();
46
+ if (!reader) throw new Error('无法获取响应流');
47
+ let fullContent = '';
48
+ let fullReasoningContent = '';
49
+ const decoder = new TextDecoder();
50
+ while(true){
51
+ const { done, value } = await reader.read();
52
+ if (done) break;
53
+ const chunk = decoder.decode(value, {
54
+ stream: true
55
+ });
56
+ const lines = chunk.split('\n').filter((line)=>line.trim());
57
+ for (const line of lines)if (line.startsWith('data: ')) {
58
+ const jsonStr = line.slice(6);
59
+ try {
60
+ const data = JSON.parse(jsonStr);
61
+ if (0 !== data.code) return {
62
+ content: '',
63
+ reasoning_content: '',
64
+ success: false,
65
+ error: data.msg || '生成失败'
66
+ };
67
+ if (data.data.content) fullContent += data.data.content;
68
+ if (data.data.reasoning_content) fullReasoningContent += data.data.reasoning_content;
69
+ if (onChunk) onChunk({
70
+ content: data.data.content || '',
71
+ reasoning_content: data.data.reasoning_content || '',
72
+ finished: data.finished
73
+ });
74
+ if (data.finished) return {
75
+ content: fullContent,
76
+ reasoning_content: fullReasoningContent,
77
+ success: true
78
+ };
79
+ } catch (parseError) {
80
+ console.error(`解析JSON失败: ${jsonStr}`);
81
+ }
82
+ }
83
+ }
84
+ return {
85
+ content: fullContent,
86
+ reasoning_content: fullReasoningContent,
87
+ success: true
88
+ };
89
+ } catch (error) {
90
+ return {
91
+ content: '',
92
+ reasoning_content: '',
93
+ success: false,
94
+ error: error instanceof Error ? error.message : '未知错误'
95
+ };
96
+ }
97
+ }
98
+ export { generateTextStream };
@@ -1,8 +1,7 @@
1
1
  import { getAppId } from "../../utils/getAppId.js";
2
- import { isNewPathEnabled } from "../../utils/apiPath.js";
3
2
  const DEFAULT_CONFIG = {
4
- getAppId: ()=>getAppId(),
5
- searchDepartmentUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/search_department` : `/af/app/${appId}/runtime/api/v1/account/search_department`
3
+ getAppId: ()=>getAppId(window.location.pathname),
4
+ searchDepartmentUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/search_department`
6
5
  };
7
6
  class DepartmentService {
8
7
  config;
@@ -1,12 +1,11 @@
1
1
  import { getAppId } from "../../utils/getAppId.js";
2
- import { isNewPathEnabled } from "../../utils/apiPath.js";
3
2
  const CDN_HOST = 'https://lf3-static.bytednsdoc.com';
4
3
  function getAssetsUrl(path) {
5
4
  return `${CDN_HOST}${path}`;
6
5
  }
7
6
  const DEFAULT_CONFIG = {
8
- getAppId: ()=>getAppId(),
9
- userProfileUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/user_profile` : `/af/app/${appId}/runtime/api/v1/account/user_profile`
7
+ getAppId: ()=>getAppId(window.location.pathname),
8
+ userProfileUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/user_profile`
10
9
  };
11
10
  class UserProfileService {
12
11
  config;
@@ -1,9 +1,8 @@
1
1
  import { getAppId } from "../../utils/getAppId.js";
2
- import { isNewPathEnabled } from "../../utils/apiPath.js";
3
2
  const DEFAULT_CONFIG = {
4
- getAppId: ()=>getAppId(),
5
- searchUserUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/search_user` : `/af/app/${appId}/runtime/api/v1/account/search_user`,
6
- listUsersUrl: (appId)=>isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/account/list_users` : `/af/app/${appId}/runtime/api/v1/account/list_users`
3
+ getAppId: ()=>getAppId(window.location.pathname),
4
+ searchUserUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/search_user`,
5
+ listUsersUrl: (appId)=>`/af/app/${appId}/runtime/api/v1/account/list_users`
7
6
  };
8
7
  class UserService {
9
8
  config;
@@ -15,6 +15,7 @@
15
15
  * - 使用 __FULLSTACK_RUNTIME_INITIALIZED__ 标志位防止重复初始化
16
16
  * - 旧版 AppContainer 和新版 runtime 可以共存
17
17
  */
18
+ import './react-devtools-hook';
18
19
  import './styles';
19
20
  declare global {
20
21
  interface Window {
@@ -1,3 +1,4 @@
1
+ import "./react-devtools-hook.js";
1
2
  import "./styles.js";
2
3
  import { registerDayjsPlugins } from "./dayjs.js";
3
4
  import { initAxiosConfig } from "./axios.js";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Inject minimal __REACT_DEVTOOLS_GLOBAL_HOOK__ before React loads.
3
+ * React checks for this hook during module initialization and registers its
4
+ * renderer via hook.inject(). This gives us access to renderer.overrideProps()
5
+ * for live component prop modification in the inspector.
6
+ *
7
+ * Must execute before React's module-level code runs.
8
+ *
9
+ * When react-refresh-runtime runs first (as an rspack runtime module),
10
+ * it may create __REACT_DEVTOOLS_GLOBAL_HOOK__ with an inject() that
11
+ * doesn't populate the renderers Map. We patch the existing hook to
12
+ * ensure renderers are always tracked.
13
+ */
14
+ export {};
15
+ declare global {
16
+ interface Window {
17
+ __REACT_DEVTOOLS_GLOBAL_HOOK__?: any;
18
+ }
19
+ }
@@ -0,0 +1,20 @@
1
+ if ('undefined' != typeof window) if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
2
+ const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
3
+ if (!(hook.renderers instanceof Map)) hook.renderers = new Map();
4
+ const originalInject = 'function' == typeof hook.inject ? hook.inject.bind(hook) : null;
5
+ hook.inject = function(renderer) {
6
+ const id = originalInject ? originalInject(renderer) : hook.renderers.size + 1;
7
+ if (null != id && !hook.renderers.has(id)) hook.renderers.set(id, renderer);
8
+ return id;
9
+ };
10
+ } else window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
11
+ renderers: new Map(),
12
+ supportsFiber: true,
13
+ inject (renderer) {
14
+ const id = this.renderers.size + 1;
15
+ this.renderers.set(id, renderer);
16
+ return id;
17
+ },
18
+ onCommitFiberRoot () {},
19
+ onCommitFiberUnmount () {}
20
+ };
@@ -1,4 +1,6 @@
1
1
  /**
2
- * 获取应用 ID
2
+ * 提取固定前缀后的第一个目录名
3
+ * @param {string} path - 输入路径字符串
4
+ * @returns {string|null} - 提取的目录名或null
3
5
  */
4
- export declare function getAppId(): string | null;
6
+ export declare function getAppId(path: string): string | null;
@@ -1,5 +1,12 @@
1
- function getAppId() {
1
+ function getAppId(path) {
2
+ if (window.MIAODA_APP_ID) return window.MIAODA_APP_ID;
3
+ let prefix;
4
+ prefix = path.includes('/ai/feida/runtime/') ? '/ai/feida/runtime/' : path.includes('/spark/r/') ? '/spark/r/' : '/ai/miaoda/';
2
5
  const windowAppId = window.appId || null;
3
- return windowAppId;
6
+ if (!path.startsWith(prefix)) return windowAppId;
7
+ const remainder = path.substring(prefix.length);
8
+ const nextSlashIndex = remainder.indexOf('/');
9
+ if (-1 === nextSlashIndex) return remainder || windowAppId;
10
+ return remainder.substring(0, nextSlashIndex) || windowAppId;
4
11
  }
5
12
  export { getAppId };
@@ -1,6 +1,5 @@
1
1
  import { getAppId } from "./getAppId.js";
2
2
  import { getCsrfToken } from "./getCsrfToken.js";
3
- import { isNewPathEnabled } from "./apiPath.js";
4
3
  async function getAppPublished() {
5
4
  try {
6
5
  const headers = {
@@ -9,9 +8,8 @@ async function getAppPublished() {
9
8
  'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
10
9
  'X-Suda-Csrf-Token': getCsrfToken()
11
10
  };
12
- const appId = getAppId();
13
- const path = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/get_published` : `/spark/b/${appId}/get_published`;
14
- const url = `${window.location.origin}${path}`;
11
+ const appId = getAppId(window.location.pathname) || window.appId;
12
+ const url = `${window.location.origin}/spark/b/${appId}/get_published`;
15
13
  const response = await fetch(url, {
16
14
  method: 'GET',
17
15
  headers,
@@ -1,8 +1,9 @@
1
1
  import { getAppId } from "./getAppId.js";
2
2
  import { getCsrfToken } from "./getCsrfToken.js";
3
- import { isNewPathEnabled } from "./apiPath.js";
3
+ import { getEnvPath } from "./getEnvPath.js";
4
+ import { isSparkRuntime } from "./utils.js";
4
5
  async function getUserProfile(request, headers = {}) {
5
- const appId = getAppId();
6
+ const appId = getAppId(window.location.pathname);
6
7
  if (!appId) return {
7
8
  code: 1,
8
9
  msg: 'appId is required',
@@ -14,10 +15,17 @@ async function getUserProfile(request, headers = {}) {
14
15
  const mergedHeaders = {
15
16
  ...defaultHeaders,
16
17
  ...headers,
18
+ 'X-Kunlun-Token': window.token,
19
+ 'x-miaoda-token': window.MIAODA_BUILTIN_TTT,
20
+ 'x-lgw-csrf-token': window.lgw_csrf_token,
17
21
  ...window.CSRF_HEADERS || {}
18
22
  };
19
- const endpoint = isNewPathEnabled() ? `/app/${appId}/__runtime__/api/v1/studio/user/profile` : `/spark/b/${appId}/user/profile`;
20
- mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
23
+ const envPath = getEnvPath();
24
+ let endpoint;
25
+ if (isSparkRuntime()) {
26
+ endpoint = `/spark/b/${appId}/user/profile`;
27
+ mergedHeaders['X-Suda-Csrf-Token'] = getCsrfToken();
28
+ } else endpoint = `/ai/api/${envPath}/v1/apps/${appId}/user/profile`;
21
29
  const response = await fetch(`${window.location.origin}${endpoint}`, {
22
30
  method: 'POST',
23
31
  headers: mergedHeaders,
@@ -1,6 +1,6 @@
1
1
  import { getAppId } from "./getAppId.js";
2
2
  function getPrefix() {
3
- const appId = getAppId();
3
+ const appId = getAppId(window.location.pathname);
4
4
  const namespace = appId || '__global__';
5
5
  return `__miaoda_${namespace}__:`;
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/client-toolkit",
3
- "version": "1.2.10-alpha.35",
3
+ "version": "1.2.10-alpha.36",
4
4
  "types": "./lib/index.d.ts",
5
5
  "main": "./lib/index.js",
6
6
  "files": [
@@ -93,10 +93,10 @@
93
93
  "dependencies": {
94
94
  "@ant-design/colors": "^7.2.1",
95
95
  "@ant-design/cssinjs": "^1.24.0",
96
- "@data-loom/js": "0.4.7",
97
- "@lark-apaas/auth-sdk": "0.1.0-alpha.52",
98
- "@lark-apaas/client-capability": "0.1.3-alpha.11",
99
- "@lark-apaas/miaoda-inspector": "^1.0.15",
96
+ "@data-loom/js": "0.4.6",
97
+ "@lark-apaas/auth-sdk": "^0.1.0",
98
+ "@lark-apaas/client-capability": "^0.1.4",
99
+ "@lark-apaas/miaoda-inspector": "1.0.14-alpha.18",
100
100
  "@lark-apaas/observable-web": "^1.0.1",
101
101
  "@radix-ui/react-avatar": "^1.1.10",
102
102
  "@radix-ui/react-popover": "^1.1.15",
@@ -1 +0,0 @@
1
- export { defaultUIConfig, type UIComponentConfig, } from '@lark-apaas/miaoda-inspector';
@@ -1,2 +0,0 @@
1
- import { defaultUIConfig } from "@lark-apaas/miaoda-inspector";
2
- export { defaultUIConfig };
@@ -1,5 +0,0 @@
1
- /**
2
- * 判断当前是否启用新的路径规范
3
- * 新路径规范:CLIENT_BASE_PATH 以 /app/:appId 格式开头
4
- */
5
- export declare function isNewPathEnabled(): boolean;
@@ -1,5 +0,0 @@
1
- function isNewPathEnabled() {
2
- const basePath = process.env.CLIENT_BASE_PATH || '/';
3
- return /^\/app\/[^/]/.test(basePath);
4
- }
5
- export { isNewPathEnabled };