Skip to content

Commit e4fc64e

Browse files
committed
Configure graph agents with VLM env
1 parent eeb5a14 commit e4fc64e

7 files changed

Lines changed: 103 additions & 50 deletions

File tree

client/start.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ info "Install completed"
5757
# --------------------------------------------------
5858
# 5. Launch app
5959
# --------------------------------------------------
60-
PACKAGE="com.haomai.promotor"
60+
PACKAGE="com.coremate.opengui"
6161
adb shell am start -n "$PACKAGE/.login.SplashActivity" >/dev/null 2>&1
6262
info "App launched"
6363

server/apps/backend/.env.example

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,10 @@ REDIS_PORT=6379
1414
REDIS_DB=0
1515
REDIS_PASSWORD=
1616

17-
# Claude Agent (plan-supervisor, summarizer, executor-a11y)
18-
CLAUDE_API_KEY=
19-
CLAUDE_BASE_URL=
20-
CLAUDE_MODEL=anthropic/claude-sonnet-4.6
21-
CLAUDE_SMALL_MODEL=anthropic/claude-haiku-4.5
22-
23-
# VLM Agent (executor-vlm) — 视觉模型
17+
# AI model config (used by all graph agents)
2418
VLM_API_KEY=
25-
VLM_BASE_URL=
26-
VLM_MODEL=
27-
28-
# Creator Agent (Claude Agent SDK)
29-
ANTHROPIC_API_KEY=
30-
# ANTHROPIC_BASE_URL=
19+
VLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
20+
VLM_MODEL=qwen3.6-plus
3121

3222
# LangSmith tracing (optional, for debugging agent execution)
3323
# LANGSMITH_TRACING=true

server/apps/backend/src/modules/graph-agent/config/agent-config.provider.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,50 +45,39 @@ export class AgentConfigProvider {
4545

4646
/**
4747
*
48-
* - executor-vlm: VLM_API_KEY, VLM_BASE_URL, VLM_MODEL
49-
* - action-summarizer: CLAUDE_API_KEY, CLAUDE_BASE_URL, CLAUDE_SMALL_MODEL
50-
* - Other Agent: CLAUDE_API_KEY, CLAUDE_BASE_URL, CLAUDE_MODEL
48+
* All graph agents use the same OpenAI-compatible model config:
49+
* - VLM_API_KEY
50+
* - VLM_BASE_URL
51+
* - VLM_MODEL
5152
*
5253
*/
5354
async getModelConfig(agentName: AgentName, region = "CN"): Promise<ModelConfig> {
5455
const config = await this.getConfig(agentName, region);
5556

56-
const isVLM = agentName === AgentName.EXECUTOR_VLM;
57-
const isSmall = agentName === AgentName.ACTION_SUMMARIZER;
57+
const apiKey = this.configService.get<string>("VLM_API_KEY");
58+
const baseURL = this.configService.get<string>("VLM_BASE_URL");
59+
const model = this.configService.get<string>("VLM_MODEL");
5860

59-
const apiKey = isVLM
60-
? this.configService.get<string>("VLM_API_KEY")
61-
: this.configService.get<string>("CLAUDE_API_KEY");
62-
const baseURL = isVLM
63-
? this.configService.get<string>("VLM_BASE_URL")
64-
: this.configService.get<string>("CLAUDE_BASE_URL");
65-
const envModel = isVLM
66-
? this.configService.get<string>("VLM_MODEL")
67-
: isSmall
68-
? this.configService.get<string>("CLAUDE_SMALL_MODEL")
69-
: this.configService.get<string>("CLAUDE_MODEL");
70-
71-
const model = envModel;
7261

7362
if (!apiKey) {
7463
throw new Error(
7564
`API key not configured for agent: ${agentName}. ` +
76-
`Set ${isVLM ? "VLM_API_KEY" : "CLAUDE_API_KEY"} in .env`,
65+
"Set VLM_API_KEY in .env",
7766
);
7867
}
7968

8069
if (!model) {
8170
throw new Error(
8271
`Model not configured for agent: ${agentName}. ` +
83-
`Set ${isVLM ? "VLM_MODEL" : "CLAUDE_MODEL"} in .env`,
72+
"Set VLM_MODEL in .env",
8473
);
8574
}
8675

8776
return {
8877
model,
8978
apiKey,
9079
baseURL: baseURL || undefined,
91-
fallbackModel: config.fallbackModel ?? undefined,
80+
fallbackModel: model,
9281
temperature: config.temperature ?? undefined,
9382
maxTokens: config.maxTokens ?? undefined,
9483
topP: config.topP ?? undefined,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { ChatOpenAI } from "@langchain/openai";
2+
import type { ModelConfig } from "./types";
3+
4+
/**
5+
* Creates the single OpenAI-compatible chat model used by OpenGUI graph agents.
6+
*
7+
* Provider credentials and model selection come from AgentConfigProvider, which
8+
* is backed by VLM_API_KEY, VLM_BASE_URL, and VLM_MODEL.
9+
*/
10+
export function createConfiguredChatModel(
11+
config: ModelConfig,
12+
options: {
13+
model?: string;
14+
temperature?: number;
15+
maxTokens?: number;
16+
maxRetries?: number;
17+
timeout?: number;
18+
topP?: number;
19+
} = {},
20+
) {
21+
return new ChatOpenAI({
22+
model: options.model ?? config.model,
23+
apiKey: config.apiKey,
24+
temperature: options.temperature ?? config.temperature,
25+
maxTokens: options.maxTokens ?? config.maxTokens,
26+
maxRetries: options.maxRetries,
27+
timeout: options.timeout,
28+
topP: options.topP ?? config.topP,
29+
...(config.baseURL && {
30+
configuration: { baseURL: config.baseURL },
31+
}),
32+
});
33+
}

server/apps/backend/src/modules/graph-agent/graph/nodes/plan-supervisor.node.spec.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
/**
22
* Plan Supervisor 结构化输出集成测试
33
*
4-
* 验证 ChatAnthropic + createAgent + providerStrategy 能否拿到 structuredResponse
4+
* 验证 ChatOpenAI + createAgent + providerStrategy 能否拿到 structuredResponse
55
* 使用真实模型调用,mock 数据尽量简化
66
*
77
* 运行:pnpm test -- plan-supervisor.node.spec
88
*/
99

10-
import { ChatAnthropic } from "@langchain/anthropic";
1110
import { HumanMessage } from "@langchain/core/messages";
1211
import { tool } from "@langchain/core/tools";
12+
import { ChatOpenAI } from "@langchain/openai";
1313
import { createAgent, providerStrategy } from "langchain";
1414
import { z } from "zod";
1515

1616
// ====== API 配置(与 plan-supervisor.node.ts 保持一致)======
17-
const API_KEY = process.env.CLAUDE_API_KEY ?? "test-api-key-placeholder";
18-
const BASE_URL = process.env.CLAUDE_BASE_URL ?? "https://ai-gateway.vercel.sh";
19-
const MODEL = process.env.CLAUDE_MODEL ?? "anthropic/claude-sonnet-4.6";
17+
const API_KEY = process.env.VLM_API_KEY ?? "test-api-key-placeholder";
18+
const BASE_URL =
19+
process.env.VLM_BASE_URL ?? "https://dashscope.aliyuncs.com/compatible-mode/v1";
20+
const MODEL = process.env.VLM_MODEL ?? "qwen3.6-plus";
2021
// =============================================================
2122

2223
const SupervisorOutputSchema = z.object({
@@ -72,18 +73,17 @@ const mockLoadSkill = tool(
7273
},
7374
);
7475

75-
describe("PlanSupervisor - ChatAnthropic 结构化输出集成测试", () => {
76-
let model: ChatAnthropic;
76+
describe("PlanSupervisor - ChatOpenAI 结构化输出集成测试", () => {
77+
let model: ChatOpenAI;
7778

7879
beforeAll(() => {
79-
model = new ChatAnthropic({
80+
model = new ChatOpenAI({
8081
model: MODEL,
8182
apiKey: API_KEY,
82-
clientOptions: {
83+
maxRetries: 2,
84+
timeout: 120000,
85+
configuration: {
8386
baseURL: BASE_URL,
84-
maxRetries: 2,
85-
timeout: 120000,
86-
authToken: null,
8787
},
8888
});
8989
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const CONNECTION_LOST_PATTERNS = [
2+
"no connection for execution",
3+
"socket disconnected",
4+
"client disconnected",
5+
"connection lost",
6+
"ack timeout",
7+
"operation has timed out",
8+
"timeout",
9+
];
10+
11+
function getErrorText(error: unknown): string {
12+
if (error instanceof Error) {
13+
return `${error.name} ${error.message}`.toLowerCase();
14+
}
15+
if (typeof error === "string") {
16+
return error.toLowerCase();
17+
}
18+
return "";
19+
}
20+
21+
export function isExecutionConnectionLost(error: unknown): boolean {
22+
return isExecutionConnectionLostMessage(getErrorText(error));
23+
}
24+
25+
export function isExecutionConnectionLostMessage(message: unknown): boolean {
26+
if (typeof message !== "string") return false;
27+
const lower = message.toLowerCase();
28+
return CONNECTION_LOST_PATTERNS.some((pattern) => lower.includes(pattern));
29+
}
30+
31+
export function buildExecutionConnectionLostMessage(executionId: number): string {
32+
return `Execution ${executionId} lost the client connection. Reconnect the device and retry.`;
33+
}

server/start.sh

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ if [ ! -f "$ENV_FILE" ]; then
8585
cp "$ENV_EXAMPLE" "$ENV_FILE"
8686
warn ".env was created from .env.example. Please edit it and add your API keys:"
8787
warn " File: $ENV_FILE"
88-
warn " CLAUDE_API_KEY, VLM_API_KEY, ANTHROPIC_API_KEY"
88+
warn " VLM_API_KEY, VLM_BASE_URL, VLM_MODEL"
8989
warn "Run this script again after editing the file."
9090
exit 0
9191
else
@@ -95,8 +95,16 @@ fi
9595

9696
set -a; source "$ENV_FILE" 2>/dev/null || true; set +a
9797

98-
if [ -z "$CLAUDE_API_KEY" ]; then
99-
warn "CLAUDE_API_KEY is not set. Please edit .env."
98+
if [ -z "$VLM_API_KEY" ]; then
99+
warn "VLM_API_KEY is not set. Please edit .env."
100+
fi
101+
102+
if [ -z "$VLM_MODEL" ]; then
103+
warn "VLM_MODEL is not set. Please edit .env."
104+
fi
105+
106+
if [ -z "$VLM_BASE_URL" ]; then
107+
warn "VLM_BASE_URL is not set. Please edit .env."
100108
fi
101109

102110
info ".env loaded"

0 commit comments

Comments
 (0)