mirror of
https://fastgit.cc/github.com/openclaw/openclaw
synced 2026-04-30 22:12:32 +08:00
refactor: tighten plugin runtime sdk boundaries
This commit is contained in:
@@ -8,6 +8,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Changes
|
||||
|
||||
- Plugins/runtime: expose provider-backed thinking policy and normalization through `api.runtime.agent`, letting tool plugins validate thinking overrides without duplicating provider/model level lists. Thanks @openclaw.
|
||||
- Providers: add Cerebras as a bundled plugin with onboarding, static model catalog, docs, and manifest-owned endpoint metadata.
|
||||
- Memory/OpenAI-compatible: add optional `memorySearch.inputType`, `queryInputType`, and `documentInputType` config for asymmetric embedding endpoints, including direct query embeddings and provider batch indexing. Carries forward #63313 and #60727. Thanks @HOYALIM and @prospect1314521.
|
||||
- Ollama/memory: add model-specific retrieval query prefixes for `nomic-embed-text`, `qwen3-embedding`, and `mxbai-embed-large` memory-search queries while leaving document batches unchanged. Carries forward #45013. Thanks @laolin5564.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
491267e919c6bf426f673a9066e703811c7779a32de87edd0ce493147fd4438e plugin-sdk-api-baseline.json
|
||||
590d21aeb520f34b5bf23abb7b17602b204f170547c772d60b604bb34a3940bb plugin-sdk-api-baseline.jsonl
|
||||
b81647828ee6599cdd1d76d96ea02c92ccdebb8c1b3b443cefe10ca8bd2ddbfe plugin-sdk-api-baseline.json
|
||||
ca9f3569352522621857b51872f30b3c31881505fd9eff2451b1b46d77670726 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -62,7 +62,18 @@ Internal OpenClaw runtime code has the same direction: load config once at the C
|
||||
const identity = api.runtime.agent.resolveAgentIdentity(cfg);
|
||||
|
||||
// Get default thinking level
|
||||
const thinking = api.runtime.agent.resolveThinkingDefault(cfg, provider, model);
|
||||
const thinking = api.runtime.agent.resolveThinkingDefault({
|
||||
cfg,
|
||||
provider,
|
||||
model,
|
||||
});
|
||||
|
||||
// Validate a user-provided thinking level against the active provider profile
|
||||
const policy = api.runtime.agent.resolveThinkingPolicy({ provider, model });
|
||||
const level = api.runtime.agent.normalizeThinkingLevel("extra high");
|
||||
if (level && policy.levels.some((entry) => entry.id === level)) {
|
||||
// pass level to an embedded run
|
||||
}
|
||||
|
||||
// Get agent timeout
|
||||
const timeoutMs = api.runtime.agent.resolveAgentTimeoutMs(cfg);
|
||||
@@ -86,6 +97,10 @@ Internal OpenClaw runtime code has the same direction: load config once at the C
|
||||
|
||||
`runEmbeddedPiAgent(...)` remains as a compatibility alias.
|
||||
|
||||
`resolveThinkingPolicy(...)` returns the provider/model's supported thinking levels and optional default. Provider plugins own the model-specific profile through their thinking hooks, so tool plugins should call this runtime helper instead of importing or duplicating provider lists.
|
||||
|
||||
`normalizeThinkingLevel(...)` converts user text such as `on`, `x-high`, or `extra high` to the canonical stored level before checking it against the resolved policy.
|
||||
|
||||
**Session store helpers** are under `api.runtime.agent.session`:
|
||||
|
||||
```typescript
|
||||
|
||||
@@ -138,7 +138,7 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview)
|
||||
| `plugin-sdk/allow-from` | `formatAllowFromLowercase` |
|
||||
| `plugin-sdk/channel-secret-runtime` | Narrow secret-contract collection helpers for channel/plugin secret surfaces |
|
||||
| `plugin-sdk/secret-ref-runtime` | Narrow `coerceSecretRef` and SecretRef typing helpers for secret-contract/config parsing |
|
||||
| `plugin-sdk/security-runtime` | Shared trust, DM gating, external-content, constant-time secret comparison, and secret-collection helpers |
|
||||
| `plugin-sdk/security-runtime` | Shared trust, DM gating, external-content, sensitive text redaction, constant-time secret comparison, and secret-collection helpers |
|
||||
| `plugin-sdk/ssrf-policy` | Host allowlist and private-network SSRF policy helpers |
|
||||
| `plugin-sdk/ssrf-dispatcher` | Narrow pinned-dispatcher helpers without the broad infra runtime surface |
|
||||
| `plugin-sdk/ssrf-runtime` | Pinned-dispatcher, SSRF-guarded fetch, SSRF error, and SSRF policy helpers |
|
||||
@@ -201,7 +201,7 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview)
|
||||
| `plugin-sdk/provider-zai-endpoint` | Z.AI endpoint detection helpers |
|
||||
| `plugin-sdk/infra-runtime` | System event/heartbeat helpers |
|
||||
| `plugin-sdk/collection-runtime` | Small bounded cache helpers |
|
||||
| `plugin-sdk/diagnostic-runtime` | Diagnostic flag and event helpers |
|
||||
| `plugin-sdk/diagnostic-runtime` | Diagnostic flag, event, and trace-context helpers |
|
||||
| `plugin-sdk/error-runtime` | Error graph, formatting, shared error classification helpers, `isApprovalNotFoundError` |
|
||||
| `plugin-sdk/fetch-runtime` | Wrapped fetch, proxy, and pinned lookup helpers |
|
||||
| `plugin-sdk/runtime-fetch` | Dispatcher-aware runtime fetch without proxy/guarded-fetch imports |
|
||||
|
||||
@@ -124,5 +124,6 @@ Malformed local-model reasoning tags are handled conservatively. Closed `<think>
|
||||
|
||||
- Provider plugins can expose `resolveThinkingProfile(ctx)` to define the model's supported levels and default.
|
||||
- Each profile level has a stored canonical `id` (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `adaptive`, or `max`) and may include a display `label`. Binary providers use `{ id: "low", label: "on" }`.
|
||||
- Tool plugins that need to validate an explicit thinking override should use `api.runtime.agent.resolveThinkingPolicy({ provider, model })` plus `api.runtime.agent.normalizeThinkingLevel(...)`; they should not keep their own provider/model level lists.
|
||||
- Published legacy hooks (`supportsXHighThinking`, `isBinaryThinking`, and `resolveDefaultThinkingLevel`) remain as compatibility adapters, but new custom level sets should use `resolveThinkingProfile`.
|
||||
- Gateway rows/defaults expose `thinkingLevels`, `thinkingOptions`, and `thinkingDefault` so ACP/chat clients render the same profile ids and labels that runtime validation uses.
|
||||
|
||||
@@ -1 +1,20 @@
|
||||
export * from "openclaw/plugin-sdk/diagnostics-otel";
|
||||
export {
|
||||
createChildDiagnosticTraceContext,
|
||||
createDiagnosticTraceContext,
|
||||
emitDiagnosticEvent,
|
||||
formatDiagnosticTraceparent,
|
||||
isValidDiagnosticSpanId,
|
||||
isValidDiagnosticTraceFlags,
|
||||
isValidDiagnosticTraceId,
|
||||
onDiagnosticEvent,
|
||||
parseDiagnosticTraceparent,
|
||||
type DiagnosticEventMetadata,
|
||||
type DiagnosticEventPayload,
|
||||
type DiagnosticTraceContext,
|
||||
} from "openclaw/plugin-sdk/diagnostic-runtime";
|
||||
export { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
export type {
|
||||
OpenClawPluginService,
|
||||
OpenClawPluginServiceContext,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
export { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
export * from "openclaw/plugin-sdk/diagnostics-prometheus";
|
||||
export type {
|
||||
DiagnosticEventMetadata,
|
||||
DiagnosticEventPayload,
|
||||
} from "openclaw/plugin-sdk/diagnostic-runtime";
|
||||
export {
|
||||
emptyPluginConfigSchema,
|
||||
type OpenClawPluginApi,
|
||||
type OpenClawPluginHttpRouteHandler,
|
||||
type OpenClawPluginService,
|
||||
type OpenClawPluginServiceContext,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
export { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
|
||||
|
||||
@@ -1 +1,10 @@
|
||||
export * from "openclaw/plugin-sdk/diffs";
|
||||
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
export {
|
||||
definePluginEntry,
|
||||
type AnyAgentTool,
|
||||
type OpenClawPluginApi,
|
||||
type OpenClawPluginConfigSchema,
|
||||
type OpenClawPluginToolContext,
|
||||
type PluginLogger,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
export { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
|
||||
@@ -30,6 +30,7 @@ export {
|
||||
export { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
|
||||
export { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
|
||||
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
export { GoogleChatConfigSchema } from "openclaw/plugin-sdk/channel-config-schema-legacy";
|
||||
export {
|
||||
GROUP_POLICY_BLOCKED_LABEL,
|
||||
isDangerousNameMatchingEnabled,
|
||||
@@ -41,11 +42,7 @@ export { fetchRemoteMedia, resolveChannelMediaMaxBytes } from "openclaw/plugin-s
|
||||
export { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
|
||||
export type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";
|
||||
export { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
export {
|
||||
GoogleChatConfigSchema,
|
||||
type GoogleChatAccountConfig,
|
||||
type GoogleChatConfig,
|
||||
} from "openclaw/plugin-sdk/googlechat-runtime-shared";
|
||||
export type { GoogleChatAccountConfig, GoogleChatConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
export { extractToolSend } from "openclaw/plugin-sdk/tool-send";
|
||||
export { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
|
||||
export { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
export * from "openclaw/plugin-sdk/llm-task";
|
||||
export * from "./src/runtime-api.js";
|
||||
export {
|
||||
definePluginEntry,
|
||||
type AnyAgentTool,
|
||||
type OpenClawPluginApi,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
|
||||
@@ -41,7 +41,6 @@ vi.mock("../api.js", async () => {
|
||||
return {
|
||||
...actual,
|
||||
resolvePreferredOpenClawTmpDir: () => "/tmp",
|
||||
supportsXHighThinking: () => false,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -52,6 +51,30 @@ const runEmbeddedPiAgent = vi.fn(async () => ({
|
||||
payloads: [{ text: "{}" }],
|
||||
}));
|
||||
|
||||
const resolveThinkingPolicy = vi.fn(() => ({
|
||||
levels: [
|
||||
{ id: "off", label: "off" },
|
||||
{ id: "minimal", label: "minimal" },
|
||||
{ id: "low", label: "low" },
|
||||
{ id: "medium", label: "medium" },
|
||||
{ id: "high", label: "high" },
|
||||
],
|
||||
}));
|
||||
|
||||
const normalizeThinkingLevel = vi.fn((raw?: string | null) => {
|
||||
const value = raw?.trim().toLowerCase();
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
if (value === "on") {
|
||||
return "low";
|
||||
}
|
||||
if (["off", "minimal", "low", "medium", "high", "xhigh", "adaptive", "max"].includes(value)) {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
function fakeApi(overrides: any = {}) {
|
||||
return {
|
||||
id: "llm-task",
|
||||
@@ -65,6 +88,8 @@ function fakeApi(overrides: any = {}) {
|
||||
version: "test",
|
||||
agent: {
|
||||
runEmbeddedPiAgent,
|
||||
resolveThinkingPolicy,
|
||||
normalizeThinkingLevel,
|
||||
},
|
||||
},
|
||||
logger: { debug() {}, info() {}, warn() {}, error() {} },
|
||||
@@ -170,6 +195,10 @@ describe("llm-task tool (json-only)", () => {
|
||||
mockEmbeddedRunJson({ ok: true });
|
||||
const call = await executeEmbeddedRun({ prompt: "x", thinking: "high" });
|
||||
expect(call.thinkLevel).toBe("high");
|
||||
expect(resolveThinkingPolicy).toHaveBeenCalledWith({
|
||||
provider: "openai-codex",
|
||||
model: "gpt-5.2",
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes thinking aliases", async () => {
|
||||
|
||||
@@ -3,12 +3,7 @@ import path from "node:path";
|
||||
import Ajv from "ajv";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { Type } from "typebox";
|
||||
import {
|
||||
formatThinkingLevels,
|
||||
isThinkingLevelSupported,
|
||||
normalizeThinkLevel,
|
||||
resolvePreferredOpenClawTmpDir,
|
||||
} from "../api.js";
|
||||
import { resolvePreferredOpenClawTmpDir } from "../api.js";
|
||||
import type { OpenClawPluginApi } from "../api.js";
|
||||
|
||||
const AjvCtor = Ajv as unknown as typeof import("ajv").default;
|
||||
@@ -70,8 +65,18 @@ type LlmTaskParams = {
|
||||
timeoutMs?: unknown;
|
||||
};
|
||||
|
||||
const INVALID_THINKING_LEVELS_HINT =
|
||||
"off, minimal, low, medium, high, adaptive, xhigh where supported, and max where supported";
|
||||
type ThinkingPolicy = ReturnType<OpenClawPluginApi["runtime"]["agent"]["resolveThinkingPolicy"]>;
|
||||
|
||||
function formatThinkingPolicy(policy: ThinkingPolicy): string {
|
||||
return policy.levels.map((level) => level.label).join(", ");
|
||||
}
|
||||
|
||||
function supportsThinkingPolicyLevel(
|
||||
policy: ThinkingPolicy,
|
||||
level: ReturnType<OpenClawPluginApi["runtime"]["agent"]["normalizeThinkingLevel"]>,
|
||||
): boolean {
|
||||
return !!level && policy.levels.some((entry) => entry.id === level);
|
||||
}
|
||||
|
||||
export function createLlmTaskTool(api: OpenClawPluginApi) {
|
||||
return {
|
||||
@@ -148,24 +153,22 @@ export function createLlmTaskTool(api: OpenClawPluginApi) {
|
||||
|
||||
const thinkingRaw =
|
||||
typeof params.thinking === "string" && params.thinking.trim() ? params.thinking : undefined;
|
||||
const thinkLevel = thinkingRaw ? normalizeThinkLevel(thinkingRaw) : undefined;
|
||||
if (thinkingRaw && !thinkLevel) {
|
||||
throw new Error(
|
||||
`Invalid thinking level "${thinkingRaw}". Use one of: ${INVALID_THINKING_LEVELS_HINT}.`,
|
||||
);
|
||||
}
|
||||
let resolvedThinkLevel = thinkLevel;
|
||||
if (
|
||||
thinkLevel &&
|
||||
!isThinkingLevelSupported({
|
||||
provider,
|
||||
model,
|
||||
level: thinkLevel,
|
||||
})
|
||||
) {
|
||||
throw new Error(
|
||||
`Thinking level "${thinkLevel}" is not supported for ${provider}/${model}. Use one of: ${formatThinkingLevels(provider, model)}.`,
|
||||
);
|
||||
let thinkLevel: ReturnType<OpenClawPluginApi["runtime"]["agent"]["normalizeThinkingLevel"]> =
|
||||
undefined;
|
||||
if (thinkingRaw) {
|
||||
const thinkingPolicy = api.runtime.agent.resolveThinkingPolicy({ provider, model });
|
||||
const thinkingLevelsHint = formatThinkingPolicy(thinkingPolicy);
|
||||
thinkLevel = api.runtime.agent.normalizeThinkingLevel(thinkingRaw);
|
||||
if (!thinkLevel) {
|
||||
throw new Error(
|
||||
`Invalid thinking level "${thinkingRaw}". Use one of: ${thinkingLevelsHint}.`,
|
||||
);
|
||||
}
|
||||
if (!supportsThinkingPolicyLevel(thinkingPolicy, thinkLevel)) {
|
||||
throw new Error(
|
||||
`Thinking level "${thinkLevel}" is not supported for ${provider}/${model}. Use one of: ${thinkingLevelsHint}.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const timeoutMs =
|
||||
@@ -225,7 +228,7 @@ export function createLlmTaskTool(api: OpenClawPluginApi) {
|
||||
model,
|
||||
authProfileId,
|
||||
authProfileIdSource: authProfileId ? "user" : "auto",
|
||||
thinkLevel: resolvedThinkLevel,
|
||||
thinkLevel,
|
||||
streamParams,
|
||||
disableTools: true,
|
||||
});
|
||||
|
||||
1
extensions/llm-task/src/runtime-api.ts
Normal file
1
extensions/llm-task/src/runtime-api.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
@@ -29,13 +29,12 @@ export { writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store";
|
||||
export type {
|
||||
ChannelDirectoryEntry,
|
||||
ChannelMessageActionContext,
|
||||
OpenClawConfig,
|
||||
PluginRuntime,
|
||||
RuntimeLogger,
|
||||
RuntimeEnv,
|
||||
WizardPrompter,
|
||||
} from "openclaw/plugin-sdk/matrix-runtime-shared";
|
||||
export { formatZonedTimestamp } from "openclaw/plugin-sdk/matrix-runtime-shared";
|
||||
} from "openclaw/plugin-sdk/channel-contract";
|
||||
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
export { formatZonedTimestamp } from "openclaw/plugin-sdk/core";
|
||||
export type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";
|
||||
export type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
export type { WizardPrompter } from "openclaw/plugin-sdk/setup";
|
||||
|
||||
export function chunkTextForOutbound(text: string, limit: number): string[] {
|
||||
const chunks: string[] = [];
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
||||
import type { DmPolicy } from "openclaw/plugin-sdk/config-runtime";
|
||||
import type { WizardPrompter } from "openclaw/plugin-sdk/matrix-runtime-shared";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
|
||||
import {
|
||||
type ChannelSetupDmPolicy,
|
||||
type ChannelSetupWizardAdapter,
|
||||
@@ -34,6 +32,7 @@ import {
|
||||
} from "./matrix/client/url-validation.js";
|
||||
import { resolveMatrixConfigFieldPath, updateMatrixAccountConfig } from "./matrix/config-update.js";
|
||||
import { ensureMatrixSdkInstalled, isMatrixSdkAvailable } from "./matrix/deps.js";
|
||||
import type { RuntimeEnv, WizardPrompter } from "./runtime-api.js";
|
||||
import { moveSingleMatrixAccountConfigToNamedAccount } from "./setup-config.js";
|
||||
import { resolveMatrixSetupDmAllowFrom } from "./setup-dm-policy.js";
|
||||
import type { CoreConfig, MatrixConfig } from "./types.js";
|
||||
|
||||
@@ -42,7 +42,7 @@ export type {
|
||||
GroupPolicy,
|
||||
} from "openclaw/plugin-sdk/config-runtime";
|
||||
export type { GroupToolPolicyConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
export type { WizardPrompter } from "openclaw/plugin-sdk/matrix-runtime-shared";
|
||||
export type { WizardPrompter } from "openclaw/plugin-sdk/setup";
|
||||
export type { SecretInput } from "openclaw/plugin-sdk/secret-input";
|
||||
export {
|
||||
GROUP_POLICY_BLOCKED_LABEL,
|
||||
@@ -107,7 +107,7 @@ export {
|
||||
formatZonedTimestamp,
|
||||
type PluginRuntime,
|
||||
type RuntimeLogger,
|
||||
} from "openclaw/plugin-sdk/matrix-runtime-shared";
|
||||
} from "openclaw/plugin-sdk/core";
|
||||
export type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
|
||||
// resolveMatrixAccountStringValues already comes from plugin-sdk/matrix.
|
||||
// Re-exporting auth-precedence here makes Jiti try to define the same export twice.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type { OpenClawConfig } from "openclaw/plugin-sdk/memory-core";
|
||||
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
export type {
|
||||
MemoryEmbeddingProbeResult,
|
||||
MemoryProviderStatus,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { OpenClawConfig, OpenClawPluginApi } from "openclaw/plugin-sdk/memory-core";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { resolveMemoryDreamingConfig } from "openclaw/plugin-sdk/memory-core-host-status";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { asRecord } from "./dreaming-shared.js";
|
||||
import { resolveShortTermPromotionDreamingConfig } from "./dreaming.js";
|
||||
|
||||
@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
|
||||
import type { Dirent } from "node:fs";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/memory-core";
|
||||
import {
|
||||
buildSessionEntry,
|
||||
listSessionFilesForAgent,
|
||||
@@ -18,6 +17,7 @@ import {
|
||||
resolveMemoryLightDreamingConfig,
|
||||
resolveMemoryRemDreamingConfig,
|
||||
} from "openclaw/plugin-sdk/memory-core-host-status";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { writeDailyDreamingPhaseBlock } from "./dreaming-markdown.js";
|
||||
import { generateAndAppendDreamNarrative, type NarrativePhaseData } from "./dreaming-narrative.js";
|
||||
import { asRecord, formatErrorMessage, normalizeTrimmedString } from "./dreaming-shared.js";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { peekSystemEventEntries } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import type { OpenClawConfig, OpenClawPluginApi } from "openclaw/plugin-sdk/memory-core";
|
||||
import {
|
||||
DEFAULT_MEMORY_DREAMING_FREQUENCY as DEFAULT_MEMORY_DREAMING_CRON_EXPR,
|
||||
DEFAULT_MEMORY_DEEP_DREAMING_LIMIT as DEFAULT_MEMORY_DREAMING_LIMIT,
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
resolveMemoryDeepDreamingConfig,
|
||||
resolveMemoryDreamingWorkspaces,
|
||||
} from "openclaw/plugin-sdk/memory-core-host-status";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { writeDeepDreamingReport } from "./dreaming-markdown.js";
|
||||
import { generateAndAppendDreamNarrative, type NarrativePhaseData } from "./dreaming-narrative.js";
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from "openclaw/plugin-sdk/memory-lancedb";
|
||||
export { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
export { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
|
||||
|
||||
@@ -1 +1,7 @@
|
||||
export * from "openclaw/plugin-sdk/thread-ownership";
|
||||
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
export { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
export {
|
||||
fetchWithSsrFGuard,
|
||||
ssrfPolicyFromAllowPrivateNetwork,
|
||||
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
|
||||
} from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
|
||||
@@ -128,6 +128,8 @@ export type {
|
||||
DiscordSlashCommandConfig,
|
||||
DmConfig,
|
||||
DmPolicy,
|
||||
GoogleChatAccountConfig,
|
||||
GoogleChatConfig,
|
||||
ContextVisibilityMode,
|
||||
GroupPolicy,
|
||||
GroupToolPolicyBySenderConfig,
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
// Diagnostic flag/event helpers for plugins that want narrow runtime gating.
|
||||
|
||||
export { isDiagnosticFlagEnabled } from "../infra/diagnostic-flags.js";
|
||||
export { isDiagnosticsEnabled } from "../infra/diagnostic-events.js";
|
||||
export type {
|
||||
DiagnosticEventMetadata,
|
||||
DiagnosticEventPayload,
|
||||
} from "../infra/diagnostic-events.js";
|
||||
export {
|
||||
emitDiagnosticEvent,
|
||||
isDiagnosticsEnabled,
|
||||
onDiagnosticEvent,
|
||||
} from "../infra/diagnostic-events.js";
|
||||
export type { DiagnosticTraceContext } from "../infra/diagnostic-trace-context.js";
|
||||
export {
|
||||
createChildDiagnosticTraceContext,
|
||||
createDiagnosticTraceContext,
|
||||
formatDiagnosticTraceparent,
|
||||
isValidDiagnosticSpanId,
|
||||
isValidDiagnosticTraceFlags,
|
||||
isValidDiagnosticTraceId,
|
||||
parseDiagnosticTraceparent,
|
||||
} from "../infra/diagnostic-trace-context.js";
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
OpenClawPluginCommandDefinition,
|
||||
OpenClawPluginConfigSchema,
|
||||
OpenClawPluginDefinition,
|
||||
OpenClawPluginHttpRouteHandler,
|
||||
OpenClawPluginNodeHostCommand,
|
||||
OpenClawPluginReloadRegistration,
|
||||
OpenClawPluginSecurityAuditCollector,
|
||||
@@ -104,6 +105,7 @@ export type {
|
||||
PluginCommandContext,
|
||||
PluginCommandResult,
|
||||
OpenClawPluginConfigSchema,
|
||||
OpenClawPluginHttpRouteHandler,
|
||||
ProviderDiscoveryContext,
|
||||
ProviderCatalogContext,
|
||||
ProviderCatalogResult,
|
||||
|
||||
@@ -9,4 +9,5 @@ export * from "../security/context-visibility.js";
|
||||
export * from "../security/dm-policy-shared.js";
|
||||
export * from "../security/external-content.js";
|
||||
export * from "../security/safe-regex.js";
|
||||
export { redactSensitiveText } from "../logging/redact.js";
|
||||
export { safeEqualSecret } from "../security/secret-equal.js";
|
||||
|
||||
@@ -67,12 +67,13 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
|
||||
'export { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";',
|
||||
'export { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";',
|
||||
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
|
||||
'export { GoogleChatConfigSchema } from "openclaw/plugin-sdk/channel-config-schema-legacy";',
|
||||
'export { GROUP_POLICY_BLOCKED_LABEL, isDangerousNameMatchingEnabled, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/config-runtime";',
|
||||
'export { fetchRemoteMedia, resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";',
|
||||
'export { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";',
|
||||
'export type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";',
|
||||
'export { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";',
|
||||
'export { GoogleChatConfigSchema, type GoogleChatAccountConfig, type GoogleChatConfig } from "openclaw/plugin-sdk/googlechat-runtime-shared";',
|
||||
'export type { GoogleChatAccountConfig, GoogleChatConfig } from "openclaw/plugin-sdk/config-runtime";',
|
||||
'export { extractToolSend } from "openclaw/plugin-sdk/tool-send";',
|
||||
'export { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";',
|
||||
'export { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";',
|
||||
@@ -125,8 +126,12 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
|
||||
'export { setMatrixThreadBindingIdleTimeoutBySessionKey, setMatrixThreadBindingMaxAgeBySessionKey } from "./src/matrix/thread-bindings-shared.js";',
|
||||
'export { setMatrixRuntime } from "./src/runtime.js";',
|
||||
'export { writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store";',
|
||||
'export type { ChannelDirectoryEntry, ChannelMessageActionContext, OpenClawConfig, PluginRuntime, RuntimeLogger, RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/matrix-runtime-shared";',
|
||||
'export { formatZonedTimestamp } from "openclaw/plugin-sdk/matrix-runtime-shared";',
|
||||
'export type { ChannelDirectoryEntry, ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-contract";',
|
||||
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
|
||||
'export { formatZonedTimestamp } from "openclaw/plugin-sdk/core";',
|
||||
'export type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";',
|
||||
'export type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";',
|
||||
'export type { WizardPrompter } from "openclaw/plugin-sdk/setup";',
|
||||
'export function chunkTextForOutbound(text: string, limit: number): string[] { const chunks: string[] = []; let remaining = text; while (remaining.length > limit) { const window = remaining.slice(0, limit); const splitAt = Math.max(window.lastIndexOf("\\n"), window.lastIndexOf(" ")); const breakAt = splitAt > 0 ? splitAt : limit; chunks.push(remaining.slice(0, breakAt).trimEnd()); remaining = remaining.slice(breakAt).trimStart(); } if (remaining.length > 0 || text.length === 0) { chunks.push(remaining); } return chunks; }',
|
||||
],
|
||||
[bundledPluginFile({
|
||||
|
||||
@@ -218,6 +218,8 @@ describe("plugin runtime command execution", () => {
|
||||
expectFunctionKeys(runtime.agent as Record<string, unknown>, [
|
||||
"runEmbeddedAgent",
|
||||
"runEmbeddedPiAgent",
|
||||
"normalizeThinkingLevel",
|
||||
"resolveThinkingPolicy",
|
||||
"resolveAgentDir",
|
||||
]);
|
||||
expectFunctionKeys(runtime.agent.session as Record<string, unknown>, [
|
||||
|
||||
@@ -4,6 +4,7 @@ import { resolveAgentIdentity } from "../../agents/identity.js";
|
||||
import { resolveThinkingDefault } from "../../agents/model-selection.js";
|
||||
import { resolveAgentTimeoutMs } from "../../agents/timeout.js";
|
||||
import { ensureAgentWorkspace } from "../../agents/workspace.js";
|
||||
import { normalizeThinkLevel, resolveThinkingProfile } from "../../auto-reply/thinking.js";
|
||||
import { resolveSessionFilePath, resolveStorePath } from "../../config/sessions/paths.js";
|
||||
import { loadSessionStore, saveSessionStore } from "../../config/sessions/store.js";
|
||||
import { createLazyRuntimeMethod, createLazyRuntimeModule } from "../../shared/lazy-runtime.js";
|
||||
@@ -24,6 +25,17 @@ export function createRuntimeAgent(): PluginRuntime["agent"] {
|
||||
resolveAgentWorkspaceDir,
|
||||
resolveAgentIdentity,
|
||||
resolveThinkingDefault,
|
||||
normalizeThinkingLevel: normalizeThinkLevel,
|
||||
resolveThinkingPolicy: (params) => {
|
||||
const profile = resolveThinkingProfile(params);
|
||||
const policy: Omit<
|
||||
ReturnType<PluginRuntime["agent"]["resolveThinkingPolicy"]>,
|
||||
"defaultLevel"
|
||||
> = {
|
||||
levels: profile.levels.map(({ id, label }) => ({ id, label })),
|
||||
};
|
||||
return profile.defaultLevel ? { ...policy, defaultLevel: profile.defaultLevel } : policy;
|
||||
},
|
||||
resolveAgentTimeoutMs,
|
||||
ensureAgentWorkspace,
|
||||
} satisfies Omit<PluginRuntime["agent"], "runEmbeddedAgent" | "runEmbeddedPiAgent" | "session"> &
|
||||
|
||||
@@ -47,6 +47,19 @@ type RuntimeReplaceConfigFileParams = {
|
||||
afterWrite: RuntimeConfigAfterWrite;
|
||||
writeOptions?: RuntimeWriteConfigOptions;
|
||||
};
|
||||
export type PluginRuntimeThinkingPolicyRequest = {
|
||||
provider?: string | null;
|
||||
model?: string | null;
|
||||
catalog?: import("../../auto-reply/thinking.js").ThinkingCatalogEntry[];
|
||||
};
|
||||
export type PluginRuntimeThinkingPolicyLevel = {
|
||||
id: import("../../auto-reply/thinking.js").ThinkLevel;
|
||||
label: string;
|
||||
};
|
||||
export type PluginRuntimeThinkingPolicy = {
|
||||
levels: PluginRuntimeThinkingPolicyLevel[];
|
||||
defaultLevel?: import("../../auto-reply/thinking.js").ThinkLevel | null;
|
||||
};
|
||||
|
||||
/** Structured logger surface injected into runtime-backed plugin helpers. */
|
||||
export type RuntimeLogger = {
|
||||
@@ -116,6 +129,12 @@ export type PluginRuntimeCore = {
|
||||
model: string;
|
||||
catalog?: import("../../agents/model-catalog.types.js").ModelCatalogEntry[];
|
||||
}) => import("../../auto-reply/thinking.js").ThinkLevel;
|
||||
normalizeThinkingLevel: (
|
||||
raw?: string | null,
|
||||
) => import("../../auto-reply/thinking.js").ThinkLevel | undefined;
|
||||
resolveThinkingPolicy: (
|
||||
params: PluginRuntimeThinkingPolicyRequest,
|
||||
) => PluginRuntimeThinkingPolicy;
|
||||
runEmbeddedAgent: import("../../agents/pi-embedded-runtime.types.js").RunEmbeddedAgentFn;
|
||||
runEmbeddedPiAgent: import("../../agents/pi-embedded-runtime.types.js").RunEmbeddedPiAgentFn;
|
||||
resolveAgentTimeoutMs: typeof import("../../agents/timeout.js").resolveAgentTimeoutMs;
|
||||
|
||||
@@ -123,6 +123,18 @@ export function createPluginRuntimeMock(overrides: DeepPartial<PluginRuntime> =
|
||||
resolveThinkingDefault: vi.fn(
|
||||
() => "off",
|
||||
) as unknown as PluginRuntime["agent"]["resolveThinkingDefault"],
|
||||
normalizeThinkingLevel: vi.fn(
|
||||
(raw?: string | null) => raw,
|
||||
) as unknown as PluginRuntime["agent"]["normalizeThinkingLevel"],
|
||||
resolveThinkingPolicy: vi.fn(() => ({
|
||||
levels: [
|
||||
{ id: "off", label: "off" },
|
||||
{ id: "minimal", label: "minimal" },
|
||||
{ id: "low", label: "low" },
|
||||
{ id: "medium", label: "medium" },
|
||||
{ id: "high", label: "high" },
|
||||
],
|
||||
})) as unknown as PluginRuntime["agent"]["resolveThinkingPolicy"],
|
||||
runEmbeddedPiAgent: vi.fn().mockResolvedValue({
|
||||
payloads: [],
|
||||
meta: {},
|
||||
|
||||
Reference in New Issue
Block a user