fix(protocol): connect session presentation to native rows

This commit is contained in:
Dallin Romney
2026-07-21 12:00:41 +09:00
parent d9e9ca66e6
commit b5919d8733
5 changed files with 32 additions and 3 deletions
@@ -1,4 +1,5 @@
import Foundation
import OpenClawProtocol
public struct OpenClawChatThinkingLevelOption: Codable, Identifiable, Sendable, Hashable {
public let id: String
@@ -312,6 +313,8 @@ public struct OpenClawChatSessionEntry: Codable, Identifiable, Sendable, Hashabl
}
public var key: String
/// Client-ready, non-sensitive session identity and display metadata.
public var presentation: SessionPresentation?
public var kind: String?
public var displayName: String?
public var label: String?
@@ -364,6 +367,7 @@ public struct OpenClawChatSessionEntry: Codable, Identifiable, Sendable, Hashabl
public init(
key: String,
presentation: SessionPresentation? = nil,
kind: String?,
displayName: String?,
surface: String?,
@@ -411,6 +415,7 @@ public struct OpenClawChatSessionEntry: Codable, Identifiable, Sendable, Hashabl
agentRuntime: OpenClawChatAgentRuntime? = nil)
{
self.key = key
self.presentation = presentation
self.kind = kind
self.displayName = displayName
self.label = label
@@ -3967,7 +3967,7 @@ public struct SessionsListParams: Codable, Sendable {
}
}
public struct SessionPresentation: Codable, Sendable {
public struct SessionPresentation: Codable, Sendable, Hashable {
public let title: String
public let titlesource: String
public let subtitle: String?
@@ -1,6 +1,7 @@
import Foundation
import Testing
@testable import OpenClawChatUI
import OpenClawProtocol
@MainActor
struct ChatSessionSidebarModelTests {
@@ -275,6 +276,14 @@ struct ChatSessionSidebarModelTests {
let data = try #require("""
{
"key": "agent:main:child",
"presentation": {
"title": "Child session",
"titleSource": "generated",
"family": "subagent",
"agentId": "main",
"isMain": false,
"isBackground": true
},
"parentSessionKey": "agent:main:main",
"spawnedBy": "agent:main:controller",
"childSessions": ["agent:main:grandchild"],
@@ -293,6 +302,13 @@ struct ChatSessionSidebarModelTests {
let entry = try JSONDecoder().decode(OpenClawChatSessionEntry.self, from: data)
#expect(entry.parentSessionKey == "agent:main:main")
#expect(entry.presentation == SessionPresentation(
title: "Child session",
titlesource: "generated",
family: "subagent",
agentid: "main",
ismain: false,
isbackground: true))
#expect(entry.spawnedBy == "agent:main:controller")
#expect(entry.childSessions == ["agent:main:grandchild"])
#expect(entry.status == "running")
+9 -1
View File
@@ -42,6 +42,11 @@ const STRICT_LITERAL_STRUCTS = new Set([
"PluginsSessionActionFailureResult",
]);
// These generated value objects are embedded in manually maintained Hashable
// client response models. Keep the generated conformance so those clients can
// expose the protocol field without duplicating its wire shape.
const HASHABLE_STRUCTS = new Set(["SessionPresentation"]);
const header = `// Generated by scripts/protocol-gen-swift.ts — do not edit by hand\n// swiftlint:disable file_length\nimport Foundation\n\npublic let GATEWAY_PROTOCOL_VERSION = ${PROTOCOL_VERSION}\npublic let GATEWAY_MIN_PROTOCOL_VERSION = ${MIN_CLIENT_PROTOCOL_VERSION}\npublic let GATEWAY_MIN_NODE_PROTOCOL_VERSION = ${MIN_NODE_PROTOCOL_VERSION}\n\nprivate struct GatewayAnyCodingKey: CodingKey, Hashable {\n let stringValue: String\n let intValue: Int?\n\n init?(stringValue: String) {\n self.stringValue = stringValue\n self.intValue = nil\n }\n\n init?(intValue: Int) {\n self.stringValue = String(intValue)\n self.intValue = intValue\n }\n}\n\npublic enum ErrorCode: String, Codable, Sendable {\n${Object.values(
ErrorCodes,
)
@@ -356,7 +361,10 @@ function emitStruct(name: string, schema: JsonSchema): string {
lines.push("");
return lines.join("\n");
}
lines.push(`public struct ${name}: Codable, Sendable {`);
const conformances = HASHABLE_STRUCTS.has(name)
? "Codable, Sendable, Hashable"
: "Codable, Sendable";
lines.push(`public struct ${name}: ${conformances} {`);
const codingKeys: string[] = [];
for (const [key, propSchema] of Object.entries(props)) {
const propName = swiftStoredPropertyName(name, key);
+1 -1
View File
@@ -2222,7 +2222,7 @@ export function buildGatewaySessionRow(params: {
space,
chatType: entry?.chatType,
origin,
updatedAt: entry?.updatedAt ?? null,
updatedAt,
archived: entry?.archivedAt !== undefined,
archivedAt: entry?.archivedAt,
pinned: entry?.pinnedAt !== undefined,