fix(deploy): patch models.generated.js for LLM gateway + fix AGENTS.md template symlink

After container starts, sed-replace api.anthropic.com with iConsulting LLM gateway URL
in all models.generated.js files (ANTHROPIC_BASE_URL env alone is not enough since
baseUrl is hardcoded). Also create missing AGENTS.md template symlink so OpenClaw
does not 500 on workspace init.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-08 15:25:52 -07:00
parent 50401660ef
commit 54ed8290b1
1 changed files with 30 additions and 1 deletions

View File

@ -38,6 +38,12 @@ export class AgentInstanceDeployService {
private readonly encKey: string; private readonly encKey: string;
private readonly agentServicePublicUrl: string; private readonly agentServicePublicUrl: string;
// iConsulting LLM gateway URL — OpenClaw containers MUST route all Anthropic calls here,
// never directly to api.anthropic.com. The gateway key is provisioned in the iConsulting
// admin panel ("OpenClaw Training Server" key).
private readonly llmGatewayUrl: string;
private readonly openclawLlmGatewayKey: string;
constructor( constructor(
private readonly configService: ConfigService, private readonly configService: ConfigService,
private readonly instanceRepo: AgentInstanceRepository, private readonly instanceRepo: AgentInstanceRepository,
@ -47,6 +53,8 @@ export class AgentInstanceDeployService {
this.internalApiKey = this.configService.get<string>('INTERNAL_API_KEY', ''); this.internalApiKey = this.configService.get<string>('INTERNAL_API_KEY', '');
this.encKey = this.configService.get<string>('VAULT_MASTER_KEY', 'dev-master-key'); this.encKey = this.configService.get<string>('VAULT_MASTER_KEY', 'dev-master-key');
this.agentServicePublicUrl = this.configService.get<string>('AGENT_SERVICE_PUBLIC_URL', ''); this.agentServicePublicUrl = this.configService.get<string>('AGENT_SERVICE_PUBLIC_URL', '');
this.llmGatewayUrl = this.configService.get<string>('OPENCLAW_LLM_GATEWAY_URL', 'http://154.84.135.121:3008');
this.openclawLlmGatewayKey = this.configService.get<string>('OPENCLAW_LLM_GATEWAY_KEY', '');
} }
// ── Public API ──────────────────────────────────────────────────────────── // ── Public API ────────────────────────────────────────────────────────────
@ -182,10 +190,15 @@ export class AgentInstanceDeployService {
instance.openclawToken = encrypted; instance.openclawToken = encrypted;
instance.openclawTokenIv = iv; instance.openclawTokenIv = iv;
// Use the iConsulting LLM gateway key for OpenClaw.
// OpenClaw MUST NOT call api.anthropic.com directly — it goes through the gateway.
const effectiveApiKey = this.openclawLlmGatewayKey || claudeApiKey;
const envParts = [ const envParts = [
`-e OPENCLAW_GATEWAY_TOKEN=${token}`, `-e OPENCLAW_GATEWAY_TOKEN=${token}`,
`-e IT0_INSTANCE_ID=${instance.id}`, `-e IT0_INSTANCE_ID=${instance.id}`,
`-e CLAUDE_API_KEY=${claudeApiKey}`, `-e CLAUDE_API_KEY=${effectiveApiKey}`,
`-e ANTHROPIC_BASE_URL=${this.llmGatewayUrl}`,
`-e IT0_AGENT_SERVICE_URL=${this.agentServicePublicUrl}`, `-e IT0_AGENT_SERVICE_URL=${this.agentServicePublicUrl}`,
]; ];
if (dingTalkClientId && dingTalkClientSecret) { if (dingTalkClientId && dingTalkClientSecret) {
@ -229,6 +242,22 @@ export class AgentInstanceDeployService {
await this.sshExec(sshCreds, cmd); await this.sshExec(sshCreds, cmd);
// Wait for container to start, then patch models.generated.js to route all
// Anthropic API calls through the iConsulting LLM gateway instead of api.anthropic.com.
await new Promise(r => setTimeout(r, 3000));
await this.sshExec(sshCreds,
`docker exec -u root ${instance.containerName} ` +
`find /app/openclaw/node_modules -name "models.generated.js" ` +
`-exec sed -i 's|https://api.anthropic.com|${this.llmGatewayUrl}|g' {} \\; 2>/dev/null || true`,
);
// Fix missing AGENTS.md template: create symlink at expected path if not already present.
await this.sshExec(sshCreds,
`docker exec -u root ${instance.containerName} bash -c ` +
`'TMPL=$(find /app/openclaw/node_modules -path "*/openclaw/docs/reference/templates" -type d 2>/dev/null | head -1); ` +
`[ -n "$TMPL" ] && mkdir -p /app/openclaw/docs/reference && ln -sfn "$TMPL" /app/openclaw/docs/reference/templates || true'`,
);
instance.status = 'running'; instance.status = 'running';
} }