@yeaft/webchat-agent 1.0.435 → 1.0.437

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/container-cli.js CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  createContainerAgent,
6
6
  inspectContainerAgent,
7
7
  logsContainerAgent,
8
- readSecretInput,
9
8
  removeContainerAgent,
10
9
  startContainerAgent,
11
10
  stopContainerAgent,
@@ -15,10 +14,12 @@ import {
15
14
  function help() {
16
15
  console.log(`
17
16
  Usage:
18
- yeaft-agent container create --server <ws-url> --name <name> (--secret <value> | --secret-file <path>) [--image <image>]
17
+ yeaft-agent container install --server <ws-url> --name <name> --secret <secret> [--image <image>]
19
18
  yeaft-agent container start|stop|status|remove|logs --name <name>
20
19
 
21
20
  The container is an ordinary yeaft-agent. This command only manages its Docker lifecycle.
21
+ The secret is passed as an argument, like 'yeaft-agent install', and persisted by this
22
+ command to a private 0600 file before the container is created.
22
23
  Use --keep-volumes with remove to preserve its Yeaft data and workspace volumes.
23
24
  `);
24
25
  }
@@ -48,11 +49,13 @@ export async function runContainerCli(args) {
48
49
  const { action, options } = parseContainerArgs(args);
49
50
  const name = options.name;
50
51
  let result;
51
- if (action === 'create') {
52
- const secret = await readSecretInput(options);
53
- const secretFile = options.secretFile
54
- ? resolve(options.secretFile)
55
- : join(homedir(), '.yeaft', 'container-agents', name, 'agent-secret');
52
+ if (action === 'install' || action === 'create') {
53
+ if (options.secretFile) {
54
+ throw new Error('--secret-file is no longer supported; pass the secret directly with --secret');
55
+ }
56
+ const secret = String(options.secret || '').trim();
57
+ if (!secret) throw new Error('--secret <secret> is required');
58
+ const secretFile = join(homedir(), '.yeaft', 'container-agents', name, 'agent-secret');
56
59
  await writeAgentSecretFile(secretFile, secret);
57
60
  result = await createContainerAgent({
58
61
  name,
@@ -1,5 +1,5 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { chmod, mkdir, writeFile } from 'node:fs/promises';
3
3
  import { dirname, resolve } from 'node:path';
4
4
 
5
5
  export const DEFAULT_AGENT_IMAGE = 'ghcr.io/yeaft/yeaft-web-code-agent-agent:dev';
@@ -182,8 +182,3 @@ export async function logsContainerAgent(name, { follow = false, ...runtime } =
182
182
  args.push(containerNameForAgent(name));
183
183
  return runDocker(args, { ...runtime, stdout: follow ? 'inherit' : 'pipe' });
184
184
  }
185
-
186
- export async function readSecretInput({ secret, secretFile }) {
187
- if (secretFile) return (await readFile(resolve(secretFile), 'utf8')).trim();
188
- return String(secret || '').trim();
189
- }
@@ -1,5 +1,5 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { chmod, mkdir, writeFile } from 'node:fs/promises';
3
3
  import { dirname, resolve } from 'node:path';
4
4
 
5
5
  export const DEFAULT_AGENT_IMAGE = 'ghcr.io/yeaft/yeaft-web-code-agent-agent:dev';
@@ -182,8 +182,3 @@ export async function logsContainerAgent(name, { follow = false, ...runtime } =
182
182
  args.push(containerNameForAgent(name));
183
183
  return runDocker(args, { ...runtime, stdout: follow ? 'inherit' : 'pipe' });
184
184
  }
185
-
186
- export async function readSecretInput({ secret, secretFile }) {
187
- if (secretFile) return (await readFile(resolve(secretFile), 'utf8')).trim();
188
- return String(secret || '').trim();
189
- }
@@ -234,6 +234,12 @@ export async function handleClientBrowser(client, msg, checkAgentAccess) {
234
234
  connectionGeneration: peer.connectionGeneration,
235
235
  };
236
236
  try {
237
+ // Commit the Web endpoint's scoped ICE credentials before the Agent can
238
+ // synchronously answer `browser_peer_prepare`. Otherwise a fast Agent
239
+ // may produce `browser_peer_prepared` while this field is still unset,
240
+ // causing the Web RTCPeerConnection to be created with no ICE servers.
241
+ peer.webIceServers = mintBrowserIceServers({ ...commonScope, endpointRole: 'web' });
242
+ peer.state = 'preparing';
237
243
  await sendToAgent(agent, {
238
244
  type: 'browser_peer_prepare',
239
245
  agentId,
@@ -247,8 +253,6 @@ export async function handleClientBrowser(client, msg, checkAgentAccess) {
247
253
  iceTransportPolicy: CONFIG.browserRuntime.iceTransportPolicy,
248
254
  agentIceServers: mintBrowserIceServers({ ...commonScope, endpointRole: 'agent' }),
249
255
  });
250
- peer.webIceServers = mintBrowserIceServers({ ...commonScope, endpointRole: 'web' });
251
- peer.state = 'preparing';
252
256
  } catch (error) {
253
257
  deleteBrowserPeer(peer.peerId);
254
258
  return fail(client, msg, 'browser_peer_prepare_failed', String(error?.message || error).slice(0, 500));
@@ -1 +1 @@
1
- {"version":"1.0.435"}
1
+ {"version":"1.0.437"}