Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

122 lines
2.7 KiB
TypeScript

import { AGENT_PROVIDERS, type AgentProvider } from "./agentSettings.providers";
import { normalizeBoolean, normalizeTextValue } from "./settingsNormalization";
export type AgentEnvRow = {
id: string;
key: string;
value: string;
enabled: boolean;
};
export type AgentEnvByProvider = Record<AgentProvider, AgentEnvRow[]>;
function isPlainRecord(value: unknown): value is Record<string, unknown> {
return !!value && typeof value === "object" && !Array.isArray(value);
}
const MAX_ENV_ROWS_PER_PROVIDER = 100;
const MAX_ENV_KEY_LENGTH = 120;
const MAX_ENV_VALUE_LENGTH = 10_000;
const ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
function normalizeAgentEnvRow(value: unknown): AgentEnvRow | null {
if (!isPlainRecord(value)) {
return null;
}
const id = normalizeTextValue(value.id);
const key = normalizeTextValue(value.key).slice(0, MAX_ENV_KEY_LENGTH);
const envValue = normalizeTextValue(value.value).slice(
0,
MAX_ENV_VALUE_LENGTH
);
const enabled = normalizeBoolean(value.enabled) ?? true;
if (id.length === 0 || key.length === 0) {
return null;
}
if (!ENV_KEY_PATTERN.test(key)) {
return null;
}
return { id, key, value: envValue, enabled };
}
function normalizeAgentEnvRows(value: unknown): AgentEnvRow[] {
if (!Array.isArray(value)) {
return [];
}
const normalized: AgentEnvRow[] = [];
const seenIds = new Set<string>();
for (const item of value) {
const row = normalizeAgentEnvRow(item);
if (!row) {
continue;
}
if (seenIds.has(row.id)) {
continue;
}
seenIds.add(row.id);
normalized.push(row);
if (normalized.length >= MAX_ENV_ROWS_PER_PROVIDER) {
break;
}
}
return normalized;
}
export const DEFAULT_AGENT_ENV_BY_PROVIDER: AgentEnvByProvider =
AGENT_PROVIDERS.reduce((acc, provider) => {
acc[provider] = [];
return acc;
}, {} as AgentEnvByProvider);
export function normalizeAgentEnvByProvider(
value: unknown
): AgentEnvByProvider {
if (!isPlainRecord(value)) {
return { ...DEFAULT_AGENT_ENV_BY_PROVIDER };
}
return AGENT_PROVIDERS.reduce((acc, provider) => {
acc[provider] = normalizeAgentEnvRows(value[provider]);
return acc;
}, {} as AgentEnvByProvider);
}
export function resolveEnabledEnvForAgent({
rows,
reservedPrefix = "TSH_"
}: {
rows: AgentEnvRow[];
reservedPrefix?: string;
}): Record<string, string> {
const resolved: Record<string, string> = {};
for (const row of rows) {
if (!row.enabled) {
continue;
}
const key = row.key.trim();
if (key.length === 0) {
continue;
}
if (reservedPrefix.length > 0 && key.startsWith(reservedPrefix)) {
continue;
}
resolved[key] = row.value;
}
return resolved;
}