@yeaft/webchat-agent 0.1.944 → 0.1.946

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.
@@ -41,7 +41,11 @@ export async function sendToServer(msg) {
41
41
  }
42
42
 
43
43
  try {
44
- if (ctx.sessionKey) {
44
+ // feat-ws-plaintext-negotiation: encrypt only when the server has
45
+ // NOT advertised plaintext acceptance. Defaults to encrypted for
46
+ // back-compat with old servers; flipped to plaintext when the
47
+ // `registered` frame includes `acceptPlaintext: true`.
48
+ if (ctx.serverEncryptionRequired && ctx.sessionKey) {
45
49
  const encrypted = await encrypt(msg, ctx.sessionKey);
46
50
  ctx.ws.send(JSON.stringify(encrypted));
47
51
  } else {
@@ -21,7 +21,17 @@ export function connect() {
21
21
  console.log(`Disallowed tools: ${ctx.CONFIG.disallowedTools.join(', ')}`);
22
22
  }
23
23
 
24
- ctx.ws = new WebSocket(url);
24
+ ctx.ws = new WebSocket(url, {
25
+ // Match server's permessage-deflate config (bounded memory,
26
+ // skip compression for small frames). The `ws` library handles
27
+ // streaming compression so we no longer need the synchronous
28
+ // gzip-before-encrypt on the hot path.
29
+ perMessageDeflate: {
30
+ clientNoContextTakeover: true,
31
+ serverNoContextTakeover: true,
32
+ threshold: 1024
33
+ }
34
+ });
25
35
 
26
36
  ctx.ws.on('open', () => {
27
37
  console.log('Connected to server, waiting for auth challenge...');
@@ -48,6 +48,15 @@ export async function handleMessage(msg) {
48
48
  console.log('Encryption enabled');
49
49
  }
50
50
 
51
+ // feat-ws-plaintext-negotiation: new server advertises that it
52
+ // will accept plaintext frames from us. Stop encrypting outbound.
53
+ // The receive path (parseMessage) stays unconditional so the old
54
+ // ciphertext that may already be in flight still decrypts.
55
+ if (msg.acceptPlaintext === true) {
56
+ ctx.serverEncryptionRequired = false;
57
+ console.log('[WS] Server accepts plaintext, disabling outbound encryption');
58
+ }
59
+
51
60
  // 只保存基本配置(不再保存 agentId,因为现在用 agentName 作为 ID)
52
61
  ctx.saveConfig({
53
62
  serverUrl: ctx.CONFIG.serverUrl,
package/context.js CHANGED
@@ -4,6 +4,11 @@
4
4
  export default {
5
5
  ws: null,
6
6
  sessionKey: null,
7
+ // feat-ws-plaintext-negotiation: defaults `true` (= assume old server,
8
+ // keep encrypting outbound for back-compat). Cleared to `false` when
9
+ // the agent receives `registered { acceptPlaintext: true }` from a
10
+ // new server — see message-router.js `case 'registered'`.
11
+ serverEncryptionRequired: true,
7
12
  conversations: new Map(),
8
13
  terminals: new Map(),
9
14
  proxyPorts: [],
package/index.js CHANGED
@@ -111,7 +111,11 @@ loadMcpServers();
111
111
 
112
112
  // Agent capabilities(启动时自动检测)
113
113
  async function detectCapabilities() {
114
- const capabilities = ['background_tasks', 'file_editor', 'ping_session'];
114
+ // feat-ws-plaintext-negotiation: `plaintext-ok` advertises that this
115
+ // agent build can speak plaintext WS frames. New servers see this and
116
+ // flip `agent.encryptOutbound = false`, stopping outbound encryption
117
+ // to this peer. Old servers ignore the unknown capability token.
118
+ const capabilities = ['background_tasks', 'file_editor', 'ping_session', 'plaintext-ok'];
115
119
  const pty = await loadNodePty();
116
120
  if (pty) capabilities.push('terminal');
117
121
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.944",
3
+ "version": "0.1.946",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",