mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-12 04:20:48 +08:00
重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。 Made-with: Cursor
This commit is contained in:
parent
4a23b715a2
commit
dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions
123
openclaw/extensions/openai/shared.ts
Normal file
123
openclaw/extensions/openai/shared.ts
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { findCatalogTemplate } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import {
|
||||
cloneFirstTemplateModel,
|
||||
matchesExactOrPrefix,
|
||||
type ProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { OPENAI_RESPONSES_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { buildOpenAIReplayPolicy } from "./replay-policy.js";
|
||||
import {
|
||||
resolveOpenAITransportTurnState,
|
||||
resolveOpenAIWebSocketSessionPolicy,
|
||||
} from "./transport-policy.js";
|
||||
|
||||
type SyntheticOpenAIModelCatalogCost = {
|
||||
input: number;
|
||||
output: number;
|
||||
cacheRead: number;
|
||||
cacheWrite: number;
|
||||
};
|
||||
|
||||
type SyntheticOpenAIModelCatalogEntry = {
|
||||
provider: string;
|
||||
id: string;
|
||||
name: string;
|
||||
reasoning?: boolean;
|
||||
input?: ("text" | "image")[];
|
||||
contextWindow?: number;
|
||||
contextTokens?: number;
|
||||
cost?: SyntheticOpenAIModelCatalogCost;
|
||||
};
|
||||
|
||||
export const OPENAI_API_BASE_URL = "https://api.openai.com/v1";
|
||||
|
||||
export function toOpenAIDataUrl(buffer: Buffer, mimeType: string): string {
|
||||
return `data:${mimeType};base64,${buffer.toString("base64")}`;
|
||||
}
|
||||
|
||||
export function resolveConfiguredOpenAIBaseUrl(cfg: OpenClawConfig | undefined): string {
|
||||
return normalizeOptionalString(cfg?.models?.providers?.openai?.baseUrl) ?? OPENAI_API_BASE_URL;
|
||||
}
|
||||
|
||||
function hasSupportedOpenAIResponsesTransport(
|
||||
transport: unknown,
|
||||
): transport is "auto" | "sse" | "websocket" {
|
||||
return transport === "auto" || transport === "sse" || transport === "websocket";
|
||||
}
|
||||
|
||||
export function defaultOpenAIResponsesExtraParams(
|
||||
extraParams: Record<string, unknown> | undefined,
|
||||
options?: { openaiWsWarmup?: boolean },
|
||||
): Record<string, unknown> | undefined {
|
||||
const hasSupportedTransport = hasSupportedOpenAIResponsesTransport(extraParams?.transport);
|
||||
const hasExplicitWarmup = typeof extraParams?.openaiWsWarmup === "boolean";
|
||||
const shouldDefaultWarmup = options?.openaiWsWarmup === true;
|
||||
if (hasSupportedTransport && (!shouldDefaultWarmup || hasExplicitWarmup)) {
|
||||
return extraParams;
|
||||
}
|
||||
|
||||
return {
|
||||
...extraParams,
|
||||
...(hasSupportedTransport ? {} : { transport: "auto" }),
|
||||
...(shouldDefaultWarmup && !hasExplicitWarmup ? { openaiWsWarmup: true } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
type OpenAIResponsesProviderHooks = Pick<
|
||||
ProviderPlugin,
|
||||
| "buildReplayPolicy"
|
||||
| "prepareExtraParams"
|
||||
| "wrapStreamFn"
|
||||
| "resolveTransportTurnState"
|
||||
| "resolveWebSocketSessionPolicy"
|
||||
>;
|
||||
|
||||
const resolveOpenAIResponsesTransportTurnState: NonNullable<
|
||||
OpenAIResponsesProviderHooks["resolveTransportTurnState"]
|
||||
> = (ctx) => resolveOpenAITransportTurnState(ctx);
|
||||
|
||||
const resolveOpenAIResponsesWebSocketSessionPolicy: NonNullable<
|
||||
OpenAIResponsesProviderHooks["resolveWebSocketSessionPolicy"]
|
||||
> = (ctx) => resolveOpenAIWebSocketSessionPolicy(ctx);
|
||||
|
||||
export function buildOpenAIResponsesProviderHooks(options?: {
|
||||
openaiWsWarmup?: boolean;
|
||||
}): OpenAIResponsesProviderHooks {
|
||||
return {
|
||||
buildReplayPolicy: buildOpenAIReplayPolicy,
|
||||
prepareExtraParams: (ctx) => defaultOpenAIResponsesExtraParams(ctx.extraParams, options),
|
||||
...OPENAI_RESPONSES_STREAM_HOOKS,
|
||||
resolveTransportTurnState: resolveOpenAIResponsesTransportTurnState,
|
||||
resolveWebSocketSessionPolicy: resolveOpenAIResponsesWebSocketSessionPolicy,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildOpenAISyntheticCatalogEntry(
|
||||
template: ReturnType<typeof findCatalogTemplate>,
|
||||
entry: {
|
||||
id: string;
|
||||
reasoning: boolean;
|
||||
input: readonly ("text" | "image")[];
|
||||
contextWindow: number;
|
||||
contextTokens?: number;
|
||||
cost?: SyntheticOpenAIModelCatalogCost;
|
||||
},
|
||||
): SyntheticOpenAIModelCatalogEntry | undefined {
|
||||
if (!template) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
...template,
|
||||
id: entry.id,
|
||||
name: entry.id,
|
||||
reasoning: entry.reasoning,
|
||||
input: [...entry.input],
|
||||
contextWindow: entry.contextWindow,
|
||||
...(entry.contextTokens === undefined ? {} : { contextTokens: entry.contextTokens }),
|
||||
...(entry.cost === undefined ? {} : { cost: entry.cost }),
|
||||
};
|
||||
}
|
||||
|
||||
export { cloneFirstTemplateModel, findCatalogTemplate, matchesExactOrPrefix };
|
||||
Loading…
Add table
Add a link
Reference in a new issue