Files
openclaw/extensions/tencent/config-compat.ts
Sulaga 2b51c255f8 feat(tencent): add Tencent Hy3 provider (TokenHub and TokenPlan) (#99076)
Summary:
- Merged feat(tencent): add Tencent Hy3 provider (TokenHub and TokenPlan) after ClawSweeper review.

Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: fix(tencent): preserve TokenHub auth compatibility
- Included post-review commit in the final squash: refactor(tencent): unify TokenPlan env/flag naming with TokenHub
- Included post-review commit in the final squash: docs: refresh Tencent provider docs metadata
- Included post-review commit in the final squash: fix: allow TokenPlan provider config overlays
- Included post-review commit in the final squash: docs: dedupe Tencent provider glossary labels
- Included post-review commit in the final squash: fix(tencent): repair TokenHub model defaults

Validation:
- ClawSweeper review passed for head 30c9fc130f.
- Required merge gates passed before the squash merge.

Prepared head SHA: 30c9fc130f
Review: https://github.com/openclaw/openclaw/pull/99076#issuecomment-4888527271

Co-authored-by: leisang <leisang@tencent.com>
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: hxy91819
2026-07-06 04:29:48 +00:00

121 lines
3.7 KiB
TypeScript

// Tencent config compatibility repairs shipped TokenHub model allowlists.
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
export const TENCENT_TOKENHUB_DEFAULT_MODEL_REF = "tencent-tokenhub/hy3";
export const TENCENT_TOKENHUB_PREVIEW_MODEL_REF = "tencent-tokenhub/hy3-preview";
const TOKENHUB_DEFAULT_ALIAS = "Hy3 (TokenHub)";
const TOKENHUB_PREVIEW_ALIAS = "Hy3 preview (TokenHub)";
type AgentDefaults = NonNullable<NonNullable<OpenClawConfig["agents"]>["defaults"]>;
type AgentDefaultModel = AgentDefaults["model"];
type AgentModelEntry = NonNullable<AgentDefaults["models"]>[string];
function isTokenHubModelMapConfigured(models: Record<string, AgentModelEntry>): boolean {
return (
Object.hasOwn(models, TENCENT_TOKENHUB_DEFAULT_MODEL_REF) ||
Object.hasOwn(models, TENCENT_TOKENHUB_PREVIEW_MODEL_REF)
);
}
function withDefaultAlias(entry: AgentModelEntry | undefined, alias: string): AgentModelEntry {
return {
...entry,
alias: entry?.alias ?? alias,
};
}
function needsDefaultAlias(entry: AgentModelEntry | undefined): boolean {
return entry?.alias === undefined;
}
function migrateDefaultModel(model: AgentDefaultModel): {
model: AgentDefaultModel;
changed: boolean;
} {
if (model === TENCENT_TOKENHUB_PREVIEW_MODEL_REF) {
return {
model: { primary: TENCENT_TOKENHUB_DEFAULT_MODEL_REF },
changed: true,
};
}
if (
model &&
typeof model === "object" &&
"primary" in model &&
model.primary === TENCENT_TOKENHUB_PREVIEW_MODEL_REF
) {
return {
model: {
...model,
primary: TENCENT_TOKENHUB_DEFAULT_MODEL_REF,
},
changed: true,
};
}
return { model, changed: false };
}
export function migrateTencentTokenHubModelDefaults(cfg: OpenClawConfig): {
config: OpenClawConfig;
changes: string[];
} {
const existingModels = cfg.agents?.defaults?.models;
if (!existingModels || !isTokenHubModelMapConfigured(existingModels)) {
return { config: cfg, changes: [] };
}
const needsDefaultRepair =
!Object.hasOwn(existingModels, TENCENT_TOKENHUB_DEFAULT_MODEL_REF) ||
needsDefaultAlias(existingModels[TENCENT_TOKENHUB_DEFAULT_MODEL_REF]);
const needsPreviewRepair =
!Object.hasOwn(existingModels, TENCENT_TOKENHUB_PREVIEW_MODEL_REF) ||
needsDefaultAlias(existingModels[TENCENT_TOKENHUB_PREVIEW_MODEL_REF]);
const migratedModel = migrateDefaultModel(cfg.agents?.defaults?.model);
if (!needsDefaultRepair && !needsPreviewRepair && !migratedModel.changed) {
return { config: cfg, changes: [] };
}
const nextModels = {
...existingModels,
[TENCENT_TOKENHUB_DEFAULT_MODEL_REF]: withDefaultAlias(
existingModels[TENCENT_TOKENHUB_DEFAULT_MODEL_REF],
TOKENHUB_DEFAULT_ALIAS,
),
[TENCENT_TOKENHUB_PREVIEW_MODEL_REF]: withDefaultAlias(
existingModels[TENCENT_TOKENHUB_PREVIEW_MODEL_REF],
TOKENHUB_PREVIEW_ALIAS,
),
};
const nextConfig: OpenClawConfig = {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
models: nextModels,
...(migratedModel.model !== undefined ? { model: migratedModel.model } : undefined),
},
},
};
const changes = [
`Updated Tencent TokenHub agent model defaults to include ${TENCENT_TOKENHUB_DEFAULT_MODEL_REF} and ${TENCENT_TOKENHUB_PREVIEW_MODEL_REF}.`,
];
if (migratedModel.changed) {
changes.push(
`Changed Tencent TokenHub primary default from ${TENCENT_TOKENHUB_PREVIEW_MODEL_REF} to ${TENCENT_TOKENHUB_DEFAULT_MODEL_REF}.`,
);
}
return { config: nextConfig, changes };
}
export function normalizeCompatibilityConfig({ cfg }: { cfg: OpenClawConfig }): {
config: OpenClawConfig;
changes: string[];
} {
return migrateTencentTokenHubModelDefaults(cfg);
}