Clean up auto routing gateway terminology
This commit is contained in:
parent
e018fc15dd
commit
85eab1806c
@ -16,6 +16,7 @@
|
||||
2. [ARIS 缺陷修复与审阅循环](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/docs/cases/aris_bugfix_review_loop.md)
|
||||
3. [外部 Agent CLI Bridge 会话](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/docs/cases/external_agent_bridge_session.md)
|
||||
4. [模式切换与线程连续追问](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/docs/cases/thread_mode_switch_followup.md)
|
||||
5. [Intent Router + Skill Resolver + Memory Injector 典型用例](/Users/shenlan/workspaces/cloud-neutral-toolkit/xworkmate/docs/cases/intent_router_skill_memory_typical_cases.md)
|
||||
|
||||
## 相关设计文档
|
||||
|
||||
|
||||
@ -65,28 +65,28 @@ func TestHandleRoutingResolveCoversNineScenarioBuckets(t *testing.T) {
|
||||
{
|
||||
name: "image-cog",
|
||||
prompt: "use image-cog to generate consistent characters",
|
||||
expectedExecutionTarget: "gateway-chat",
|
||||
expectedExecutionTarget: "gateway",
|
||||
expectedSkillSource: "find_skills",
|
||||
expectedNeedsSkillInstall: true,
|
||||
},
|
||||
{
|
||||
name: "image-video-generation-editting",
|
||||
prompt: "wan 图生视频并做视频编辑",
|
||||
expectedExecutionTarget: "gateway-chat",
|
||||
expectedExecutionTarget: "gateway",
|
||||
expectedSkillSource: "find_skills",
|
||||
expectedNeedsSkillInstall: true,
|
||||
},
|
||||
{
|
||||
name: "video-translator",
|
||||
prompt: "translate video subtitles and dub the clip",
|
||||
expectedExecutionTarget: "gateway-chat",
|
||||
expectedExecutionTarget: "gateway",
|
||||
expectedSkillSource: "find_skills",
|
||||
expectedNeedsSkillInstall: true,
|
||||
},
|
||||
{
|
||||
name: "browser-search-news",
|
||||
prompt: "跨浏览器执行并搜索最新资讯采集结果",
|
||||
expectedExecutionTarget: "gateway-chat",
|
||||
expectedExecutionTarget: "gateway",
|
||||
expectedSkillSource: "local_match",
|
||||
expectedResolvedSkill: "Browser Automation",
|
||||
},
|
||||
|
||||
@ -149,7 +149,9 @@ func parsePreferences(text string) Preferences {
|
||||
trimmed := strings.TrimSpace(line)
|
||||
switch {
|
||||
case strings.HasPrefix(strings.ToLower(trimmed), "preferred-route:"):
|
||||
prefs.PreferredRoute = strings.TrimSpace(strings.TrimPrefix(trimmed, "preferred-route:"))
|
||||
prefs.PreferredRoute = normalizePreferredRoute(
|
||||
strings.TrimSpace(strings.TrimPrefix(trimmed, "preferred-route:")),
|
||||
)
|
||||
case strings.HasPrefix(strings.ToLower(trimmed), "preferred-model:"):
|
||||
prefs.PreferredModel = strings.TrimSpace(strings.TrimPrefix(trimmed, "preferred-model:"))
|
||||
case strings.HasPrefix(strings.ToLower(trimmed), "preferred-skills:"):
|
||||
@ -205,3 +207,12 @@ func projectNameFromWorkingDirectory(workingDirectory string) string {
|
||||
}
|
||||
return strings.TrimSpace(filepath.Base(cleaned))
|
||||
}
|
||||
|
||||
func normalizePreferredRoute(value string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case "gateway-chat":
|
||||
return "gateway"
|
||||
default:
|
||||
return strings.TrimSpace(value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ func TestLoadMergesGlobalAndProjectMemoryAndSanitizesSecrets(t *testing.T) {
|
||||
if strings.Contains(strings.ToLower(result.MergedText), "api_key") || strings.Contains(strings.ToLower(result.MergedText), "password") {
|
||||
t.Fatalf("expected sanitized merged text, got %q", result.MergedText)
|
||||
}
|
||||
if result.Preferences.PreferredRoute != "gateway-chat" {
|
||||
if result.Preferences.PreferredRoute != "gateway" {
|
||||
t.Fatalf("unexpected preferred route: %#v", result.Preferences)
|
||||
}
|
||||
if result.Preferences.PreferredModel != "gpt-5.4" {
|
||||
|
||||
@ -14,6 +14,7 @@ const (
|
||||
|
||||
ExecutionTargetSingleAgent = "single-agent"
|
||||
ExecutionTargetMultiAgent = "multi-agent"
|
||||
ExecutionTargetGateway = "gateway"
|
||||
ExecutionTargetGatewayChat = "gateway-chat"
|
||||
|
||||
EndpointTargetSingleAgent = "singleAgent"
|
||||
@ -114,15 +115,15 @@ func resolveExecution(req Request, prefs memory.Preferences) (string, string) {
|
||||
return ExecutionTargetMultiAgent, EndpointTargetSingleAgent
|
||||
}
|
||||
if looksOnline(prompt) {
|
||||
return ExecutionTargetGatewayChat, normalizeGatewayTarget(req.PreferredGatewayTarget)
|
||||
return ExecutionTargetGateway, normalizeGatewayTarget(req.PreferredGatewayTarget)
|
||||
}
|
||||
if looksLocal(prompt) {
|
||||
return ExecutionTargetSingleAgent, EndpointTargetSingleAgent
|
||||
}
|
||||
|
||||
switch strings.TrimSpace(prefs.PreferredRoute) {
|
||||
case ExecutionTargetGatewayChat:
|
||||
return ExecutionTargetGatewayChat, normalizeGatewayTarget(req.PreferredGatewayTarget)
|
||||
switch normalizeExecutionTarget(strings.TrimSpace(prefs.PreferredRoute)) {
|
||||
case ExecutionTargetGateway:
|
||||
return ExecutionTargetGateway, normalizeGatewayTarget(req.PreferredGatewayTarget)
|
||||
case ExecutionTargetMultiAgent:
|
||||
return ExecutionTargetMultiAgent, EndpointTargetSingleAgent
|
||||
}
|
||||
@ -132,9 +133,9 @@ func resolveExecution(req Request, prefs memory.Preferences) (string, string) {
|
||||
func mapExplicitTarget(value string) (string, string) {
|
||||
switch strings.TrimSpace(value) {
|
||||
case EndpointTargetLocal:
|
||||
return ExecutionTargetGatewayChat, EndpointTargetLocal
|
||||
return ExecutionTargetGateway, EndpointTargetLocal
|
||||
case EndpointTargetRemote:
|
||||
return ExecutionTargetGatewayChat, EndpointTargetRemote
|
||||
return ExecutionTargetGateway, EndpointTargetRemote
|
||||
case "multiAgent", ExecutionTargetMultiAgent:
|
||||
return ExecutionTargetMultiAgent, EndpointTargetSingleAgent
|
||||
case EndpointTargetSingleAgent, ExecutionTargetSingleAgent:
|
||||
@ -187,3 +188,12 @@ func containsAny(haystack string, needles []string) bool {
|
||||
func normalize(value string) string {
|
||||
return strings.ToLower(strings.TrimSpace(value))
|
||||
}
|
||||
|
||||
func normalizeExecutionTarget(value string) string {
|
||||
switch normalize(value) {
|
||||
case ExecutionTargetGatewayChat:
|
||||
return ExecutionTargetGateway
|
||||
default:
|
||||
return normalize(value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,8 +58,8 @@ func TestResolveAutoOnlineTaskToGateway(t *testing.T) {
|
||||
PreferredGatewayTarget: EndpointTargetLocal,
|
||||
})
|
||||
|
||||
if result.ResolvedExecutionTarget != ExecutionTargetGatewayChat {
|
||||
t.Fatalf("expected gateway-chat route, got %#v", result)
|
||||
if result.ResolvedExecutionTarget != ExecutionTargetGateway {
|
||||
t.Fatalf("expected gateway route, got %#v", result)
|
||||
}
|
||||
if result.ResolvedEndpointTarget != EndpointTargetLocal {
|
||||
t.Fatalf("expected local gateway target, got %#v", result)
|
||||
|
||||
@ -148,8 +148,19 @@ class GoAgentCoreSessionRequest {
|
||||
}
|
||||
return switch (target) {
|
||||
AssistantExecutionTarget.singleAgent => 'single-agent',
|
||||
AssistantExecutionTarget.local => 'gateway-chat',
|
||||
AssistantExecutionTarget.remote => 'gateway-chat',
|
||||
AssistantExecutionTarget.local => _gatewaySessionMode,
|
||||
AssistantExecutionTarget.remote => _gatewaySessionMode,
|
||||
};
|
||||
}
|
||||
|
||||
String get routingExecutionTarget {
|
||||
if (multiAgent) {
|
||||
return 'multi-agent';
|
||||
}
|
||||
return switch (target) {
|
||||
AssistantExecutionTarget.singleAgent => 'single-agent',
|
||||
AssistantExecutionTarget.local => 'gateway',
|
||||
AssistantExecutionTarget.remote => 'gateway',
|
||||
};
|
||||
}
|
||||
|
||||
@ -198,7 +209,7 @@ class GoAgentCoreSessionRequest {
|
||||
if (aiGatewayApiKey.trim().isNotEmpty)
|
||||
'aiGatewayApiKey': aiGatewayApiKey.trim(),
|
||||
if (routing != null) 'routing': routing!.toJson(),
|
||||
if (mode == 'gateway-chat') ...<String, dynamic>{
|
||||
if (_usesGatewaySessionMode(mode)) ...<String, dynamic>{
|
||||
'executionTarget': target.promptValue,
|
||||
if (agentId.trim().isNotEmpty) 'agentId': agentId.trim(),
|
||||
if (metadata.isNotEmpty) 'metadata': metadata,
|
||||
@ -208,6 +219,13 @@ class GoAgentCoreSessionRequest {
|
||||
}
|
||||
}
|
||||
|
||||
const String _gatewaySessionMode = 'gateway-chat';
|
||||
|
||||
bool _usesGatewaySessionMode(String mode) {
|
||||
final normalized = mode.trim();
|
||||
return normalized == 'gateway' || normalized == _gatewaySessionMode;
|
||||
}
|
||||
|
||||
class GoAgentCoreSessionUpdate {
|
||||
const GoAgentCoreSessionUpdate({
|
||||
required this.sessionId,
|
||||
|
||||
@ -285,7 +285,7 @@ class GoAgentCoreDesktopTransport implements GoAgentCoreClient {
|
||||
}
|
||||
if (resolvedEndpointTarget.isNotEmpty) {
|
||||
params['resolvedEndpointTarget'] = resolvedEndpointTarget;
|
||||
if (resolvedExecutionTarget == 'gateway-chat') {
|
||||
if (_isGatewayExecutionTarget(resolvedExecutionTarget)) {
|
||||
params['executionTarget'] = resolvedEndpointTarget;
|
||||
}
|
||||
}
|
||||
@ -323,7 +323,7 @@ class GoAgentCoreDesktopTransport implements GoAgentCoreClient {
|
||||
}
|
||||
final resolvedExecutionTarget =
|
||||
routingResult['resolvedExecutionTarget']?.toString().trim() ?? '';
|
||||
if (resolvedExecutionTarget == 'gateway-chat') {
|
||||
if (_isGatewayExecutionTarget(resolvedExecutionTarget)) {
|
||||
final endpointTarget =
|
||||
routingResult['resolvedEndpointTarget']?.toString().trim() ?? '';
|
||||
return switch (endpointTarget) {
|
||||
@ -354,4 +354,9 @@ class GoAgentCoreDesktopTransport implements GoAgentCoreClient {
|
||||
.where((item) => item.isNotEmpty)
|
||||
.toList(growable: false);
|
||||
}
|
||||
|
||||
bool _isGatewayExecutionTarget(String value) {
|
||||
final normalized = value.trim();
|
||||
return normalized == 'gateway' || normalized == 'gateway-chat';
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ class GoAgentCoreWebTransport implements GoAgentCoreClient {
|
||||
}
|
||||
if (resolvedEndpointTarget.isNotEmpty) {
|
||||
params['resolvedEndpointTarget'] = resolvedEndpointTarget;
|
||||
if (resolvedExecutionTarget == 'gateway-chat') {
|
||||
if (_isGatewayExecutionTarget(resolvedExecutionTarget)) {
|
||||
params['executionTarget'] = resolvedEndpointTarget;
|
||||
}
|
||||
}
|
||||
@ -197,7 +197,7 @@ class GoAgentCoreWebTransport implements GoAgentCoreClient {
|
||||
}
|
||||
final resolvedExecutionTarget =
|
||||
routingResult['resolvedExecutionTarget']?.toString().trim() ?? '';
|
||||
if (resolvedExecutionTarget == 'gateway-chat') {
|
||||
if (_isGatewayExecutionTarget(resolvedExecutionTarget)) {
|
||||
final endpointTarget =
|
||||
routingResult['resolvedEndpointTarget']?.toString().trim() ?? '';
|
||||
return switch (endpointTarget) {
|
||||
@ -219,6 +219,11 @@ class GoAgentCoreWebTransport implements GoAgentCoreClient {
|
||||
return const <String, dynamic>{};
|
||||
}
|
||||
|
||||
bool _isGatewayExecutionTarget(String value) {
|
||||
final normalized = value.trim();
|
||||
return normalized == 'gateway' || normalized == 'gateway-chat';
|
||||
}
|
||||
|
||||
List<String> _castStringList(Object? raw) {
|
||||
if (raw is! List) {
|
||||
return const <String>[];
|
||||
|
||||
@ -24,7 +24,7 @@ void registerAppControllerAiGatewayChatSuiteChatTestsInternal() {
|
||||
'AppController streams and restores persistent Single Agent conversation turns',
|
||||
() async {
|
||||
final tempDirectory = await createTempDirectoryInternal(
|
||||
'xworkmate-ai-gateway-chat-',
|
||||
'xworkmate-ai-gateway-session-',
|
||||
);
|
||||
final server = await FakeAiGatewayServerInternal.start(
|
||||
responseMode: AiGatewayResponseModeInternal.sse,
|
||||
|
||||
@ -95,6 +95,33 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
test('routing execution target uses gateway while session mode stays compatible', () {
|
||||
const request = GoAgentCoreSessionRequest(
|
||||
sessionId: 'session-2',
|
||||
threadId: 'thread-2',
|
||||
target: AssistantExecutionTarget.local,
|
||||
prompt: 'search latest news',
|
||||
workingDirectory: '/tmp/workspace',
|
||||
model: '',
|
||||
thinking: '',
|
||||
selectedSkills: <String>[],
|
||||
inlineAttachments: <GatewayChatAttachmentPayload>[],
|
||||
localAttachments: <CollaborationAttachment>[],
|
||||
aiGatewayBaseUrl: '',
|
||||
aiGatewayApiKey: '',
|
||||
agentId: 'agent-1',
|
||||
metadata: <String, dynamic>{'source': 'test'},
|
||||
provider: SingleAgentProvider.auto,
|
||||
);
|
||||
|
||||
final params = request.toAcpParams();
|
||||
|
||||
expect(request.routingExecutionTarget, 'gateway');
|
||||
expect(params['mode'], 'gateway-chat');
|
||||
expect(params['executionTarget'], 'local');
|
||||
expect(params['agentId'], 'agent-1');
|
||||
});
|
||||
|
||||
test(
|
||||
'run result prefers completion text and preserves resolved workspace',
|
||||
() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user