feat: expose active model plugin context · openclaw/openclaw@525767c
steipete
·
2026-05-10
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -12,6 +12,7 @@ Docs: https://docs.openclaw.ai
|
12 | 12 | - Plugin SDK: deprecate public subpaths currently used by only one or two bundled plugin owners, keeping them importable while steering new plugin code to focused shared SDK seams or plugin-owned APIs. |
13 | 13 | - Plugin SDK: remove the owner-specific `provider-auth-login` public subpath after moving Chutes, GitHub Copilot, and OpenAI Codex auth flows back to provider-owned modules. |
14 | 14 | - Plugin SDK: remove provider-specific model, stream, and xAI compatibility helpers from public exports after moving bundled callers to provider-owned modules. |
| 15 | +- Plugin SDK: expose runtime-supplied active model metadata to native plugin tool factories for diagnostics and plugin-owned policy decisions. Fixes #77857. Thanks @jamiezigelbaum. |
15 | 16 | - QA/Mantis: add Telegram live PR evidence automation with Convex-leased credentials, Crabbox transcript capture, motion GIF previews, and inline PR comments. |
16 | 17 | - QA/Mantis: add a Telegram desktop scenario builder that leases Crabbox, installs native Telegram Desktop, configures an OpenClaw Telegram gateway with leased bot credentials, and records VNC screenshot/video artifacts. |
17 | 18 | - Discord/voice: add realtime voice diagnostics for speaker turns, playback resets, barge-in detection, and audio cutoff analysis. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -248,6 +248,14 @@ register(api) {
|
248 | 248 | } |
249 | 249 | ``` |
250 | 250 | |
| 251 | +Tool factories receive a runtime-supplied context object. Use |
| 252 | +`ctx.activeModel` when a tool needs to log, display, or adapt to the active |
| 253 | +model for the current turn. The object can include `provider`, `modelId`, and |
| 254 | +`modelRef`. Treat it as informational runtime metadata, not as a security |
| 255 | +boundary against the local operator, installed plugin code, or a modified |
| 256 | +OpenClaw runtime. For sensitive local tools, keep an explicit plugin or operator |
| 257 | +opt-in and fail closed when the active model metadata is missing or unsuitable. |
| 258 | + |
251 | 259 | Every tool registered with `api.registerTool(...)` must also be declared in the |
252 | 260 | plugin manifest: |
253 | 261 | |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -24,6 +24,7 @@ type ResolveOpenClawPluginToolsOptions = OpenClawPluginToolOptions & {
|
24 | 24 | sandboxRoot?: string; |
25 | 25 | modelHasVision?: boolean; |
26 | 26 | modelProvider?: string; |
| 27 | +modelId?: string; |
27 | 28 | allowMediaInvokeCommands?: boolean; |
28 | 29 | requesterAgentIdOverride?: string; |
29 | 30 | requireExplicitMessageTarget?: boolean; |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -42,6 +42,22 @@ describe("openclaw plugin tool context", () => {
|
42 | 42 | expect(result.context.sessionId).toBe("a1b2c3d4-e5f6-7890-abcd-ef1234567890"); |
43 | 43 | }); |
44 | 44 | |
| 45 | +it("forwards runtime-owned active model metadata", () => { |
| 46 | +const result = resolveOpenClawPluginToolInputs({ |
| 47 | +options: { |
| 48 | +config: {} as never, |
| 49 | +modelProvider: " local-provider ", |
| 50 | +modelId: " local-model ", |
| 51 | +}, |
| 52 | +}); |
| 53 | + |
| 54 | +expect(result.context.activeModel).toStrictEqual({ |
| 55 | +provider: "local-provider", |
| 56 | +modelId: "local-model", |
| 57 | +modelRef: "local-provider/local-model", |
| 58 | +}); |
| 59 | +}); |
| 60 | + |
45 | 61 | it("infers the default agent workspace when workspaceDir is omitted", () => { |
46 | 62 | const workspaceDir = path.join(process.cwd(), "tmp-main-workspace"); |
47 | 63 | const result = resolveOpenClawPluginToolInputs({ |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -15,6 +15,8 @@ export type OpenClawPluginToolOptions = {
|
15 | 15 | workspaceDir?: string; |
16 | 16 | config?: OpenClawConfig; |
17 | 17 | fsPolicy?: ToolFsPolicy; |
| 18 | +modelProvider?: string; |
| 19 | +modelId?: string; |
18 | 20 | requesterSenderId?: string | null; |
19 | 21 | requesterAgentIdOverride?: string; |
20 | 22 | senderIsOwner?: boolean; |
@@ -42,6 +44,16 @@ export function resolveOpenClawPluginToolInputs(params: {
|
42 | 44 | ? undefined |
43 | 45 | : resolveAgentWorkspaceDir(resolvedConfig, sessionAgentId); |
44 | 46 | const workspaceDir = resolveWorkspaceRoot(options?.workspaceDir ?? inferredWorkspaceDir); |
| 47 | +const modelProvider = options?.modelProvider?.trim(); |
| 48 | +const modelId = options?.modelId?.trim(); |
| 49 | +const activeModel = |
| 50 | +modelProvider || modelId |
| 51 | + ? { |
| 52 | + ...(modelProvider ? { provider: modelProvider } : {}), |
| 53 | + ...(modelId ? { modelId } : {}), |
| 54 | + ...(modelProvider && modelId ? { modelRef: `${modelProvider}/${modelId}` } : {}), |
| 55 | +} |
| 56 | + : undefined; |
45 | 57 | const deliveryContext = normalizeDeliveryContext({ |
46 | 58 | channel: options?.agentChannel, |
47 | 59 | to: options?.agentTo, |
@@ -60,6 +72,7 @@ export function resolveOpenClawPluginToolInputs(params: {
|
60 | 72 | agentId: sessionAgentId, |
61 | 73 | sessionKey: options?.agentSessionKey, |
62 | 74 | sessionId: options?.sessionId, |
| 75 | + activeModel, |
63 | 76 | browser: { |
64 | 77 | sandboxBridgeUrl: options?.sandboxBrowserBridgeUrl, |
65 | 78 | allowHostControl: options?.allowHostBrowserControl, |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -121,7 +121,11 @@ export type {
|
121 | 121 | UnifiedModelCatalogSource, |
122 | 122 | } from "../model-catalog/types.js"; |
123 | 123 | export type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js"; |
124 | | -export type { OpenClawPluginToolContext, OpenClawPluginToolFactory } from "../plugins/types.js"; |
| 124 | +export type { |
| 125 | +OpenClawPluginActiveModelContext, |
| 126 | +OpenClawPluginToolContext, |
| 127 | +OpenClawPluginToolFactory, |
| 128 | +} from "../plugins/types.js"; |
125 | 129 | export type { |
126 | 130 | MemoryPluginCapability, |
127 | 131 | MemoryPluginPublicArtifact, |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -4,6 +4,12 @@ import type { OpenClawConfig } from "../config/types.openclaw.js";
|
4 | 4 | import type { HookEntry } from "../hooks/types.js"; |
5 | 5 | import type { DeliveryContext } from "../utils/delivery-context.types.js"; |
6 | 6 | |
| 7 | +export type OpenClawPluginActiveModelContext = { |
| 8 | +provider?: string; |
| 9 | +modelId?: string; |
| 10 | +modelRef?: string; |
| 11 | +}; |
| 12 | + |
7 | 13 | /** Trusted execution context passed to plugin-owned agent tool factories. */ |
8 | 14 | export type OpenClawPluginToolContext = { |
9 | 15 | config?: OpenClawConfig; |
@@ -19,6 +25,12 @@ export type OpenClawPluginToolContext = {
|
19 | 25 | sessionKey?: string; |
20 | 26 | /** Ephemeral session UUID - regenerated on /new and /reset. Use for per-conversation isolation. */ |
21 | 27 | sessionId?: string; |
| 28 | +/** |
| 29 | + * Runtime-supplied active model metadata for informational use, diagnostics, |
| 30 | + * and plugin-owned policy decisions. This is not a security boundary against |
| 31 | + * the local operator, installed plugin code, or a modified OpenClaw runtime. |
| 32 | + */ |
| 33 | +activeModel?: OpenClawPluginActiveModelContext; |
22 | 34 | browser?: { |
23 | 35 | sandboxBridgeUrl?: string; |
24 | 36 | allowHostControl?: boolean; |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -151,6 +151,7 @@ export type {
|
151 | 151 | PluginFormat, |
152 | 152 | } from "./manifest-types.js"; |
153 | 153 | export type { |
| 154 | +OpenClawPluginActiveModelContext, |
154 | 155 | OpenClawPluginHookOptions, |
155 | 156 | OpenClawPluginToolContext, |
156 | 157 | OpenClawPluginToolFactory, |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。