mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:20:43 +00:00
refactor(lint): reduce map spread patterns
This commit is contained in:
@@ -32,11 +32,10 @@ function createExtensionFallbackBrowserHarness(options?: {
|
||||
|
||||
const pages = (options?.urls ?? [undefined]).map(
|
||||
(url) =>
|
||||
({
|
||||
on: pageOn,
|
||||
context: () => context,
|
||||
...(url ? { url: () => url } : {}),
|
||||
}) as unknown as import("playwright-core").Page,
|
||||
Object.assign(
|
||||
{ on: pageOn, context: () => context },
|
||||
url ? { url: () => url } : {},
|
||||
) as unknown as import("playwright-core").Page,
|
||||
);
|
||||
(context as unknown as { pages: () => unknown[] }).pages = () => pages;
|
||||
|
||||
|
||||
@@ -106,11 +106,12 @@ export async function handleDiscordPresenceAction(
|
||||
return jsonResult({
|
||||
ok: true,
|
||||
status,
|
||||
activities: activities.map((a) => ({
|
||||
type: a.type,
|
||||
name: a.name,
|
||||
...(a.url ? { url: a.url } : {}),
|
||||
...(a.state ? { state: a.state } : {}),
|
||||
})),
|
||||
activities: activities.map((a) =>
|
||||
Object.assign(
|
||||
{ type: a.type, name: a.name },
|
||||
a.url ? { url: a.url } : {},
|
||||
a.state ? { state: a.state } : {},
|
||||
),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -497,15 +497,17 @@ export async function executeExaWebSearchProviderTool(
|
||||
typeof entry.publishedDate === "string" && entry.publishedDate
|
||||
? entry.publishedDate
|
||||
: undefined;
|
||||
return {
|
||||
title: title ? wrapWebContent(title, "web_search") : "",
|
||||
url,
|
||||
description: description ? wrapWebContent(description, "web_search") : "",
|
||||
published,
|
||||
siteName: resolveSiteName(url) || undefined,
|
||||
...(summary ? { summary: wrapWebContent(summary, "web_search") } : {}),
|
||||
...(highlightScores.length > 0 ? { highlightScores } : {}),
|
||||
};
|
||||
return Object.assign(
|
||||
{
|
||||
title: title ? wrapWebContent(title, `web_search`) : ``,
|
||||
url,
|
||||
description: description ? wrapWebContent(description, `web_search`) : ``,
|
||||
published,
|
||||
siteName: resolveSiteName(url) || undefined,
|
||||
},
|
||||
summary ? { summary: wrapWebContent(summary, `web_search`) } : {},
|
||||
highlightScores.length > 0 ? { highlightScores } : {},
|
||||
);
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
@@ -154,10 +154,12 @@ export async function sendGoogleChatMessage(params: {
|
||||
body.thread = { name: thread };
|
||||
}
|
||||
if (attachments && attachments.length > 0) {
|
||||
body.attachment = attachments.map((item) => ({
|
||||
attachmentDataRef: { attachmentUploadToken: item.attachmentUploadToken },
|
||||
...(item.contentName ? { contentName: item.contentName } : {}),
|
||||
}));
|
||||
body.attachment = attachments.map((item) =>
|
||||
Object.assign(
|
||||
{ attachmentDataRef: { attachmentUploadToken: item.attachmentUploadToken } },
|
||||
item.contentName ? { contentName: item.contentName } : {},
|
||||
),
|
||||
);
|
||||
}
|
||||
const urlObj = new URL(`${CHAT_API_BASE}/${space}/messages`);
|
||||
if (thread) {
|
||||
|
||||
@@ -403,19 +403,21 @@ export async function listMemoryWikiImportInsights(
|
||||
const updatedAt = sortedItems
|
||||
.map((item) => item.updatedAt ?? item.createdAt)
|
||||
.find((value): value is string => typeof value === "string" && value.length > 0);
|
||||
return {
|
||||
key,
|
||||
label: sortedItems[0]?.topicLabel ?? humanizeLabelSuffix(key),
|
||||
itemCount: sortedItems.length,
|
||||
highRiskCount: sortedItems.filter((item) => item.riskLevel === "high").length,
|
||||
withheldCount: sortedItems.filter((item) => item.digestStatus === "withheld").length,
|
||||
preferenceSignalCount: sortedItems.reduce(
|
||||
(sum, item) => sum + item.preferenceSignals.length,
|
||||
0,
|
||||
),
|
||||
...(updatedAt ? { updatedAt } : {}),
|
||||
items: sortedItems,
|
||||
} satisfies MemoryWikiImportInsightCluster;
|
||||
return Object.assign(
|
||||
{
|
||||
key,
|
||||
label: sortedItems[0]?.topicLabel ?? humanizeLabelSuffix(key),
|
||||
itemCount: sortedItems.length,
|
||||
highRiskCount: sortedItems.filter((item) => item.riskLevel === `high`).length,
|
||||
withheldCount: sortedItems.filter((item) => item.digestStatus === `withheld`).length,
|
||||
preferenceSignalCount: sortedItems.reduce(
|
||||
(sum, item) => sum + item.preferenceSignals.length,
|
||||
0,
|
||||
),
|
||||
},
|
||||
updatedAt ? { updatedAt } : {},
|
||||
{ items: sortedItems },
|
||||
) satisfies MemoryWikiImportInsightCluster;
|
||||
})
|
||||
.toSorted((left, right) => {
|
||||
const leftKey = left.updatedAt ?? "";
|
||||
|
||||
@@ -92,25 +92,23 @@ export async function listMemoryWikiPalace(
|
||||
const items = pages
|
||||
.map((page) => {
|
||||
const parsed = parseWikiMarkdown(page.raw);
|
||||
return {
|
||||
pagePath: page.relativePath,
|
||||
title: page.title,
|
||||
kind: page.kind,
|
||||
...(page.id ? { id: page.id } : {}),
|
||||
...(normalizeTimestamp(page.updatedAt)
|
||||
? { updatedAt: normalizeTimestamp(page.updatedAt) }
|
||||
: {}),
|
||||
...(typeof page.sourceType === "string" && page.sourceType.trim().length > 0
|
||||
return Object.assign(
|
||||
{ pagePath: page.relativePath, title: page.title, kind: page.kind },
|
||||
page.id ? { id: page.id } : {},
|
||||
normalizeTimestamp(page.updatedAt) ? { updatedAt: normalizeTimestamp(page.updatedAt) } : {},
|
||||
typeof page.sourceType === `string` && page.sourceType.trim().length > 0
|
||||
? { sourceType: page.sourceType.trim() }
|
||||
: {}),
|
||||
claimCount: page.claims.length,
|
||||
questionCount: page.questions.length,
|
||||
contradictionCount: page.contradictions.length,
|
||||
claims: page.claims.map((claim) => claim.text).slice(0, 3),
|
||||
questions: page.questions.slice(0, 3),
|
||||
contradictions: page.contradictions.slice(0, 3),
|
||||
...(extractSnippet(parsed.body) ? { snippet: extractSnippet(parsed.body) } : {}),
|
||||
} satisfies MemoryWikiPalaceItem;
|
||||
: {},
|
||||
{
|
||||
claimCount: page.claims.length,
|
||||
questionCount: page.questions.length,
|
||||
contradictionCount: page.contradictions.length,
|
||||
claims: page.claims.map((claim) => claim.text).slice(0, 3),
|
||||
questions: page.questions.slice(0, 3),
|
||||
contradictions: page.contradictions.slice(0, 3),
|
||||
},
|
||||
extractSnippet(parsed.body) ? { snippet: extractSnippet(parsed.body) } : {},
|
||||
) satisfies MemoryWikiPalaceItem;
|
||||
})
|
||||
.filter(
|
||||
(item) =>
|
||||
@@ -126,16 +124,18 @@ export async function listMemoryWikiPalace(
|
||||
if (clusterItems.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
key: kind,
|
||||
label: PALACE_KIND_LABELS[kind],
|
||||
itemCount: clusterItems.length,
|
||||
claimCount: clusterItems.reduce((sum, item) => sum + item.claimCount, 0),
|
||||
questionCount: clusterItems.reduce((sum, item) => sum + item.questionCount, 0),
|
||||
contradictionCount: clusterItems.reduce((sum, item) => sum + item.contradictionCount, 0),
|
||||
...(clusterItems[0]?.updatedAt ? { updatedAt: clusterItems[0].updatedAt } : {}),
|
||||
items: clusterItems,
|
||||
} satisfies MemoryWikiPalaceCluster;
|
||||
return Object.assign(
|
||||
{
|
||||
key: kind,
|
||||
label: PALACE_KIND_LABELS[kind],
|
||||
itemCount: clusterItems.length,
|
||||
claimCount: clusterItems.reduce((sum, item) => sum + item.claimCount, 0),
|
||||
questionCount: clusterItems.reduce((sum, item) => sum + item.questionCount, 0),
|
||||
contradictionCount: clusterItems.reduce((sum, item) => sum + item.contradictionCount, 0),
|
||||
},
|
||||
clusterItems[0]?.updatedAt ? { updatedAt: clusterItems[0].updatedAt } : {},
|
||||
{ items: clusterItems },
|
||||
) satisfies MemoryWikiPalaceCluster;
|
||||
}).filter((entry): entry is MemoryWikiPalaceCluster => entry !== null);
|
||||
|
||||
return {
|
||||
|
||||
@@ -126,11 +126,13 @@ export const entraIdAuthMethod: ProviderAuthMethod = {
|
||||
selectedResource,
|
||||
resourceDeployments,
|
||||
);
|
||||
discoveredDeployments = resourceDeployments.map((deployment) => ({
|
||||
name: deployment.name,
|
||||
...(deployment.modelName ? { modelName: deployment.modelName } : {}),
|
||||
api: resolveFoundryApi(deployment.name, deployment.modelName),
|
||||
}));
|
||||
discoveredDeployments = resourceDeployments.map((deployment) =>
|
||||
Object.assign(
|
||||
{ name: deployment.name },
|
||||
deployment.modelName ? { modelName: deployment.modelName } : {},
|
||||
{ api: resolveFoundryApi(deployment.name, deployment.modelName) },
|
||||
),
|
||||
);
|
||||
endpoint = selectedResource.endpoint;
|
||||
modelId = selectedDeployment.name;
|
||||
modelNameHint = resolveConfiguredModelNameHint(modelId, selectedDeployment.modelName);
|
||||
|
||||
@@ -301,17 +301,19 @@ export function buildFoundryProviderConfig(
|
||||
deployment.modelName,
|
||||
deployment.api,
|
||||
);
|
||||
return {
|
||||
id: deployment.name,
|
||||
name: capabilities.modelName,
|
||||
api: capabilities.api,
|
||||
reasoning: false,
|
||||
input: capabilities.input,
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 128_000,
|
||||
maxTokens: 16_384,
|
||||
...(capabilities.compat ? { compat: capabilities.compat } : {}),
|
||||
};
|
||||
return Object.assign(
|
||||
{
|
||||
id: deployment.name,
|
||||
name: capabilities.modelName,
|
||||
api: capabilities.api,
|
||||
reasoning: false,
|
||||
input: capabilities.input,
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 128e3,
|
||||
maxTokens: 16384,
|
||||
},
|
||||
capabilities.compat ? { compat: capabilities.compat } : {},
|
||||
);
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -152,12 +152,14 @@ export function buildOpenAIImageGenerationProvider(): ImageGenerationProvider {
|
||||
if (!entry.b64_json) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
buffer: Buffer.from(entry.b64_json, "base64"),
|
||||
mimeType: DEFAULT_OUTPUT_MIME,
|
||||
fileName: `image-${index + 1}.png`,
|
||||
...(entry.revised_prompt ? { revisedPrompt: entry.revised_prompt } : {}),
|
||||
};
|
||||
return Object.assign(
|
||||
{
|
||||
buffer: Buffer.from(entry.b64_json, `base64`),
|
||||
mimeType: DEFAULT_OUTPUT_MIME,
|
||||
fileName: `image-${index + 1}.png`,
|
||||
},
|
||||
entry.revised_prompt ? { revisedPrompt: entry.revised_prompt } : {},
|
||||
);
|
||||
})
|
||||
.filter((entry): entry is NonNullable<typeof entry> => entry !== null);
|
||||
|
||||
|
||||
@@ -369,13 +369,20 @@ export function buildQaAgenticParityComparison(params: {
|
||||
.map((name) => {
|
||||
const candidate = candidateByName.get(name);
|
||||
const baseline = baselineByName.get(name);
|
||||
return {
|
||||
const candidateStatus = candidate ? normalizeScenarioStatus(candidate.status) : "missing";
|
||||
const baselineStatus = baseline ? normalizeScenarioStatus(baseline.status) : "missing";
|
||||
const comparison: QaAgenticParityScenarioComparison = {
|
||||
name,
|
||||
candidateStatus: candidate ? normalizeScenarioStatus(candidate.status) : "missing",
|
||||
baselineStatus: baseline ? normalizeScenarioStatus(baseline.status) : "missing",
|
||||
...(candidate?.details ? { candidateDetails: candidate.details } : {}),
|
||||
...(baseline?.details ? { baselineDetails: baseline.details } : {}),
|
||||
} satisfies QaAgenticParityScenarioComparison;
|
||||
candidateStatus,
|
||||
baselineStatus,
|
||||
};
|
||||
if (candidate?.details) {
|
||||
comparison.candidateDetails = candidate.details;
|
||||
}
|
||||
if (baseline?.details) {
|
||||
comparison.baselineDetails = baseline.details;
|
||||
}
|
||||
return comparison;
|
||||
});
|
||||
|
||||
const failures: string[] = [];
|
||||
|
||||
@@ -86,11 +86,12 @@ function buildButtonsBlock(
|
||||
}
|
||||
return {
|
||||
type: "buttons",
|
||||
buttons: choices.map((choice) => ({
|
||||
label: choice.label,
|
||||
value: choice.value,
|
||||
...(choice.style ? { style: choice.style } : {}),
|
||||
})),
|
||||
buttons: choices.map((choice) =>
|
||||
Object.assign(
|
||||
{ label: choice.label, value: choice.value },
|
||||
choice.style ? { style: choice.style } : {},
|
||||
),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -137,13 +137,17 @@ export async function runTavilySearch(
|
||||
);
|
||||
|
||||
const rawResults = Array.isArray(payload.results) ? payload.results : [];
|
||||
const results = rawResults.map((r: Record<string, unknown>) => ({
|
||||
title: typeof r.title === "string" ? wrapWebContent(r.title, "web_search") : "",
|
||||
url: typeof r.url === "string" ? r.url : "",
|
||||
snippet: typeof r.content === "string" ? wrapWebContent(r.content, "web_search") : "",
|
||||
score: typeof r.score === "number" ? r.score : undefined,
|
||||
...(typeof r.published_date === "string" ? { published: r.published_date } : {}),
|
||||
}));
|
||||
const results = rawResults.map((r: Record<string, unknown>) =>
|
||||
Object.assign(
|
||||
{
|
||||
title: typeof r.title === `string` ? wrapWebContent(r.title, `web_search`) : ``,
|
||||
url: typeof r.url === `string` ? r.url : ``,
|
||||
snippet: typeof r.content === `string` ? wrapWebContent(r.content, `web_search`) : ``,
|
||||
score: typeof r.score === `number` ? r.score : undefined,
|
||||
},
|
||||
typeof r.published_date === `string` ? { published: r.published_date } : {},
|
||||
),
|
||||
);
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
query: params.query,
|
||||
@@ -227,23 +231,29 @@ export async function runTavilyExtract(
|
||||
);
|
||||
|
||||
const rawResults = Array.isArray(payload.results) ? payload.results : [];
|
||||
const results = rawResults.map((r: Record<string, unknown>) => ({
|
||||
url: typeof r.url === "string" ? r.url : "",
|
||||
rawContent:
|
||||
typeof r.raw_content === "string"
|
||||
? wrapExternalContent(r.raw_content, { source: "web_fetch", includeWarning: false })
|
||||
: "",
|
||||
...(typeof r.content === "string"
|
||||
? { content: wrapExternalContent(r.content, { source: "web_fetch", includeWarning: false }) }
|
||||
: {}),
|
||||
...(Array.isArray(r.images)
|
||||
? {
|
||||
images: (r.images as string[]).map((img) =>
|
||||
wrapExternalContent(img, { source: "web_fetch", includeWarning: false }),
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
}));
|
||||
const results = rawResults.map((r: Record<string, unknown>) =>
|
||||
Object.assign(
|
||||
{
|
||||
url: typeof r.url === `string` ? r.url : ``,
|
||||
rawContent:
|
||||
typeof r.raw_content === `string`
|
||||
? wrapExternalContent(r.raw_content, { source: `web_fetch`, includeWarning: false })
|
||||
: ``,
|
||||
},
|
||||
typeof r.content === `string`
|
||||
? {
|
||||
content: wrapExternalContent(r.content, { source: `web_fetch`, includeWarning: false }),
|
||||
}
|
||||
: {},
|
||||
Array.isArray(r.images)
|
||||
? {
|
||||
images: (r.images as string[]).map((img) =>
|
||||
wrapExternalContent(img, { source: `web_fetch`, includeWarning: false }),
|
||||
),
|
||||
}
|
||||
: {},
|
||||
),
|
||||
);
|
||||
|
||||
const failedResults = Array.isArray(payload.failed_results) ? payload.failed_results : [];
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@ export function buildInlineKeyboard(
|
||||
row
|
||||
.filter((button) => button?.text && button?.callback_data)
|
||||
.map(
|
||||
(button): InlineKeyboardButton => ({
|
||||
text: button.text,
|
||||
callback_data: button.callback_data,
|
||||
...(button.style ? { style: button.style } : {}),
|
||||
}),
|
||||
(button): InlineKeyboardButton =>
|
||||
Object.assign(
|
||||
{ text: button.text, callback_data: button.callback_data },
|
||||
button.style ? { style: button.style } : {},
|
||||
),
|
||||
),
|
||||
)
|
||||
.filter((row) => row.length > 0);
|
||||
|
||||
@@ -277,10 +277,11 @@ export function createExtensionTestShards(params = {}) {
|
||||
}
|
||||
|
||||
return shards
|
||||
.map((shard, index) => ({
|
||||
index,
|
||||
checkName: `checks-node-extensions-shard-${index + 1}`,
|
||||
...mergeTestPlans(shard.plans),
|
||||
}))
|
||||
.map((shard, index) =>
|
||||
Object.assign(
|
||||
{ index, checkName: `checks-node-extensions-shard-${index + 1}` },
|
||||
mergeTestPlans(shard.plans),
|
||||
),
|
||||
)
|
||||
.filter((shard) => shard.hasTests);
|
||||
}
|
||||
|
||||
@@ -157,13 +157,15 @@ export function resolveEffectiveToolInventory(
|
||||
effectiveTools
|
||||
.map((tool) => {
|
||||
const source = resolveEffectiveToolSource(tool);
|
||||
return {
|
||||
id: tool.name,
|
||||
label: resolveEffectiveToolLabel(tool),
|
||||
description: summarizeToolDescription(tool),
|
||||
rawDescription: resolveRawToolDescription(tool) || summarizeToolDescription(tool),
|
||||
...source,
|
||||
} satisfies EffectiveToolInventoryEntry;
|
||||
return Object.assign(
|
||||
{
|
||||
id: tool.name,
|
||||
label: resolveEffectiveToolLabel(tool),
|
||||
description: summarizeToolDescription(tool),
|
||||
rawDescription: resolveRawToolDescription(tool) || summarizeToolDescription(tool),
|
||||
},
|
||||
source,
|
||||
) satisfies EffectiveToolInventoryEntry;
|
||||
})
|
||||
.toSorted((a, b) => a.label.localeCompare(b.label)),
|
||||
);
|
||||
|
||||
@@ -396,20 +396,24 @@ export function createImageGenerateTool(options?: {
|
||||
const action = resolveAction(params);
|
||||
if (action === "list") {
|
||||
const runtimeProviders = listRuntimeImageGenerationProviders({ config: effectiveCfg });
|
||||
const providers = runtimeProviders.map((provider) => ({
|
||||
id: provider.id,
|
||||
...(provider.label ? { label: provider.label } : {}),
|
||||
...(provider.defaultModel ? { defaultModel: provider.defaultModel } : {}),
|
||||
models: provider.models ?? (provider.defaultModel ? [provider.defaultModel] : []),
|
||||
configured: isCapabilityProviderConfigured({
|
||||
providers: runtimeProviders,
|
||||
provider,
|
||||
cfg: effectiveCfg,
|
||||
agentDir: options?.agentDir,
|
||||
}),
|
||||
authEnvVars: getImageGenerationProviderAuthEnvVars(provider.id),
|
||||
capabilities: provider.capabilities,
|
||||
}));
|
||||
const providers = runtimeProviders.map((provider) =>
|
||||
Object.assign(
|
||||
{ id: provider.id },
|
||||
provider.label ? { label: provider.label } : {},
|
||||
provider.defaultModel ? { defaultModel: provider.defaultModel } : {},
|
||||
{
|
||||
models: provider.models ?? (provider.defaultModel ? [provider.defaultModel] : []),
|
||||
configured: isCapabilityProviderConfigured({
|
||||
providers: runtimeProviders,
|
||||
provider,
|
||||
cfg: effectiveCfg,
|
||||
agentDir: options?.agentDir,
|
||||
}),
|
||||
authEnvVars: getImageGenerationProviderAuthEnvVars(provider.id),
|
||||
capabilities: provider.capabilities,
|
||||
},
|
||||
),
|
||||
);
|
||||
const lines = providers.flatMap((provider) => {
|
||||
const caps: string[] = [];
|
||||
if (provider.capabilities.edit.enabled) {
|
||||
|
||||
@@ -524,10 +524,12 @@ export function createImageTool(options?: {
|
||||
: {}),
|
||||
}
|
||||
: {
|
||||
images: loadedImages.map((img) => ({
|
||||
image: img.resolvedImage,
|
||||
...(img.rewrittenFrom ? { rewrittenFrom: img.rewrittenFrom } : {}),
|
||||
})),
|
||||
images: loadedImages.map((img) =>
|
||||
Object.assign(
|
||||
{ image: img.resolvedImage },
|
||||
img.rewrittenFrom ? { rewrittenFrom: img.rewrittenFrom } : {},
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
return buildTextToolResult(result, imageDetails);
|
||||
|
||||
@@ -457,10 +457,12 @@ export function createPdfTool(options?: {
|
||||
: {}),
|
||||
}
|
||||
: {
|
||||
pdfs: loadedPdfs.map((p) => ({
|
||||
pdf: p.resolvedPath,
|
||||
...(p.rewrittenFrom ? { rewrittenFrom: p.rewrittenFrom } : {}),
|
||||
})),
|
||||
pdfs: loadedPdfs.map((p) =>
|
||||
Object.assign(
|
||||
{ pdf: p.resolvedPath },
|
||||
p.rewrittenFrom ? { rewrittenFrom: p.rewrittenFrom } : {},
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
return buildTextToolResult(result, { native: result.native, ...pdfDetails });
|
||||
|
||||
@@ -249,13 +249,17 @@ function mergeExecutionTrace(params: {
|
||||
runner: "embedded" | "cli";
|
||||
}): TraceExecutionView | undefined {
|
||||
const attempts: TraceAttemptView[] = [
|
||||
...(params.fallbackAttempts ?? []).map((attempt) => ({
|
||||
provider: attempt.provider,
|
||||
model: attempt.model,
|
||||
result: inferFallbackAttemptResult(attempt),
|
||||
...(attempt.reason ? { reason: attempt.reason } : {}),
|
||||
...(typeof attempt.status === "number" ? { status: attempt.status } : {}),
|
||||
})),
|
||||
...(params.fallbackAttempts ?? []).map((attempt) =>
|
||||
Object.assign(
|
||||
{
|
||||
provider: attempt.provider,
|
||||
model: attempt.model,
|
||||
result: inferFallbackAttemptResult(attempt),
|
||||
},
|
||||
attempt.reason ? { reason: attempt.reason } : {},
|
||||
typeof attempt.status === `number` ? { status: attempt.status } : {},
|
||||
),
|
||||
),
|
||||
...(params.executionTrace?.attempts ?? []),
|
||||
];
|
||||
const winnerProvider =
|
||||
|
||||
@@ -1012,15 +1012,17 @@ async function runTtsProviders(transport: CapabilityTransport) {
|
||||
...payload,
|
||||
providers: (payload.providers ?? []).map((provider) => {
|
||||
const id = typeof provider.id === "string" ? provider.id : "";
|
||||
return {
|
||||
available: true,
|
||||
configured:
|
||||
typeof provider.configured === "boolean"
|
||||
? provider.configured
|
||||
: providerHasGenericConfig({ cfg, providerId: id }),
|
||||
selected: Boolean(id && payload.active === id),
|
||||
...provider,
|
||||
};
|
||||
return Object.assign(
|
||||
{
|
||||
available: true,
|
||||
configured:
|
||||
typeof provider.configured === `boolean`
|
||||
? provider.configured
|
||||
: providerHasGenericConfig({ cfg, providerId: id }),
|
||||
selected: Boolean(id && payload.active === id),
|
||||
},
|
||||
provider,
|
||||
);
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,24 +31,27 @@ function resolveProviderChoiceOptions(params?: {
|
||||
return resolveProviderSetupFlowContributions({
|
||||
...params,
|
||||
scope: "text-inference",
|
||||
}).map((contribution) => ({
|
||||
value: contribution.option.value as AuthChoice,
|
||||
label: contribution.option.label,
|
||||
...(contribution.option.hint ? { hint: contribution.option.hint } : {}),
|
||||
...(contribution.option.assistantPriority !== undefined
|
||||
? { assistantPriority: contribution.option.assistantPriority }
|
||||
: {}),
|
||||
...(contribution.option.assistantVisibility
|
||||
? { assistantVisibility: contribution.option.assistantVisibility }
|
||||
: {}),
|
||||
...(contribution.option.group
|
||||
? {
|
||||
groupId: contribution.option.group.id as AuthChoiceGroupId,
|
||||
groupLabel: contribution.option.group.label,
|
||||
...(contribution.option.group.hint ? { groupHint: contribution.option.group.hint } : {}),
|
||||
}
|
||||
: {}),
|
||||
}));
|
||||
}).map((contribution) =>
|
||||
Object.assign(
|
||||
{ value: contribution.option.value as AuthChoice, label: contribution.option.label },
|
||||
contribution.option.hint ? { hint: contribution.option.hint } : {},
|
||||
contribution.option.assistantPriority !== undefined
|
||||
? { assistantPriority: contribution.option.assistantPriority }
|
||||
: {},
|
||||
contribution.option.assistantVisibility
|
||||
? { assistantVisibility: contribution.option.assistantVisibility }
|
||||
: {},
|
||||
contribution.option.group
|
||||
? {
|
||||
groupId: contribution.option.group.id as AuthChoiceGroupId,
|
||||
groupLabel: contribution.option.group.label,
|
||||
...(contribution.option.group.hint
|
||||
? { groupHint: contribution.option.group.hint }
|
||||
: {}),
|
||||
}
|
||||
: {},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function formatAuthChoiceChoicesForCli(params?: {
|
||||
|
||||
@@ -443,12 +443,12 @@ function setMergedSchemaCache(key: string, value: ConfigSchemaResponse): void {
|
||||
|
||||
function getBundledChannelSchemaMetadata(): ChannelUiMetadata[] {
|
||||
return GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA.map((entry) => {
|
||||
const metadata: ChannelUiMetadata = {
|
||||
id: entry.channelId,
|
||||
...(entry.label ? { label: entry.label } : {}),
|
||||
...(entry.description ? { description: entry.description } : {}),
|
||||
configSchema: entry.schema,
|
||||
};
|
||||
const metadata: ChannelUiMetadata = Object.assign(
|
||||
{ id: entry.channelId },
|
||||
entry.label ? { label: entry.label } : {},
|
||||
entry.description ? { description: entry.description } : {},
|
||||
{ configSchema: entry.schema },
|
||||
);
|
||||
if ("uiHints" in entry) {
|
||||
metadata.configUiHints = entry.uiHints as ChannelUiMetadata["configUiHints"];
|
||||
}
|
||||
|
||||
@@ -319,11 +319,12 @@ async function resolveProviderPluginSetupOptions(params: {
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
});
|
||||
return providerModelPickerOptions.map((entry) => ({
|
||||
value: entry.value,
|
||||
label: entry.label,
|
||||
...(entry.hint ? { hint: entry.hint } : {}),
|
||||
}));
|
||||
return providerModelPickerOptions.map((entry) =>
|
||||
Object.assign(
|
||||
{ value: entry.value, label: entry.label },
|
||||
entry.hint ? { hint: entry.hint } : {},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async function maybeHandleProviderPluginSelection(params: {
|
||||
|
||||
@@ -83,33 +83,37 @@ export function resolveProviderSetupFlowContributions(params?: {
|
||||
return sortFlowContributionsByLabel(
|
||||
resolveProviderWizardOptions(params ?? {})
|
||||
.filter((option) => includesProviderFlowScope(option.onboardingScopes, scope))
|
||||
.map((option) => ({
|
||||
id: `provider:setup:${option.value}`,
|
||||
kind: "provider" as const,
|
||||
surface: "setup" as const,
|
||||
providerId: option.groupId,
|
||||
option: {
|
||||
value: option.value,
|
||||
label: option.label,
|
||||
...(option.hint ? { hint: option.hint } : {}),
|
||||
...(option.assistantPriority !== undefined
|
||||
? { assistantPriority: option.assistantPriority }
|
||||
: {}),
|
||||
...(option.assistantVisibility
|
||||
? { assistantVisibility: option.assistantVisibility }
|
||||
: {}),
|
||||
group: {
|
||||
id: option.groupId,
|
||||
label: option.groupLabel,
|
||||
...(option.groupHint ? { hint: option.groupHint } : {}),
|
||||
.map((option) =>
|
||||
Object.assign(
|
||||
{
|
||||
id: `provider:setup:${option.value}`,
|
||||
kind: `provider` as const,
|
||||
surface: `setup` as const,
|
||||
providerId: option.groupId,
|
||||
option: {
|
||||
value: option.value,
|
||||
label: option.label,
|
||||
...(option.hint ? { hint: option.hint } : {}),
|
||||
...(option.assistantPriority !== undefined
|
||||
? { assistantPriority: option.assistantPriority }
|
||||
: {}),
|
||||
...(option.assistantVisibility
|
||||
? { assistantVisibility: option.assistantVisibility }
|
||||
: {}),
|
||||
group: {
|
||||
id: option.groupId,
|
||||
label: option.groupLabel,
|
||||
...(option.groupHint ? { hint: option.groupHint } : {}),
|
||||
},
|
||||
...(docsByProvider.get(option.groupId)
|
||||
? { docs: { path: docsByProvider.get(option.groupId)! } }
|
||||
: {}),
|
||||
},
|
||||
},
|
||||
...(docsByProvider.get(option.groupId)
|
||||
? { docs: { path: docsByProvider.get(option.groupId)! } }
|
||||
: {}),
|
||||
},
|
||||
...(option.onboardingScopes ? { onboardingScopes: [...option.onboardingScopes] } : {}),
|
||||
source: "runtime" as const,
|
||||
})),
|
||||
option.onboardingScopes ? { onboardingScopes: [...option.onboardingScopes] } : {},
|
||||
{ source: `runtime` as const },
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -699,13 +699,15 @@ export function listAgentsForGateway(cfg: OpenClawConfig): {
|
||||
const agents = agentIds.map((id) => {
|
||||
const meta = configuredById.get(id);
|
||||
const model = resolveGatewayAgentModel(cfg, id);
|
||||
return {
|
||||
id,
|
||||
name: meta?.name,
|
||||
identity: meta?.identity,
|
||||
workspace: resolveAgentWorkspaceDir(cfg, id),
|
||||
...(model ? { model } : {}),
|
||||
};
|
||||
return Object.assign(
|
||||
{
|
||||
id,
|
||||
name: meta?.name,
|
||||
identity: meta?.identity,
|
||||
workspace: resolveAgentWorkspaceDir(cfg, id),
|
||||
},
|
||||
model ? { model } : {},
|
||||
);
|
||||
});
|
||||
return { defaultId, mainKey, scope, agents };
|
||||
}
|
||||
|
||||
@@ -762,7 +762,7 @@ export async function loadSessionCostSummary(params: {
|
||||
if (!stats) {
|
||||
return null;
|
||||
}
|
||||
return { date, ...stats };
|
||||
return Object.assign({ date }, stats);
|
||||
})
|
||||
.filter((entry): entry is SessionDailyLatency => Boolean(entry))
|
||||
.toSorted((a, b) => a.date.localeCompare(b.date));
|
||||
|
||||
@@ -98,10 +98,9 @@ describe("plugin shape compatibility matrix", () => {
|
||||
workspaceDir: "/virtual-workspace",
|
||||
...registry.registry,
|
||||
};
|
||||
const inspect = report.plugins.map((plugin) => ({
|
||||
plugin,
|
||||
...buildPluginShapeSummary({ plugin, report }),
|
||||
}));
|
||||
const inspect = report.plugins.map((plugin) =>
|
||||
Object.assign({ plugin }, buildPluginShapeSummary({ plugin, report })),
|
||||
);
|
||||
|
||||
expect(
|
||||
inspect.map((entry) => ({
|
||||
|
||||
@@ -97,18 +97,20 @@ export function buildConfigureCandidatesForScope(params: {
|
||||
const refPathExists = entry.refPathSegments
|
||||
? hasPathInAuthoredConfig(entry.refPathSegments)
|
||||
: false;
|
||||
return {
|
||||
type: entry.entry.targetType,
|
||||
path: entry.path,
|
||||
pathSegments: [...entry.pathSegments],
|
||||
label: entry.path,
|
||||
configFile: "openclaw.json" as const,
|
||||
expectedResolvedValue: entry.entry.expectedResolvedValue,
|
||||
...(resolved.ref ? { existingRef: resolved.ref } : {}),
|
||||
...(pathExists || refPathExists ? {} : { isDerived: true }),
|
||||
...(entry.providerId ? { providerId: entry.providerId } : {}),
|
||||
...(entry.accountId ? { accountId: entry.accountId } : {}),
|
||||
};
|
||||
return Object.assign(
|
||||
{
|
||||
type: entry.entry.targetType,
|
||||
path: entry.path,
|
||||
pathSegments: [...entry.pathSegments],
|
||||
label: entry.path,
|
||||
configFile: `openclaw.json` as const,
|
||||
expectedResolvedValue: entry.entry.expectedResolvedValue,
|
||||
},
|
||||
resolved.ref ? { existingRef: resolved.ref } : {},
|
||||
pathExists || refPathExists ? {} : { isDerived: true },
|
||||
entry.providerId ? { providerId: entry.providerId } : {},
|
||||
entry.accountId ? { accountId: entry.accountId } : {},
|
||||
);
|
||||
});
|
||||
|
||||
const authCandidates =
|
||||
@@ -130,17 +132,19 @@ export function buildConfigureCandidatesForScope(params: {
|
||||
refValue: entry.refValue,
|
||||
defaults: params.config.secrets?.defaults,
|
||||
});
|
||||
return {
|
||||
type: entry.entry.targetType,
|
||||
path: entry.path,
|
||||
pathSegments: [...entry.pathSegments],
|
||||
label: `${entry.path} (auth profile, agent ${authProfiles.agentId})`,
|
||||
configFile: "auth-profiles.json" as const,
|
||||
expectedResolvedValue: entry.entry.expectedResolvedValue,
|
||||
...(resolved.ref ? { existingRef: resolved.ref } : {}),
|
||||
agentId: authProfiles.agentId,
|
||||
...(authProfileProvider ? { authProfileProvider } : {}),
|
||||
};
|
||||
return Object.assign(
|
||||
{
|
||||
type: entry.entry.targetType,
|
||||
path: entry.path,
|
||||
pathSegments: [...entry.pathSegments],
|
||||
label: `${entry.path} (auth profile, agent ${authProfiles.agentId})`,
|
||||
configFile: `auth-profiles.json` as const,
|
||||
expectedResolvedValue: entry.entry.expectedResolvedValue,
|
||||
},
|
||||
resolved.ref ? { existingRef: resolved.ref } : {},
|
||||
{ agentId: authProfiles.agentId },
|
||||
authProfileProvider ? { authProfileProvider } : {},
|
||||
);
|
||||
});
|
||||
|
||||
return [...openclawCandidates, ...authCandidates].toSorted((a, b) =>
|
||||
@@ -234,16 +238,20 @@ export function buildSecretsConfigurePlan(params: {
|
||||
protocolVersion: 1,
|
||||
generatedAt: params.generatedAt ?? new Date().toISOString(),
|
||||
generatedBy: "openclaw secrets configure",
|
||||
targets: [...params.selectedTargets.values()].map((entry) => ({
|
||||
type: entry.type,
|
||||
path: entry.path,
|
||||
pathSegments: [...entry.pathSegments],
|
||||
ref: entry.ref,
|
||||
...(entry.agentId ? { agentId: entry.agentId } : {}),
|
||||
...(entry.providerId ? { providerId: entry.providerId } : {}),
|
||||
...(entry.accountId ? { accountId: entry.accountId } : {}),
|
||||
...(entry.authProfileProvider ? { authProfileProvider: entry.authProfileProvider } : {}),
|
||||
})),
|
||||
targets: [...params.selectedTargets.values()].map((entry) =>
|
||||
Object.assign(
|
||||
{
|
||||
type: entry.type,
|
||||
path: entry.path,
|
||||
pathSegments: [...entry.pathSegments],
|
||||
ref: entry.ref,
|
||||
},
|
||||
entry.agentId ? { agentId: entry.agentId } : {},
|
||||
entry.providerId ? { providerId: entry.providerId } : {},
|
||||
entry.accountId ? { accountId: entry.accountId } : {},
|
||||
entry.authProfileProvider ? { authProfileProvider: entry.authProfileProvider } : {},
|
||||
),
|
||||
),
|
||||
...(Object.keys(params.providerChanges.upserts).length > 0
|
||||
? { providerUpserts: params.providerChanges.upserts }
|
||||
: {}),
|
||||
|
||||
@@ -33,18 +33,15 @@ export function buildSecretRefCredentialMatrix(): SecretRefCredentialMatrixDocum
|
||||
? "tools.web.fetch.firecrawl.apiKey"
|
||||
: entry.pathPattern;
|
||||
|
||||
return {
|
||||
id: canonicalId,
|
||||
configFile: entry.configFile,
|
||||
path: canonicalPath,
|
||||
...(entry.refPathPattern ? { refPath: entry.refPathPattern } : {}),
|
||||
...(entry.authProfileType ? { when: { type: entry.authProfileType } } : {}),
|
||||
secretShape: entry.secretShape,
|
||||
optIn: true as const,
|
||||
...(entry.secretShape === "sibling_ref" && entry.refPathPattern
|
||||
? { notes: "Compatibility exception: sibling ref field remains canonical." }
|
||||
: {}),
|
||||
};
|
||||
return Object.assign(
|
||||
{ id: canonicalId, configFile: entry.configFile, path: canonicalPath },
|
||||
entry.refPathPattern ? { refPath: entry.refPathPattern } : {},
|
||||
entry.authProfileType ? { when: { type: entry.authProfileType } } : {},
|
||||
{ secretShape: entry.secretShape, optIn: true as const },
|
||||
entry.secretShape === `sibling_ref` && entry.refPathPattern
|
||||
? { notes: `Compatibility exception: sibling ref field remains canonical.` }
|
||||
: {},
|
||||
);
|
||||
})
|
||||
.toSorted((a, b) => a.id.localeCompare(b.id));
|
||||
|
||||
|
||||
@@ -38,15 +38,14 @@ function loadCoverageRegistryEntries(): SecretRegistryEntry[] {
|
||||
"secretref-user-supplied-credentials-matrix.json",
|
||||
);
|
||||
const matrix = JSON.parse(fs.readFileSync(matrixPath, "utf8")) as SecretRefCredentialMatrix;
|
||||
return matrix.entries.map((entry) => ({
|
||||
id: entry.id,
|
||||
configFile: entry.configFile,
|
||||
pathPattern: entry.path,
|
||||
...(entry.refPath ? { refPathPattern: entry.refPath } : {}),
|
||||
secretShape: entry.secretShape,
|
||||
expectedResolvedValue: "string",
|
||||
...(entry.when?.type ? { authProfileType: entry.when.type } : {}),
|
||||
}));
|
||||
return matrix.entries.map((entry) =>
|
||||
Object.assign(
|
||||
{ id: entry.id, configFile: entry.configFile, pathPattern: entry.path },
|
||||
entry.refPath ? { refPathPattern: entry.refPath } : {},
|
||||
{ secretShape: entry.secretShape, expectedResolvedValue: "string" as const },
|
||||
entry.when?.type ? { authProfileType: entry.when.type } : {},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const COVERAGE_REGISTRY_ENTRIES = loadCoverageRegistryEntries();
|
||||
|
||||
@@ -226,27 +226,29 @@ function toResolvedPlanTarget(
|
||||
}
|
||||
|
||||
export function listSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] {
|
||||
return getCompiledSecretTargetRegistryState().compiledSecretTargetRegistry.map((entry) => ({
|
||||
id: entry.id,
|
||||
targetType: entry.targetType,
|
||||
...(entry.targetTypeAliases ? { targetTypeAliases: [...entry.targetTypeAliases] } : {}),
|
||||
configFile: entry.configFile,
|
||||
pathPattern: entry.pathPattern,
|
||||
...(entry.refPathPattern ? { refPathPattern: entry.refPathPattern } : {}),
|
||||
secretShape: entry.secretShape,
|
||||
expectedResolvedValue: entry.expectedResolvedValue,
|
||||
includeInPlan: entry.includeInPlan,
|
||||
includeInConfigure: entry.includeInConfigure,
|
||||
includeInAudit: entry.includeInAudit,
|
||||
...(entry.providerIdPathSegmentIndex !== undefined
|
||||
? { providerIdPathSegmentIndex: entry.providerIdPathSegmentIndex }
|
||||
: {}),
|
||||
...(entry.accountIdPathSegmentIndex !== undefined
|
||||
? { accountIdPathSegmentIndex: entry.accountIdPathSegmentIndex }
|
||||
: {}),
|
||||
...(entry.authProfileType ? { authProfileType: entry.authProfileType } : {}),
|
||||
...(entry.trackProviderShadowing ? { trackProviderShadowing: true } : {}),
|
||||
}));
|
||||
return getCompiledSecretTargetRegistryState().compiledSecretTargetRegistry.map((entry) =>
|
||||
Object.assign(
|
||||
{ id: entry.id, targetType: entry.targetType },
|
||||
entry.targetTypeAliases ? { targetTypeAliases: [...entry.targetTypeAliases] } : {},
|
||||
{ configFile: entry.configFile, pathPattern: entry.pathPattern },
|
||||
entry.refPathPattern ? { refPathPattern: entry.refPathPattern } : {},
|
||||
{
|
||||
secretShape: entry.secretShape,
|
||||
expectedResolvedValue: entry.expectedResolvedValue,
|
||||
includeInPlan: entry.includeInPlan,
|
||||
includeInConfigure: entry.includeInConfigure,
|
||||
includeInAudit: entry.includeInAudit,
|
||||
},
|
||||
entry.providerIdPathSegmentIndex !== undefined
|
||||
? { providerIdPathSegmentIndex: entry.providerIdPathSegmentIndex }
|
||||
: {},
|
||||
entry.accountIdPathSegmentIndex !== undefined
|
||||
? { accountIdPathSegmentIndex: entry.accountIdPathSegmentIndex }
|
||||
: {},
|
||||
entry.authProfileType ? { authProfileType: entry.authProfileType } : {},
|
||||
entry.trackProviderShadowing ? { trackProviderShadowing: true } : {},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function isKnownSecretTargetType(value: unknown): value is string {
|
||||
|
||||
@@ -623,9 +623,8 @@ const sessionBindingContractEntries: Record<
|
||||
let sessionBindingContractRegistryCache: SessionBindingContractEntry[] | undefined;
|
||||
|
||||
export function getSessionBindingContractRegistry(): SessionBindingContractEntry[] {
|
||||
sessionBindingContractRegistryCache ??= sessionBindingContractChannelIds.map((id) => ({
|
||||
id,
|
||||
...sessionBindingContractEntries[id],
|
||||
}));
|
||||
sessionBindingContractRegistryCache ??= sessionBindingContractChannelIds.map((id) =>
|
||||
Object.assign({ id }, sessionBindingContractEntries[id]),
|
||||
);
|
||||
return sessionBindingContractRegistryCache;
|
||||
}
|
||||
|
||||
@@ -369,11 +369,13 @@ function normalizeCommandEntry(
|
||||
choices: getArgChoices(arg).slice(0, MAX_REMOTE_CHOICES),
|
||||
}))
|
||||
.filter((arg) => arg.name.length > 0)
|
||||
.map((arg) => ({
|
||||
name: arg.name,
|
||||
...(arg.required ? { required: true } : {}),
|
||||
...(arg.choices.length > 0 ? { choices: arg.choices } : {}),
|
||||
}));
|
||||
.map((arg) =>
|
||||
Object.assign(
|
||||
{ name: arg.name },
|
||||
arg.required ? { required: true } : {},
|
||||
arg.choices.length > 0 ? { choices: arg.choices } : {},
|
||||
),
|
||||
);
|
||||
return {
|
||||
key: primaryName,
|
||||
name: primaryName,
|
||||
|
||||
Reference in New Issue
Block a user