Merge branch 'main' into feat/deepinfra-integration

This commit is contained in:
Georgi Atsev 2026-03-21 06:56:33 +02:00 committed by GitHub
commit fc733c5abd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
467 changed files with 12284 additions and 2798 deletions

View File

@ -11,7 +11,7 @@ Describe the problem and fix in 25 bullets:
- [ ] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Refactor required for the fix
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra

View File

@ -6,6 +6,7 @@ Docs: https://docs.openclaw.ai
### Changes
- Models/Anthropic Vertex: add core `anthropic-vertex` provider support for Claude via Google Vertex AI, including GCP auth/discovery and main run-path routing. (#43356) Thanks @sallyom and @yossiovadia.
- Commands/btw: add `/btw` side questions for quick tool-less answers about the current session without changing future session context, with dismissible in-session TUI answers and explicit BTW replies on external channels. (#45444) Thanks @ngutman.
- Gateway/docs: clarify that empty URL input allowlists are treated as unset, document `allowUrl: false` as the deny-all switch, and add regression coverage for the normalization path.
- Sandbox/runtime: add pluggable sandbox backends, ship an OpenShell backend with `mirror` and `remote` workspace modes, and make sandbox list/recreate/prune backend-aware instead of Docker-only.
@ -53,6 +54,8 @@ Docs: https://docs.openclaw.ai
- Docs/plugins: add the community DingTalk plugin listing to the docs catalog. (#29913) Thanks @sliverp.
- Docs/plugins: add the community QQbot plugin listing to the docs catalog. (#29898) Thanks @sliverp.
- Plugins/context engines: pass the embedded runner `modelId` into context-engine `assemble()` so plugins can adapt context formatting per model. (#47437) thanks @jscianna.
- Plugins/context engines: add transcript maintenance rewrites for context engines, preserve active-branch transcript metadata during rewrites, and harden overflow-recovery truncation to rewrite sessions under the normal session write lock. (#51191) Thanks @jalehman.
- Telegram/apiRoot: add per-account custom Bot API endpoint support across send, probe, setup, doctor repair, and inbound media download paths so proxied or self-hosted Telegram deployments work end to end. (#48842) Thanks @Cypherm.
### Fixes
@ -153,6 +156,9 @@ Docs: https://docs.openclaw.ai
- Telegram: stabilize pairing/session/forum routing and reply formatting tests (#50155) Thanks @joshavant.
- Hardening: refresh stale device pairing requests and pending metadata (#50695) Thanks @smaeljaish771 and @joshavant.
- Gateway: harden OpenResponses file-context escaping (#50782) Thanks @YLChen-007 and @joshavant.
- LINE: harden Express webhook parsing to verified raw body (#51202) Thanks @gladiator9797 and @joshavant.
- Exec: harden host env override handling across gateway and node (#51207) Thanks @gladiator9797 and @joshavant.
- xAI/models: rename the bundled Grok 4.20 catalog entries to the GA IDs and normalize saved deprecated beta IDs at runtime so existing configs and sessions keep resolving. (#50772) thanks @Jaaneek
### Fixes
@ -184,6 +190,10 @@ Docs: https://docs.openclaw.ai
- Gateway/plugins: share plugin interactive callback routing and plugin bind approval state across duplicate module graphs so Telegram Codex picker buttons and plugin bind approvals no longer fall through to normal inbound message routing. (#50722) Thanks @huntharo.
- Agents/compaction: add an opt-in post-compaction session JSONL truncation step that drops summarized transcript entries while preserving the retained branch tail and live session metadata. (#41021) thanks @thirumaleshp.
- Telegram/routing: fail loud when `message send` targets an unknown non-default Telegram `accountId`, instead of silently falling back to the channel-level bot token and sending through the wrong bot. (#50853) Thanks @hclsys.
- Web search: align onboarding, configure, and finalize with plugin-owned provider contracts, including disabled-provider recovery, config-aware credential hooks, and runtime-visible summaries. (#50935) Thanks @gumadeiras.
- Agents/replay: sanitize malformed assistant tool-call replay blocks before provider replay so follow-up Anthropic requests do not inherit the downstream `replace` crash. (#50005) Thanks @jalehman.
- Plugins/context engines: retry strict legacy `assemble()` calls without the new `prompt` field when older engines reject it, preserving prompt-aware retrieval compatibility for pre-prompt plugins. (#50848) thanks @danhdoan.
- Agents/embedded transport errors: distinguish common network failures like connection refused, DNS lookup failure, and interrupted sockets from true timeouts in embedded-run user messaging and lifecycle diagnostics. (#51419) Thanks @scoootscooob.
### Breaking
@ -197,6 +207,7 @@ Docs: https://docs.openclaw.ai
- Exec/env sandbox: block build-tool JVM injection (`MAVEN_OPTS`, `SBT_OPTS`, `GRADLE_OPTS`, `ANT_OPTS`), glibc tunable exploitation (`GLIBC_TUNABLES`), and .NET dependency resolution hijack (`DOTNET_ADDITIONAL_DEPS`) from the host exec environment, and restrict Gradle init script redirect (`GRADLE_USER_HOME`) as an override-only block so user-configured Gradle homes still propagate. (#49702)
- Plugins/Matrix: add a new Matrix plugin backed by the official `matrix-js-sdk`. If you are upgrading from the previous public Matrix plugin, follow the migration guide: https://docs.openclaw.ai/install/migrating-matrix Thanks @gumadeiras.
- Discord/commands: switch native command deployment to Carbon reconcile by default so Discord restarts stop churning slash commands through OpenClaws local deploy path. (#46597) Thanks @huntharo and @thewilloftheshadow.
- Plugins/Matrix: durably dedupe inbound room events across gateway restarts so previously handled Matrix messages are not replayed as new, while preserving clean-restart backlog delivery for unseen events. (#50922) thanks @gumadeiras
## 2026.3.13

View File

@ -83,8 +83,9 @@ Welcome to the lobster tank! 🦞
1. **Bugs & small fixes** → Open a PR!
2. **New features / architecture** → Start a [GitHub Discussion](https://github.com/openclaw/openclaw/discussions) or ask in Discord first
3. **Test/CI-only PRs for known `main` failures** → Don't open a PR, the Maintainer team is already tracking it and such PRs will be closed automatically. If you've spotted a _new_ regression not yet shown in main CI, report it as an issue first.
4. **Questions** → Discord [#help](https://discord.com/channels/1456350064065904867/1459642797895319552) / [#users-helping-users](https://discord.com/channels/1456350064065904867/1459007081603403828)
3. **Refactor-only PRs** → Don't open a PR. We are not accepting refactor-only changes unless a maintainer explicitly asks for them as part of a concrete fix.
4. **Test/CI-only PRs for known `main` failures** → Don't open a PR. The Maintainer team is already tracking those failures, and PRs that only tweak tests or CI to chase them will be closed unless they are required to validate a new fix.
5. **Questions** → Discord [#help](https://discord.com/channels/1456350064065904867/1459642797895319552) / [#users-helping-users](https://discord.com/channels/1456350064065904867/1459007081603403828)
## Before You PR
@ -97,7 +98,9 @@ Welcome to the lobster tank! 🦞
- For targeted shared-surface work, use `pnpm test:contracts:channels` or `pnpm test:contracts:plugins`
- If you changed broader runtime behavior, still run the relevant wider lanes (`pnpm test:extensions`, `pnpm test:channels`, or `pnpm test`) before asking for review
- If you have access to Codex, run `codex review --base origin/main` locally before opening or updating your PR. Treat this as the current highest standard of AI review, even if GitHub Codex review also runs.
- Do not submit refactor-only PRs unless a maintainer explicitly requested that refactor for an active fix or deliverable.
- Do not submit test or CI-config fixes for failures already red on `main` CI. If a failure is already visible in the [main branch CI runs](https://github.com/openclaw/openclaw/actions), it's a known issue the Maintainer team is tracking, and a PR that only addresses those failures will be closed automatically. If you spot a _new_ regression not yet shown in main CI, report it as an issue first.
- Do not submit test-only PRs that just try to make known `main` CI failures pass. Test changes are acceptable when they are required to validate a new fix or cover new behavior in the same PR.
- Ensure CI checks pass
- Keep PRs focused (one thing per PR; do not mix unrelated concerns)
- Describe what & why

View File

@ -1,5 +1,10 @@
import Foundation
struct HostEnvOverrideDiagnostics: Equatable {
var blockedKeys: [String]
var invalidKeys: [String]
}
enum HostEnvSanitizer {
/// Generated from src/infra/host-env-security-policy.json via scripts/generate-host-env-security-policy-swift.mjs.
/// Parity is validated by src/infra/host-env-security.policy-parity.test.ts.
@ -41,6 +46,67 @@ enum HostEnvSanitizer {
return filtered.isEmpty ? nil : filtered
}
private static func isPortableHead(_ scalar: UnicodeScalar) -> Bool {
let value = scalar.value
return value == 95 || (65...90).contains(value) || (97...122).contains(value)
}
private static func isPortableTail(_ scalar: UnicodeScalar) -> Bool {
let value = scalar.value
return self.isPortableHead(scalar) || (48...57).contains(value)
}
private static func normalizeOverrideKey(_ rawKey: String) -> String? {
let key = rawKey.trimmingCharacters(in: .whitespacesAndNewlines)
guard !key.isEmpty else { return nil }
guard let first = key.unicodeScalars.first, self.isPortableHead(first) else {
return nil
}
for scalar in key.unicodeScalars.dropFirst() {
if self.isPortableTail(scalar) || scalar == "(" || scalar == ")" {
continue
}
return nil
}
return key
}
private static func sortedUnique(_ values: [String]) -> [String] {
Array(Set(values)).sorted()
}
static func inspectOverrides(
overrides: [String: String]?,
blockPathOverrides: Bool = true) -> HostEnvOverrideDiagnostics
{
guard let overrides else {
return HostEnvOverrideDiagnostics(blockedKeys: [], invalidKeys: [])
}
var blocked: [String] = []
var invalid: [String] = []
for (rawKey, _) in overrides {
let candidate = rawKey.trimmingCharacters(in: .whitespacesAndNewlines)
guard let normalized = self.normalizeOverrideKey(rawKey) else {
invalid.append(candidate.isEmpty ? rawKey : candidate)
continue
}
let upper = normalized.uppercased()
if blockPathOverrides, upper == "PATH" {
blocked.append(upper)
continue
}
if self.isBlockedOverride(upper) || self.isBlocked(upper) {
blocked.append(upper)
continue
}
}
return HostEnvOverrideDiagnostics(
blockedKeys: self.sortedUnique(blocked),
invalidKeys: self.sortedUnique(invalid))
}
static func sanitize(overrides: [String: String]?, shellWrapper: Bool = false) -> [String: String] {
var merged: [String: String] = [:]
for (rawKey, value) in ProcessInfo.processInfo.environment {
@ -57,8 +123,7 @@ enum HostEnvSanitizer {
guard let effectiveOverrides else { return merged }
for (rawKey, value) in effectiveOverrides {
let key = rawKey.trimmingCharacters(in: .whitespacesAndNewlines)
guard !key.isEmpty else { continue }
guard let key = self.normalizeOverrideKey(rawKey) else { continue }
let upper = key.uppercased()
// PATH is part of the security boundary (command resolution + safe-bin checks). Never
// allow request-scoped PATH overrides from agents/gateways.

View File

@ -63,7 +63,23 @@ enum HostEnvSecurityPolicy {
"OPENSSL_ENGINES",
"PYTHONSTARTUP",
"WGETRC",
"CURL_HOME"
"CURL_HOME",
"CLASSPATH",
"CGO_CFLAGS",
"CGO_LDFLAGS",
"GOFLAGS",
"CORECLR_PROFILER_PATH",
"PHPRC",
"PHP_INI_SCAN_DIR",
"DENO_DIR",
"BUN_CONFIG_REGISTRY",
"LUA_PATH",
"LUA_CPATH",
"GEM_HOME",
"GEM_PATH",
"BUNDLE_GEMFILE",
"COMPOSER_HOME",
"XDG_CONFIG_HOME"
]
static let blockedOverridePrefixes: [String] = [

View File

@ -465,6 +465,23 @@ actor MacNodeRuntime {
? params.sessionKey!.trimmingCharacters(in: .whitespacesAndNewlines)
: self.mainSessionKey
let runId = UUID().uuidString
let envOverrideDiagnostics = HostEnvSanitizer.inspectOverrides(
overrides: params.env,
blockPathOverrides: true)
if !envOverrideDiagnostics.blockedKeys.isEmpty || !envOverrideDiagnostics.invalidKeys.isEmpty {
var details: [String] = []
if !envOverrideDiagnostics.blockedKeys.isEmpty {
details.append("blocked override keys: \(envOverrideDiagnostics.blockedKeys.joined(separator: ", "))")
}
if !envOverrideDiagnostics.invalidKeys.isEmpty {
details.append(
"invalid non-portable override keys: \(envOverrideDiagnostics.invalidKeys.joined(separator: ", "))")
}
return Self.errorResponse(
req,
code: .invalidRequest,
message: "SYSTEM_RUN_DENIED: environment override rejected (\(details.joined(separator: "; ")))")
}
let evaluation = await ExecApprovalEvaluator.evaluate(
command: command,
rawCommand: params.rawCommand,

View File

@ -33,4 +33,24 @@ struct HostEnvSanitizerTests {
let env = HostEnvSanitizer.sanitize(overrides: ["OPENCLAW_TOKEN": "secret"])
#expect(env["OPENCLAW_TOKEN"] == "secret")
}
@Test func `inspect overrides rejects blocked and invalid keys`() {
let diagnostics = HostEnvSanitizer.inspectOverrides(overrides: [
"CLASSPATH": "/tmp/evil-classpath",
"BAD-KEY": "x",
"ProgramFiles(x86)": "C:\\Program Files (x86)",
])
#expect(diagnostics.blockedKeys == ["CLASSPATH"])
#expect(diagnostics.invalidKeys == ["BAD-KEY"])
}
@Test func `sanitize accepts Windows-style override key names`() {
let env = HostEnvSanitizer.sanitize(overrides: [
"ProgramFiles(x86)": "D:\\SDKs",
"CommonProgramFiles(x86)": "D:\\Common",
])
#expect(env["ProgramFiles(x86)"] == "D:\\SDKs")
#expect(env["CommonProgramFiles(x86)"] == "D:\\Common")
}
}

View File

@ -21,6 +21,32 @@ struct MacNodeRuntimeTests {
#expect(response.ok == false)
}
@Test func `handle invoke rejects blocked system run env override before execution`() async throws {
let runtime = MacNodeRuntime()
let params = OpenClawSystemRunParams(
command: ["/bin/sh", "-lc", "echo ok"],
env: ["CLASSPATH": "/tmp/evil-classpath"])
let json = try String(data: JSONEncoder().encode(params), encoding: .utf8)
let response = await runtime.handleInvoke(
BridgeInvokeRequest(id: "req-2c", command: OpenClawSystemCommand.run.rawValue, paramsJSON: json))
#expect(response.ok == false)
#expect(response.error?.message.contains("SYSTEM_RUN_DENIED: environment override rejected") == true)
#expect(response.error?.message.contains("CLASSPATH") == true)
}
@Test func `handle invoke rejects invalid system run env override key before execution`() async throws {
let runtime = MacNodeRuntime()
let params = OpenClawSystemRunParams(
command: ["/bin/sh", "-lc", "echo ok"],
env: ["BAD-KEY": "x"])
let json = try String(data: JSONEncoder().encode(params), encoding: .utf8)
let response = await runtime.handleInvoke(
BridgeInvokeRequest(id: "req-2d", command: OpenClawSystemCommand.run.rawValue, paramsJSON: json))
#expect(response.ok == false)
#expect(response.error?.message.contains("SYSTEM_RUN_DENIED: environment override rejected") == true)
#expect(response.error?.message.contains("BAD-KEY") == true)
}
@Test func `handle invoke rejects empty system which`() async throws {
let runtime = MacNodeRuntime()
let params = OpenClawSystemWhichParams(bins: [])

View File

@ -51,6 +51,7 @@ If you need a custom path, set `channels.line.webhookPath` or
Security note:
- LINE signature verification is body-dependent (HMAC over the raw body), so OpenClaw applies strict pre-auth body limits and timeout before verification.
- OpenClaw processes webhook events from the verified raw request bytes. Upstream middleware-transformed `req.body` values are ignored for signature-integrity safety.
## Configure

View File

@ -933,25 +933,31 @@ authoring plugins:
- `openclaw/plugin-sdk/core` for the generic shared plugin-facing contract.
- Stable channel primitives such as `openclaw/plugin-sdk/channel-setup`,
`openclaw/plugin-sdk/channel-pairing`,
`openclaw/plugin-sdk/channel-contract`,
`openclaw/plugin-sdk/channel-feedback`,
`openclaw/plugin-sdk/channel-inbound`,
`openclaw/plugin-sdk/channel-lifecycle`,
`openclaw/plugin-sdk/channel-reply-pipeline`,
`openclaw/plugin-sdk/command-auth`,
`openclaw/plugin-sdk/secret-input`, and
`openclaw/plugin-sdk/webhook-ingress` for shared setup/auth/reply/webhook
wiring.
wiring. `channel-inbound` is the shared home for debounce, mention matching,
envelope formatting, and inbound envelope context helpers.
- Domain subpaths such as `openclaw/plugin-sdk/channel-config-helpers`,
`openclaw/plugin-sdk/allow-from`,
`openclaw/plugin-sdk/channel-config-schema`,
`openclaw/plugin-sdk/channel-policy`,
`openclaw/plugin-sdk/channel-runtime`,
`openclaw/plugin-sdk/config-runtime`,
`openclaw/plugin-sdk/infra-runtime`,
`openclaw/plugin-sdk/agent-runtime`,
`openclaw/plugin-sdk/lazy-runtime`,
`openclaw/plugin-sdk/reply-history`,
`openclaw/plugin-sdk/routing`,
`openclaw/plugin-sdk/status-helpers`,
`openclaw/plugin-sdk/runtime-store`, and
`openclaw/plugin-sdk/directory-runtime` for shared runtime/config helpers.
- Narrow channel-core subpaths such as `openclaw/plugin-sdk/discord-core`,
`openclaw/plugin-sdk/telegram-core`, and `openclaw/plugin-sdk/whatsapp-core`
for channel-specific primitives that should stay smaller than the full
channel helper barrels.
- `openclaw/plugin-sdk/channel-runtime` remains only as a compatibility shim.
New code should import the narrower primitives instead.
- Bundled extension internals remain private. External plugins should use only
`openclaw/plugin-sdk/*` subpaths. OpenClaw core/test code may use the repo
public entry points under `extensions/<id>/index.js`, `api.js`, `runtime-api.js`,
@ -962,26 +968,25 @@ authoring plugins:
`extensions/<id>/runtime-api.js` is the runtime-only barrel,
`extensions/<id>/index.js` is the bundled plugin entry,
and `extensions/<id>/setup-entry.js` is the setup plugin entry.
- `openclaw/plugin-sdk/telegram` for Telegram channel plugin types and shared channel-facing helpers. Built-in Telegram implementation internals stay private to the bundled extension.
- `openclaw/plugin-sdk/discord` for Discord channel plugin types and shared channel-facing helpers. Built-in Discord implementation internals stay private to the bundled extension.
- `openclaw/plugin-sdk/slack` for Slack channel plugin types and shared channel-facing helpers. Built-in Slack implementation internals stay private to the bundled extension.
- `openclaw/plugin-sdk/imessage` for iMessage channel plugin types and shared channel-facing helpers. Built-in iMessage implementation internals stay private to the bundled extension.
- `openclaw/plugin-sdk/whatsapp` for WhatsApp channel plugin types and shared channel-facing helpers. Built-in WhatsApp implementation internals stay private to the bundled extension.
- `openclaw/plugin-sdk/bluebubbles` remains public because it carries a small
focused helper surface that is shared intentionally.
- No bundled channel-branded public subpaths remain. Channel-specific helper and
runtime seams live under `extensions/<id>/api.js` and `extensions/<id>/runtime-api.js`;
the public SDK contract is the generic shared primitives instead.
Compatibility note:
- Avoid the root `openclaw/plugin-sdk` barrel for new code.
- Prefer the narrow stable primitives first. The newer setup/pairing/reply/
secret-input/webhook subpaths are the intended contract for new bundled and
external plugin work.
feedback/contract/inbound/threading/command/secret-input/webhook/infra/
allowlist/status/message-tool subpaths are the intended contract for new
bundled and external plugin work.
Target parsing/matching belongs on `openclaw/plugin-sdk/channel-targets`.
Message action gates and reaction message-id helpers belong on
`openclaw/plugin-sdk/channel-actions`.
- Bundled extension-specific helper barrels are not stable by default. If a
helper is only needed by a bundled extension, keep it behind the extension's
local `api.js` or `runtime-api.js` seam instead of promoting it into
`openclaw/plugin-sdk/<extension>`.
- Channel-branded bundled bars such as `feishu`, `googlechat`, `irc`, `line`,
`nostr`, `twitch`, and `zalo` stay private unless they are explicitly added
- Channel-branded bundled bars stay private unless they are explicitly added
back to the public contract.
- Capability-specific subpaths such as `image-generation`,
`media-understanding`, and `speech` exist because bundled/native plugins use
@ -994,7 +999,7 @@ Plugins should own channel-specific `describeMessageTool(...)` schema
contributions. Keep provider-specific fields in the plugin, not in shared core.
For shared portable schema fragments, reuse the generic helpers exported through
`openclaw/plugin-sdk/channel-runtime`:
`openclaw/plugin-sdk/channel-actions`:
- `createMessageToolButtonsSchema()` for button-grid style payloads
- `createMessageToolCardSchema()` for structured card payloads

View File

@ -365,5 +365,5 @@ patterns is strongly recommended.
- [Plugin SDK Migration](/plugins/sdk-migration) — migrating from deprecated compat surfaces
- [Plugin Architecture](/plugins/architecture) — internals and capability model
- [Plugin Manifest](/plugins/manifest) — full manifest schema
- [Plugin Agent Tools](/plugins/agent-tools) — adding agent tools in a plugin
- [Plugin Agent Tools](/plugins/building-plugins#registering-agent-tools) — adding agent tools in a plugin
- [Community Plugins](/plugins/community) — listing and quality bar

View File

@ -34,8 +34,7 @@ OpenClaw now includes these xAI model families out of the box:
- `grok-4`, `grok-4-0709`
- `grok-4-fast-reasoning`, `grok-4-fast-non-reasoning`
- `grok-4-1-fast-reasoning`, `grok-4-1-fast-non-reasoning`
- `grok-4.20-experimental-beta-0304-reasoning`
- `grok-4.20-experimental-beta-0304-non-reasoning`
- `grok-4.20-reasoning`, `grok-4.20-non-reasoning`
- `grok-code-fast-1`
The plugin also forward-resolves newer `grok-4*` and `grok-code-fast*` ids when

View File

@ -166,7 +166,7 @@ Use these hubs to discover every page, including deep dives and reference docs t
- [Plugins overview](/tools/plugin)
- [Building plugins](/plugins/building-plugins)
- [Plugin manifest](/plugins/manifest)
- [Agent tools](/plugins/agent-tools)
- [Agent tools](/plugins/building-plugins#registering-agent-tools)
- [Plugin bundles](/plugins/bundles)
- [Community plugins](/plugins/community)
- [Capability cookbook](/tools/capability-cookbook)

View File

@ -330,7 +330,7 @@ OpenProse pairs well with Lobster: use `/prose` to orchestrate multi-agent prep,
## Learn more
- [Plugins](/tools/plugin)
- [Plugin tool authoring](/plugins/agent-tools)
- [Plugin tool authoring](/plugins/building-plugins#registering-agent-tools)
## Case study: community workflows

View File

@ -246,6 +246,6 @@ Common registration methods:
- [Building Plugins](/plugins/building-plugins) — create your own plugin
- [Plugin Bundles](/plugins/bundles) — Codex/Claude/Cursor bundle compatibility
- [Plugin Manifest](/plugins/manifest) — manifest schema
- [Registering Tools](/plugins/agent-tools) — add agent tools in a plugin
- [Registering Tools](/plugins/building-plugins#registering-agent-tools) — add agent tools in a plugin
- [Plugin Internals](/plugins/architecture) — capability model and load pipeline
- [Community Plugins](/plugins/community) — third-party listings

View File

@ -0,0 +1,65 @@
import type {
ModelDefinitionConfig,
ModelProviderConfig,
} from "openclaw/plugin-sdk/provider-models";
import { resolveAnthropicVertexRegion } from "openclaw/plugin-sdk/provider-models";
export const ANTHROPIC_VERTEX_DEFAULT_MODEL_ID = "claude-sonnet-4-6";
const ANTHROPIC_VERTEX_DEFAULT_CONTEXT_WINDOW = 1_000_000;
const GCP_VERTEX_CREDENTIALS_MARKER = "gcp-vertex-credentials";
function buildAnthropicVertexModel(params: {
id: string;
name: string;
reasoning: boolean;
input: ModelDefinitionConfig["input"];
cost: ModelDefinitionConfig["cost"];
maxTokens: number;
}): ModelDefinitionConfig {
return {
id: params.id,
name: params.name,
reasoning: params.reasoning,
input: params.input,
cost: params.cost,
contextWindow: ANTHROPIC_VERTEX_DEFAULT_CONTEXT_WINDOW,
maxTokens: params.maxTokens,
};
}
function buildAnthropicVertexCatalog(): ModelDefinitionConfig[] {
return [
buildAnthropicVertexModel({
id: "claude-opus-4-6",
name: "Claude Opus 4.6",
reasoning: true,
input: ["text", "image"],
cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
maxTokens: 128000,
}),
buildAnthropicVertexModel({
id: ANTHROPIC_VERTEX_DEFAULT_MODEL_ID,
name: "Claude Sonnet 4.6",
reasoning: true,
input: ["text", "image"],
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
maxTokens: 128000,
}),
];
}
export function buildAnthropicVertexProvider(params?: {
env?: NodeJS.ProcessEnv;
}): ModelProviderConfig {
const region = resolveAnthropicVertexRegion(params?.env);
const baseUrl =
region.toLowerCase() === "global"
? "https://aiplatform.googleapis.com"
: `https://${region}-aiplatform.googleapis.com`;
return {
baseUrl,
api: "anthropic-messages",
apiKey: GCP_VERTEX_CREDENTIALS_MARKER,
models: buildAnthropicVertexCatalog(),
};
}

View File

@ -1,4 +1,3 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/bluebubbles";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { bluebubblesMessageActions } from "./actions.js";
import { sendBlueBubblesAttachment } from "./attachments.js";
@ -6,6 +5,7 @@ import { editBlueBubblesMessage, setGroupIconBlueBubbles } from "./chat.js";
import { resolveBlueBubblesMessageId } from "./monitor.js";
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
import { sendBlueBubblesReaction } from "./reactions.js";
import type { OpenClawConfig } from "./runtime-api.js";
import { resolveChatGuidForTarget, sendMessageBlueBubbles } from "./send.js";
vi.mock("./accounts.js", async () => {

View File

@ -1,8 +1,8 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/bluebubbles";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import "./test-mocks.js";
import { downloadBlueBubblesAttachment, sendBlueBubblesAttachment } from "./attachments.js";
import "./test-mocks.js";
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
import type { PluginRuntime } from "./runtime-api.js";
import { setBlueBubblesRuntime } from "./runtime.js";
import {
BLUE_BUBBLES_PRIVATE_API_STATUS,

View File

@ -4,15 +4,15 @@ import {
createScopedDmSecurityResolver,
} from "openclaw/plugin-sdk/channel-config-helpers";
import { createAccountStatusSink } from "openclaw/plugin-sdk/channel-lifecycle";
import {
createPairingPrefixStripper,
createTextPairingAdapter,
} from "openclaw/plugin-sdk/channel-pairing";
import {
createOpenGroupPolicyRestrictSendersWarningCollector,
projectWarningCollector,
} from "openclaw/plugin-sdk/channel-policy";
import {
createAttachedChannelResultAdapter,
createPairingPrefixStripper,
createTextPairingAdapter,
} from "openclaw/plugin-sdk/channel-runtime";
import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
import {
listBlueBubblesAccountIds,

View File

@ -2,9 +2,9 @@ import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk/bluebubbles";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { sendBlueBubblesMedia } from "./media-send.js";
import type { OpenClawConfig, PluginRuntime } from "./runtime-api.js";
import { setBlueBubblesRuntime } from "./runtime.js";
const sendBlueBubblesAttachmentMock = vi.hoisted(() => vi.fn());

View File

@ -1,6 +1,5 @@
import { EventEmitter } from "node:events";
import type { IncomingMessage, ServerResponse } from "node:http";
import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk/bluebubbles";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createPluginRuntimeMock } from "../../../test/helpers/extensions/plugin-runtime-mock.js";
import type { ResolvedBlueBubblesAccount } from "./accounts.js";
@ -12,6 +11,7 @@ import {
resolveBlueBubblesMessageId,
_resetBlueBubblesShortIdState,
} from "./monitor.js";
import type { OpenClawConfig, PluginRuntime } from "./runtime-api.js";
import { setBlueBubblesRuntime } from "./runtime.js";
// Mock dependencies

View File

@ -1,6 +1,5 @@
import { EventEmitter } from "node:events";
import type { IncomingMessage, ServerResponse } from "node:http";
import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk/bluebubbles";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createPluginRuntimeMock } from "../../../test/helpers/extensions/plugin-runtime-mock.js";
import type { ResolvedBlueBubblesAccount } from "./accounts.js";
@ -11,6 +10,7 @@ import {
resolveBlueBubblesMessageId,
_resetBlueBubblesShortIdState,
} from "./monitor.js";
import type { OpenClawConfig, PluginRuntime } from "./runtime-api.js";
import { setBlueBubblesRuntime } from "./runtime.js";
// Mock dependencies

View File

@ -1,9 +1,9 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/bluebubbles";
import { afterEach, describe, expect, it } from "vitest";
import { createEmptyPluginRegistry } from "../../../src/plugins/registry.js";
import { setActivePluginRegistry } from "../../../src/plugins/runtime.js";
import type { WebhookTarget } from "./monitor-shared.js";
import { registerBlueBubblesWebhookTarget } from "./monitor.js";
import type { OpenClawConfig } from "./runtime-api.js";
function createTarget(): WebhookTarget {
return {

View File

@ -1 +1 @@
export * from "openclaw/plugin-sdk/bluebubbles";
export * from "../../../src/plugin-sdk/bluebubbles.js";

View File

@ -1,7 +1,7 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/bluebubbles";
import { beforeEach, describe, expect, it, vi } from "vitest";
import "./test-mocks.js";
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
import type { PluginRuntime } from "./runtime-api.js";
import { clearBlueBubblesRuntime, setBlueBubblesRuntime } from "./runtime.js";
import { sendMessageBlueBubbles, resolveChatGuidForTarget, createChatForHandle } from "./send.js";
import {

View File

@ -5,7 +5,7 @@ import {
type ParsedChatTarget,
resolveServicePrefixedAllowTarget,
resolveServicePrefixedTarget,
} from "openclaw/plugin-sdk/imessage-core";
} from "../../imessage/api.js";
export type BlueBubblesService = "imessage" | "sms" | "auto";

View File

@ -62,14 +62,16 @@ export function createBlueBubblesProbeMockModule(): BlueBubblesProbeMockModule {
export function installBlueBubblesFetchTestHooks(params: {
mockFetch: ReturnType<typeof vi.fn>;
privateApiStatusMock: {
mockReset: () => unknown;
mockReset?: () => unknown;
mockClear?: () => unknown;
mockReturnValue: (value: boolean | null) => unknown;
};
}) {
beforeEach(() => {
vi.stubGlobal("fetch", params.mockFetch);
params.mockFetch.mockReset();
params.privateApiStatusMock.mockReset();
params.privateApiStatusMock.mockReset?.();
params.privateApiStatusMock.mockClear?.();
params.privateApiStatusMock.mockReturnValue(BLUE_BUBBLES_PRIVATE_API_STATUS.unknown);
});

View File

@ -5,8 +5,8 @@ import {
type ProviderAuthContext,
type ProviderAuthResult,
} from "openclaw/plugin-sdk/provider-auth";
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-auth";
import { loginChutes } from "openclaw/plugin-sdk/provider-auth-login";
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-oauth";
import {
CHUTES_DEFAULT_MODEL_REF,
applyChutesApiKeyConfig,

View File

@ -2,7 +2,7 @@ import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/acco
import {
hasConfiguredSecretInput,
normalizeSecretInputString,
} from "openclaw/plugin-sdk/config-runtime";
} from "openclaw/plugin-sdk/secret-input";
import {
mergeDiscordAccountConfig,
resolveDefaultDiscordAccountId,

View File

@ -5,7 +5,7 @@ import {
readStringArrayParam,
readStringParam,
} from "openclaw/plugin-sdk/agent-runtime";
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-runtime";
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-contract";
import { handleDiscordAction } from "./runtime.js";
import {
isDiscordModerationAction,

View File

@ -5,8 +5,8 @@ import {
readStringParam,
} from "openclaw/plugin-sdk/agent-runtime";
import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
import { resolveReactionMessageId } from "openclaw/plugin-sdk/channel-runtime";
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-runtime";
import { resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-contract";
import { normalizeInteractiveReply } from "openclaw/plugin-sdk/interactive-runtime";
import { buildDiscordInteractiveComponents } from "../shared-interactive.js";
import { resolveDiscordChannelId } from "../targets.js";

View File

@ -1,12 +1,12 @@
import {
createUnionActionGate,
listTokenSourcedAccounts,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-actions";
import type {
ChannelMessageActionAdapter,
ChannelMessageActionName,
ChannelMessageToolDiscovery,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-contract";
import type { DiscordActionConfig } from "openclaw/plugin-sdk/config-runtime";
import { createDiscordActionGate, listEnabledDiscordAccounts } from "./accounts.js";
import { handleDiscordMessageAction } from "./actions/handle-action.js";

View File

@ -1,13 +1,13 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import type {
ChannelAccountSnapshot,
ChannelGatewayContext,
OpenClawConfig,
PluginRuntime,
} from "openclaw/plugin-sdk/discord";
import { afterEach, describe, expect, it, vi } from "vitest";
} from "../../../src/channels/plugins/types.js";
import type { PluginRuntime } from "../../../src/plugins/runtime/types.js";
import { createRuntimeEnv } from "../../../test/helpers/extensions/runtime-env.js";
import type { ResolvedDiscordAccount } from "./accounts.js";
import { discordPlugin } from "./channel.js";
import type { OpenClawConfig } from "./runtime-api.js";
import { setDiscordRuntime } from "./runtime.js";
const probeDiscordMock = vi.hoisted(() => vi.fn());

View File

@ -5,20 +5,29 @@ import {
createNestedAllowlistOverrideResolver,
} from "openclaw/plugin-sdk/allowlist-config-edit";
import { createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
import { createOpenProviderConfiguredRouteWarningCollector } from "openclaw/plugin-sdk/channel-policy";
import {
createAttachedChannelResultAdapter,
createChannelDirectoryAdapter,
createPairingPrefixStripper,
createTopLevelChannelReplyToModeResolver,
createRuntimeDirectoryLiveAdapter,
createTextPairingAdapter,
normalizeMessageChannel,
} from "openclaw/plugin-sdk/channel-pairing";
import { createOpenProviderConfiguredRouteWarningCollector } from "openclaw/plugin-sdk/channel-policy";
import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
import { resolveTargetsWithOptionalToken } from "openclaw/plugin-sdk/channel-targets";
import { createTopLevelChannelReplyToModeResolver } from "openclaw/plugin-sdk/conversation-runtime";
import {
createChannelDirectoryAdapter,
createRuntimeDirectoryLiveAdapter,
} from "openclaw/plugin-sdk/directory-runtime";
import {
createRuntimeOutboundDelegates,
resolveOutboundSendDep,
resolveTargetsWithOptionalToken,
} from "openclaw/plugin-sdk/channel-runtime";
import { buildOutboundBaseSessionKey, normalizeOutboundThreadId } from "openclaw/plugin-sdk/core";
import { resolveThreadSessionKeys, type RoutePeer } from "openclaw/plugin-sdk/routing";
} from "openclaw/plugin-sdk/infra-runtime";
import {
buildOutboundBaseSessionKey,
normalizeMessageChannel,
normalizeOutboundThreadId,
resolveThreadSessionKeys,
type RoutePeer,
} from "openclaw/plugin-sdk/routing";
import {
listDiscordAccountIds,
resolveDiscordAccount,

View File

@ -1,3 +1,3 @@
import { buildChannelConfigSchema, DiscordConfigSchema } from "openclaw/plugin-sdk/discord-core";
import { buildChannelConfigSchema, DiscordConfigSchema } from "./runtime-api.js";
export const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema);

View File

@ -1,5 +1,7 @@
import type { DirectoryConfigParams } from "openclaw/plugin-sdk/channel-runtime";
import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk/channel-runtime";
import type {
ChannelDirectoryEntry,
DirectoryConfigParams,
} from "openclaw/plugin-sdk/directory-runtime";
import { resolveDiscordAccount } from "./accounts.js";
import { fetchDiscord } from "./api.js";
import { rememberDiscordDirectoryUser } from "./directory-cache.js";

View File

@ -1,6 +1,6 @@
import type { RequestClient } from "@buape/carbon";
import { Routes } from "discord-api-types/v10";
import { createFinalizableDraftLifecycle } from "openclaw/plugin-sdk/channel-runtime";
import { createFinalizableDraftLifecycle } from "openclaw/plugin-sdk/channel-lifecycle";
/** Discord messages cap at 2000 characters. */
const DISCORD_STREAM_MAX_CHARS = 2000;

View File

@ -1,9 +1,9 @@
import type { ChannelGroupContext } from "openclaw/plugin-sdk/channel-contract";
import {
resolveToolsBySender,
type GroupToolPolicyBySenderConfig,
type GroupToolPolicyConfig,
} from "openclaw/plugin-sdk/channel-policy";
import { type ChannelGroupContext } from "openclaw/plugin-sdk/channel-runtime";
import { normalizeAtHashSlug } from "openclaw/plugin-sdk/core";
import type { DiscordConfig } from "./runtime-api.js";

View File

@ -11,7 +11,7 @@ import {
import type { APIStringSelectComponent } from "discord-api-types/v10";
import { ChannelType } from "discord-api-types/v10";
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/channel-runtime";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/command-auth";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import type { DiscordAccountConfig } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";

View File

@ -19,8 +19,11 @@ import {
import type { APIStringSelectComponent } from "discord-api-types/v10";
import { ButtonStyle, ChannelType } from "discord-api-types/v10";
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
import {
formatInboundEnvelope,
resolveEnvelopeFormatOptions,
} from "openclaw/plugin-sdk/channel-inbound";
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { recordInboundSession } from "openclaw/plugin-sdk/channel-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
@ -31,6 +34,7 @@ import {
parsePluginBindingApprovalCustomId,
resolvePluginConversationBindingApproval,
} from "openclaw/plugin-sdk/conversation-runtime";
import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";
import { enqueueSystemEvent } from "openclaw/plugin-sdk/infra-runtime";
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
import {
@ -38,10 +42,6 @@ import {
type PluginInteractiveDiscordHandlerContext,
} from "openclaw/plugin-sdk/plugin-runtime";
import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
import {
formatInboundEnvelope,
resolveEnvelopeFormatOptions,
} from "openclaw/plugin-sdk/reply-runtime";
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-runtime";
import { dispatchReplyWithBufferedBlockDispatcher } from "openclaw/plugin-sdk/reply-runtime";
import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-runtime";

View File

@ -1,11 +1,11 @@
import type { Guild, User } from "@buape/carbon";
import type { AllowlistMatch } from "openclaw/plugin-sdk/channel-runtime";
import type { AllowlistMatch } from "openclaw/plugin-sdk/allow-from";
import {
buildChannelKeyCandidates,
resolveChannelEntryMatchWithFallback,
resolveChannelMatchConfig,
type ChannelMatchSource,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-targets";
import { evaluateGroupRouteAccessForPolicy } from "openclaw/plugin-sdk/group-access";
import { formatDiscordUserTag } from "./format.js";

View File

@ -1,4 +1,4 @@
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/channel-runtime";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/command-auth";
import {
readStoreAllowFromForDmPolicy,
resolveDmGroupAccessWithLists,

View File

@ -10,7 +10,6 @@ import {
type TopLevelComponents,
} from "@buape/carbon";
import { ButtonStyle, Routes } from "discord-api-types/v10";
import { normalizeMessageChannel } from "openclaw/plugin-sdk/channel-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { loadSessionStore, resolveStorePath } from "openclaw/plugin-sdk/config-runtime";
import type { DiscordExecApprovalConfig } from "openclaw/plugin-sdk/config-runtime";
@ -24,7 +23,11 @@ import type {
ExecApprovalRequest,
ExecApprovalResolved,
} from "openclaw/plugin-sdk/infra-runtime";
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
import {
normalizeAccountId,
normalizeMessageChannel,
resolveAgentIdFromSessionKey,
} from "openclaw/plugin-sdk/routing";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { compileSafeRegex, testRegexWithBoundedInput } from "openclaw/plugin-sdk/security-runtime";
import { logDebug, logError } from "openclaw/plugin-sdk/text-runtime";

View File

@ -1,4 +1,4 @@
import { createRunStateMachine } from "openclaw/plugin-sdk/channel-runtime";
import { createRunStateMachine } from "openclaw/plugin-sdk/channel-lifecycle";
import { formatDurationSeconds } from "openclaw/plugin-sdk/infra-runtime";
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
import { danger } from "openclaw/plugin-sdk/runtime-env";

View File

@ -1,9 +1,15 @@
import { ChannelType, MessageType, type Message, type User } from "@buape/carbon";
import { Routes, type APIMessage } from "discord-api-types/v10";
import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/channel-runtime";
import { resolveControlCommandGate } from "openclaw/plugin-sdk/channel-runtime";
import { logInboundDrop } from "openclaw/plugin-sdk/channel-runtime";
import { resolveMentionGatingWithBypass } from "openclaw/plugin-sdk/channel-runtime";
import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/allow-from";
import {
buildMentionRegexes,
logInboundDrop,
matchesMentionWithExplicit,
resolveMentionGatingWithBypass,
} from "openclaw/plugin-sdk/channel-inbound";
import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth";
import { hasControlCommand } from "openclaw/plugin-sdk/command-auth";
import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-auth";
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
import {
@ -18,13 +24,10 @@ import { buildPairingReply } from "openclaw/plugin-sdk/conversation-runtime";
import { isPluginOwnedSessionBindingRecord } from "openclaw/plugin-sdk/conversation-runtime";
import { recordChannelActivity } from "openclaw/plugin-sdk/infra-runtime";
import { enqueueSystemEvent } from "openclaw/plugin-sdk/infra-runtime";
import { hasControlCommand } from "openclaw/plugin-sdk/reply-runtime";
import { shouldHandleTextCommands } from "openclaw/plugin-sdk/reply-runtime";
import {
recordPendingHistoryEntryIfEnabled,
type HistoryEntry,
} from "openclaw/plugin-sdk/reply-runtime";
import { buildMentionRegexes, matchesMentionWithExplicit } from "openclaw/plugin-sdk/reply-runtime";
} from "openclaw/plugin-sdk/reply-history";
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/routing";
import { logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
import { getChildLogger } from "openclaw/plugin-sdk/runtime-env";

View File

@ -1,7 +1,7 @@
import type { ChannelType, Client, User } from "@buape/carbon";
import type { ReplyToMode } from "openclaw/plugin-sdk/config-runtime";
import type { SessionBindingRecord } from "openclaw/plugin-sdk/conversation-runtime";
import type { HistoryEntry } from "openclaw/plugin-sdk/reply-runtime";
import type { HistoryEntry } from "openclaw/plugin-sdk/reply-history";
import type { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
import type { DiscordChannelConfigResolved, DiscordGuildEntryResolved } from "./allow-list.js";
import type { DiscordChannelInfo } from "./message-utils.js";

View File

@ -1,31 +1,32 @@
import { ChannelType, type RequestClient } from "@buape/carbon";
import { resolveAckReaction, resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
import { EmbeddedBlockChunker } from "openclaw/plugin-sdk/agent-runtime";
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { shouldAckReaction as shouldAckReactionGate } from "openclaw/plugin-sdk/channel-runtime";
import { logTypingFailure, logAckFailure } from "openclaw/plugin-sdk/channel-runtime";
import { recordInboundSession } from "openclaw/plugin-sdk/channel-runtime";
import {
createStatusReactionController,
DEFAULT_TIMING,
logAckFailure,
logTypingFailure,
shouldAckReaction as shouldAckReactionGate,
type StatusReactionAdapter,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-feedback";
import {
formatInboundEnvelope,
resolveEnvelopeFormatOptions,
} from "openclaw/plugin-sdk/channel-inbound";
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
import { resolveDiscordPreviewStreamMode } from "openclaw/plugin-sdk/config-runtime";
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
import { readSessionUpdatedAt, resolveStorePath } from "openclaw/plugin-sdk/config-runtime";
import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
import { resolveChunkMode } from "openclaw/plugin-sdk/reply-runtime";
import { dispatchInboundMessage } from "openclaw/plugin-sdk/reply-runtime";
import {
formatInboundEnvelope,
resolveEnvelopeFormatOptions,
} from "openclaw/plugin-sdk/reply-runtime";
import {
buildPendingHistoryContextFromMap,
clearHistoryEntriesIfEnabled,
} from "openclaw/plugin-sdk/reply-runtime";
} from "openclaw/plugin-sdk/reply-history";
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
import { resolveChunkMode } from "openclaw/plugin-sdk/reply-runtime";
import { dispatchInboundMessage } from "openclaw/plugin-sdk/reply-runtime";
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-runtime";
import { createReplyDispatcherWithTyping } from "openclaw/plugin-sdk/reply-runtime";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";

View File

@ -2,7 +2,7 @@ import type { Client } from "@buape/carbon";
import {
createChannelInboundDebouncer,
shouldDebounceTextInbound,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-inbound";
import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/config-runtime";
import { danger } from "openclaw/plugin-sdk/runtime-env";
import { buildDiscordInboundJob } from "./inbound-job.js";

View File

@ -1,9 +1,9 @@
import type { ChannelType, Client, Message } from "@buape/carbon";
import { StickerFormatType, type APIAttachment, type APIStickerItem } from "discord-api-types/v10";
import { buildMediaPayload } from "openclaw/plugin-sdk/channel-runtime";
import type { SsrFPolicy } from "openclaw/plugin-sdk/infra-runtime";
import { fetchRemoteMedia, type FetchLike } from "openclaw/plugin-sdk/media-runtime";
import { saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
import { buildMediaPayload } from "openclaw/plugin-sdk/reply-payload";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
const DISCORD_CDN_HOSTNAMES = [

View File

@ -1,4 +1,4 @@
import type { ModelsProviderData } from "openclaw/plugin-sdk/reply-runtime";
import type { ModelsProviderData } from "openclaw/plugin-sdk/command-auth";
export function createModelsProviderData(
entries: Record<string, string[]>,

View File

@ -12,11 +12,8 @@ import {
import type { APISelectMenuOption } from "discord-api-types/v10";
import { ButtonStyle } from "discord-api-types/v10";
import { normalizeProviderId } from "openclaw/plugin-sdk/agent-runtime";
import { buildModelsProviderData, type ModelsProviderData } from "openclaw/plugin-sdk/command-auth";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
buildModelsProviderData,
type ModelsProviderData,
} from "openclaw/plugin-sdk/reply-runtime";
export const DISCORD_MODEL_PICKER_CUSTOM_ID_KEY = "mdlpk";
export const DISCORD_CUSTOM_ID_MAX_CHARS = 100;

View File

@ -117,8 +117,8 @@ vi.mock("../../../../src/auto-reply/reply/provider-dispatcher.js", async (import
};
});
vi.mock("openclaw/plugin-sdk/channel-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/channel-runtime")>();
vi.mock("openclaw/plugin-sdk/conversation-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/conversation-runtime")>();
return {
...actual,
recordInboundSession: (...args: unknown[]) => recordInboundSessionMock(...args),

View File

@ -1,4 +1,4 @@
import type { CommandArgs } from "openclaw/plugin-sdk/reply-runtime";
import type { CommandArgs } from "openclaw/plugin-sdk/command-auth";
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-runtime";
import { type DiscordChannelConfigResolved, type DiscordGuildEntryResolved } from "./allow-list.js";
import { buildDiscordInboundAccessContext } from "./inbound-context.js";

View File

@ -11,22 +11,20 @@ import {
type StringSelectMenuInteraction,
} from "@buape/carbon";
import { ButtonStyle } from "discord-api-types/v10";
import type { OpenClawConfig, loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { loadSessionStore, resolveStorePath } from "openclaw/plugin-sdk/config-runtime";
import {
buildCommandTextFromArgs,
findCommandByNativeName,
listChatCommands,
resolveCommandArgChoices,
resolveStoredModelOverride,
serializeCommandArgs,
} from "openclaw/plugin-sdk/reply-runtime";
import { resolveStoredModelOverride } from "openclaw/plugin-sdk/reply-runtime";
import type {
ChatCommandDefinition,
CommandArgDefinition,
CommandArgValues,
CommandArgs,
} from "openclaw/plugin-sdk/reply-runtime";
type ChatCommandDefinition,
type CommandArgDefinition,
type CommandArgValues,
type CommandArgs,
} from "openclaw/plugin-sdk/command-auth";
import type { OpenClawConfig, loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { loadSessionStore, resolveStorePath } from "openclaw/plugin-sdk/config-runtime";
import type { ResolvedAgentRoute } from "openclaw/plugin-sdk/routing";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import { chunkItems, withTimeout } from "openclaw/plugin-sdk/text-runtime";

View File

@ -13,8 +13,24 @@ import {
import { ApplicationCommandOptionType } from "discord-api-types/v10";
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/channel-runtime";
import { resolveNativeCommandSessionTargets } from "openclaw/plugin-sdk/channel-runtime";
import {
resolveCommandAuthorizedFromAuthorizers,
resolveNativeCommandSessionTargets,
} from "openclaw/plugin-sdk/command-auth";
import {
buildCommandTextFromArgs,
findCommandByNativeName,
listChatCommands,
parseCommandArgs,
resolveCommandArgChoices,
resolveCommandArgMenu,
serializeCommandArgs,
type ChatCommandDefinition,
type CommandArgDefinition,
type CommandArgValues,
type CommandArgs,
type NativeCommandSpec,
} from "openclaw/plugin-sdk/command-auth";
import type { OpenClawConfig, loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/config-runtime";
@ -30,22 +46,6 @@ import {
resolveTextChunksWithFallback,
} from "openclaw/plugin-sdk/reply-payload";
import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
import type {
ChatCommandDefinition,
CommandArgDefinition,
CommandArgValues,
CommandArgs,
NativeCommandSpec,
} from "openclaw/plugin-sdk/reply-runtime";
import {
buildCommandTextFromArgs,
findCommandByNativeName,
listChatCommands,
parseCommandArgs,
resolveCommandArgChoices,
resolveCommandArgMenu,
serializeCommandArgs,
} from "openclaw/plugin-sdk/reply-runtime";
import { dispatchReplyWithDispatcher } from "openclaw/plugin-sdk/reply-runtime";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";

View File

@ -4,7 +4,7 @@ import {
canonicalizeAllowlistWithResolvedIds,
patchAllowlistUsersInConfigEntries,
summarizeMapping,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/allow-from";
import type { DiscordGuildEntry } from "openclaw/plugin-sdk/config-runtime";
import { formatErrorMessage } from "openclaw/plugin-sdk/infra-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";

View File

@ -1,6 +1,6 @@
import type { Client } from "@buape/carbon";
import type { GatewayPlugin } from "@buape/carbon/gateway";
import { createArmableStallWatchdog } from "openclaw/plugin-sdk/channel-runtime";
import { createArmableStallWatchdog } from "openclaw/plugin-sdk/channel-lifecycle";
import { createConnectedChannelStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
import { danger } from "openclaw/plugin-sdk/runtime-env";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";

View File

@ -14,10 +14,10 @@ import { Routes } from "discord-api-types/v10";
import { getAcpSessionManager } from "openclaw/plugin-sdk/acp-runtime";
import { isAcpRuntimeError } from "openclaw/plugin-sdk/acp-runtime";
import {
resolveThreadBindingIdleTimeoutMs,
resolveThreadBindingMaxAgeMs,
resolveThreadBindingsEnabled,
} from "openclaw/plugin-sdk/channel-runtime";
listNativeCommandSpecsForConfig,
listSkillCommandsForAgents,
type NativeCommandSpec,
} from "openclaw/plugin-sdk/command-auth";
import {
isNativeCommandsExplicitlyDisabled,
resolveNativeCommandsEnabled,
@ -32,14 +32,16 @@ import {
resolveDefaultGroupPolicy,
warnMissingProviderGroupPolicyFallbackOnce,
} from "openclaw/plugin-sdk/config-runtime";
import {
resolveThreadBindingIdleTimeoutMs,
resolveThreadBindingMaxAgeMs,
resolveThreadBindingsEnabled,
} from "openclaw/plugin-sdk/conversation-runtime";
import { createConnectedChannelStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
import { formatErrorMessage } from "openclaw/plugin-sdk/infra-runtime";
import { getPluginCommandSpecs } from "openclaw/plugin-sdk/plugin-runtime";
import type { HistoryEntry } from "openclaw/plugin-sdk/reply-history";
import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
import type { NativeCommandSpec } from "openclaw/plugin-sdk/reply-runtime";
import { listNativeCommandSpecsForConfig } from "openclaw/plugin-sdk/reply-runtime";
import type { HistoryEntry } from "openclaw/plugin-sdk/reply-runtime";
import { listSkillCommandsForAgents } from "openclaw/plugin-sdk/reply-runtime";
import {
danger,
isVerbose,

View File

@ -1,9 +1,9 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
resolveThreadBindingIdleTimeoutMs,
resolveThreadBindingMaxAgeMs,
resolveThreadBindingsEnabled,
} from "openclaw/plugin-sdk/channel-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
} from "openclaw/plugin-sdk/conversation-runtime";
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
export {

View File

@ -1,8 +1,8 @@
import { Routes } from "discord-api-types/v10";
import { resolveThreadBindingConversationIdFromBindingId } from "openclaw/plugin-sdk/channel-runtime";
import { getRuntimeConfigSnapshot, type OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
registerSessionBindingAdapter,
resolveThreadBindingConversationIdFromBindingId,
unregisterSessionBindingAdapter,
type BindingTargetKind,
type SessionBindingRecord,

View File

@ -1,6 +1,6 @@
export {
formatThreadBindingDurationLabel,
resolveThreadBindingFarewellText,
resolveThreadBindingIntroText,
resolveThreadBindingThreadName,
} from "openclaw/plugin-sdk/channel-runtime";
formatThreadBindingDurationLabel,
} from "openclaw/plugin-sdk/conversation-runtime";

View File

@ -1,16 +1,15 @@
import {
attachChannelToResult,
type ChannelOutboundAdapter,
createAttachedChannelResultAdapter,
} from "openclaw/plugin-sdk/channel-send-result";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { resolveOutboundSendDep, type OutboundIdentity } from "openclaw/plugin-sdk/infra-runtime";
import {
resolvePayloadMediaUrls,
sendPayloadMediaSequenceOrFallback,
sendTextMediaPayload,
} from "openclaw/plugin-sdk/channel-runtime";
import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/channel-runtime";
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime";
import {
attachChannelToResult,
createAttachedChannelResultAdapter,
} from "openclaw/plugin-sdk/channel-send-result";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import type { OutboundIdentity } from "openclaw/plugin-sdk/infra-runtime";
} from "openclaw/plugin-sdk/reply-payload";
import type { DiscordComponentMessageSpec } from "./components.js";
import { getThreadBindingManager, type ThreadBindingRecord } from "./monitor/thread-bindings.js";
import { normalizeDiscordOutboundTarget } from "./normalize.js";

View File

@ -1,4 +1,4 @@
import type { BaseProbeResult } from "openclaw/plugin-sdk/channel-runtime";
import type { BaseProbeResult } from "openclaw/plugin-sdk/channel-contract";
import { resolveFetch } from "openclaw/plugin-sdk/infra-runtime";
import { fetchWithTimeout } from "openclaw/plugin-sdk/text-runtime";
import { normalizeDiscordToken } from "./token.js";

View File

@ -4,7 +4,7 @@ export {
PAIRING_APPROVED_MESSAGE,
projectCredentialSnapshotFields,
resolveConfiguredFromCredentialStatuses,
} from "openclaw/plugin-sdk/channel-runtime";
} from "../../../src/plugin-sdk/discord.js";
export {
buildChannelConfigSchema,
getChatChannelMeta,
@ -19,15 +19,15 @@ export {
type DiscordActionConfig,
type DiscordConfig,
type OpenClawConfig,
} from "openclaw/plugin-sdk/discord-core";
export { DiscordConfigSchema } from "openclaw/plugin-sdk/discord-core";
} from "../../../src/plugin-sdk/discord-core.js";
export { DiscordConfigSchema } from "../../../src/plugin-sdk/discord-core.js";
export { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
export {
assertMediaNotDataUrl,
parseAvailableTags,
readReactionParams,
withNormalizedTimestamp,
} from "openclaw/plugin-sdk/discord-core";
} from "../../../src/plugin-sdk/discord-core.js";
export {
createHybridChannelConfigAdapter,
createScopedChannelConfigAdapter,
@ -44,9 +44,9 @@ export { resolveAccountEntry } from "openclaw/plugin-sdk/routing";
export type {
ChannelMessageActionAdapter,
ChannelMessageActionName,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-contract";
export {
hasConfiguredSecretInput,
normalizeResolvedSecretInputString,
normalizeSecretInputString,
} from "openclaw/plugin-sdk/config-runtime";
} from "openclaw/plugin-sdk/secret-input";

View File

@ -1,4 +1,4 @@
import { normalizeChatType } from "openclaw/plugin-sdk/channel-runtime";
import { normalizeChatType } from "openclaw/plugin-sdk/account-resolution";
import type { MsgContext } from "openclaw/plugin-sdk/reply-runtime";
export function normalizeExplicitDiscordSessionKey(

View File

@ -1,9 +1,9 @@
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
hasConfiguredSecretInput,
normalizeSecretInputString,
type OpenClawConfig,
} from "openclaw/plugin-sdk/config-runtime";
} from "openclaw/plugin-sdk/secret-input";
import type { DiscordAccountConfig } from "./runtime-api.js";
import { resolveDiscordToken } from "./token.js";

View File

@ -1,13 +1,13 @@
import type {
ChannelAccountSnapshot,
ChannelStatusIssue,
} from "openclaw/plugin-sdk/channel-contract";
import {
appendMatchMetadata,
asString,
isRecord,
resolveEnabledConfiguredAccountId,
} from "openclaw/plugin-sdk/channel-runtime";
import type {
ChannelAccountSnapshot,
ChannelStatusIssue,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/status-helpers";
type DiscordIntentSummary = {
messageContent?: "enabled" | "limited" | "disabled";

View File

@ -1,4 +1,4 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/discord";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
getRequiredHookHandler,

View File

@ -1,4 +1,3 @@
import type { DirectoryConfigParams } from "openclaw/plugin-sdk/channel-runtime";
import {
buildMessagingTarget,
parseMentionPrefixOrAtUserTarget,
@ -6,7 +5,8 @@ import {
type MessagingTarget,
type MessagingTargetKind,
type MessagingTargetParseOptions,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-targets";
import type { DirectoryConfigParams } from "openclaw/plugin-sdk/directory-runtime";
import { rememberDiscordDirectoryUser } from "./directory-cache.js";
import { listDiscordDirectoryPeersLive } from "./directory-live.js";

View File

@ -1,7 +1,7 @@
import type { BaseTokenResolution } from "openclaw/plugin-sdk/channel-runtime";
import type { BaseTokenResolution } from "openclaw/plugin-sdk/channel-contract";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/config-runtime";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/routing";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
export type DiscordTokenSource = "env" | "config" | "none";

View File

@ -10,7 +10,7 @@ import {
ChannelType as DiscordChannelType,
type APIApplicationCommandChannelOption,
} from "discord-api-types/v10";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/channel-runtime";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/command-auth";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
import type { DiscordAccountConfig } from "openclaw/plugin-sdk/config-runtime";

View File

@ -1,4 +1,4 @@
// Private runtime barrel for the bundled Feishu extension.
// Keep this barrel thin and aligned with the local extension surface.
export * from "openclaw/plugin-sdk/feishu";
export * from "../../src/plugin-sdk/feishu.js";

View File

@ -1,21 +1,23 @@
import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
import { createMessageToolCardSchema } from "openclaw/plugin-sdk/channel-actions";
import { createHybridChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
import type {
ChannelMessageActionAdapter,
ChannelMessageToolDiscovery,
} from "openclaw/plugin-sdk/channel-contract";
import {
createPairingPrefixStripper,
createTextPairingAdapter,
} from "openclaw/plugin-sdk/channel-pairing";
import {
createAllowlistProviderGroupPolicyWarningCollector,
projectWarningCollector,
} from "openclaw/plugin-sdk/channel-policy";
import {
createChannelDirectoryAdapter,
createMessageToolCardSchema,
createPairingPrefixStripper,
createRuntimeDirectoryLiveAdapter,
createRuntimeOutboundDelegates,
createTextPairingAdapter,
} from "openclaw/plugin-sdk/channel-runtime";
import type {
ChannelMessageActionAdapter,
ChannelMessageToolDiscovery,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/directory-runtime";
import { createRuntimeOutboundDelegates } from "openclaw/plugin-sdk/infra-runtime";
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
import type { ChannelMeta, ChannelPlugin, ClawdbotConfig } from "../runtime-api.js";
import {

View File

@ -1,11 +1,9 @@
import { resolveThreadBindingConversationIdFromBindingId } from "openclaw/plugin-sdk/channel-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
resolveThreadBindingIdleTimeoutMsForChannel,
resolveThreadBindingMaxAgeMsForChannel,
} from "openclaw/plugin-sdk/channel-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
registerSessionBindingAdapter,
resolveThreadBindingConversationIdFromBindingId,
unregisterSessionBindingAdapter,
type BindingTargetKind,
type SessionBindingRecord,

View File

@ -1,6 +1,6 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/config-runtime";
import { normalizeSecretInput } from "openclaw/plugin-sdk/provider-auth";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
export const DEFAULT_FIRECRAWL_BASE_URL = "https://api.firecrawl.dev";
export const DEFAULT_FIRECRAWL_SEARCH_TIMEOUT_SECONDS = 30;

View File

@ -3,7 +3,7 @@ import type {
ProviderAuthContext,
ProviderFetchUsageSnapshotContext,
} from "openclaw/plugin-sdk/plugin-entry";
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-oauth";
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-auth";
import { fetchGeminiUsage } from "openclaw/plugin-sdk/provider-usage";
import { isModernGoogleModel, resolveGoogle31ForwardCompatModel } from "./provider-models.js";

View File

@ -1,4 +1,4 @@
// Private runtime barrel for the bundled Google Chat extension.
// Keep this barrel thin and aligned with the local extension surface.
export * from "openclaw/plugin-sdk/googlechat";
export * from "../../src/plugin-sdk/googlechat.js";

View File

@ -3,19 +3,17 @@ import {
createScopedChannelConfigAdapter,
createScopedDmSecurityResolver,
} from "openclaw/plugin-sdk/channel-config-helpers";
import { createTextPairingAdapter } from "openclaw/plugin-sdk/channel-pairing";
import {
composeWarningCollectors,
createAllowlistProviderGroupPolicyWarningCollector,
createConditionalWarningCollector,
createAllowlistProviderOpenWarningCollector,
} from "openclaw/plugin-sdk/channel-policy";
import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
import { createTopLevelChannelReplyToModeResolver } from "openclaw/plugin-sdk/conversation-runtime";
import {
createAttachedChannelResultAdapter,
createChannelDirectoryAdapter,
createTopLevelChannelReplyToModeResolver,
createTextPairingAdapter,
} from "openclaw/plugin-sdk/channel-runtime";
import {
listResolvedDirectoryGroupEntriesFromMapKeys,
listResolvedDirectoryUserEntriesFromAllowFrom,
} from "openclaw/plugin-sdk/directory-runtime";

View File

@ -13,7 +13,7 @@ export {
IMessageConfigSchema,
type ChannelPlugin,
type IMessageAccountConfig,
} from "openclaw/plugin-sdk/imessage";
} from "../../src/plugin-sdk/imessage.js";
export {
resolveIMessageGroupRequireMention,
resolveIMessageGroupToolPolicy,

View File

@ -1,4 +1,4 @@
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime";
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/infra-runtime";
import { PAIRING_APPROVED_MESSAGE, resolveChannelMediaMaxBytes } from "../runtime-api.js";
import type { ResolvedIMessageAccount } from "./accounts.js";
import { monitorIMessageProvider } from "./monitor.js";

View File

@ -1,12 +1,9 @@
import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
import {
createAttachedChannelResultAdapter,
resolveOutboundSendDep,
} from "openclaw/plugin-sdk/channel-runtime";
import { buildOutboundBaseSessionKey } from "openclaw/plugin-sdk/core";
import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
import { buildPassiveProbedChannelStatusSummary } from "openclaw/plugin-sdk/extension-shared";
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/infra-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { type RoutePeer } from "openclaw/plugin-sdk/routing";
import { buildOutboundBaseSessionKey, type RoutePeer } from "openclaw/plugin-sdk/routing";
import {
collectStatusIssuesFromLastError,
DEFAULT_ACCOUNT_ID,

View File

@ -1,3 +1,3 @@
import { buildChannelConfigSchema, IMessageConfigSchema } from "openclaw/plugin-sdk/imessage-core";
import { buildChannelConfigSchema, IMessageConfigSchema } from "../runtime-api.js";
export const IMessageChannelConfigSchema = buildChannelConfigSchema(IMessageConfigSchema);

View File

@ -1,24 +1,25 @@
import { resolveDualTextControlCommandGate } from "openclaw/plugin-sdk/channel-runtime";
import { logInboundDrop } from "openclaw/plugin-sdk/channel-runtime";
import {
buildMentionRegexes,
type EnvelopeFormatOptions,
formatInboundEnvelope,
formatInboundFromLabel,
logInboundDrop,
matchesMentionPatterns,
resolveEnvelopeFormatOptions,
} from "openclaw/plugin-sdk/channel-inbound";
import { hasControlCommand } from "openclaw/plugin-sdk/command-auth";
import { resolveDualTextControlCommandGate } from "openclaw/plugin-sdk/command-auth";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
resolveChannelGroupPolicy,
resolveChannelGroupRequireMention,
} from "openclaw/plugin-sdk/config-runtime";
import { hasControlCommand } from "openclaw/plugin-sdk/reply-runtime";
import {
formatInboundEnvelope,
formatInboundFromLabel,
resolveEnvelopeFormatOptions,
type EnvelopeFormatOptions,
} from "openclaw/plugin-sdk/reply-runtime";
import {
buildPendingHistoryContextFromMap,
recordPendingHistoryEntryIfEnabled,
type HistoryEntry,
} from "openclaw/plugin-sdk/reply-runtime";
} from "openclaw/plugin-sdk/reply-history";
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-runtime";
import { buildMentionRegexes, matchesMentionPatterns } from "openclaw/plugin-sdk/reply-runtime";
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
import {
DM_GROUP_ACCESS_REASON,

View File

@ -1,12 +1,11 @@
import fs from "node:fs/promises";
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import {
createChannelInboundDebouncer,
shouldDebounceTextInbound,
} from "openclaw/plugin-sdk/channel-runtime";
import { recordInboundSession } from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-inbound";
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import {
resolveOpenProviderRuntimeGroupPolicy,
@ -18,6 +17,7 @@ import {
readChannelAllowFromStore,
upsertChannelPairingRequest,
} from "openclaw/plugin-sdk/conversation-runtime";
import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";
import { normalizeScpRemoteHost } from "openclaw/plugin-sdk/infra-runtime";
import { waitForTransportReady } from "openclaw/plugin-sdk/infra-runtime";
import {
@ -26,13 +26,13 @@ import {
resolveIMessageRemoteAttachmentRoots,
} from "openclaw/plugin-sdk/media-runtime";
import { kindFromMime } from "openclaw/plugin-sdk/media-runtime";
import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
import { dispatchInboundMessage } from "openclaw/plugin-sdk/reply-runtime";
import {
clearHistoryEntriesIfEnabled,
DEFAULT_GROUP_HISTORY_LIMIT,
type HistoryEntry,
} from "openclaw/plugin-sdk/reply-runtime";
} from "openclaw/plugin-sdk/reply-history";
import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
import { dispatchInboundMessage } from "openclaw/plugin-sdk/reply-runtime";
import { createReplyDispatcher } from "openclaw/plugin-sdk/reply-runtime";
import { danger, logVerbose, shouldLogVerbose, warn } from "openclaw/plugin-sdk/runtime-env";
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";

View File

@ -1,8 +1,8 @@
import { resolveOutboundSendDep, type OutboundSendDeps } from "openclaw/plugin-sdk/infra-runtime";
import {
createScopedChannelMediaMaxBytesResolver,
createDirectTextMediaOutbound,
} from "openclaw/plugin-sdk/channel-runtime";
import { resolveOutboundSendDep, type OutboundSendDeps } from "openclaw/plugin-sdk/channel-runtime";
createScopedChannelMediaMaxBytesResolver,
} from "openclaw/plugin-sdk/media-runtime";
import { sendMessageIMessage } from "./send.js";
function resolveIMessageSender(deps: OutboundSendDeps | undefined) {

View File

@ -1,4 +1,4 @@
import type { BaseProbeResult } from "openclaw/plugin-sdk/channel-runtime";
import type { BaseProbeResult } from "openclaw/plugin-sdk/channel-contract";
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { runCommandWithTimeout } from "openclaw/plugin-sdk/process-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";

View File

@ -1,8 +1,8 @@
import { createAccountListHelpers } from "openclaw/plugin-sdk/account-helpers";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/config-runtime";
import { parseOptionalDelimitedEntries } from "openclaw/plugin-sdk/core";
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/infra-runtime";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
import type { CoreConfig, IrcAccountConfig, IrcNickServConfig } from "./types.js";
const TRUTHY_ENV = new Set(["true", "1", "yes", "on"]);

View File

@ -3,17 +3,17 @@ import {
createScopedChannelConfigAdapter,
createScopedDmSecurityResolver,
} from "openclaw/plugin-sdk/channel-config-helpers";
import { createTextPairingAdapter } from "openclaw/plugin-sdk/channel-pairing";
import {
composeWarningCollectors,
createAllowlistProviderOpenWarningCollector,
createConditionalWarningCollector,
} from "openclaw/plugin-sdk/channel-policy";
import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
import {
createAttachedChannelResultAdapter,
createChannelDirectoryAdapter,
createTextPairingAdapter,
listResolvedDirectoryEntriesFromSources,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/directory-runtime";
import { runStoppablePassiveMonitor } from "openclaw/plugin-sdk/extension-shared";
import {
listIrcAccountIds,

View File

@ -1,4 +1,4 @@
// Private runtime barrel for the bundled IRC extension.
// Keep this barrel thin and aligned with the local extension surface.
export * from "openclaw/plugin-sdk/irc";
export * from "../../../src/plugin-sdk/irc.js";

View File

@ -1,5 +1,4 @@
import type { ChannelSetupAdapter } from "openclaw/plugin-sdk/channel-runtime";
import type { ChannelSetupInput } from "openclaw/plugin-sdk/channel-runtime";
import type { ChannelSetupAdapter, ChannelSetupInput } from "openclaw/plugin-sdk/channel-setup";
import type { DmPolicy } from "openclaw/plugin-sdk/config-runtime";
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
import {

View File

@ -7,18 +7,18 @@ export type {
export { buildChannelConfigSchema, clearAccountEntryFields } from "openclaw/plugin-sdk/core";
export type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
export type { ChannelAccountSnapshot, ChannelGatewayContext } from "openclaw/plugin-sdk/testing";
export type { ChannelStatusIssue } from "openclaw/plugin-sdk/channel-runtime";
export type { ChannelStatusIssue } from "openclaw/plugin-sdk/channel-contract";
export {
buildComputedAccountStatusSnapshot,
buildTokenChannelStatusSummary,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/status-helpers";
export type {
CardAction,
LineChannelData,
LineConfig,
ListItem,
ResolvedLineAccount,
} from "openclaw/plugin-sdk/line-core";
} from "./runtime-api.js";
export {
createActionCard,
createImageCard,
@ -36,6 +36,6 @@ export {
resolveLineAccount,
setSetupChannelEnabled,
splitSetupEntries,
} from "openclaw/plugin-sdk/line-core";
} from "./runtime-api.js";
export * from "./runtime-api.js";
export * from "./setup-api.js";

View File

@ -1,19 +1,13 @@
// Private runtime barrel for the bundled LINE extension.
// Keep this barrel thin and aligned with the local extension surface.
export type { OpenClawConfig } from "openclaw/plugin-sdk/line-core";
export type { ChannelSetupDmPolicy, ChannelSetupWizard } from "openclaw/plugin-sdk/channel-setup";
export type { LineConfig, ResolvedLineAccount } from "openclaw/plugin-sdk/line-core";
export { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
export * from "../../src/plugin-sdk/line.js";
export {
DEFAULT_ACCOUNT_ID,
formatDocsLink,
LineConfigSchema,
listLineAccountIds,
normalizeAccountId,
resolveDefaultLineAccountId,
resolveExactLineGroupConfigKey,
resolveLineAccount,
setSetupChannelEnabled,
splitSetupEntries,
} from "openclaw/plugin-sdk/line-core";
type ChannelSetupDmPolicy,
type ChannelSetupWizard,
} from "../../src/plugin-sdk/line-core.js";

View File

@ -1,12 +1,14 @@
import { createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
import {
createPairingPrefixStripper,
createTextPairingAdapter,
} from "openclaw/plugin-sdk/channel-pairing";
import { createAllowlistProviderRestrictSendersWarningCollector } from "openclaw/plugin-sdk/channel-policy";
import {
createAttachedChannelResultAdapter,
createEmptyChannelDirectoryAdapter,
createEmptyChannelResult,
createPairingPrefixStripper,
createTextPairingAdapter,
} from "openclaw/plugin-sdk/channel-runtime";
} from "openclaw/plugin-sdk/channel-send-result";
import { createEmptyChannelDirectoryAdapter } from "openclaw/plugin-sdk/directory-runtime";
import { resolveOutboundMediaUrls } from "openclaw/plugin-sdk/reply-payload";
import {
buildComputedAccountStatusSnapshot,

View File

@ -5,7 +5,7 @@ import {
resolveLineAccount,
type OpenClawConfig,
type ResolvedLineAccount,
} from "openclaw/plugin-sdk/line-core";
} from "../runtime-api.js";
export function normalizeLineAllowFrom(entry: string): string {
return entry.replace(/^line:(?:user:)?/i, "");

View File

@ -1,5 +1,5 @@
import { resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
import { resolveExactLineGroupConfigKey, type OpenClawConfig } from "openclaw/plugin-sdk/line-core";
import { resolveExactLineGroupConfigKey, type OpenClawConfig } from "../runtime-api.js";
type LineGroupContext = {
cfg: OpenClawConfig;

View File

@ -1,11 +1,11 @@
import type { ChannelSetupAdapter, OpenClawConfig } from "openclaw/plugin-sdk/setup";
import {
DEFAULT_ACCOUNT_ID,
listLineAccountIds,
normalizeAccountId,
resolveLineAccount,
type LineConfig,
} from "openclaw/plugin-sdk/line-core";
import type { ChannelSetupAdapter, OpenClawConfig } from "openclaw/plugin-sdk/setup";
} from "../runtime-api.js";
const channel = "line" as const;

View File

@ -1,3 +1,4 @@
import { createAllowFromSection, createTopLevelChannelDmPolicy } from "openclaw/plugin-sdk/setup";
import {
DEFAULT_ACCOUNT_ID,
formatDocsLink,
@ -6,8 +7,7 @@ import {
splitSetupEntries,
type ChannelSetupDmPolicy,
type ChannelSetupWizard,
} from "openclaw/plugin-sdk/line-core";
import { createAllowFromSection, createTopLevelChannelDmPolicy } from "openclaw/plugin-sdk/setup";
} from "../runtime-api.js";
import {
isLineConfigured,
listLineAccountIds,

View File

@ -3,4 +3,27 @@
// matrix-js-sdk during plain runtime-api import.
export * from "./src/auth-precedence.js";
export * from "./helper-api.js";
export * from "./thread-bindings-runtime.js";
export {
assertHttpUrlTargetsPrivateNetwork,
closeDispatcher,
createPinnedDispatcher,
resolvePinnedHostnameWithPolicy,
ssrfPolicyFromAllowPrivateNetwork,
type LookupFn,
type SsrFPolicy,
} from "openclaw/plugin-sdk/ssrf-runtime";
export {
setMatrixThreadBindingIdleTimeoutBySessionKey,
setMatrixThreadBindingMaxAgeBySessionKey,
} from "./thread-bindings-runtime.js";
export { writeJsonFileAtomically } from "../../src/plugin-sdk/json-store.js";
export type {
ChannelDirectoryEntry,
ChannelMessageActionContext,
OpenClawConfig,
PluginRuntime,
RuntimeLogger,
RuntimeEnv,
WizardPrompter,
} from "../../src/plugin-sdk/matrix.js";
export { formatZonedTimestamp } from "../../src/plugin-sdk/matrix.js";

View File

@ -1,5 +1,5 @@
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/matrix";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ChannelMessageActionContext } from "../runtime-api.js";
import type { CoreConfig } from "./types.js";
const mocks = vi.hoisted(() => ({

View File

@ -1,5 +1,5 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/matrix";
import { beforeEach, describe, expect, it } from "vitest";
import type { PluginRuntime } from "../runtime-api.js";
import { matrixMessageActions } from "./actions.js";
import { setMatrixRuntime } from "./runtime.js";
import type { CoreConfig } from "./types.js";

Some files were not shown because too many files have changed in this diff Show More