Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
357b0d1
refactor new agents
xuyaqist Aug 13, 2026
e08d0c5
update atuo-save
xuyaqist Aug 14, 2026
fe8455e
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 17, 2026
2837e25
Merge remote-tracking branch 'remote/develop' into xyq/feat_newagents
xuyaqist Aug 18, 2026
1553cf4
update
xuyaqist Aug 18, 2026
67699fa
update
xuyaqist Aug 18, 2026
3d5e59f
📝 Docs: Add NL2Agent capability design handoff
RedShakespeare Aug 17, 2026
96a1965
📝 Docs: Refine NL2Agent development and merge plan
RedShakespeare Aug 17, 2026
b3333c3
📝 Docs: Detail NL2Agent phase one implementation
RedShakespeare Aug 18, 2026
d31dc6f
✨ Feature: Add NL2Agent draft workflow
RedShakespeare Aug 18, 2026
9d954e4
✅ Test: Cover NL2Agent draft lifecycle
RedShakespeare Aug 18, 2026
e5f23f2
🐛 Bugfix: Refine NL2Agent clarification flow
RedShakespeare Aug 18, 2026
3b38ab7
📝 Docs: Detail NL2Agent phase two contracts
RedShakespeare Aug 18, 2026
b759c10
✨ Feature: Add NL2Agent installed resource binding
RedShakespeare Aug 18, 2026
03d6e36
✅ Test: Cover NL2Agent resource binding lifecycle
RedShakespeare Aug 18, 2026
277407a
🐛 Bugfix: Refresh Agent resources after binding
RedShakespeare Aug 18, 2026
4d688dd
🚚 migrate NL2Agent workflow to newagents
RedShakespeare Aug 19, 2026
c28182d
🐛 Bugfix: Synchronize Agent resource bindings
RedShakespeare Aug 19, 2026
80edb3b
✨ Feature: Complete NL2Agent prompt confirmation flow
RedShakespeare Aug 19, 2026
1455fbb
🐛 Bugfix: Enforce NL2Agent interactive card boundaries
RedShakespeare Aug 19, 2026
f49bea2
♻️ Refactor: Configure NL2Agent from existing drafts
RedShakespeare Aug 19, 2026
87a85fe
🐛 Bugfix: Prevent NL2Agent false completion answers
RedShakespeare Aug 19, 2026
d98cbc0
🐛 Bugfix: Preserve NL2Agent system prompt context
RedShakespeare Aug 20, 2026
ce65af1
🐛 Bugfix: Refresh NL2Agent form after draft saves
RedShakespeare Aug 20, 2026
6c3c854
🐛 Bugfix: Prevent NL2Agent few-shot generation truncation
RedShakespeare Aug 20, 2026
e929afb
🐛 Bugfix: Enforce atomic NL2Agent prompt generation
RedShakespeare Aug 20, 2026
f2417fe
♻️ Refactor: Replace NL2Agent final confirmation with summary
RedShakespeare Aug 20, 2026
8837ada
✨ Feature: Focus updated NL2Agent config sections
RedShakespeare Aug 20, 2026
6e370d4
解决冲突
xuyaqist Aug 20, 2026
0757929
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 20, 2026
4033e59
update
xuyaqist Aug 20, 2026
1162a6e
删除newagents
xuyaqist Aug 20, 2026
64119c2
fix 前端build问题
xuyaqist Aug 21, 2026
1095d54
fix agent version publish ut
xuyaqist Aug 21, 2026
543291b
♻️ Refactor: Isolate NL2Agent MCP service
RedShakespeare Aug 21, 2026
d110f2c
fix ut
xuyaqist Aug 21, 2026
745ddbc
fix(benchmark): retain agent example config
xuyaqist Aug 21, 2026
7d4e4c6
过滤is_user_selectable为false的tool
xuyaqist Aug 21, 2026
e29a5f9
♻️ Refactor: Use automatic NL2A tool prefixes
RedShakespeare Aug 21, 2026
4293a11
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 21, 2026
146ba70
Merge remote-tracking branch 'remote/xyq/feat_newagents' into xyq/fea…
xuyaqist Aug 21, 2026
a9c7a49
✅ Test: Align skill instance error handling mocks
RedShakespeare Aug 21, 2026
08bf57f
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 21, 2026
8fbb68f
1. 修复conversation stop时没有调用接口
xuyaqist Aug 21, 2026
754f148
🐛 Bugfix: Restore skill file upload helper import
RedShakespeare Aug 21, 2026
1b83251
add ut
xuyaqist Aug 21, 2026
cd8369d
fix ut
xuyaqist Aug 21, 2026
c03d7d0
🐛 Bugfix: Bypass proxies for local MCP connections
RedShakespeare Aug 21, 2026
c6e558c
🐛 Bugfix: Defer NL2Agent scheduled task setup
RedShakespeare Aug 21, 2026
308f119
✨ Feature: Add NL2Agent conversational revisions
RedShakespeare Aug 21, 2026
e04c61a
Merge remote/develop into xyq/feat_newagents
xuyaqist Aug 22, 2026
3c51cd4
1. 统一Agent配置页面的校验逻辑
xuyaqist Aug 22, 2026
6a75041
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 22, 2026
52f7860
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 22, 2026
0266e2a
fix form input
xuyaqist Aug 22, 2026
d64d576
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 22, 2026
e3bbf55
恢复文件修改
xuyaqist Aug 22, 2026
8aef6be
恢复文件修改
xuyaqist Aug 22, 2026
9e268aa
fix ut
xuyaqist Aug 22, 2026
322efde
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 24, 2026
0895007
1. 添加tour引导用户使用nl2agent功能
xuyaqist Aug 24, 2026
e1826a0
优化agent info接口的缓存机制,默认设置不缓存,确保数据的新鲜
xuyaqist Aug 24, 2026
f98dcb6
修复无法修改是否发布为A2A Agent的问题
xuyaqist Aug 24, 2026
585646a
支持当用户导入智能体后,自动跳转到这个导入的智能体
xuyaqist Aug 24, 2026
c8d31fc
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 24, 2026
1bd9d78
fix ut
xuyaqist Aug 24, 2026
1d9f654
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 25, 2026
296767c
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 25, 2026
096c931
在问答的composer中,仅上传文件无法发送消息,只有包含文本时才能正常发送消息
xuyaqist Aug 25, 2026
87a55cd
支持chat页面断点重传
xuyaqist Aug 25, 2026
3c9160e
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 25, 2026
242a54e
提示用户默认编辑的是草稿态
xuyaqist Aug 25, 2026
59433b1
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 25, 2026
937777b
set aidp_serach_tool user_selectable
xuyaqist Aug 25, 2026
8c75e85
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 25, 2026
a9efb17
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 26, 2026
0469216
Merge branch 'develop' into xyq/feat_newagents
xuyaqist Aug 26, 2026
b969eb7
设置sql 支持幂等执行
xuyaqist Aug 26, 2026
66cc203
设置“智能生成”和“调试” panel在关闭时仅隐藏,而非销毁
xuyaqist Aug 26, 2026
4075944
修复频繁调用check_name接口
xuyaqist Aug 26, 2026
361dcff
优化对话时的图片渲染
xuyaqist Aug 26, 2026
5d9c733
支持删除conversation,设置修改conversation title的样式
xuyaqist Aug 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions deploy/sql/migrations/v2.5.0_0817_add_agent_is_a2a.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,29 @@ COMMENT ON COLUMN nexent.ag_tenant_agent_t.is_a2a IS
'Whether the draft configuration publishes this agent as an A2A Server';

-- Preserve the A2A state of agents that have at least one historical A2A version.
UPDATE nexent.ag_tenant_agent_t AS agent
SET is_a2a = TRUE
WHERE agent.version_no = 0
AND agent.delete_flag = 'N'
AND EXISTS (
SELECT 1
FROM nexent.ag_tenant_agent_version_t AS version
WHERE version.agent_id = agent.agent_id
AND version.tenant_id = agent.tenant_id
AND version.is_a2a IS TRUE
);
DO $$
BEGIN
IF EXISTS (
SELECT 1
Comment thread
WMC001 marked this conversation as resolved.
FROM information_schema.columns
WHERE table_schema = 'nexent'
AND table_name = 'ag_tenant_agent_version_t'
AND column_name = 'is_a2a'
) THEN
UPDATE nexent.ag_tenant_agent_t AS agent
SET is_a2a = TRUE
WHERE agent.version_no = 0
AND agent.delete_flag = 'N'
AND EXISTS (
SELECT 1
FROM nexent.ag_tenant_agent_version_t AS version
WHERE version.agent_id = agent.agent_id
AND version.tenant_id = agent.tenant_id
AND version.is_a2a IS TRUE
);
END IF;
END
$$;
Comment thread
WMC001 marked this conversation as resolved.

-- A2A publication state is now owned exclusively by ag_tenant_agent_t.
ALTER TABLE nexent.ag_tenant_agent_version_t
Expand Down
228 changes: 114 additions & 114 deletions frontend/app/[locale]/agents/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
);
}

function AgentSetupContent() {

Check failure on line 109 in frontend/app/[locale]/agents/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AaA9XakC1uH0JAZwFB17&open=AaA9XakC1uH0JAZwFB17&pullRequest=3785
const { t } = useTranslation("common");
const searchParams = useSearchParams();
const queryClient = useQueryClient();
Expand Down Expand Up @@ -277,67 +277,67 @@

<main className="flex min-h-0 flex-1 flex-row gap-4 overflow-hidden p-6">
<div className="flex min-w-0 min-h-0 flex-1 flex-row gap-4">
{isGenerationVisible && (
<PanelCard
panelRef={generationPanelRef}
title={t("agent.page.panel.nl2agent")}
className={isDebugVisible ? "flex-1" : "flex-[1]"}
rightAction={
<button
type="button"
aria-label={t("agent.page.panel.nl2agent.closeAria")}
onClick={() => setIsGenerationVisible(false)}
className="rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-700"
<PanelCard
panelRef={generationPanelRef}
title={t("agent.page.panel.nl2agent")}
className={
isGenerationVisible ? (isDebugVisible ? "flex-1" : "flex-[1]") : "hidden"

Check warning on line 284 in frontend/app/[locale]/agents/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AaA9XakC1uH0JAZwFB18&open=AaA9XakC1uH0JAZwFB18&pullRequest=3785
}
rightAction={
<button
type="button"
aria-label={t("agent.page.panel.nl2agent.closeAria")}
onClick={() => setIsGenerationVisible(false)}
className="rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-700"
>
<X size={18} />
</button>
}
>
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
{isNl2AgentUnavailable ? (
<div
className="shrink-0 border-b border-amber-200 bg-amber-50 px-4 py-2 text-sm text-amber-900"
role="status"
>
<X size={18} />
</button>
}
>
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
{isNl2AgentUnavailable ? (
<div
className="shrink-0 border-b border-amber-200 bg-amber-50 px-4 py-2 text-sm text-amber-900"
role="status"
>
{t(
"nl2agent.unavailable",
"Create or select an editable Agent first."
)}
</div>
) : null}
{completionSyncFailed ? (
<div
className="flex shrink-0 items-center justify-between gap-3 border-b border-amber-200 bg-amber-50 px-4 py-2 text-sm text-amber-900"
role="alert"
>
<span>
{t(
"nl2agent.unavailable",
"Create or select an editable Agent first."
"nl2agent.completion.syncFailed",
"The Agent was generated, but the form could not be refreshed."
)}
</div>
) : null}
{completionSyncFailed ? (
<div
className="flex shrink-0 items-center justify-between gap-3 border-b border-amber-200 bg-amber-50 px-4 py-2 text-sm text-amber-900"
role="alert"
</span>
<Button
icon={<RefreshCw size={14} />}
onClick={retryCompletionSync}
size="small"
>
<span>
{t(
"nl2agent.completion.syncFailed",
"The Agent was generated, but the form could not be refreshed."
)}
</span>
<Button
icon={<RefreshCw size={14} />}
onClick={retryCompletionSync}
size="small"
>
{t("nl2agent.completion.retry", "Retry")}
</Button>
</div>
) : null}
<Nl2AgentChatPanel
key={sessionGeneration}
agentId={currentAgentId}
disabled={
isComposerDisabled ||
isRequestedAgentLoading ||
isNl2AgentUnavailable
}
onStateEvent={handleStateEvent}
/>
</div>
</PanelCard>
)}
{t("nl2agent.completion.retry", "Retry")}
</Button>
</div>
) : null}
<Nl2AgentChatPanel
key={sessionGeneration}
agentId={currentAgentId}
disabled={
isComposerDisabled ||
isRequestedAgentLoading ||
isNl2AgentUnavailable
}
onStateEvent={handleStateEvent}
/>
</div>
</PanelCard>

<PanelCard
panelRef={configPanelRef}
Expand Down Expand Up @@ -394,66 +394,66 @@
</div>
</PanelCard>

{isDebugVisible && (
<PanelCard
title={t("agent.page.panel.debug")}
className={isDebugFullscreen ? "flex-[2]" : "flex-1"}
leftAction={
<div className="flex items-center gap-2 text-sm text-gray-600">
<span>{t("agent.debug.compareMode")}</span>
<Switch
checked={isCompareMode}
onChange={setIsCompareMode}
size="small"
/>
</div>
}
rightAction={
<div className="flex items-center gap-1">
<button
type="button"
aria-label={
isDebugFullscreen
? "Restore debug panel size"
: "Maximize debug panel"
<PanelCard
title={t("agent.page.panel.debug")}
className={
isDebugVisible ? (isDebugFullscreen ? "flex-[2]" : "flex-1") : "hidden"

Check warning on line 400 in frontend/app/[locale]/agents/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AaA9XakC1uH0JAZwFB19&open=AaA9XakC1uH0JAZwFB19&pullRequest=3785
}
leftAction={
<div className="flex items-center gap-2 text-sm text-gray-600">
<span>{t("agent.debug.compareMode")}</span>
<Switch
checked={isCompareMode}
onChange={setIsCompareMode}
size="small"
/>
</div>
}
rightAction={
<div className="flex items-center gap-1">
<button
type="button"
aria-label={
isDebugFullscreen
? "Restore debug panel size"
: "Maximize debug panel"
}
onClick={() => {
if (isDebugFullscreen) {
setIsDebugFullscreen(false);
return;
}
onClick={() => {
if (isDebugFullscreen) {
setIsDebugFullscreen(false);
return;
}

setIsGenerationVisible(false);
setIsShowVersionManagePanel(false);
setIsDebugFullscreen(true);
}}
className="rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-700"
>
{isDebugFullscreen ? (
<Minimize2 size={18} />
) : (
<Maximize2 size={18} />
)}
</button>
<button
type="button"
aria-label={t("agent.page.panel.debug.closeAria")}
onClick={() => {
setIsDebugVisible(false);
setIsDebugFullscreen(false);
}}
className="rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-700"
>
<X size={18} />
</button>
</div>
}
>
<div className="min-h-0 flex-1 overflow-hidden">
<AgentDebugPanel isCompareMode={isCompareMode} />
setIsGenerationVisible(false);
setIsShowVersionManagePanel(false);
setIsDebugFullscreen(true);
}}
className="rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-700"
>
{isDebugFullscreen ? (
<Minimize2 size={18} />
) : (
<Maximize2 size={18} />
)}
</button>
<button
type="button"
aria-label={t("agent.page.panel.debug.closeAria")}
onClick={() => {
setIsDebugVisible(false);
setIsDebugFullscreen(false);
}}
className="rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-700"
>
<X size={18} />
</button>
</div>
</PanelCard>
)}
}
>
<div className="min-h-0 flex-1 overflow-hidden">
<AgentDebugPanel isCompareMode={isCompareMode} />
</div>
</PanelCard>

{isShowVersionManagePanel && (
<PanelCard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,12 @@ export const setServerConversationIdState = (
serverConversationIdState = state;
};

let pendingThreadOperationId: string | undefined;

export const setPendingThreadOperationId = (threadId: string | undefined) => {
pendingThreadOperationId = threadId;
};

const MAX_TITLE_WAIT_MS = 5_000;
const TITLE_POLL_INTERVAL_MS = 50;

Expand All @@ -1282,13 +1288,21 @@ const waitForServerConversationId = async (
// reliable than the active-thread registry while the sidebar is switching.
if (isValidConversationId(fallbackRemoteId)) return fallbackRemoteId;

// Fast path: the ref is already populated for a new thread after its first
// agent run has returned the server-side conversation ID.
// New threads use an empty remoteId until they are reloaded from the
// backend. The sidebar captures the local ID before calling rename/delete,
// because assistant-ui may switch the active thread as part of that action.
const readNow = (): string | undefined => {
if (pendingThreadOperationId) {
const fromPendingThread = idsRef.current.get(pendingThreadOperationId);
if (isValidConversationId(fromPendingThread)) return fromPendingThread;
}

const activeThreadId = getActiveThreadId();
if (!activeThreadId) return undefined;
const fromRef = idsRef.current.get(activeThreadId);
return isValidConversationId(fromRef) ? fromRef : undefined;
const fromActiveThread = idsRef.current.get(activeThreadId);
return isValidConversationId(fromActiveThread)
? fromActiveThread
: undefined;
};

const immediate = readNow();
Expand Down Expand Up @@ -1348,19 +1362,6 @@ export const conversationThreadListAdapter: RemoteThreadListAdapter = {
// doing so would create a second, empty conversation that the agent
// run never reuses (see commit history for details).
//
// We return an empty-string `remoteId` rather than `undefined` because
// the assistant-ui `RemoteThreadListAdapter["initialize"]` contract
// requires a string. The empty string is a safe placeholder: the page
// resolves `activeConversationId` with priority
// `serverConversationIdsRef → remoteId → activeThreadId`, so as soon as
// the adapter captures the server id from the response header the page
// starts using the real id instead of this placeholder.
//
// `generateTitle` follows the same priority chain: it consults the page's
// `serverConversationIdsRef` via `waitForServerConversationId` before
// falling back to the raw `remoteId`, so a brand-new thread no longer
// triggers a `conversation_id: 0` request (which would silently fail on
// the backend's `WHERE conversation_id = 0` filter).
return {
remoteId: "",
externalId: "",
Expand Down Expand Up @@ -1417,8 +1418,7 @@ export const conversationThreadListAdapter: RemoteThreadListAdapter = {

return toRemoteThreadMetadata({
conversation_id: Number(detail.conversation_id),
conversation_title:
detail.conversation_title ?? "Untitled conversation",
conversation_title: detail.conversation_title ?? "Untitled conversation",
agent_id: detail.agent_id,
create_time: detail.create_time,
update_time: detail.create_time,
Expand Down
Loading
Loading