Skip to content

Commit c98236c

Browse files
committed
release: 2026.2.2
1 parent ee47137 commit c98236c

104 files changed

Lines changed: 8891 additions & 649 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,49 @@
11
# Changelog
22

3+
## 2026.2.2 - 2026-03-11
4+
5+
### Added
6+
7+
- Canonical TS-shaped model/auth config surface:
8+
`OpenClawConfig.auth`, canonical `models.providers`, Bedrock discovery
9+
settings, auth profiles, and shared provider catalog parity against the pinned
10+
OpenClaw TS reference.
11+
- Auth profile persistence and routing:
12+
secure credential indirection through `CredentialStore`, profile cooldown and
13+
last-good tracking, and router integration for profile-aware fallback.
14+
- Interactive auth descriptors and Apple browser-auth presentation helpers for
15+
OAuth-capable providers, with device-code metadata for Copilot/Qwen-style
16+
sign-in flows.
17+
- Provider parity coverage for additional TS-main families and APIs, including
18+
`openai-codex`, Google Generative AI-style providers, GitHub Copilot, and the
19+
coding-focused provider aliases in the shared catalog.
20+
- Checked-in provider catalog snapshot coverage via
21+
`ProviderCatalogReferenceFixture` to keep parity tests independent from
22+
`.cursor/**` at runtime.
23+
24+
### Changed
25+
26+
- Apple Keychain credentials now default to
27+
`kSecAttrAccessibleWhenUnlockedThisDeviceOnly` for device-bound, unlock-only
28+
storage.
29+
- Apple sample defaults now prefer Foundation Models when the runtime reports
30+
Apple Intelligence availability, while leaving generic config decoding
31+
behavior unchanged.
32+
- The incomplete visionOS spatial demo has been deferred from `2026.2.2`; the
33+
shipped example-app validation gate now covers iOS and tvOS only.
34+
- README, testing docs, and parity notes now describe the Apple hardware model,
35+
canonical Swift config sources, and the current validation gate.
36+
- Legacy provider-service JSON now decodes into canonical provider configs
37+
without losing auth mode, API style, or default model information.
38+
39+
### Tests
40+
41+
- Added regression coverage for auth profile persistence, rotation ordering, and
42+
Keychain accessibility query handling.
43+
- Added provider catalog parity snapshot assertions plus canonical/legacy config
44+
serialization coverage for `models.providers`.
45+
- Revalidated `swift build -Xswiftc -warnings-as-errors` and `swift test`.
46+
347
## 2026.2.1 - 2026-03-01
448

549
### Added
@@ -400,4 +444,3 @@
400444
`Scripts/check-networking-concurrency.sh`.
401445
- Project documentation set: comprehensive `README.md`, architecture guide,
402446
testing guide, API surface reference, and MIT `LICENSE`.
403-

Examples/iOS/OpenClawiOS/OpenClawiOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 64 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Examples/iOS/OpenClawiOS/OpenClawiOS/ChannelsView.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ struct ChannelsView: View {
3030

3131
Section("Channel Health") {
3232
if appState.channelHealthItems.isEmpty {
33-
Text("No channel health data available yet.")
34-
.foregroundStyle(.secondary)
33+
ContentUnavailableView(
34+
"No Channels Active",
35+
systemImage: "bolt.horizontal.circle.fill",
36+
description: Text("Deploy the agent to see channel health.")
37+
)
3538
} else {
3639
ForEach(appState.channelHealthItems) { item in
3740
VStack(alignment: .leading, spacing: 4) {

Examples/iOS/OpenClawiOS/OpenClawiOS/ChatView.swift

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import SwiftUI
22
import UniformTypeIdentifiers
3+
import OpenClawProtocol
34
#if canImport(PhotosUI)
45
import PhotosUI
56
#endif
@@ -209,15 +210,15 @@ private struct ChatBubble: View {
209210
var body: some View {
210211
HStack {
211212
if message.role == .assistant {
212-
bubble(color: .blue.opacity(0.14), alignment: .leading)
213-
Spacer(minLength: 24)
213+
bubble(color: Theme.assistantBubbleColor, alignment: .leading)
214+
Spacer(minLength: Theme.bubbleSpacing)
214215
} else if message.role == .user {
215-
Spacer(minLength: 24)
216-
bubble(color: .green.opacity(0.14), alignment: .trailing)
216+
Spacer(minLength: Theme.bubbleSpacing)
217+
bubble(color: Theme.userBubbleColor, alignment: .trailing)
217218
} else {
218-
Spacer(minLength: 24)
219-
bubble(color: .orange.opacity(0.14), alignment: .leading)
220-
Spacer(minLength: 24)
219+
Spacer(minLength: Theme.bubbleSpacing)
220+
bubble(color: Theme.systemBubbleColor, alignment: .leading)
221+
Spacer(minLength: Theme.bubbleSpacing)
221222
}
222223
}
223224
}
@@ -228,15 +229,45 @@ private struct ChatBubble: View {
228229
Text(message.role.rawValue.capitalized)
229230
.font(.caption2)
230231
.foregroundStyle(.secondary)
231-
Text(message.text)
232+
233+
if let attachments = message.attachments, !attachments.isEmpty {
234+
ForEach(attachments) { attachment in
235+
if attachment.mimeType.hasPrefix("image/"), let uiImage = UIImage(data: attachment.data) {
236+
Image(uiImage: uiImage)
237+
.resizable()
238+
.scaledToFit()
239+
.frame(maxHeight: 200)
240+
.clipShape(RoundedRectangle(cornerRadius: 8))
241+
} else {
242+
HStack {
243+
Image(systemName: "doc.fill")
244+
Text(attachment.fileName ?? "File")
245+
.font(.caption)
246+
.lineLimit(1)
247+
}
248+
.padding(8)
249+
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 8))
250+
}
251+
}
252+
}
253+
254+
if !message.text.isEmpty {
255+
Group {
256+
if let attr = try? AttributedString(markdown: message.text, options: .init(interpretedSyntax: .full)) {
257+
Text(attr)
258+
} else {
259+
Text(message.text)
260+
}
261+
}
232262
.font(.body)
233263
.foregroundStyle(.primary)
234264
.multilineTextAlignment(alignment == .trailing ? .trailing : .leading)
265+
}
235266
}
236-
.padding(10)
267+
.padding(Theme.bubblePadding)
237268
.background(color)
238-
.clipShape(RoundedRectangle(cornerRadius: 10))
239-
.frame(maxWidth: 280, alignment: alignment)
269+
.clipShape(RoundedRectangle(cornerRadius: Theme.bubbleCornerRadius))
270+
.frame(maxWidth: Theme.bubbleMaxWidth, alignment: alignment)
240271
}
241272
}
242273

0 commit comments

Comments
 (0)