@lobehub/lobehub 2.0.0-next.336 → 2.0.0-next.338

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 (40) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/changelog/v1.json +18 -0
  3. package/locales/en-US/setting.json +19 -0
  4. package/locales/zh-CN/auth.json +1 -0
  5. package/locales/zh-CN/setting.json +19 -0
  6. package/package.json +1 -1
  7. package/packages/builtin-tool-agent-builder/src/manifest.ts +0 -2
  8. package/packages/builtin-tool-memory/src/client/Render/AddPreferenceMemory/index.tsx +17 -0
  9. package/packages/builtin-tool-memory/src/client/Render/index.ts +2 -0
  10. package/packages/builtin-tool-memory/src/client/Streaming/AddPreferenceMemory/index.tsx +17 -0
  11. package/packages/builtin-tool-memory/src/client/Streaming/index.ts +4 -3
  12. package/packages/builtin-tool-memory/src/client/components/PreferenceMemoryCard.tsx +357 -0
  13. package/packages/builtin-tool-memory/src/client/components/index.ts +1 -0
  14. package/packages/builtin-tool-memory/src/executor/index.ts +3 -3
  15. package/packages/builtin-tool-memory/src/systemRole.ts +1 -0
  16. package/packages/database/src/models/userMemory/model.ts +1 -1
  17. package/packages/memory-user-memory/src/extractors/context.test.ts +0 -1
  18. package/packages/memory-user-memory/src/extractors/experience.test.ts +0 -1
  19. package/packages/memory-user-memory/src/extractors/identity.test.ts +0 -1
  20. package/packages/memory-user-memory/src/extractors/preference.test.ts +0 -1
  21. package/packages/memory-user-memory/src/schemas/context.ts +0 -2
  22. package/packages/memory-user-memory/src/schemas/experience.ts +0 -2
  23. package/packages/memory-user-memory/src/schemas/identity.ts +1 -2
  24. package/packages/memory-user-memory/src/schemas/preference.ts +0 -2
  25. package/packages/model-runtime/src/providers/google/index.ts +14 -14
  26. package/packages/model-runtime/src/providers/moonshot/index.ts +1 -1
  27. package/packages/model-runtime/src/providers/openai/index.ts +3 -3
  28. package/packages/types/src/discover/index.ts +1 -1
  29. package/src/app/[variants]/(main)/agent/cron/[cronId]/CronConfig.ts +16 -16
  30. package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobSaveButton.tsx +1 -1
  31. package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobScheduleConfig.tsx +5 -2
  32. package/src/app/[variants]/(main)/community/features/Search.tsx +1 -1
  33. package/src/app/[variants]/(mobile)/router/mobileRouter.config.tsx +27 -0
  34. package/src/app/[variants]/(mobile)/settings/_layout/Header.tsx +8 -17
  35. package/src/app/[variants]/(mobile)/settings/_layout/index.tsx +6 -1
  36. package/src/app/[variants]/(mobile)/settings/provider/_layout/index.tsx +22 -0
  37. package/src/locales/default/setting.ts +19 -0
  38. package/src/server/routers/lambda/userMemories/tools.ts +5 -4
  39. package/src/server/routers/lambda/userMemories.ts +4 -4
  40. package/src/server/services/memory/userMemory/extract.ts +3 -3
@@ -39,7 +39,6 @@ describe('ContextExtractor', () => {
39
39
  const memoryItem = memories.items;
40
40
 
41
41
  expect(memories.type).toBe('array');
42
- expect(memoryItem.properties.memoryLayer.const).toBe('context');
43
42
  // memoryCategory is a plain string in schema, not an enum
44
43
  expect(memoryItem.properties.memoryCategory.type).toBe('string');
45
44
  expect(memoryItem.properties.memoryType.enum).toEqual(memoryTypeValues);
@@ -39,7 +39,6 @@ describe('ExperienceExtractor', () => {
39
39
  const memoryItem = memories.items;
40
40
 
41
41
  expect(memories.type).toBe('array');
42
- expect(memoryItem.properties.memoryLayer.const).toBe('experience');
43
42
  // memoryCategory is a plain string in schema, not an enum
44
43
  expect(memoryItem.properties.memoryCategory.type).toBe('string');
45
44
  expect(memoryItem.properties.memoryType.enum).toEqual(memoryTypeValues);
@@ -46,7 +46,6 @@ describe('IdentityExtractor', () => {
46
46
  {
47
47
  details: null,
48
48
  memoryCategory: 'personal',
49
- memoryLayer: 'identity',
50
49
  memoryType: 'fact',
51
50
  summary: 'New identity summary',
52
51
  tags: ['tag'],
@@ -39,7 +39,6 @@ describe('PreferenceExtractor', () => {
39
39
  const memoryItem = memories.items;
40
40
 
41
41
  expect(memories.type).toBe('array');
42
- expect(memoryItem.properties.memoryLayer.const).toBe('preference');
43
42
  // memoryCategory is a plain string in schema, not an enum
44
43
  expect(memoryItem.properties.memoryCategory.type).toBe('string');
45
44
  expect(memoryItem.properties.memoryType.enum).toEqual(memoryTypeValues);
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  ContextStatusEnum,
3
- LayersEnum,
4
3
  UserMemoryContextObjectType,
5
4
  UserMemoryContextSubjectType,
6
5
  } from '@lobechat/types';
@@ -79,7 +78,6 @@ export const WithContextSchema = z.object({
79
78
  export const ContextMemoryItemSchema = z.object({
80
79
  details: z.string().describe('Optional detailed information'),
81
80
  memoryCategory: z.string().describe('Memory category'),
82
- memoryLayer: z.literal(LayersEnum.Context).describe('Memory layer'),
83
81
  memoryType: MemoryTypeSchema.describe('Memory type'),
84
82
  summary: z.string().describe('Concise overview of this specific memory'),
85
83
  tags: z.array(z.string()).describe('User defined tags that summarize the context facets'),
@@ -1,4 +1,3 @@
1
- import { LayersEnum } from '@lobechat/types';
2
1
  import { z } from 'zod';
3
2
 
4
3
  import { MemoryTypeSchema } from './common';
@@ -37,7 +36,6 @@ export const WithExperienceSchema = z.object({
37
36
  export const ExperienceMemoryItemSchema = z.object({
38
37
  details: z.string().describe('Optional detailed information'),
39
38
  memoryCategory: z.string().describe('Memory category'),
40
- memoryLayer: z.literal(LayersEnum.Experience).describe('Memory layer'),
41
39
  memoryType: MemoryTypeSchema.describe('Memory type'),
42
40
  summary: z.string().describe('Concise overview of this specific memory'),
43
41
  tags: z.array(z.string()).describe('Model generated tags that summarize the experience facets'),
@@ -1,4 +1,4 @@
1
- import { LayersEnum, MergeStrategyEnum } from '@lobechat/types';
1
+ import { MergeStrategyEnum } from '@lobechat/types';
2
2
  import { z } from 'zod';
3
3
 
4
4
  import { MemoryTypeSchema } from './common';
@@ -43,7 +43,6 @@ export const AddIdentityActionSchema = z
43
43
  .object({
44
44
  details: z.union([z.string(), z.null()]).describe('Optional detailed information'),
45
45
  memoryCategory: z.string().describe('Memory category'),
46
- memoryLayer: z.literal(LayersEnum.Identity).describe('Memory layer'),
47
46
  memoryType: MemoryTypeSchema.describe('Memory type'),
48
47
  summary: z.string().describe('Concise overview of this specific memory'),
49
48
  tags: z.array(z.string()).describe('Model generated tags that summarize the identity facets'),
@@ -1,4 +1,3 @@
1
- import { LayersEnum } from '@lobechat/types';
2
1
  import { z } from 'zod';
3
2
 
4
3
  import { MemoryTypeSchema } from './common';
@@ -66,7 +65,6 @@ export const WithPreferenceSchema = z.object({
66
65
  export const PreferenceMemoryItemSchema = z.object({
67
66
  details: z.string().describe('Optional detailed information'),
68
67
  memoryCategory: z.string().describe('Memory category'),
69
- memoryLayer: z.literal(LayersEnum.Preference).describe('Memory layer'),
70
68
  memoryType: MemoryTypeSchema.describe('Memory type'),
71
69
  summary: z.string().describe('Concise overview of this specific memory'),
72
70
  tags: z.array(z.string()).describe('Model generated tags that summarize the preference facets'),
@@ -242,7 +242,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
242
242
  } catch (e) {
243
243
  const err = e as Error;
244
244
 
245
- // 移除之前的静默处理,统一抛出错误
245
+ // Remove previous silent handling, throw error uniformly
246
246
  if (isAbortError(err)) {
247
247
  log('Request was cancelled');
248
248
  throw AgentRuntimeError.chat({
@@ -307,10 +307,10 @@ export class LobeGoogleAI implements LobeRuntimeAI {
307
307
  try {
308
308
  for await (const chunk of originalStream) {
309
309
  if (signal.aborted) {
310
- // 如果有数据已经输出,优雅地关闭流而不是抛出错误
310
+ // If data has already been output, close the stream gracefully instead of throwing an error
311
311
  if (hasData) {
312
312
  log('Stream cancelled gracefully, preserving existing output');
313
- // 显式注入取消错误,避免走 SSE 兜底 unexpected_end
313
+ // Explicitly inject cancellation error to avoid SSE fallback unexpected_end
314
314
  controller.enqueue({
315
315
  [LOBE_ERROR_KEY]: {
316
316
  body: { name: 'Stream cancelled', provider, reason: 'aborted' },
@@ -322,7 +322,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
322
322
  controller.close();
323
323
  return;
324
324
  } else {
325
- // 如果还没有数据输出,直接关闭流,由下游 SSE flush 阶段补发错误事件
325
+ // If no data has been output yet, close the stream directly and let downstream SSE emit error event during flush phase
326
326
  log('Stream cancelled before any output');
327
327
  controller.close();
328
328
  return;
@@ -335,12 +335,12 @@ export class LobeGoogleAI implements LobeRuntimeAI {
335
335
  } catch (error) {
336
336
  const err = error as Error;
337
337
 
338
- // 统一处理所有错误,包括 abort 错误
338
+ // Handle all errors uniformly, including abort errors
339
339
  if (isAbortError(err) || signal.aborted) {
340
- // 如果有数据已经输出,优雅地关闭流
340
+ // If data has already been output, close the stream gracefully
341
341
  if (hasData) {
342
342
  log('Stream reading cancelled gracefully, preserving existing output');
343
- // 显式注入取消错误,避免走 SSE 兜底 unexpected_end
343
+ // Explicitly inject cancellation error to avoid SSE fallback unexpected_end
344
344
  controller.enqueue({
345
345
  [LOBE_ERROR_KEY]: {
346
346
  body: { name: 'Stream cancelled', provider, reason: 'aborted' },
@@ -353,7 +353,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
353
353
  return;
354
354
  } else {
355
355
  log('Stream reading cancelled before any output');
356
- // 注入一个带详细错误信息的错误标记,交由下游 google-ai transformer 输出 error 事件
356
+ // Inject an error marker with detailed error information to be handled by downstream google-ai transformer to output error event
357
357
  controller.enqueue({
358
358
  [LOBE_ERROR_KEY]: {
359
359
  body: {
@@ -371,14 +371,14 @@ export class LobeGoogleAI implements LobeRuntimeAI {
371
371
  return;
372
372
  }
373
373
  } else {
374
- // 处理其他流解析错误
374
+ // Handle other stream parsing errors
375
375
  log('Stream parsing error: %O', err);
376
- // 尝试解析 Google 错误并提取 code/message/status
376
+ // Try to parse Google error and extract code/message/status
377
377
  const { error: parsedError, errorType } = parseGoogleErrorMessage(
378
378
  err?.message || String(err),
379
379
  );
380
380
 
381
- // 注入一个带详细错误信息的错误标记,交由下游 google-ai transformer 输出 error 事件
381
+ // Inject an error marker with detailed error information to be handled by downstream google-ai transformer to output error event
382
382
  controller.enqueue({
383
383
  [LOBE_ERROR_KEY]: {
384
384
  body: { ...parsedError, provider },
@@ -453,12 +453,12 @@ export class LobeGoogleAI implements LobeRuntimeAI {
453
453
  const hasUrlContext = payload?.urlContext;
454
454
  const hasFunctionTools = tools && tools.length > 0;
455
455
 
456
- // 如果已经有 tool_calls,优先处理 function declarations
456
+ // If tool_calls already exist, prioritize handling function declarations
457
457
  if (hasToolCalls && hasFunctionTools) {
458
458
  return buildGoogleTools(tools);
459
459
  }
460
460
 
461
- // 构建并返回搜索相关工具(搜索工具不能与 FunctionCall 同时使用)
461
+ // Build and return search-related tools (search tools cannot be used with FunctionCall simultaneously)
462
462
  if (hasUrlContext && hasSearch) {
463
463
  return [{ urlContext: {} }, { googleSearch: {} }];
464
464
  }
@@ -469,7 +469,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
469
469
  return [{ googleSearch: {} }];
470
470
  }
471
471
 
472
- // 最后考虑 function declarations
472
+ // Finally consider function declarations
473
473
  return buildGoogleTools(tools);
474
474
  }
475
475
  }
@@ -21,7 +21,7 @@ export const params = {
21
21
  const filteredMessages = messages.map((message: any) => {
22
22
  let normalizedMessage = message;
23
23
 
24
- // assistant 空消息添加一个空格 (#8418)
24
+ // Add a space for empty assistant messages (#8418)
25
25
  if (message.role === 'assistant' && (!message.content || message.content === '')) {
26
26
  normalizedMessage = { ...normalizedMessage, content: ' ' };
27
27
  }
@@ -16,10 +16,10 @@ export interface OpenAIModelCard {
16
16
  const prunePrefixes = ['o1', 'o3', 'o4', 'codex', 'computer-use', 'gpt-5'];
17
17
  const oaiSearchContextSize = process.env.OPENAI_SEARCH_CONTEXT_SIZE; // low, medium, high
18
18
  const enableServiceTierFlex = process.env.OPENAI_SERVICE_TIER_FLEX === '1';
19
- const flexSupportedModels = ['gpt-5', 'o3', 'o4-mini']; // Flex 处理仅适用于这些模型
19
+ const flexSupportedModels = ['gpt-5', 'o3', 'o4-mini']; // Flex tier is only available for these models
20
20
 
21
21
  const supportsFlexTier = (model: string) => {
22
- // 排除 o3-mini,其不支持 Flex 处理
22
+ // Exclude o3-mini, which does not support Flex tier
23
23
  if (model.startsWith('o3-mini')) {
24
24
  return false;
25
25
  }
@@ -74,7 +74,7 @@ export const params = {
74
74
  const modelsPage = (await client.models.list()) as any;
75
75
  const modelList: OpenAIModelCard[] = modelsPage.data;
76
76
 
77
- // 自动检测模型提供商并选择相应配置
77
+ // Automatically detect model provider and select corresponding configuration
78
78
  return processMultiProviderModelList(modelList, 'openai');
79
79
  },
80
80
  provider: ModelProvider.OpenAI,
@@ -10,7 +10,7 @@ export * from './plugins';
10
10
  export * from './providers';
11
11
 
12
12
  export enum DiscoverTab {
13
- Assistants = 'assistant',
13
+ Assistants = 'agent',
14
14
  GroupAgents = 'group_agent',
15
15
  Home = 'home',
16
16
  Mcp = 'mcp',
@@ -61,24 +61,24 @@ export const TIMEZONE_OPTIONS = [
61
61
 
62
62
  // Weekday options for checkbox group
63
63
  export const WEEKDAY_OPTIONS = [
64
- { label: 'Mon', value: 1 },
65
- { label: 'Tue', value: 2 },
66
- { label: 'Wed', value: 3 },
67
- { label: 'Thu', value: 4 },
68
- { label: 'Fri', value: 5 },
69
- { label: 'Sat', value: 6 },
70
- { label: 'Sun', value: 0 },
71
- ];
64
+ { label: 'agentCronJobs.weekday.short.monday', value: 1 },
65
+ { label: 'agentCronJobs.weekday.short.tuesday', value: 2 },
66
+ { label: 'agentCronJobs.weekday.short.wednesday', value: 3 },
67
+ { label: 'agentCronJobs.weekday.short.thursday', value: 4 },
68
+ { label: 'agentCronJobs.weekday.short.friday', value: 5 },
69
+ { label: 'agentCronJobs.weekday.short.saturday', value: 6 },
70
+ { label: 'agentCronJobs.weekday.short.sunday', value: 0 },
71
+ ] as const;
72
72
 
73
- // Weekday labels for display
73
+ // Weekday labels for display (i18n keys)
74
74
  export const WEEKDAY_LABELS: Record<number, string> = {
75
- 0: 'Sunday',
76
- 1: 'Monday',
77
- 2: 'Tuesday',
78
- 3: 'Wednesday',
79
- 4: 'Thursday',
80
- 5: 'Friday',
81
- 6: 'Saturday',
75
+ 0: 'agentCronJobs.weekday.sunday',
76
+ 1: 'agentCronJobs.weekday.monday',
77
+ 2: 'agentCronJobs.weekday.tuesday',
78
+ 3: 'agentCronJobs.weekday.wednesday',
79
+ 4: 'agentCronJobs.weekday.thursday',
80
+ 5: 'agentCronJobs.weekday.friday',
81
+ 6: 'agentCronJobs.weekday.saturday',
82
82
  };
83
83
 
84
84
  /**
@@ -22,7 +22,7 @@ const CronJobSaveButton = memo<CronJobSaveButtonProps>(({ disabled, loading, onS
22
22
  style={{ width: 200 }}
23
23
  type="primary"
24
24
  >
25
- {t('agentCronJobs.saveAsNew', { defaultValue: 'Save as New Scheduled Task' })}
25
+ {t('agentCronJobs.saveAsNew')}
26
26
  </Button>
27
27
  </Flexbox>
28
28
  );
@@ -81,7 +81,7 @@ const CronJobScheduleConfig = memo<CronJobScheduleConfigProps>(
81
81
  if (scheduleType === 'weekly' && weekdays.length > 0) {
82
82
  result.push({
83
83
  key: 'weekdays',
84
- label: weekdays.map((day) => WEEKDAY_LABELS[day]).join(', '),
84
+ label: weekdays.map((day) => t(WEEKDAY_LABELS[day] as any)).join(', '),
85
85
  });
86
86
  }
87
87
 
@@ -126,7 +126,10 @@ const CronJobScheduleConfig = memo<CronJobScheduleConfigProps>(
126
126
  maxTagCount="responsive"
127
127
  mode="multiple"
128
128
  onChange={(values: number[]) => onScheduleChange({ weekdays: values })}
129
- options={WEEKDAY_OPTIONS}
129
+ options={WEEKDAY_OPTIONS.map((opt) => ({
130
+ label: t(opt.label as any),
131
+ value: opt.value,
132
+ }))}
130
133
  placeholder="Select days"
131
134
  size="small"
132
135
  style={{ minWidth: 150 }}
@@ -33,7 +33,7 @@ const Search = memo<StoreSearchBarProps>(() => {
33
33
  const { q } = useQuery() as { q?: string };
34
34
  const router = useQueryRoute();
35
35
  const [word, setWord] = useState<string>(q || '');
36
- const activeTab = pathname.split('/')[2] || 'assistant';
36
+ const activeTab = pathname.split('/')[2] || 'agent';
37
37
  const handleSearch = (value: string) => {
38
38
  router.push(urlJoin('/community', activeTab), {
39
39
  query: value ? { q: value } : {},
@@ -7,6 +7,7 @@ import MobileChatLayout from '@/app/[variants]/(mobile)/chat/_layout';
7
7
  import MobileMeHomeLayout from '@/app/[variants]/(mobile)/me/(home)/layout';
8
8
  import MobileMeProfileLayout from '@/app/[variants]/(mobile)/me/profile/layout';
9
9
  import MobileMeSettingsLayout from '@/app/[variants]/(mobile)/me/settings/layout';
10
+ import MobileSettingsProviderLayout from '@/app/[variants]/(mobile)/settings/provider/_layout';
10
11
  import {
11
12
  BusinessMobileRoutesWithMainLayout,
12
13
  BusinessMobileRoutesWithoutMainLayout,
@@ -174,6 +175,32 @@ export const mobileRoutes: RouteConfig[] = [
174
175
  element: dynamicElement(() => import('../settings'), 'Mobile > Settings'),
175
176
  index: true,
176
177
  },
178
+ // Provider routes with nested structure
179
+ {
180
+ children: [
181
+ {
182
+ element: redirectElement('/settings/provider/all'),
183
+ index: true,
184
+ },
185
+ {
186
+ element: dynamicElement(
187
+ () => import('../../(main)/settings/provider').then((m) => m.ProviderDetailPage),
188
+ 'Mobile > Settings > Provider > Detail',
189
+ ),
190
+ path: ':providerId',
191
+ },
192
+ ],
193
+ element: <MobileSettingsProviderLayout />,
194
+ path: 'provider',
195
+ },
196
+ // Other settings tabs (common, agent, memory, tts, about, etc.)
197
+ {
198
+ element: dynamicElement(
199
+ () => import('../../(main)/settings'),
200
+ 'Mobile > Settings > Tab',
201
+ ),
202
+ path: ':tab',
203
+ },
177
204
  ],
178
205
  element: <MobileSettingsLayout />,
179
206
  errorElement: <ErrorBoundary resetPath="/settings" />,
@@ -4,10 +4,9 @@ import { Flexbox } from '@lobehub/ui';
4
4
  import { ChatHeader } from '@lobehub/ui/mobile';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
- import { useNavigate } from 'react-router-dom';
7
+ import { useNavigate, useParams } from 'react-router-dom';
8
8
 
9
9
  import { enableAuth } from '@/envs/auth';
10
- import { useQueryState } from '@/hooks/useQueryParam';
11
10
  import { useShowMobileWorkspace } from '@/hooks/useShowMobileWorkspace';
12
11
  import { type SettingsTabs } from '@/store/global/initialState';
13
12
  import { useSessionStore } from '@/store/session';
@@ -17,26 +16,16 @@ const Header = memo(() => {
17
16
  const { t } = useTranslation('setting');
18
17
  const showMobileWorkspace = useShowMobileWorkspace();
19
18
  const navigate = useNavigate();
20
- const [activeSettingsKey, setActiveSettingsKey] = useQueryState('active');
21
- const [providerName, setProviderName] = useQueryState('provider');
19
+ const params = useParams<{ providerId?: string, tab?: string; }>();
22
20
 
23
21
  const isSessionActive = useSessionStore((s) => !!s.activeId);
24
- const isProvider = providerName ? true : false;
22
+ const isProvider = params.providerId && params.providerId !== 'all';
25
23
 
26
24
  const handleBackClick = () => {
27
- console.log(
28
- 'gobackclick',
29
- isSessionActive,
30
- showMobileWorkspace,
31
- activeSettingsKey,
32
- providerName,
33
- );
34
25
  if (isSessionActive && showMobileWorkspace) {
35
26
  navigate('/agent');
36
- } else if (activeSettingsKey === 'provider' && providerName) {
37
- setProviderName(null);
38
- setActiveSettingsKey('provider');
39
- navigate(-1);
27
+ } else if (isProvider) {
28
+ navigate('/settings/provider/all');
40
29
  } else {
41
30
  navigate(enableAuth ? '/me/settings' : '/me');
42
31
  }
@@ -49,7 +38,9 @@ const Header = memo(() => {
49
38
  title={
50
39
  <Flexbox align={'center'} gap={8} horizontal>
51
40
  <span style={{ lineHeight: 1.2 }}>
52
- {isProvider ? providerName : t(`tab.${activeSettingsKey as SettingsTabs}` as any)}
41
+ {isProvider
42
+ ? params.providerId
43
+ : t(`tab.${(params.tab || 'all') as SettingsTabs}` as any)}
53
44
  </span>
54
45
  </Flexbox>
55
46
  }
@@ -3,7 +3,10 @@
3
3
  import { memo } from 'react';
4
4
  import { Outlet } from 'react-router-dom';
5
5
 
6
+ import MobileContentLayout from '@/components/server/MobileNavLayout';
7
+
6
8
  import SettingsContextProvider from '../../../(main)/settings/_layout/ContextProvider';
9
+ import Header from './Header';
7
10
 
8
11
  const MobileSettingsWrapper = memo(() => {
9
12
  return (
@@ -13,7 +16,9 @@ const MobileSettingsWrapper = memo(() => {
13
16
  showOpenAIProxyUrl: true,
14
17
  }}
15
18
  >
16
- <Outlet />
19
+ <MobileContentLayout header={<Header />}>
20
+ <Outlet />
21
+ </MobileContentLayout>
17
22
  </SettingsContextProvider>
18
23
  );
19
24
  });
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+
3
+ import { Outlet, useNavigate, useParams } from 'react-router-dom';
4
+
5
+ import ProviderMenu from '../../../../(main)/settings/provider/ProviderMenu';
6
+
7
+ const Layout = () => {
8
+ const params = useParams<{ providerId: string }>();
9
+ const navigate = useNavigate();
10
+
11
+ const handleProviderSelect = (providerKey: string) => {
12
+ navigate(`/settings/provider/${providerKey}`);
13
+ };
14
+
15
+ return params.providerId === 'all' ? (
16
+ <ProviderMenu mobile={true} onProviderSelect={handleProviderSelect} />
17
+ ) : (
18
+ <Outlet />
19
+ );
20
+ };
21
+
22
+ export default Layout;
@@ -36,7 +36,11 @@ export default {
36
36
  'agentCronJobs.noExecutionResults': 'No execution results',
37
37
  'agentCronJobs.remainingExecutions': 'Remaining: {{count}}',
38
38
  'agentCronJobs.save': 'Save',
39
+ 'agentCronJobs.saveAsNew': 'Save as New',
39
40
  'agentCronJobs.schedule': 'Schedule',
41
+ 'agentCronJobs.scheduleType.daily': 'Daily',
42
+ 'agentCronJobs.scheduleType.hourly': 'Hourly',
43
+ 'agentCronJobs.scheduleType.weekly': 'Weekly',
40
44
  'agentCronJobs.status.depleted': 'Depleted',
41
45
  'agentCronJobs.status.disabled': 'Disabled',
42
46
  'agentCronJobs.status.enabled': 'Enabled',
@@ -45,6 +49,20 @@ export default {
45
49
  'agentCronJobs.unlimited': 'Unlimited',
46
50
  'agentCronJobs.unnamedTask': 'Unnamed Task',
47
51
  'agentCronJobs.updateSuccess': 'Scheduled task updated successfully',
52
+ 'agentCronJobs.weekday.friday': 'Friday',
53
+ 'agentCronJobs.weekday.monday': 'Monday',
54
+ 'agentCronJobs.weekday.saturday': 'Saturday',
55
+ 'agentCronJobs.weekday.short.friday': 'Fri',
56
+ 'agentCronJobs.weekday.short.monday': 'Mon',
57
+ 'agentCronJobs.weekday.short.saturday': 'Sat',
58
+ 'agentCronJobs.weekday.short.sunday': 'Sun',
59
+ 'agentCronJobs.weekday.short.thursday': 'Thu',
60
+ 'agentCronJobs.weekday.short.tuesday': 'Tue',
61
+ 'agentCronJobs.weekday.short.wednesday': 'Wed',
62
+ 'agentCronJobs.weekday.sunday': 'Sunday',
63
+ 'agentCronJobs.weekday.thursday': 'Thursday',
64
+ 'agentCronJobs.weekday.tuesday': 'Tuesday',
65
+ 'agentCronJobs.weekday.wednesday': 'Wednesday',
48
66
  'agentCronJobs.weekdays': 'Weekdays',
49
67
  'agentInfoDescription.basic.avatar': 'Avatar',
50
68
  'agentInfoDescription.basic.description': 'Description',
@@ -622,6 +640,7 @@ export default {
622
640
  'systemAgent.translation.title': 'Message Translation Agent',
623
641
  'tab.about': 'About',
624
642
  'tab.agent': 'Agent Service',
643
+ 'tab.all': 'All',
625
644
  'tab.apikey': 'API Key Management',
626
645
  'tab.chatAppearance': 'Chat Appearance',
627
646
  'tab.common': 'Appearance',
@@ -6,6 +6,7 @@ import {
6
6
  RemoveIdentityActionSchema,
7
7
  UpdateIdentityActionSchema,
8
8
  } from '@lobechat/memory-user-memory';
9
+ import { LayersEnum } from '@lobechat/types';
9
10
 
10
11
  import {
11
12
  type IdentityEntryBasePayload,
@@ -51,7 +52,7 @@ export const toolsRouter = router({
51
52
  details: input.details || '',
52
53
  detailsEmbedding,
53
54
  memoryCategory: input.memoryCategory,
54
- memoryLayer: input.memoryLayer,
55
+ memoryLayer: LayersEnum.Context,
55
56
  memoryType: input.memoryType,
56
57
  summary: input.summary,
57
58
  summaryEmbedding,
@@ -107,7 +108,7 @@ export const toolsRouter = router({
107
108
  type: input.memoryType,
108
109
  },
109
110
  memoryCategory: input.memoryCategory,
110
- memoryLayer: input.memoryLayer,
111
+ memoryLayer: LayersEnum.Experience,
111
112
  memoryType: input.memoryType,
112
113
  summary: input.summary,
113
114
  summaryEmbedding,
@@ -162,7 +163,7 @@ export const toolsRouter = router({
162
163
  details: input.details,
163
164
  detailsVector1024: detailsEmbedding ?? null,
164
165
  memoryCategory: input.memoryCategory,
165
- memoryLayer: input.memoryLayer,
166
+ memoryLayer: LayersEnum.Identity,
166
167
  memoryType: input.memoryType,
167
168
  metadata: Object.keys(identityMetadata).length > 0 ? identityMetadata : undefined,
168
169
  summary: input.summary,
@@ -226,7 +227,7 @@ export const toolsRouter = router({
226
227
  details: input.details || '',
227
228
  detailsEmbedding,
228
229
  memoryCategory: input.memoryCategory,
229
- memoryLayer: input.memoryLayer,
230
+ memoryLayer: LayersEnum.Preference,
230
231
  memoryType: input.memoryType,
231
232
  preference: {
232
233
  conclusionDirectives: input.withPreference.conclusionDirectives || '',
@@ -774,7 +774,7 @@ export const userMemoriesRouter = router({
774
774
  details: input.details || '',
775
775
  detailsEmbedding,
776
776
  memoryCategory: input.memoryCategory,
777
- memoryLayer: input.memoryLayer,
777
+ memoryLayer: LayersEnum.Context,
778
778
  memoryType: input.memoryType,
779
779
  summary: input.summary,
780
780
  summaryEmbedding,
@@ -830,7 +830,7 @@ export const userMemoriesRouter = router({
830
830
  type: input.memoryType,
831
831
  },
832
832
  memoryCategory: input.memoryCategory,
833
- memoryLayer: input.memoryLayer,
833
+ memoryLayer: LayersEnum.Experience,
834
834
  memoryType: input.memoryType,
835
835
  summary: input.summary,
836
836
  summaryEmbedding,
@@ -885,7 +885,7 @@ export const userMemoriesRouter = router({
885
885
  details: input.details,
886
886
  detailsVector1024: detailsEmbedding ?? null,
887
887
  memoryCategory: input.memoryCategory,
888
- memoryLayer: input.memoryLayer,
888
+ memoryLayer: LayersEnum.Identity,
889
889
  memoryType: input.memoryType,
890
890
  metadata: Object.keys(identityMetadata).length > 0 ? identityMetadata : undefined,
891
891
  summary: input.summary,
@@ -949,7 +949,7 @@ export const userMemoriesRouter = router({
949
949
  details: input.details || '',
950
950
  detailsEmbedding,
951
951
  memoryCategory: input.memoryCategory,
952
- memoryLayer: input.memoryLayer,
952
+ memoryLayer: LayersEnum.Preference,
953
953
  memoryType: input.memoryType,
954
954
  preference: {
955
955
  conclusionDirectives: input.withPreference.conclusionDirectives || '',
@@ -618,7 +618,7 @@ export class MemoryExtractionExecutor {
618
618
  details: item.details ?? '',
619
619
  detailsEmbedding: detailsVector ?? undefined,
620
620
  memoryCategory: item.memoryCategory ?? null,
621
- memoryLayer: (item.memoryLayer as LayersEnum) ?? LayersEnum.Context,
621
+ memoryLayer: LayersEnum.Context,
622
622
  memoryType: (item.memoryType as TypesEnum) ?? TypesEnum.Context,
623
623
  summary: item.summary ?? '',
624
624
  summaryEmbedding: summaryVector ?? undefined,
@@ -684,7 +684,7 @@ export class MemoryExtractionExecutor {
684
684
  type: item.withExperience?.type ?? null,
685
685
  },
686
686
  memoryCategory: item.memoryCategory ?? null,
687
- memoryLayer: (item.memoryLayer as LayersEnum) ?? LayersEnum.Experience,
687
+ memoryLayer: LayersEnum.Experience,
688
688
  memoryType: (item.memoryType as TypesEnum) ?? TypesEnum.Activity,
689
689
  summary: item.summary ?? '',
690
690
  summaryEmbedding: summaryVector ?? undefined,
@@ -728,7 +728,7 @@ export class MemoryExtractionExecutor {
728
728
  details: item.details ?? '',
729
729
  detailsEmbedding: detailsVector ?? undefined,
730
730
  memoryCategory: item.memoryCategory ?? null,
731
- memoryLayer: (item.memoryLayer as LayersEnum) ?? LayersEnum.Preference,
731
+ memoryLayer: LayersEnum.Preference,
732
732
  memoryType: (item.memoryType as TypesEnum) ?? TypesEnum.Preference,
733
733
  preference: {
734
734
  capturedAt: job.sourceUpdatedAt,