@rubytech/create-realagent 1.0.722 → 1.0.736

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.
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Real Agent</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/admin-GdSFnwBR.js"></script>
8
+ <script type="module" crossorigin src="/assets/admin-BKdSPr9G.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/jsx-runtime-BkCc5_JK.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-BEFjQwLd.js">
@@ -1,35 +1,65 @@
1
1
  import {
2
- GREETING_DIRECTIVE,
3
- HAIKU_MODEL,
4
2
  Hono,
5
3
  LOG_DIR,
6
4
  MAXY_DIR,
7
5
  TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
8
6
  TELEGRAM_WEBHOOK_SECRET_FILE,
9
7
  USERS_FILE,
10
- __commonJS,
11
- __toESM,
12
- agentLogStream,
13
- backfillNullUserIdConversations,
14
- bindVisitorToGroup,
15
8
  buildX11Env,
16
9
  callOauthLlm,
17
10
  canAccessAdmin,
18
- checkGroupMembership,
19
11
  checkRateLimit,
20
12
  clearRateLimit,
21
- clearSessionHistory,
22
13
  clientIpMiddleware,
23
14
  compactSession,
24
- completeGrantSetup,
25
15
  computeConstraints,
26
16
  createRemoteSession,
27
- deleteConversation,
28
- embed,
29
17
  ensureAuth,
30
18
  ensureCdp,
31
19
  ensureLogDir,
32
20
  ensureVnc,
21
+ hashPassword,
22
+ invokeAgent,
23
+ isActionActive,
24
+ isPasswordValid,
25
+ isRemoteAuthConfigured,
26
+ keyFilePath,
27
+ launchAction,
28
+ load,
29
+ logPath,
30
+ recordFailedAttempt,
31
+ render,
32
+ renderLoginPage,
33
+ requireAdminSession,
34
+ resolveBrowserTransport,
35
+ resolveClientIp,
36
+ safeJson,
37
+ sanitizeClientCorrId,
38
+ serve,
39
+ setRemotePassword,
40
+ sleep,
41
+ streamLogPathFor,
42
+ validateKey,
43
+ validatePasswordStrength,
44
+ verifyPassword,
45
+ verifyRemotePassword,
46
+ vncLog,
47
+ waitForExit,
48
+ writeChromiumWrapper
49
+ } from "./chunk-ULVR2RRY.js";
50
+ import {
51
+ GREETING_DIRECTIVE,
52
+ HAIKU_MODEL,
53
+ __commonJS,
54
+ __toESM,
55
+ agentLogStream,
56
+ backfillNullUserIdConversations,
57
+ bindVisitorToGroup,
58
+ checkGroupMembership,
59
+ clearSessionHistory,
60
+ completeGrantSetup,
61
+ deleteConversation,
62
+ embed,
33
63
  fetchBranding,
34
64
  findGroupBySlug,
35
65
  findRecentConversation,
@@ -49,56 +79,30 @@ import {
49
79
  getUserNameForSession,
50
80
  getUserTimezone,
51
81
  getVisitorIdForSession,
52
- hashPassword,
53
- invokeAgent,
54
- isActionActive,
55
- isPasswordValid,
56
- isRemoteAuthConfigured,
57
- keyFilePath,
58
- launchAction,
82
+ interruptClient,
59
83
  listAdminSessions,
60
84
  listAdminSessionsInProgress,
61
- load,
62
85
  loadOnboardingStep,
63
- logPath,
64
86
  preConversationLogStream,
65
- recordFailedAttempt,
87
+ preflushStreamLogKey,
66
88
  registerGrantSession,
67
89
  registerResumedSession,
68
90
  registerSession,
69
91
  renameConversation,
70
- render,
71
- renderLoginPage,
72
- requireAdminSession,
73
92
  resolveAccount,
74
93
  resolveAgentConfig,
75
- resolveBrowserTransport,
76
- resolveClientIp,
77
94
  resolveDefaultAgentSlug,
78
95
  resolveUserAccounts,
79
- safeJson,
80
- sanitizeClientCorrId,
81
96
  seedSessionHistory,
82
- serve,
83
97
  setConversationIdForSession,
84
98
  setGroupContextForSession,
85
- setRemotePassword,
86
99
  sigtermFlushStreamLogs,
87
- sleep,
88
- streamLogPathFor,
89
100
  unregisterSession,
90
101
  validateAgentSlug,
91
- validateKey,
92
- validatePasswordStrength,
93
102
  validateSession,
94
103
  verifyAndGetConversationUpdatedAt,
95
- verifyConversationOwnership,
96
- verifyPassword,
97
- verifyRemotePassword,
98
- vncLog,
99
- waitForExit,
100
- writeChromiumWrapper
101
- } from "./chunk-FM5JMRED.js";
104
+ verifyConversationOwnership
105
+ } from "./chunk-3KDVGWPQ.js";
102
106
 
103
107
  // ../lib/graph-trash/dist/index.js
104
108
  var require_dist = __commonJS({
@@ -7820,6 +7824,7 @@ var session_default2 = app10;
7820
7824
 
7821
7825
  // server/routes/admin/chat.ts
7822
7826
  import { resolve as resolve12 } from "path";
7827
+ import { appendFileSync as appendFileSync4 } from "fs";
7823
7828
 
7824
7829
  // app/lib/script-stream-tailer.ts
7825
7830
  import * as childProcess from "child_process";
@@ -8106,6 +8111,16 @@ function chatReject(status, error, sk) {
8106
8111
  });
8107
8112
  }
8108
8113
  var app11 = new Hono();
8114
+ app11.post("/cancel", requireAdminSession, async (c) => {
8115
+ const session_key = c.var.sessionKey;
8116
+ try {
8117
+ const { interruptClient: interruptClient2 } = await import("./client-pool-I5TCP7WI.js");
8118
+ await interruptClient2(session_key);
8119
+ return c.json({ ok: true });
8120
+ } catch (err) {
8121
+ return c.json({ ok: false, error: err instanceof Error ? err.message : String(err) }, 500);
8122
+ }
8123
+ });
8109
8124
  app11.post("/", requireAdminSession, async (c) => {
8110
8125
  const session_key = c.var.sessionKey;
8111
8126
  const contentType = c.req.header("content-type") ?? "";
@@ -8254,13 +8269,107 @@ app11.post("/", requireAdminSession, async (c) => {
8254
8269
  }
8255
8270
  const encoder = new TextEncoder();
8256
8271
  const sseConvId = getConversationIdForSession(session_key);
8257
- const sseLog = sseConvId ? agentLogStream("sse-events", account.accountDir, sseConvId) : preConversationLogStream("sse-events", account.accountDir);
8272
+ const sseLogStream = sseConvId ? agentLogStream("sse-events", account.accountDir, sseConvId) : preConversationLogStream("sse-events", account.accountDir);
8258
8273
  const sk = sseConvId?.slice(0, 8) ?? session_key.slice(0, 8);
8274
+ const teeStreamLogKey = sseConvId ?? preflushStreamLogKey(session_key);
8275
+ const teeStreamLogPath = resolve12(account.accountDir, "logs", `claude-agent-stream-${teeStreamLogKey}.log`);
8276
+ try {
8277
+ appendFileSync4(teeStreamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [chat-route-version=task606-incoming-close] sessionKey=${session_key.slice(0, 12)}\u2026
8278
+ `);
8279
+ } catch {
8280
+ }
8281
+ const incoming = c.env?.incoming;
8282
+ if (incoming && typeof incoming.on === "function") {
8283
+ incoming.on("close", () => {
8284
+ const tsClose = (/* @__PURE__ */ new Date()).toISOString();
8285
+ try {
8286
+ appendFileSync4(teeStreamLogPath, `[${tsClose}] [incoming-close] sessionKey=${session_key.slice(0, 12)}\u2026 complete=${incoming.complete}
8287
+ `);
8288
+ } catch {
8289
+ }
8290
+ if (incoming.complete === false) {
8291
+ console.error(`[${tsClose}] [incoming-close] DISCONNECT sessionKey=${session_key.slice(0, 12)}\u2026`);
8292
+ interruptClient(session_key).catch((err) => {
8293
+ try {
8294
+ appendFileSync4(teeStreamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] interrupt-failed: ${err instanceof Error ? err.message : String(err)}
8295
+ `);
8296
+ } catch {
8297
+ }
8298
+ });
8299
+ }
8300
+ });
8301
+ } else {
8302
+ try {
8303
+ appendFileSync4(teeStreamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] UNAVAILABLE \u2014 c.env.incoming is not an EventEmitter
8304
+ `);
8305
+ } catch {
8306
+ }
8307
+ }
8308
+ const sseLog = {
8309
+ write(line) {
8310
+ try {
8311
+ sseLogStream.write(line);
8312
+ } catch {
8313
+ }
8314
+ try {
8315
+ appendFileSync4(teeStreamLogPath, line);
8316
+ } catch {
8317
+ }
8318
+ return true;
8319
+ },
8320
+ end() {
8321
+ try {
8322
+ sseLogStream.end();
8323
+ } catch {
8324
+ }
8325
+ }
8326
+ };
8259
8327
  let tailer = null;
8260
8328
  const readable = new ReadableStream({
8329
+ // Task 606 — fires when the consumer (Hono's response writer / Node
8330
+ // adapter) cancels the stream because the client disconnected. This is
8331
+ // the only signal that arrives WHILE start()'s for-await is blocked
8332
+ // awaiting the SDK's next message — c.req.raw.signal didn't propagate
8333
+ // under @hono/node-server, and controller.enqueue throwing only
8334
+ // surfaces on the next yielded event (which never comes if the model
8335
+ // is mid-response when Cancel is pressed). cancel() is the load-bearing
8336
+ // hook for operator abort.
8337
+ //
8338
+ // Synchronous trace writes go to BOTH the per-conv stream log (where
8339
+ // operators read) AND console.error (server.log backstop). This lets
8340
+ // us prove definitively whether this callback is even being invoked
8341
+ // by @hono/node-server on disconnect.
8342
+ cancel(reason) {
8343
+ const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
8344
+ const reasonStr = typeof reason === "string" ? reason : reason instanceof Error ? reason.message : "consumer-cancelled";
8345
+ sseLog.write(`[${ts}] [${sk}] admin: CANCEL [stream-cancel] reason=${reasonStr}
8346
+ `);
8347
+ console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}] [stream-cancel-callback] sessionKey=${session_key.slice(0, 12)}\u2026 reason=${JSON.stringify(reasonStr)}`);
8348
+ interruptClient(session_key).catch((err) => {
8349
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${err instanceof Error ? err.message : String(err)}
8350
+ `);
8351
+ });
8352
+ },
8261
8353
  async start(controller) {
8262
8354
  let controllerOpen = true;
8263
8355
  const sseEntry = { controller, conversationId: sseConvId ?? null, sessionKey: session_key };
8356
+ try {
8357
+ const reqSignal = c.req.raw?.signal;
8358
+ if (reqSignal) {
8359
+ reqSignal.addEventListener("abort", () => {
8360
+ const abortLogKey = sseConvId ?? preflushStreamLogKey(session_key);
8361
+ const abortStreamLog = agentLogStream("claude-agent-stream", account.accountDir, abortLogKey);
8362
+ const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
8363
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [operator-cancel] interrupting pool client
8364
+ `);
8365
+ interruptClient(session_key, abortStreamLog).catch((err) => {
8366
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${err instanceof Error ? err.message : String(err)}
8367
+ `);
8368
+ });
8369
+ }, { once: true });
8370
+ }
8371
+ } catch {
8372
+ }
8264
8373
  try {
8265
8374
  registerAdminSSE(sseEntry);
8266
8375
  if (sseConvId) {
@@ -8308,6 +8417,10 @@ app11.post("/", requireAdminSession, async (c) => {
8308
8417
  if (controllerClosed) {
8309
8418
  sseLog.write(`[${ts}] [${sk}] admin: DISCONNECT [client_disconnect] ${rawMessage}
8310
8419
  `);
8420
+ interruptClient(session_key).catch((interruptErr) => {
8421
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${interruptErr instanceof Error ? interruptErr.message : String(interruptErr)}
8422
+ `);
8423
+ });
8311
8424
  } else {
8312
8425
  const category = classifyAgentError(err);
8313
8426
  const errEvent = JSON.stringify({ type: "text", content: friendlyAgentError(err) });