@privateclaw/privateclaw-relay 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -0
- package/README.md +20 -0
- package/dist/admin-api.d.ts +11 -0
- package/dist/admin-api.js +111 -0
- package/dist/admin-api.js.map +1 -0
- package/dist/admin-metrics-store.d.ts +245 -0
- package/dist/admin-metrics-store.js +952 -0
- package/dist/admin-metrics-store.js.map +1 -0
- package/dist/admin-web/admin.css +379 -0
- package/dist/admin-web/admin.js +366 -0
- package/dist/admin-web/index.html +145 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/relay-cluster.js +102 -6
- package/dist/relay-cluster.js.map +1 -1
- package/dist/relay-server.d.ts +17 -0
- package/dist/relay-server.js +345 -27
- package/dist/relay-server.js.map +1 -1
- package/dist/relay-web.d.ts +2 -0
- package/dist/relay-web.js +35 -6
- package/dist/relay-web.js.map +1 -1
- package/dist/web/chat/index.html +2 -2
- package/dist/web/scripts/chat.js +166 -4
- package/dist/web/scripts/i18n.js +15 -0
- package/dist/web/scripts/session-client.js +65 -0
- package/dist/web/styles.css +180 -0
- package/package.json +1 -1
|
@@ -59,6 +59,52 @@ function parseParticipants(value) {
|
|
|
59
59
|
}));
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
function parseThinkingStatus(value) {
|
|
63
|
+
switch (value) {
|
|
64
|
+
case "started":
|
|
65
|
+
case "streaming":
|
|
66
|
+
case "completed":
|
|
67
|
+
case "failed":
|
|
68
|
+
return value;
|
|
69
|
+
default:
|
|
70
|
+
return "completed";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parseThinkingEntryKind(value) {
|
|
75
|
+
switch (value) {
|
|
76
|
+
case "thought":
|
|
77
|
+
case "action":
|
|
78
|
+
case "result":
|
|
79
|
+
case "error":
|
|
80
|
+
return value;
|
|
81
|
+
default:
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function parseThinkingEntries(value) {
|
|
87
|
+
if (!Array.isArray(value)) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
return value
|
|
91
|
+
.filter((item) => item && typeof item === "object")
|
|
92
|
+
.flatMap((item) => {
|
|
93
|
+
const kind = parseThinkingEntryKind(item.kind);
|
|
94
|
+
if (!kind) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
return [{
|
|
98
|
+
id: typeof item.id === "string" ? item.id : createMessageId("thinking-entry"),
|
|
99
|
+
kind,
|
|
100
|
+
title: typeof item.title === "string" ? item.title : "",
|
|
101
|
+
text: typeof item.text === "string" ? item.text : "",
|
|
102
|
+
sentAt: normalizeTimestamp(item.sentAt),
|
|
103
|
+
toolName: typeof item.toolName === "string" ? item.toolName : null,
|
|
104
|
+
}];
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
62
108
|
export class PrivateClawWebSessionClient extends EventTarget {
|
|
63
109
|
constructor(invite, { identity }) {
|
|
64
110
|
super();
|
|
@@ -263,6 +309,7 @@ export class PrivateClawWebSessionClient extends EventTarget {
|
|
|
263
309
|
appVersion: "privateclaw_web/0.1.0",
|
|
264
310
|
appId: this.identity.appId,
|
|
265
311
|
deviceLabel: "PrivateClaw Web",
|
|
312
|
+
supportsThinkingTrace: true,
|
|
266
313
|
...(this.identity.displayName ? { displayName: this.identity.displayName } : {}),
|
|
267
314
|
sentAt: new Date().toISOString(),
|
|
268
315
|
});
|
|
@@ -334,6 +381,23 @@ export class PrivateClawWebSessionClient extends EventTarget {
|
|
|
334
381
|
});
|
|
335
382
|
return;
|
|
336
383
|
}
|
|
384
|
+
case "thinking_message": {
|
|
385
|
+
this.#dispatch("message", {
|
|
386
|
+
message: {
|
|
387
|
+
id: typeof payload.messageId === "string" ? payload.messageId : this.#nextLocalMessageId(),
|
|
388
|
+
sender: "assistant",
|
|
389
|
+
text: "",
|
|
390
|
+
sentAt: normalizeTimestamp(payload.sentAt),
|
|
391
|
+
replyTo: typeof payload.replyTo === "string" ? payload.replyTo : null,
|
|
392
|
+
isPending: false,
|
|
393
|
+
attachments: [],
|
|
394
|
+
thinkingStatus: parseThinkingStatus(payload.status),
|
|
395
|
+
thinkingSummary: typeof payload.summary === "string" ? payload.summary : "",
|
|
396
|
+
thinkingEntries: parseThinkingEntries(payload.entries),
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
337
401
|
case "participant_message": {
|
|
338
402
|
const senderAppId = typeof payload.senderAppId === "string" ? payload.senderAppId : "unknown-app";
|
|
339
403
|
this.#dispatch("message", {
|
|
@@ -429,6 +493,7 @@ export class PrivateClawWebSessionClient extends EventTarget {
|
|
|
429
493
|
appVersion: "privateclaw_web/0.1.0",
|
|
430
494
|
appId: this.identity.appId,
|
|
431
495
|
deviceLabel: "PrivateClaw Web",
|
|
496
|
+
supportsThinkingTrace: true,
|
|
432
497
|
...(this.identity.displayName ? { displayName: this.identity.displayName } : {}),
|
|
433
498
|
sentAt: new Date().toISOString(),
|
|
434
499
|
});
|
package/dist/web/styles.css
CHANGED
|
@@ -984,6 +984,11 @@ a:focus {
|
|
|
984
984
|
border-color: rgba(255, 127, 159, 0.28);
|
|
985
985
|
}
|
|
986
986
|
|
|
987
|
+
.message-bubble.thinking-bubble {
|
|
988
|
+
background: linear-gradient(180deg, rgba(143, 125, 255, 0.22), rgba(62, 217, 255, 0.08));
|
|
989
|
+
border-color: rgba(143, 125, 255, 0.24);
|
|
990
|
+
}
|
|
991
|
+
|
|
987
992
|
.message-text {
|
|
988
993
|
color: var(--text);
|
|
989
994
|
line-height: 1.6;
|
|
@@ -1020,6 +1025,181 @@ a:focus {
|
|
|
1020
1025
|
text-decoration: underline;
|
|
1021
1026
|
}
|
|
1022
1027
|
|
|
1028
|
+
.thinking-trace-card {
|
|
1029
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
1030
|
+
border-radius: 18px;
|
|
1031
|
+
background: rgba(7, 12, 26, 0.28);
|
|
1032
|
+
padding: 12px;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
details.thinking-trace-card > summary {
|
|
1036
|
+
list-style: none;
|
|
1037
|
+
cursor: pointer;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
details.thinking-trace-card > summary::-webkit-details-marker {
|
|
1041
|
+
display: none;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.thinking-trace-card.active {
|
|
1045
|
+
border-color: rgba(143, 125, 255, 0.3);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.thinking-trace-card.failed {
|
|
1049
|
+
border-color: rgba(255, 127, 159, 0.38);
|
|
1050
|
+
background: rgba(62, 10, 24, 0.26);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.thinking-trace-summary {
|
|
1054
|
+
display: flex;
|
|
1055
|
+
flex-direction: column;
|
|
1056
|
+
gap: 10px;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
.thinking-trace-header {
|
|
1060
|
+
display: flex;
|
|
1061
|
+
align-items: flex-start;
|
|
1062
|
+
justify-content: space-between;
|
|
1063
|
+
gap: 12px;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
.thinking-trace-header-main {
|
|
1067
|
+
min-width: 0;
|
|
1068
|
+
display: inline-flex;
|
|
1069
|
+
align-items: center;
|
|
1070
|
+
gap: 10px;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
.thinking-trace-header-main strong {
|
|
1074
|
+
font-size: 0.98rem;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
.thinking-trace-icon {
|
|
1078
|
+
width: 26px;
|
|
1079
|
+
height: 26px;
|
|
1080
|
+
border-radius: 999px;
|
|
1081
|
+
display: inline-flex;
|
|
1082
|
+
align-items: center;
|
|
1083
|
+
justify-content: center;
|
|
1084
|
+
flex-shrink: 0;
|
|
1085
|
+
font-size: 0.92rem;
|
|
1086
|
+
background: rgba(255, 255, 255, 0.08);
|
|
1087
|
+
color: var(--text);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
.thinking-trace-icon.thought,
|
|
1091
|
+
.thinking-trace-icon.active {
|
|
1092
|
+
background: rgba(143, 125, 255, 0.2);
|
|
1093
|
+
color: rgba(230, 224, 255, 0.96);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
.thinking-trace-icon.active {
|
|
1097
|
+
animation: pulse 1.2s ease-in-out infinite;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.thinking-trace-icon.action {
|
|
1101
|
+
background: rgba(62, 217, 255, 0.18);
|
|
1102
|
+
color: rgba(204, 247, 255, 0.96);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
.thinking-trace-icon.result {
|
|
1106
|
+
background: rgba(92, 255, 196, 0.18);
|
|
1107
|
+
color: rgba(218, 255, 241, 0.98);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
.thinking-trace-icon.error {
|
|
1111
|
+
background: rgba(255, 127, 159, 0.22);
|
|
1112
|
+
color: rgba(255, 230, 237, 0.98);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
.thinking-trace-preview {
|
|
1116
|
+
margin: 0;
|
|
1117
|
+
color: var(--text-muted);
|
|
1118
|
+
white-space: pre-wrap;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
.thinking-trace-badges {
|
|
1122
|
+
display: flex;
|
|
1123
|
+
flex-wrap: wrap;
|
|
1124
|
+
justify-content: flex-end;
|
|
1125
|
+
gap: 8px;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
.thinking-trace-badge {
|
|
1129
|
+
display: inline-flex;
|
|
1130
|
+
align-items: center;
|
|
1131
|
+
gap: 6px;
|
|
1132
|
+
padding: 6px 10px;
|
|
1133
|
+
border-radius: 999px;
|
|
1134
|
+
background: rgba(255, 255, 255, 0.08);
|
|
1135
|
+
color: var(--text-muted);
|
|
1136
|
+
font-size: 0.82rem;
|
|
1137
|
+
font-weight: 600;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
.thinking-trace-badge.live {
|
|
1141
|
+
background: rgba(143, 125, 255, 0.16);
|
|
1142
|
+
color: rgba(233, 228, 255, 0.96);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
.thinking-trace-badge.done {
|
|
1146
|
+
background: rgba(92, 255, 196, 0.14);
|
|
1147
|
+
color: rgba(220, 255, 243, 0.98);
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
.thinking-trace-badge.error {
|
|
1151
|
+
background: rgba(255, 127, 159, 0.18);
|
|
1152
|
+
color: rgba(255, 233, 239, 0.98);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
.thinking-trace-badge.tool {
|
|
1156
|
+
background: rgba(62, 217, 255, 0.16);
|
|
1157
|
+
color: rgba(208, 247, 255, 0.98);
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
.thinking-trace-history {
|
|
1161
|
+
margin-top: 12px;
|
|
1162
|
+
padding-top: 12px;
|
|
1163
|
+
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
|
1164
|
+
display: flex;
|
|
1165
|
+
flex-direction: column;
|
|
1166
|
+
gap: 10px;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
.thinking-trace-entry {
|
|
1170
|
+
border-radius: 16px;
|
|
1171
|
+
padding: 12px;
|
|
1172
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
1173
|
+
background: rgba(255, 255, 255, 0.04);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
.thinking-trace-entry.thought {
|
|
1177
|
+
border-color: rgba(143, 125, 255, 0.2);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.thinking-trace-entry.action {
|
|
1181
|
+
border-color: rgba(62, 217, 255, 0.2);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
.thinking-trace-entry.result {
|
|
1185
|
+
border-color: rgba(92, 255, 196, 0.2);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
.thinking-trace-entry.error {
|
|
1189
|
+
border-color: rgba(255, 127, 159, 0.24);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
.thinking-trace-entry-header {
|
|
1193
|
+
display: flex;
|
|
1194
|
+
align-items: center;
|
|
1195
|
+
flex-wrap: wrap;
|
|
1196
|
+
gap: 10px;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
.thinking-trace-entry-body {
|
|
1200
|
+
margin-top: 8px;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1023
1203
|
.mermaid-card {
|
|
1024
1204
|
border: 1px solid var(--line);
|
|
1025
1205
|
border-radius: 16px;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@privateclaw/privateclaw-relay",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Blind WebSocket relay for PrivateClaw encrypted sessions with local CLI startup and optional Tailscale Funnel or Cloudflare Tunnel exposure",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|