2026-03-24 15:24:18 +08:00
|
|
|
import { LobeActivatorIdentifier } from '@lobechat/builtin-tool-activator';
|
2025-12-20 22:19:42 +08:00
|
|
|
import { AgentBuilderIdentifier } from '@lobechat/builtin-tool-agent-builder';
|
2026-02-28 13:52:35 +08:00
|
|
|
import { AgentManagementIdentifier } from '@lobechat/builtin-tool-agent-management';
|
2026-04-23 17:47:10 +08:00
|
|
|
import {
|
|
|
|
|
CredsIdentifier,
|
|
|
|
|
type CredSummary,
|
|
|
|
|
generateCredsList,
|
|
|
|
|
generateKlavisServicesList,
|
|
|
|
|
type KlavisServiceSummary,
|
|
|
|
|
} from '@lobechat/builtin-tool-creds';
|
2025-12-20 22:19:42 +08:00
|
|
|
import { GroupAgentBuilderIdentifier } from '@lobechat/builtin-tool-group-agent-builder';
|
2026-05-13 01:13:04 +08:00
|
|
|
import { LobeAgentIdentifier } from '@lobechat/builtin-tool-lobe-agent';
|
2026-04-24 23:56:25 +08:00
|
|
|
import { PageAgentIdentifier } from '@lobechat/builtin-tool-page-agent';
|
2026-04-07 19:25:16 +08:00
|
|
|
import { WebOnboardingIdentifier } from '@lobechat/builtin-tool-web-onboarding';
|
2026-05-02 22:18:50 +08:00
|
|
|
import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const';
|
2026-02-28 13:52:35 +08:00
|
|
|
import type {
|
|
|
|
|
AgentBuilderContext,
|
2026-03-19 14:05:02 +08:00
|
|
|
AgentContextDocument,
|
2026-02-28 13:52:35 +08:00
|
|
|
AgentGroupConfig,
|
|
|
|
|
AgentManagementContext,
|
|
|
|
|
GroupAgentBuilderContext,
|
|
|
|
|
GroupOfficialToolItem,
|
|
|
|
|
LobeToolManifest,
|
|
|
|
|
MemoryContext,
|
2026-04-07 19:25:16 +08:00
|
|
|
OnboardingContext,
|
2026-05-13 01:13:04 +08:00
|
|
|
PlanTodoConfig,
|
2026-02-28 13:52:35 +08:00
|
|
|
ToolDiscoveryConfig,
|
|
|
|
|
UserMemoryData,
|
2025-12-20 22:19:42 +08:00
|
|
|
} from '@lobechat/context-engine';
|
2026-04-03 18:29:15 +08:00
|
|
|
import { MessagesEngine, resolveTopicReferences } from '@lobechat/context-engine';
|
2025-12-20 22:19:42 +08:00
|
|
|
import { historySummaryPrompt } from '@lobechat/prompts';
|
2026-02-28 13:52:35 +08:00
|
|
|
import type {
|
|
|
|
|
OpenAIChatMessage,
|
|
|
|
|
RuntimeInitialContext,
|
|
|
|
|
RuntimeStepContext,
|
|
|
|
|
UIChatMessage,
|
2026-02-09 16:07:43 +08:00
|
|
|
} from '@lobechat/types';
|
2025-12-20 22:19:42 +08:00
|
|
|
import debug from 'debug';
|
|
|
|
|
|
|
|
|
|
import { isCanUseFC } from '@/helpers/isCanUseFC';
|
2026-01-03 16:22:22 +08:00
|
|
|
import { VARIABLE_GENERATORS } from '@/helpers/parserPlaceholder';
|
2026-03-24 14:28:23 +08:00
|
|
|
import { lambdaClient } from '@/libs/trpc/client';
|
2026-06-04 16:23:51 +08:00
|
|
|
import {
|
|
|
|
|
agentService,
|
|
|
|
|
AVAILABLE_AGENTS_CONTEXT_LIMIT,
|
|
|
|
|
AVAILABLE_AGENTS_CONTEXT_QUERY_LIMIT,
|
|
|
|
|
} from '@/services/agent';
|
2025-12-29 20:20:11 +08:00
|
|
|
import { notebookService } from '@/services/notebook';
|
2025-12-20 22:19:42 +08:00
|
|
|
import { getAgentStoreState } from '@/store/agent';
|
2026-04-07 19:45:29 +08:00
|
|
|
import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
|
2025-12-20 22:19:42 +08:00
|
|
|
import { getChatGroupStoreState } from '@/store/agentGroup';
|
|
|
|
|
import { agentGroupSelectors } from '@/store/agentGroup/selectors';
|
2026-02-28 13:52:35 +08:00
|
|
|
import { getAiInfraStoreState } from '@/store/aiInfra';
|
2025-12-20 22:19:42 +08:00
|
|
|
import { getChatStoreState } from '@/store/chat';
|
2026-03-18 21:58:41 +08:00
|
|
|
import { topicSelectors } from '@/store/chat/selectors';
|
2025-12-20 22:19:42 +08:00
|
|
|
import { getToolStoreState } from '@/store/tool';
|
2026-01-14 19:08:37 +08:00
|
|
|
import {
|
|
|
|
|
builtinToolSelectors,
|
|
|
|
|
klavisStoreSelectors,
|
|
|
|
|
lobehubSkillStoreSelectors,
|
2026-02-27 01:59:12 +08:00
|
|
|
toolSelectors,
|
2026-01-14 19:08:37 +08:00
|
|
|
} from '@/store/tool/selectors';
|
2026-04-23 17:47:10 +08:00
|
|
|
import { KlavisServerStatus } from '@/store/tool/slices/klavisStore';
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
import { isCanUseVideo, isCanUseVision } from '../helper';
|
2026-03-05 21:37:27 +08:00
|
|
|
import { combineUserMemoryData, resolveTopicMemories, resolveUserPersona } from './memoryManager';
|
2026-03-27 10:10:06 +08:00
|
|
|
import { resolveClientSkills } from './skillEngineering';
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
const log = debug('context-engine:contextEngineering');
|
|
|
|
|
|
|
|
|
|
interface ContextEngineeringContext {
|
|
|
|
|
/** Agent Builder context for injecting current agent info */
|
|
|
|
|
agentBuilderContext?: AgentBuilderContext;
|
2026-04-03 18:29:15 +08:00
|
|
|
agentDocuments?: AgentContextDocument[];
|
2025-12-20 22:19:42 +08:00
|
|
|
/** The agent ID that will respond (for group context injection) */
|
|
|
|
|
agentId?: string;
|
|
|
|
|
enableHistoryCount?: boolean;
|
2025-12-24 09:49:32 +08:00
|
|
|
enableUserMemories?: boolean;
|
2025-12-20 22:19:42 +08:00
|
|
|
/** Group ID for multi-agent scenarios */
|
|
|
|
|
groupId?: string;
|
|
|
|
|
historyCount?: number;
|
|
|
|
|
historySummary?: string;
|
2025-12-25 11:38:15 +08:00
|
|
|
/**
|
|
|
|
|
* Initial context from Agent Runtime
|
|
|
|
|
* Contains markdown and metadata captured at operation start
|
|
|
|
|
*/
|
|
|
|
|
initialContext?: RuntimeInitialContext;
|
2025-12-20 22:19:42 +08:00
|
|
|
inputTemplate?: string;
|
2025-12-29 15:14:27 +08:00
|
|
|
/** Tool manifests with systemRole and API definitions */
|
|
|
|
|
manifests?: LobeToolManifest[];
|
2026-02-14 18:17:15 +08:00
|
|
|
/** Memory-related context for prompt/runtime behavior */
|
|
|
|
|
memoryContext?: MemoryContext;
|
2025-12-20 22:19:42 +08:00
|
|
|
messages: UIChatMessage[];
|
|
|
|
|
model: string;
|
2026-02-22 09:48:11 +08:00
|
|
|
/** Agent's enabled plugin/tool/skill identifiers (from agentConfig.plugins) */
|
|
|
|
|
plugins?: string[];
|
2025-12-20 22:19:42 +08:00
|
|
|
provider: string;
|
|
|
|
|
sessionId?: string;
|
2025-12-25 11:38:15 +08:00
|
|
|
/**
|
|
|
|
|
* Step context from Agent Runtime
|
|
|
|
|
* Contains latest XML structure updated each step
|
|
|
|
|
*/
|
|
|
|
|
stepContext?: RuntimeStepContext;
|
2025-12-20 22:19:42 +08:00
|
|
|
systemRole?: string;
|
|
|
|
|
tools?: string[];
|
2026-05-13 01:13:04 +08:00
|
|
|
/** Topic ID for plan/todo context injection */
|
2025-12-29 20:20:11 +08:00
|
|
|
topicId?: string;
|
2025-12-20 22:19:42 +08:00
|
|
|
}
|
|
|
|
|
|
2026-01-06 13:12:27 +08:00
|
|
|
// REVIEW: Maybe we can constrain identity, preference, exp to reorder or trim the context instead of passing everything in
|
2025-12-20 22:19:42 +08:00
|
|
|
export const contextEngineering = async ({
|
|
|
|
|
messages = [],
|
2025-12-29 15:14:27 +08:00
|
|
|
manifests,
|
2025-12-20 22:19:42 +08:00
|
|
|
tools,
|
|
|
|
|
model,
|
|
|
|
|
provider,
|
|
|
|
|
systemRole,
|
|
|
|
|
inputTemplate,
|
2025-12-24 09:49:32 +08:00
|
|
|
enableUserMemories,
|
2025-12-20 22:19:42 +08:00
|
|
|
enableHistoryCount,
|
|
|
|
|
historyCount,
|
|
|
|
|
historySummary,
|
|
|
|
|
agentBuilderContext,
|
2026-04-03 18:29:15 +08:00
|
|
|
agentDocuments,
|
2025-12-20 22:19:42 +08:00
|
|
|
agentId,
|
|
|
|
|
groupId,
|
2025-12-25 11:38:15 +08:00
|
|
|
initialContext,
|
2026-02-22 09:48:11 +08:00
|
|
|
plugins,
|
2025-12-25 11:38:15 +08:00
|
|
|
stepContext,
|
2025-12-29 20:20:11 +08:00
|
|
|
topicId,
|
2026-02-14 18:17:15 +08:00
|
|
|
memoryContext,
|
2025-12-20 22:19:42 +08:00
|
|
|
}: ContextEngineeringContext): Promise<OpenAIChatMessage[]> => {
|
|
|
|
|
log('tools: %o', tools);
|
|
|
|
|
|
|
|
|
|
// Check if Agent Builder tool is enabled
|
|
|
|
|
const isAgentBuilderEnabled = tools?.includes(AgentBuilderIdentifier) ?? false;
|
|
|
|
|
// Check if Group Agent Builder tool is enabled
|
|
|
|
|
const isGroupAgentBuilderEnabled = tools?.includes(GroupAgentBuilderIdentifier) ?? false;
|
2026-02-28 13:52:35 +08:00
|
|
|
// Check if Agent Management tool is enabled
|
|
|
|
|
const isAgentManagementEnabled = tools?.includes(AgentManagementIdentifier) ?? false;
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
log('isAgentBuilderEnabled: %s', isAgentBuilderEnabled);
|
|
|
|
|
log('isGroupAgentBuilderEnabled: %s', isGroupAgentBuilderEnabled);
|
2026-02-28 13:52:35 +08:00
|
|
|
log('isAgentManagementEnabled: %s', isAgentManagementEnabled);
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
// Build agent group configuration if groupId is provided
|
|
|
|
|
let agentGroup: AgentGroupConfig | undefined;
|
|
|
|
|
if (groupId) {
|
|
|
|
|
const groupStoreState = getChatGroupStoreState();
|
|
|
|
|
const groupDetail = agentGroupSelectors.getGroupById(groupId)(groupStoreState);
|
|
|
|
|
|
|
|
|
|
if (groupDetail?.agents && groupDetail.agents.length > 0) {
|
|
|
|
|
const agentMap: AgentGroupConfig['agentMap'] = {};
|
|
|
|
|
const members: AgentGroupConfig['members'] = [];
|
|
|
|
|
|
|
|
|
|
// Find the responding agent to get its name and role
|
|
|
|
|
let currentAgentName: string | undefined;
|
|
|
|
|
let currentAgentRole: 'supervisor' | 'participant' | undefined;
|
|
|
|
|
|
|
|
|
|
for (const agent of groupDetail.agents) {
|
|
|
|
|
const role = agent.isSupervisor ? 'supervisor' : 'participant';
|
|
|
|
|
const name = agent.title || 'Untitled Agent';
|
|
|
|
|
|
|
|
|
|
agentMap[agent.id] = { name, role };
|
|
|
|
|
members.push({ id: agent.id, name, role });
|
|
|
|
|
|
|
|
|
|
// Capture responding agent info
|
|
|
|
|
if (agentId && agent.id === agentId) {
|
|
|
|
|
currentAgentName = name;
|
|
|
|
|
currentAgentRole = role;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agentGroup = {
|
|
|
|
|
agentMap,
|
|
|
|
|
currentAgentId: agentId,
|
|
|
|
|
currentAgentName,
|
|
|
|
|
currentAgentRole,
|
|
|
|
|
groupTitle: groupDetail.title || undefined,
|
|
|
|
|
members,
|
2026-01-15 09:44:34 +08:00
|
|
|
// Use group.content as the group description (shared prompt/content)
|
|
|
|
|
systemPrompt: groupDetail.content || undefined,
|
2025-12-20 22:19:42 +08:00
|
|
|
};
|
|
|
|
|
log('agentGroup built: %o', agentGroup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get agent store state (used for both group agent builder context and file/knowledge base)
|
|
|
|
|
const agentStoreState = getAgentStoreState();
|
|
|
|
|
|
|
|
|
|
// Build group agent builder context if Group Agent Builder is enabled
|
|
|
|
|
// Note: Uses activeGroupId from chatStore to get the group being edited
|
|
|
|
|
let groupAgentBuilderContext: GroupAgentBuilderContext | undefined;
|
|
|
|
|
if (isGroupAgentBuilderEnabled) {
|
|
|
|
|
const activeGroupId = getChatStoreState().activeGroupId;
|
|
|
|
|
if (activeGroupId) {
|
|
|
|
|
const groupStoreState = getChatGroupStoreState();
|
|
|
|
|
const activeGroupDetail = agentGroupSelectors.getGroupById(activeGroupId)(groupStoreState);
|
|
|
|
|
|
|
|
|
|
if (activeGroupDetail) {
|
|
|
|
|
// Get supervisor agent config if supervisorAgentId exists
|
|
|
|
|
let supervisorConfig: GroupAgentBuilderContext['supervisorConfig'];
|
|
|
|
|
let enabledPlugins: string[] = [];
|
|
|
|
|
if (activeGroupDetail.supervisorAgentId) {
|
|
|
|
|
const supervisorAgentConfig = agentSelectors.getAgentConfigById(
|
|
|
|
|
activeGroupDetail.supervisorAgentId,
|
|
|
|
|
)(agentStoreState);
|
|
|
|
|
supervisorConfig = {
|
|
|
|
|
model: supervisorAgentConfig.model,
|
|
|
|
|
plugins: supervisorAgentConfig.plugins,
|
|
|
|
|
provider: supervisorAgentConfig.provider,
|
|
|
|
|
};
|
|
|
|
|
enabledPlugins = supervisorAgentConfig.plugins || [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build official tools list (builtin tools + Klavis tools)
|
|
|
|
|
const toolState = getToolStoreState();
|
|
|
|
|
const officialTools: GroupOfficialToolItem[] = [];
|
|
|
|
|
|
|
|
|
|
// Get builtin tools (excluding Klavis tools)
|
|
|
|
|
const builtinTools = builtinToolSelectors.metaList(toolState);
|
|
|
|
|
const klavisIdentifiers = new Set(KLAVIS_SERVER_TYPES.map((t) => t.identifier));
|
|
|
|
|
|
|
|
|
|
for (const tool of builtinTools) {
|
|
|
|
|
// Skip Klavis tools in builtin list (they'll be shown separately)
|
|
|
|
|
if (klavisIdentifiers.has(tool.identifier)) continue;
|
|
|
|
|
|
|
|
|
|
officialTools.push({
|
|
|
|
|
description: tool.meta?.description,
|
|
|
|
|
enabled: enabledPlugins.includes(tool.identifier),
|
|
|
|
|
identifier: tool.identifier,
|
|
|
|
|
installed: true,
|
|
|
|
|
name: tool.meta?.title || tool.identifier,
|
|
|
|
|
type: 'builtin',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get Klavis tools (if enabled)
|
|
|
|
|
const isKlavisEnabled =
|
|
|
|
|
typeof window !== 'undefined' &&
|
|
|
|
|
window.global_serverConfigStore?.getState()?.serverConfig?.enableKlavis;
|
|
|
|
|
|
|
|
|
|
if (isKlavisEnabled) {
|
|
|
|
|
const allKlavisServers = klavisStoreSelectors.getServers(toolState);
|
|
|
|
|
|
|
|
|
|
for (const klavisType of KLAVIS_SERVER_TYPES) {
|
|
|
|
|
const server = allKlavisServers.find((s) => s.identifier === klavisType.identifier);
|
|
|
|
|
|
|
|
|
|
officialTools.push({
|
|
|
|
|
description: `LobeHub Mcp Server: ${klavisType.label}`,
|
|
|
|
|
enabled: enabledPlugins.includes(klavisType.identifier),
|
|
|
|
|
identifier: klavisType.identifier,
|
|
|
|
|
installed: !!server,
|
|
|
|
|
name: klavisType.label,
|
|
|
|
|
type: 'klavis',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-14 19:08:37 +08:00
|
|
|
// Get LobehubSkill providers (if enabled)
|
|
|
|
|
const isLobehubSkillEnabled =
|
|
|
|
|
typeof window !== 'undefined' &&
|
|
|
|
|
window.global_serverConfigStore?.getState()?.serverConfig?.enableLobehubSkill;
|
|
|
|
|
|
|
|
|
|
if (isLobehubSkillEnabled) {
|
|
|
|
|
const allLobehubSkillServers = lobehubSkillStoreSelectors.getServers(toolState);
|
|
|
|
|
|
|
|
|
|
for (const provider of LOBEHUB_SKILL_PROVIDERS) {
|
|
|
|
|
const server = allLobehubSkillServers.find((s) => s.identifier === provider.id);
|
|
|
|
|
|
|
|
|
|
officialTools.push({
|
|
|
|
|
description: `LobeHub Skill Provider: ${provider.label}`,
|
|
|
|
|
enabled: enabledPlugins.includes(provider.id),
|
|
|
|
|
identifier: provider.id,
|
|
|
|
|
installed: !!server,
|
|
|
|
|
name: provider.label,
|
|
|
|
|
type: 'lobehub-skill',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 22:19:42 +08:00
|
|
|
groupAgentBuilderContext = {
|
|
|
|
|
config: {
|
|
|
|
|
openingMessage: activeGroupDetail.config?.openingMessage || undefined,
|
|
|
|
|
openingQuestions: activeGroupDetail.config?.openingQuestions,
|
|
|
|
|
systemPrompt: activeGroupDetail.config?.systemPrompt || undefined,
|
|
|
|
|
},
|
|
|
|
|
groupId: activeGroupId,
|
|
|
|
|
groupTitle: activeGroupDetail.title || undefined,
|
|
|
|
|
members: activeGroupDetail.agents?.map((agent) => ({
|
|
|
|
|
description: agent.description || undefined,
|
|
|
|
|
id: agent.id,
|
|
|
|
|
isSupervisor: agent.isSupervisor,
|
|
|
|
|
title: agent.title || 'Untitled Agent',
|
|
|
|
|
})),
|
|
|
|
|
officialTools,
|
|
|
|
|
supervisorConfig,
|
|
|
|
|
};
|
|
|
|
|
log('groupAgentBuilderContext built from activeGroupId: %o', groupAgentBuilderContext);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get enabled agent files with content and knowledge bases from agent store
|
|
|
|
|
const agentFiles = agentSelectors.currentAgentFiles(agentStoreState);
|
|
|
|
|
const agentKnowledgeBases = agentSelectors.currentAgentKnowledgeBases(agentStoreState);
|
|
|
|
|
|
|
|
|
|
const fileContents = agentFiles
|
|
|
|
|
.filter((file) => file.enabled && file.content)
|
|
|
|
|
.map((file) => ({ content: file.content!, fileId: file.id, filename: file.name }));
|
|
|
|
|
|
|
|
|
|
const knowledgeBases = agentKnowledgeBases
|
|
|
|
|
.filter((kb) => kb.enabled)
|
|
|
|
|
.map((kb) => ({ description: kb.description, id: kb.id, name: kb.name }));
|
|
|
|
|
|
2026-03-05 21:37:27 +08:00
|
|
|
// Resolve user memories: topic memories and user persona are independent layers
|
2026-01-14 11:02:09 +08:00
|
|
|
// Both functions now read from cache only (no network requests) to avoid blocking sendMessage
|
2026-02-14 18:17:15 +08:00
|
|
|
let userMemoryData: UserMemoryData | undefined;
|
2025-12-24 09:49:32 +08:00
|
|
|
if (enableUserMemories) {
|
2026-01-14 11:02:09 +08:00
|
|
|
const topicMemories = resolveTopicMemories();
|
2026-03-05 21:37:27 +08:00
|
|
|
const persona = resolveUserPersona();
|
|
|
|
|
userMemoryData = combineUserMemoryData(topicMemories, persona);
|
2025-12-24 09:49:32 +08:00
|
|
|
}
|
|
|
|
|
|
2026-05-13 01:13:04 +08:00
|
|
|
// Resolve plan + todos context (now part of the lobe-agent tool).
|
|
|
|
|
// Lobe-agent must be enabled and topicId must be provided.
|
|
|
|
|
const isPlanTodoEnabled = tools?.includes(LobeAgentIdentifier) ?? false;
|
|
|
|
|
let planTodoConfig: PlanTodoConfig | undefined;
|
2025-12-29 20:20:11 +08:00
|
|
|
|
2026-05-13 01:13:04 +08:00
|
|
|
if (isPlanTodoEnabled && topicId) {
|
2025-12-29 20:20:11 +08:00
|
|
|
try {
|
|
|
|
|
// Fetch plan document for the current topic
|
|
|
|
|
const planResult = await notebookService.listDocuments({
|
|
|
|
|
topicId,
|
|
|
|
|
type: 'agent/plan',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (planResult.data.length > 0) {
|
|
|
|
|
const planDoc = planResult.data[0]; // Most recent plan
|
|
|
|
|
|
|
|
|
|
// Build plan object for injection
|
|
|
|
|
const plan = {
|
|
|
|
|
completed: false, // TODO: Add completed field to document if needed
|
|
|
|
|
context: planDoc.content ?? undefined,
|
|
|
|
|
createdAt: planDoc.createdAt.toISOString(),
|
|
|
|
|
description: planDoc.description || '',
|
|
|
|
|
goal: planDoc.title || '',
|
|
|
|
|
id: planDoc.id,
|
|
|
|
|
updatedAt: planDoc.updatedAt.toISOString(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Get todos from plan's metadata
|
|
|
|
|
const todos = planDoc.metadata?.todos;
|
|
|
|
|
|
2026-05-13 01:13:04 +08:00
|
|
|
planTodoConfig = {
|
2025-12-29 20:20:11 +08:00
|
|
|
enabled: true,
|
|
|
|
|
plan,
|
|
|
|
|
todos,
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-13 01:13:04 +08:00
|
|
|
log('Plan/Todo context resolved: plan=%s, todos=%o', plan.goal, todos?.items?.length ?? 0);
|
2025-12-29 20:20:11 +08:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2026-05-13 01:13:04 +08:00
|
|
|
// Silently fail - plan/todo context is optional
|
|
|
|
|
log('Failed to resolve plan/todo context:', error);
|
2025-12-29 20:20:11 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 14:28:23 +08:00
|
|
|
// Resolve user credentials context for creds tool
|
|
|
|
|
// Creds tool must be enabled to fetch credentials
|
|
|
|
|
const isCredsEnabled = tools?.includes(CredsIdentifier) ?? false;
|
|
|
|
|
let credsList: CredSummary[] | undefined;
|
|
|
|
|
|
|
|
|
|
if (isCredsEnabled) {
|
|
|
|
|
try {
|
|
|
|
|
const credsResult = await lambdaClient.market.creds.list.query();
|
|
|
|
|
const userCreds = (credsResult as any)?.data ?? [];
|
|
|
|
|
credsList = userCreds.map(
|
|
|
|
|
(cred: any): CredSummary => ({
|
|
|
|
|
description: cred.description,
|
|
|
|
|
key: cred.key,
|
|
|
|
|
name: cred.name,
|
|
|
|
|
type: cred.type,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
log('Creds context resolved: count=%d', credsList?.length ?? 0);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// Silently fail - creds context is optional
|
|
|
|
|
log('Failed to resolve creds context:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-23 17:47:10 +08:00
|
|
|
// Build Klavis services list for creds context
|
|
|
|
|
// Shows which Klavis services are connected (authorized) and which are available to connect
|
|
|
|
|
let klavisServicesList = '';
|
|
|
|
|
|
|
|
|
|
const isKlavisEnabled =
|
|
|
|
|
typeof window !== 'undefined' &&
|
|
|
|
|
window.global_serverConfigStore?.getState()?.serverConfig?.enableKlavis;
|
|
|
|
|
|
|
|
|
|
if (isCredsEnabled && isKlavisEnabled) {
|
|
|
|
|
try {
|
|
|
|
|
const toolState = getToolStoreState();
|
|
|
|
|
const allKlavisServers = klavisStoreSelectors.getServers(toolState);
|
|
|
|
|
|
|
|
|
|
const connected: KlavisServiceSummary[] = allKlavisServers
|
|
|
|
|
.filter((s) => s.status === KlavisServerStatus.CONNECTED)
|
|
|
|
|
.map((s) => ({ identifier: s.identifier, name: s.serverName }));
|
|
|
|
|
|
|
|
|
|
const connectedIds = new Set(connected.map((s) => s.identifier));
|
|
|
|
|
const available: KlavisServiceSummary[] = KLAVIS_SERVER_TYPES.filter(
|
|
|
|
|
(t) => !connectedIds.has(t.identifier),
|
|
|
|
|
).map((t) => ({ identifier: t.identifier, name: t.label }));
|
|
|
|
|
|
|
|
|
|
klavisServicesList = generateKlavisServicesList(connected, available);
|
|
|
|
|
log(
|
|
|
|
|
'Klavis services context resolved: connected=%d, available=%d',
|
|
|
|
|
connected.length,
|
|
|
|
|
available.length,
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
log('Failed to resolve Klavis services context:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-14 18:17:15 +08:00
|
|
|
const userMemoryConfig =
|
|
|
|
|
enableUserMemories && userMemoryData
|
|
|
|
|
? {
|
|
|
|
|
enabled: enableUserMemories,
|
|
|
|
|
memories: userMemoryData,
|
|
|
|
|
}
|
|
|
|
|
: undefined;
|
|
|
|
|
|
2026-03-24 15:24:18 +08:00
|
|
|
// Build tool discovery config if lobe-activator is enabled
|
2026-02-27 01:59:12 +08:00
|
|
|
const enabledToolSet = new Set(tools || []);
|
2026-03-24 15:24:18 +08:00
|
|
|
const isLobeToolsEnabled = enabledToolSet.has(LobeActivatorIdentifier);
|
2026-02-27 01:59:12 +08:00
|
|
|
|
|
|
|
|
let toolDiscoveryConfig: ToolDiscoveryConfig | undefined;
|
|
|
|
|
if (isLobeToolsEnabled) {
|
|
|
|
|
const toolState = getToolStoreState();
|
|
|
|
|
const availableTools = toolSelectors
|
|
|
|
|
.availableToolsForDiscovery(toolState)
|
|
|
|
|
.filter((tool) => !enabledToolSet.has(tool.identifier));
|
|
|
|
|
|
|
|
|
|
if (availableTools.length > 0) {
|
|
|
|
|
toolDiscoveryConfig = { availableTools };
|
|
|
|
|
log('Tool discovery config built, available tools count: %d', availableTools.length);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 19:45:29 +08:00
|
|
|
// Build Agent Management context.
|
|
|
|
|
// - availableAgents is injected whenever the user is in auto skill mode (so the
|
|
|
|
|
// supervisor can decide to activate agent-management on its own) OR when the tool
|
|
|
|
|
// is explicitly enabled.
|
|
|
|
|
// - availableProviders / availablePlugins are only built when the tool is explicitly
|
|
|
|
|
// enabled, since they're solely needed for createAgent / updateAgent.
|
2026-02-28 13:52:35 +08:00
|
|
|
let agentManagementContext: AgentManagementContext | undefined;
|
2026-04-07 19:45:29 +08:00
|
|
|
|
|
|
|
|
const isInAutoSkillMode =
|
|
|
|
|
agentChatConfigSelectors.skillActivateMode(agentStoreState) !== 'manual';
|
|
|
|
|
const shouldInjectAvailableAgents = isInAutoSkillMode || isAgentManagementEnabled;
|
|
|
|
|
|
|
|
|
|
if (shouldInjectAvailableAgents) {
|
|
|
|
|
try {
|
2026-06-04 16:23:51 +08:00
|
|
|
const recentAgents =
|
|
|
|
|
agentStoreState.availableAgents ??
|
|
|
|
|
(await agentService.queryAgents({ limit: AVAILABLE_AGENTS_CONTEXT_QUERY_LIMIT }));
|
2026-04-08 11:24:53 +08:00
|
|
|
|
|
|
|
|
// Exclude current agent from `availableAgents`. The model is the current
|
|
|
|
|
// agent — its identity/persona is already established by `systemRole`, so
|
|
|
|
|
// we don't re-inject it here, and removing self from the list ensures the
|
|
|
|
|
// model never sees its own id in the agent-management context (so it
|
|
|
|
|
// cannot accidentally call itself via `callAgent`).
|
|
|
|
|
const otherAgents = agentId ? recentAgents.filter((a) => a.id !== agentId) : recentAgents;
|
2026-06-04 16:23:51 +08:00
|
|
|
const hasMoreAgents = otherAgents.length > AVAILABLE_AGENTS_CONTEXT_LIMIT;
|
|
|
|
|
const availableAgents = otherAgents.slice(0, AVAILABLE_AGENTS_CONTEXT_LIMIT).map((a) => ({
|
2026-04-07 19:45:29 +08:00
|
|
|
description: a.description ?? undefined,
|
|
|
|
|
id: a.id,
|
|
|
|
|
title: a.title ?? 'Untitled',
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
agentManagementContext = {
|
|
|
|
|
availableAgents,
|
|
|
|
|
availableAgentsHasMore: hasMoreAgents,
|
2026-04-15 17:57:05 +08:00
|
|
|
...(agentId && {
|
|
|
|
|
currentAgent: {
|
|
|
|
|
id: agentId,
|
|
|
|
|
title: agentSelectors.getAgentMetaById(agentId)(agentStoreState)?.title ?? undefined,
|
|
|
|
|
},
|
|
|
|
|
}),
|
2026-04-07 19:45:29 +08:00
|
|
|
};
|
|
|
|
|
log('availableAgents fetched: %d agents (hasMore=%s)', availableAgents.length, hasMoreAgents);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// Silently fail - availableAgents context is optional
|
|
|
|
|
log('Failed to fetch availableAgents: %O', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-28 13:52:35 +08:00
|
|
|
if (isAgentManagementEnabled) {
|
|
|
|
|
// Get enabled providers and models from aiInfra store
|
|
|
|
|
const aiProviderState = getAiInfraStoreState();
|
|
|
|
|
const enabledChatModelList = aiProviderState.enabledChatModelList || [];
|
|
|
|
|
|
|
|
|
|
// Build availableProviders from enabled chat models (only user-enabled providers)
|
|
|
|
|
// Limit to first 5 providers to avoid context bloat
|
|
|
|
|
const availableProviders = enabledChatModelList.slice(0, 5).map((provider) => ({
|
|
|
|
|
id: provider.id,
|
|
|
|
|
models: provider.children.map((model) => ({
|
|
|
|
|
abilities: model.abilities,
|
|
|
|
|
description: model.description,
|
|
|
|
|
id: model.id,
|
|
|
|
|
name: model.displayName || model.id,
|
|
|
|
|
})),
|
|
|
|
|
name: provider.name,
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
// Get tool state for plugins
|
|
|
|
|
const toolState = getToolStoreState();
|
|
|
|
|
|
|
|
|
|
// Build availablePlugins from all plugin sources
|
|
|
|
|
const availablePlugins = [];
|
|
|
|
|
|
|
|
|
|
// Builtin tools (use allMetaList to include hidden tools like web-browsing, cloud-sandbox, etc.)
|
|
|
|
|
// Exclude only truly internal tools (agent-management itself, agent-builder, page-agent)
|
|
|
|
|
const allBuiltinTools = builtinToolSelectors.allMetaList(toolState);
|
|
|
|
|
const klavisIdentifiers = new Set(KLAVIS_SERVER_TYPES.map((t) => t.identifier));
|
|
|
|
|
const INTERNAL_TOOLS = new Set([
|
|
|
|
|
'lobe-agent-management', // Don't show agent-management in its own context
|
|
|
|
|
'lobe-agent-builder', // Used for editing current agent, not for creating new agents
|
|
|
|
|
'lobe-group-agent-builder', // Used for editing current group, not for creating new agents
|
|
|
|
|
'lobe-page-agent', // Page-editor specific tool
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
for (const tool of allBuiltinTools) {
|
|
|
|
|
// Skip Klavis tools in builtin list (they'll be shown separately)
|
|
|
|
|
if (klavisIdentifiers.has(tool.identifier)) continue;
|
|
|
|
|
// Skip internal tools
|
|
|
|
|
if (INTERNAL_TOOLS.has(tool.identifier)) continue;
|
|
|
|
|
|
|
|
|
|
availablePlugins.push({
|
|
|
|
|
description: tool.meta?.description,
|
|
|
|
|
identifier: tool.identifier,
|
|
|
|
|
name: tool.meta?.title || tool.identifier,
|
|
|
|
|
type: 'builtin' as const,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Klavis tools (if enabled)
|
|
|
|
|
const isKlavisEnabled =
|
|
|
|
|
typeof window !== 'undefined' &&
|
|
|
|
|
window.global_serverConfigStore?.getState()?.serverConfig?.enableKlavis;
|
|
|
|
|
|
|
|
|
|
if (isKlavisEnabled) {
|
|
|
|
|
for (const klavisType of KLAVIS_SERVER_TYPES) {
|
|
|
|
|
availablePlugins.push({
|
|
|
|
|
description: klavisType.description,
|
|
|
|
|
identifier: klavisType.identifier,
|
|
|
|
|
name: klavisType.label,
|
|
|
|
|
type: 'klavis' as const,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// LobehubSkill providers (if enabled)
|
|
|
|
|
const isLobehubSkillEnabled =
|
|
|
|
|
typeof window !== 'undefined' &&
|
|
|
|
|
window.global_serverConfigStore?.getState()?.serverConfig?.enableLobehubSkill;
|
|
|
|
|
|
|
|
|
|
if (isLobehubSkillEnabled) {
|
|
|
|
|
for (const provider of LOBEHUB_SKILL_PROVIDERS) {
|
|
|
|
|
availablePlugins.push({
|
|
|
|
|
description: provider.description,
|
|
|
|
|
identifier: provider.id,
|
|
|
|
|
name: provider.label,
|
|
|
|
|
type: 'lobehub-skill' as const,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agentManagementContext = {
|
2026-04-07 19:45:29 +08:00
|
|
|
...agentManagementContext,
|
2026-02-28 13:52:35 +08:00
|
|
|
availablePlugins,
|
|
|
|
|
availableProviders,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
log(
|
2026-04-07 19:45:29 +08:00
|
|
|
'agentManagementContext built: %d providers, %d plugins, %d agents',
|
2026-02-28 13:52:35 +08:00
|
|
|
agentManagementContext.availableProviders?.length ?? 0,
|
|
|
|
|
agentManagementContext.availablePlugins?.length ?? 0,
|
2026-04-07 19:45:29 +08:00
|
|
|
agentManagementContext.availableAgents?.length ?? 0,
|
2026-02-28 13:52:35 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 22:17:36 +08:00
|
|
|
// Inject mentionedAgents independently of isAgentManagementEnabled.
|
|
|
|
|
// When user @mentions an agent, delegation context must always be injected
|
|
|
|
|
// even if the agent doesn't have agent-management tool in its config.
|
|
|
|
|
const hasMentionedAgents =
|
|
|
|
|
initialContext?.mentionedAgents && initialContext.mentionedAgents.length > 0;
|
|
|
|
|
|
|
|
|
|
if (hasMentionedAgents) {
|
|
|
|
|
agentManagementContext = {
|
|
|
|
|
...agentManagementContext,
|
|
|
|
|
mentionedAgents: initialContext!.mentionedAgents,
|
|
|
|
|
};
|
|
|
|
|
log('mentionedAgents injected: %d agents', initialContext!.mentionedAgents!.length);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-18 21:58:41 +08:00
|
|
|
// Resolve topic references from messages containing <refer_topic> tags
|
2026-06-04 16:23:51 +08:00
|
|
|
const topicReferences =
|
|
|
|
|
(await resolveTopicReferences(
|
|
|
|
|
messages,
|
|
|
|
|
async (topicId: string) => {
|
|
|
|
|
const topic = topicSelectors.getTopicById(topicId)(getChatStoreState());
|
|
|
|
|
return topic ?? null;
|
|
|
|
|
},
|
|
|
|
|
async (topicId: string) => {
|
|
|
|
|
const { messageService } = await import('@/services/message');
|
|
|
|
|
const msgs = await messageService.getMessages({ agentId, groupId, topicId });
|
|
|
|
|
return msgs.map((m) => ({
|
|
|
|
|
content: typeof m.content === 'string' ? m.content : '',
|
|
|
|
|
role: m.role,
|
|
|
|
|
}));
|
|
|
|
|
},
|
|
|
|
|
)) ?? [];
|
2026-03-18 21:58:41 +08:00
|
|
|
|
2026-05-01 01:20:45 +08:00
|
|
|
// Build onboarding context if this is the web-onboarding agent.
|
|
|
|
|
// Single combined trpc call — server runs state/soul/persona DB queries in parallel.
|
2026-04-07 19:25:16 +08:00
|
|
|
let onboardingContext: OnboardingContext | undefined;
|
|
|
|
|
const isOnboardingAgent = tools?.includes(WebOnboardingIdentifier);
|
|
|
|
|
if (isOnboardingAgent) {
|
|
|
|
|
try {
|
|
|
|
|
const { userService } = await import('@/services/user');
|
2026-05-01 01:20:45 +08:00
|
|
|
onboardingContext = await userService.getOnboardingAgentContext();
|
|
|
|
|
log('Built onboarding context');
|
2026-04-07 19:25:16 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
log('Failed to build onboarding context: %O', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 22:19:42 +08:00
|
|
|
// Create MessagesEngine with injected dependencies
|
|
|
|
|
const engine = new MessagesEngine({
|
|
|
|
|
// Agent configuration
|
|
|
|
|
enableHistoryCount,
|
|
|
|
|
formatHistorySummary: historySummaryPrompt,
|
|
|
|
|
historyCount,
|
|
|
|
|
historySummary,
|
|
|
|
|
inputTemplate,
|
|
|
|
|
systemRole,
|
|
|
|
|
|
|
|
|
|
// Capability injection
|
|
|
|
|
capabilities: {
|
|
|
|
|
isCanUseFC,
|
|
|
|
|
isCanUseVideo,
|
|
|
|
|
isCanUseVision,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// File context configuration
|
2026-05-02 22:18:50 +08:00
|
|
|
fileContext: { enabled: true, includeFileUrl: false },
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
// Knowledge injection
|
|
|
|
|
knowledge: {
|
|
|
|
|
fileContents,
|
|
|
|
|
knowledgeBases,
|
|
|
|
|
},
|
2026-03-19 14:05:02 +08:00
|
|
|
agentDocuments,
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
// Messages
|
|
|
|
|
messages,
|
|
|
|
|
|
|
|
|
|
// Model info
|
|
|
|
|
model,
|
|
|
|
|
provider,
|
|
|
|
|
|
2025-12-25 11:38:15 +08:00
|
|
|
// runtime context
|
|
|
|
|
initialContext,
|
|
|
|
|
stepContext,
|
|
|
|
|
|
2026-04-03 22:09:48 +08:00
|
|
|
// Selected skills/tools from user for this request
|
|
|
|
|
selectedSkills: initialContext?.selectedSkills,
|
|
|
|
|
selectedTools: initialContext?.selectedTools,
|
|
|
|
|
|
2026-05-15 00:07:47 +08:00
|
|
|
// Pass enableAgentMode through; MessagesEngine force-disables skills /
|
|
|
|
|
// agent-document injectors when this is `false` (chat mode).
|
|
|
|
|
enableAgentMode: agentChatConfigSelectors.currentChatConfig(agentStoreState).enableAgentMode,
|
|
|
|
|
|
2026-04-17 17:02:53 +08:00
|
|
|
// Skills configuration
|
|
|
|
|
// In auto mode: expose all installed skills so the AI can discover and activate them
|
|
|
|
|
// In manual mode: only expose user-selected skills (filtered by pluginIds)
|
2026-02-22 09:48:11 +08:00
|
|
|
skillsConfig: {
|
2026-04-17 17:02:53 +08:00
|
|
|
enabledSkills: plugins
|
|
|
|
|
? (() => {
|
|
|
|
|
const skillSet = resolveClientSkills(plugins);
|
|
|
|
|
if (!isInAutoSkillMode) {
|
|
|
|
|
const selectedIds = new Set(plugins);
|
|
|
|
|
return skillSet.skills.filter((s) => selectedIds.has(s.identifier));
|
|
|
|
|
}
|
|
|
|
|
return skillSet.skills;
|
|
|
|
|
})()
|
|
|
|
|
: undefined,
|
2026-02-22 09:48:11 +08:00
|
|
|
},
|
|
|
|
|
|
2026-02-27 01:59:12 +08:00
|
|
|
// Tool Discovery configuration
|
|
|
|
|
toolDiscoveryConfig,
|
|
|
|
|
|
2025-12-20 22:19:42 +08:00
|
|
|
// Tools configuration
|
|
|
|
|
toolsConfig: {
|
2026-04-24 23:56:25 +08:00
|
|
|
disabledToolIdentifiers: tools?.includes(PageAgentIdentifier)
|
|
|
|
|
? undefined
|
|
|
|
|
: [PageAgentIdentifier],
|
2025-12-29 15:14:27 +08:00
|
|
|
manifests,
|
2025-12-20 22:19:42 +08:00
|
|
|
tools,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// User memory configuration
|
2026-02-14 18:17:15 +08:00
|
|
|
userMemory: userMemoryConfig,
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
// Variable generators
|
2026-02-14 18:17:15 +08:00
|
|
|
variableGenerators: {
|
|
|
|
|
...VARIABLE_GENERATORS,
|
2026-03-24 14:28:23 +08:00
|
|
|
// NOTICE: required by builtin-tool-creds/src/systemRole.ts
|
|
|
|
|
CREDS_LIST: () => (credsList ? generateCredsList(credsList) : ''),
|
2026-04-23 17:47:10 +08:00
|
|
|
// NOTICE: required by builtin-tool-creds/src/systemRole.ts (Klavis integrations)
|
|
|
|
|
KLAVIS_SERVICES_LIST: () => klavisServicesList,
|
2026-05-31 20:03:51 +08:00
|
|
|
// NOTICE: required by builtin-tool-creds/src/systemRole.ts (session_context)
|
|
|
|
|
session_date: () =>
|
|
|
|
|
new Intl.DateTimeFormat('en-US', {
|
|
|
|
|
day: 'numeric',
|
|
|
|
|
month: 'long',
|
|
|
|
|
weekday: 'long',
|
|
|
|
|
year: 'numeric',
|
|
|
|
|
}).format(new Date()),
|
|
|
|
|
sandbox_enabled: () => String(tools?.includes('lobe-cloud-sandbox') ?? false),
|
2026-02-14 18:17:15 +08:00
|
|
|
// NOTICE(@nekomeowww): required by builtin-tool-memory/src/systemRole.ts
|
|
|
|
|
memory_effort: () => (userMemoryConfig ? (memoryContext?.effort ?? '') : ''),
|
2026-04-09 16:11:18 +08:00
|
|
|
// Current agent + topic identity — referenced by the LobeHub builtin
|
|
|
|
|
// skill (packages/builtin-skills/src/lobehub/content.ts) so the model
|
|
|
|
|
// can run `lh agent run -a {{agent_id}}` etc without first having to
|
|
|
|
|
// search for itself. Read lazily from stores so we only pay the cost
|
|
|
|
|
// when the placeholder actually appears in a rendered message.
|
|
|
|
|
agent_id: () => agentId ?? '',
|
|
|
|
|
agent_title: () =>
|
|
|
|
|
agentId ? (agentSelectors.getAgentMetaById(agentId)(agentStoreState)?.title ?? '') : '',
|
|
|
|
|
agent_description: () =>
|
|
|
|
|
agentId
|
|
|
|
|
? (agentSelectors.getAgentMetaById(agentId)(agentStoreState)?.description ?? '')
|
|
|
|
|
: '',
|
|
|
|
|
topic_id: () => topicId ?? '',
|
|
|
|
|
topic_title: () => {
|
|
|
|
|
if (!topicId) return '';
|
|
|
|
|
const topic = topicSelectors.getTopicById(topicId)(getChatStoreState());
|
|
|
|
|
return topic?.title ?? '';
|
|
|
|
|
},
|
2026-02-14 18:17:15 +08:00
|
|
|
},
|
2025-12-20 22:19:42 +08:00
|
|
|
|
|
|
|
|
// Extended contexts - only pass when enabled
|
|
|
|
|
...(isAgentBuilderEnabled && { agentBuilderContext }),
|
|
|
|
|
...(isGroupAgentBuilderEnabled && { groupAgentBuilderContext }),
|
2026-04-07 19:45:29 +08:00
|
|
|
...(agentManagementContext && { agentManagementContext }),
|
2025-12-20 22:19:42 +08:00
|
|
|
...(agentGroup && { agentGroup }),
|
2026-05-13 01:13:04 +08:00
|
|
|
...(planTodoConfig && { planTodo: planTodoConfig }),
|
2026-03-18 21:58:41 +08:00
|
|
|
...(topicReferences && topicReferences.length > 0 && { topicReferences }),
|
2026-04-07 19:25:16 +08:00
|
|
|
...(onboardingContext && { onboardingContext }),
|
2025-12-20 22:19:42 +08:00
|
|
|
});
|
|
|
|
|
|
2026-01-23 23:13:03 +08:00
|
|
|
log('Input messages count: %d', messages.length);
|
|
|
|
|
|
2025-12-20 22:19:42 +08:00
|
|
|
const result = await engine.process();
|
2026-01-23 23:13:03 +08:00
|
|
|
|
|
|
|
|
log('Output messages count: %d', result.messages.length);
|
|
|
|
|
|
|
|
|
|
if (messages.length > 0 && result.messages.length === 0) {
|
|
|
|
|
log(
|
|
|
|
|
'WARNING: Messages were reduced to 0! Input messages: %o',
|
|
|
|
|
messages.map((m) => ({ id: m.id, role: m.role })),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 22:19:42 +08:00
|
|
|
return result.messages;
|
|
|
|
|
};
|