Skip to content

Commit 24a7326

Browse files
committed
chore(release): ship OpenClawKit 2026.2.5 parity
1 parent 7429af5 commit 24a7326

20 files changed

Lines changed: 2482 additions & 701 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ DerivedData/
77
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
88
.netrc
99
.env
10-
.cursor
10+
.cursor
11+
.codex/

CHANGELOG.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
## 2026.2.5 - 2026-04-25
6+
7+
### Added
8+
9+
- OpenClaw `2026.4.25` SDK/control-plane parity pinned to `.codex/openclaw`
10+
commit `6b0c72bec8`, including regenerated gateway protocol models and
11+
compatibility shims for existing OpenClawKit gateway payloads.
12+
- Generated protocol coverage for new upstream request/result surfaces:
13+
message actions, session creation/send/abort, session compaction checkpoints,
14+
talk realtime/speech requests, command/tool catalog requests, skill
15+
search/detail requests, and approval control-plane payloads.
16+
- Provider catalog parity for the `2026.4.25` train, including
17+
`anthropic-vertex`, `amazon-bedrock-mantle`, `arcee`, `chutes`,
18+
`copilot-proxy`, `deepseek`, `fireworks`, `lmstudio`,
19+
`microsoft-foundry`, `qwen`, `stepfun`, `stepfun-plan`, and
20+
`tencent-tokenhub`.
21+
- Capability-aware provider metadata for upstream media, speech, embedding,
22+
web-search, image-generation, video-generation, and music-generation plugin
23+
providers that are metadata/config-visible without native Swift runtime
24+
adapters.
25+
- Channel metadata parity for upstream plugin channels including `feishu`,
26+
`irc`, `matrix`, `mattermost`, `nextcloud-talk`, `nostr`, `qqbot`,
27+
`synology-chat`, `tlon`, `twitch`, `zalo`, `zalouser`, and `qa-channel`,
28+
with native transport availability explicitly marked.
29+
30+
### Changed
31+
32+
- `openai-codex` now defaults to upstream `gpt-5.5` for the pinned parity
33+
snapshot.
34+
- The in-process gateway server now recognizes and decodes newly known
35+
control-plane methods, returning explicit unavailable responses for
36+
metadata-only or unconfigured Swift behavior instead of treating them as
37+
unknown requests.
38+
- `.codex/` is ignored so the embedded upstream reference checkout remains a
39+
local-only parity input.
40+
41+
### Tests
42+
43+
- Added snapshot and fixture coverage for new protocol payloads, provider
44+
capabilities, channel metadata, plugin-channel secret auditing, and known
45+
gateway-method unavailable/error-code mapping.
46+
- `swift test` remains locally blocked by the machine/toolchain error
47+
`no such module 'Testing'`; `swift build -Xswiftc -warnings-as-errors`
48+
passes for the package source.
49+
350
## 2026.2.4 - 2026-03-14
451

552
### Added

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ The repository currently ships:
2222

2323
Current baseline:
2424

25-
- latest tagged release: `2026.2.4`
26-
- OpenClaw parity target: upstream `2026.3.13`
25+
- latest tagged release: `2026.2.5`
26+
- current development parity target: upstream `2026.4.25` at `.codex/openclaw` commit `6b0c72bec8`
2727
- direct OpenAI and Codex-backed OpenAI paths run through `OpenAIKit 3.0.0`
2828
- public docs site: [marcodotio.github.io/OpenClawKit](https://marcodotio.github.io/OpenClawKit/)
2929

@@ -40,7 +40,7 @@ Add the package with Swift Package Manager:
4040

4141
```swift
4242
dependencies: [
43-
.package(url: "https://github.com/MarcoDotIO/OpenClawKit.git", from: "2026.2.4")
43+
.package(url: "https://github.com/MarcoDotIO/OpenClawKit.git", from: "2026.2.5")
4444
]
4545
```
4646

Scripts/protocol-gen-swift.mjs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ const execFileAsync = promisify(execFile);
1010
const here = path.dirname(fileURLToPath(import.meta.url));
1111
const root = path.resolve(here, "..");
1212
const outPath = path.join(root, "Sources", "OpenClawProtocol", "GatewayModels.swift");
13-
const upstreamRepoPath = path.join(root, ".cursor", "openclaw");
14-
const upstreamTag = "v2026.3.13";
15-
const upstreamTagObject = "61cd3a6e446c3d181a0a75861fd85d459c068a3d";
16-
const upstreamCommit = "f6e5b6758e74608f825218de264c96b224fe2e81";
13+
const upstreamRepoPath = path.join(root, ".codex", "openclaw");
14+
const upstreamLabel = "OpenClaw 2026.4.25";
15+
const upstreamCommit = "6b0c72bec8";
1716
const upstreamSourcePath = path.posix.join(
1817
"apps",
1918
"shared",
@@ -37,13 +36,13 @@ async function readUpstreamSnapshot() {
3736
} catch (error) {
3837
const detail = error instanceof Error ? error.message : String(error);
3938
throw new Error(
40-
`Failed to read ${upstreamTag} protocol snapshot (${upstreamCommit}) from ${upstreamRepoPath}: ${detail}`,
39+
`Failed to read ${upstreamLabel} protocol snapshot (${upstreamCommit}) from ${upstreamRepoPath}: ${detail}`,
4140
);
4241
}
4342
}
4443

4544
const body = await readUpstreamSnapshot();
4645
await fs.writeFile(outPath, body);
4746
console.log(
48-
`Synced ${outPath} from OpenClaw ${upstreamTag} (tag ${upstreamTagObject}, commit ${upstreamCommit})`,
47+
`Synced ${outPath} from ${upstreamLabel} (${upstreamCommit})`,
4948
);

Sources/OpenClawChannels/ChannelAdapter.swift

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,92 @@ public enum ChannelID: String, CaseIterable, Sendable {
1818
case msteams
1919
case line
2020
case webchat
21+
case feishu
22+
case irc
23+
case matrix
24+
case mattermost
25+
case nextcloudTalk = "nextcloud-talk"
26+
case nostr
27+
case qqbot
28+
case synologyChat = "synology-chat"
29+
case tlon
30+
case twitch
31+
case zalo
32+
case zalouser
33+
case qaChannel = "qa-channel"
34+
}
35+
36+
/// Channel metadata for upstream channel plugins and native Swift adapters.
37+
public struct ChannelMetadataEntry: Sendable, Equatable {
38+
/// Stable channel identifier.
39+
public var id: ChannelID
40+
/// Human-facing channel label.
41+
public var label: String
42+
/// Optional upstream documentation path.
43+
public var docsPath: String?
44+
/// Additional accepted upstream identifiers.
45+
public var aliases: [String]
46+
/// Whether OpenClawKit currently provides a native Swift transport adapter.
47+
public var nativeTransportAvailable: Bool
48+
49+
/// Creates a channel metadata entry.
50+
public init(
51+
id: ChannelID,
52+
label: String,
53+
docsPath: String? = nil,
54+
aliases: [String] = [],
55+
nativeTransportAvailable: Bool
56+
) {
57+
self.id = id
58+
self.label = label
59+
self.docsPath = docsPath
60+
self.aliases = aliases
61+
self.nativeTransportAvailable = nativeTransportAvailable
62+
}
63+
}
64+
65+
/// Channel metadata catalog aligned with the pinned OpenClaw upstream plugin set.
66+
public enum OpenClawChannelMetadataCatalog {
67+
/// Known channel metadata entries, including plugin-only channels without Swift transports.
68+
public static let entries: [ChannelMetadataEntry] = [
69+
native(.whatsapp, "WhatsApp", docsPath: "/channels/whatsapp"),
70+
native(.telegram, "Telegram", docsPath: "/channels/telegram"),
71+
native(.slack, "Slack", docsPath: "/channels/slack"),
72+
native(.googlechat, "Google Chat", docsPath: "/channels/googlechat"),
73+
native(.discord, "Discord", docsPath: "/channels/discord"),
74+
native(.signal, "Signal", docsPath: "/channels/signal"),
75+
native(.bluebubbles, "BlueBubbles", docsPath: "/channels/bluebubbles"),
76+
native(.imessage, "iMessage", docsPath: "/channels/imessage"),
77+
native(.msteams, "Microsoft Teams", docsPath: "/channels/msteams"),
78+
native(.webchat, "WebChat", docsPath: "/channels/webchat"),
79+
plugin(.line, "LINE", docsPath: "/channels/line"),
80+
plugin(.feishu, "Feishu", docsPath: "/channels/feishu"),
81+
plugin(.irc, "IRC", docsPath: "/channels/irc"),
82+
plugin(.matrix, "Matrix", docsPath: "/channels/matrix"),
83+
plugin(.mattermost, "Mattermost", docsPath: "/channels/mattermost"),
84+
plugin(.nextcloudTalk, "Nextcloud Talk", docsPath: "/channels/nextcloud-talk"),
85+
plugin(.nostr, "Nostr", docsPath: "/channels/nostr"),
86+
plugin(.qqbot, "QQ Bot", docsPath: "/channels/qqbot"),
87+
plugin(.synologyChat, "Synology Chat", docsPath: "/channels/synology-chat"),
88+
plugin(.tlon, "Tlon", docsPath: "/channels/tlon"),
89+
plugin(.twitch, "Twitch", docsPath: "/channels/twitch"),
90+
plugin(.zalo, "Zalo", docsPath: "/channels/zalo"),
91+
plugin(.zalouser, "Zalo User", docsPath: "/channels/zalouser"),
92+
plugin(.qaChannel, "QA Channel", docsPath: "/channels/qa-channel"),
93+
]
94+
95+
/// Returns channel metadata for one identifier.
96+
public static func entry(for id: ChannelID) -> ChannelMetadataEntry? {
97+
self.entries.first { $0.id == id }
98+
}
99+
100+
private static func native(_ id: ChannelID, _ label: String, docsPath: String? = nil) -> ChannelMetadataEntry {
101+
ChannelMetadataEntry(id: id, label: label, docsPath: docsPath, nativeTransportAvailable: true)
102+
}
103+
104+
private static func plugin(_ id: ChannelID, _ label: String, docsPath: String? = nil) -> ChannelMetadataEntry {
105+
ChannelMetadataEntry(id: id, label: label, docsPath: docsPath, nativeTransportAvailable: false)
106+
}
21107
}
22108

23109
/// Normalized inbound message envelope delivered to the runtime.

Sources/OpenClawCore/OpenClawConfig.swift

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ public struct ChannelsConfig: Codable, Sendable, Equatable {
538538
public var imessage: IMessageChannelConfig
539539
public var msteams: MicrosoftTeamsChannelConfig
540540
public var webchat: WebChatChannelConfig
541+
public var pluginChannels: [String: PluginChannelConfig]
541542

542543
/// Creates channel config.
543544
/// - Parameter discord: Discord channel settings.
@@ -550,6 +551,7 @@ public struct ChannelsConfig: Codable, Sendable, Equatable {
550551
/// - Parameter imessage: iMessage channel settings.
551552
/// - Parameter msteams: Microsoft Teams channel settings.
552553
/// - Parameter webchat: WebChat channel settings.
554+
/// - Parameter pluginChannels: Metadata/config blocks for upstream plugin-only channels.
553555
public init(
554556
discord: DiscordChannelConfig = DiscordChannelConfig(),
555557
telegram: TelegramChannelConfig = TelegramChannelConfig(),
@@ -560,7 +562,8 @@ public struct ChannelsConfig: Codable, Sendable, Equatable {
560562
bluebubbles: BlueBubblesChannelConfig = BlueBubblesChannelConfig(),
561563
imessage: IMessageChannelConfig = IMessageChannelConfig(),
562564
msteams: MicrosoftTeamsChannelConfig = MicrosoftTeamsChannelConfig(),
563-
webchat: WebChatChannelConfig = WebChatChannelConfig()
565+
webchat: WebChatChannelConfig = WebChatChannelConfig(),
566+
pluginChannels: [String: PluginChannelConfig] = [:]
564567
) {
565568
self.discord = discord
566569
self.telegram = telegram
@@ -572,6 +575,7 @@ public struct ChannelsConfig: Codable, Sendable, Equatable {
572575
self.imessage = imessage
573576
self.msteams = msteams
574577
self.webchat = webchat
578+
self.pluginChannels = pluginChannels
575579
}
576580

577581
private enum CodingKeys: String, CodingKey {
@@ -585,6 +589,7 @@ public struct ChannelsConfig: Codable, Sendable, Equatable {
585589
case imessage
586590
case msteams
587591
case webchat
592+
case pluginChannels
588593
}
589594

590595
public init(from decoder: Decoder) throws {
@@ -599,6 +604,10 @@ public struct ChannelsConfig: Codable, Sendable, Equatable {
599604
self.imessage = try container.decodeIfPresent(IMessageChannelConfig.self, forKey: .imessage) ?? IMessageChannelConfig()
600605
self.msteams = try container.decodeIfPresent(MicrosoftTeamsChannelConfig.self, forKey: .msteams) ?? MicrosoftTeamsChannelConfig()
601606
self.webchat = try container.decodeIfPresent(WebChatChannelConfig.self, forKey: .webchat) ?? WebChatChannelConfig()
607+
self.pluginChannels = try container.decodeIfPresent(
608+
[String: PluginChannelConfig].self,
609+
forKey: .pluginChannels
610+
) ?? [:]
602611
}
603612

604613
public func encode(to encoder: Encoder) throws {
@@ -613,6 +622,33 @@ public struct ChannelsConfig: Codable, Sendable, Equatable {
613622
try container.encode(self.imessage, forKey: .imessage)
614623
try container.encode(self.msteams, forKey: .msteams)
615624
try container.encode(self.webchat, forKey: .webchat)
625+
try container.encode(self.pluginChannels, forKey: .pluginChannels)
626+
}
627+
}
628+
629+
/// Generic config block for upstream plugin-only channels.
630+
public struct PluginChannelConfig: Codable, Sendable, Equatable {
631+
public var enabled: Bool
632+
public var packageName: String?
633+
public var config: [String: String]
634+
public var secrets: [String: String]
635+
636+
/// Creates plugin-channel settings.
637+
/// - Parameters:
638+
/// - enabled: Whether the host should attempt to activate this channel plugin.
639+
/// - packageName: Optional upstream package/plugin package name.
640+
/// - config: Non-secret plugin config values.
641+
/// - secrets: Secret values or secret references required by the plugin.
642+
public init(
643+
enabled: Bool = false,
644+
packageName: String? = nil,
645+
config: [String: String] = [:],
646+
secrets: [String: String] = [:]
647+
) {
648+
self.enabled = enabled
649+
self.packageName = packageName
650+
self.config = config
651+
self.secrets = secrets
616652
}
617653
}
618654

Sources/OpenClawCore/SecurityAuditReport.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,19 @@ public enum SecurityAuditRunner {
217217
exposedKeys.append("models.providers.\(normalizedID).\(secretField)")
218218
}
219219
}
220+
for (channelID, channelConfig) in config.channels.pluginChannels {
221+
let normalizedID = channelID.trimmingCharacters(in: .whitespacesAndNewlines)
222+
guard !normalizedID.isEmpty else {
223+
continue
224+
}
225+
for (secretKey, secretValue) in channelConfig.secrets {
226+
let normalizedSecretKey = secretKey.trimmingCharacters(in: .whitespacesAndNewlines)
227+
let normalizedSecretValue = secretValue.trimmingCharacters(in: .whitespacesAndNewlines)
228+
if !normalizedSecretKey.isEmpty, !normalizedSecretValue.isEmpty {
229+
exposedKeys.append("channels.pluginChannels.\(normalizedID).secrets.\(normalizedSecretKey)")
230+
}
231+
}
232+
}
220233

221234
guard !exposedKeys.isEmpty else {
222235
return []

Sources/OpenClawCore/SessionControls.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ public enum ThinkLevel: String, Sendable, Equatable, CaseIterable, Codable {
1111
case adaptive
1212

1313
private static let xhighModelRefs: Set<String> = [
14+
"openai/gpt-5.5",
1415
"openai/gpt-5.4",
1516
"openai/gpt-5.4-pro",
1617
"openai/gpt-5.2",
18+
"openai-codex/gpt-5.5",
1719
"openai-codex/gpt-5.4",
1820
"openai-codex/gpt-5.3-codex",
1921
"openai-codex/gpt-5.3-codex-spark",

0 commit comments

Comments
 (0)