@rubytech/create-realagent 1.0.722 → 1.0.737

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,110 @@ 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
+ function resolveTeeStreamLogPath() {
8275
+ const liveConvId = getConversationIdForSession(session_key);
8276
+ const key = liveConvId ?? preflushStreamLogKey(session_key);
8277
+ return resolve12(account.accountDir, "logs", `claude-agent-stream-${key}.log`);
8278
+ }
8279
+ try {
8280
+ appendFileSync4(resolveTeeStreamLogPath(), `[${(/* @__PURE__ */ new Date()).toISOString()}] [chat-route-version=task606-tee-path-resolve] sessionKey=${session_key.slice(0, 12)}\u2026
8281
+ `);
8282
+ } catch {
8283
+ }
8284
+ const incoming = c.env?.incoming;
8285
+ if (incoming && typeof incoming.on === "function") {
8286
+ incoming.on("close", () => {
8287
+ const tsClose = (/* @__PURE__ */ new Date()).toISOString();
8288
+ try {
8289
+ appendFileSync4(resolveTeeStreamLogPath(), `[${tsClose}] [incoming-close] sessionKey=${session_key.slice(0, 12)}\u2026 complete=${incoming.complete}
8290
+ `);
8291
+ } catch {
8292
+ }
8293
+ if (incoming.complete === false) {
8294
+ console.error(`[${tsClose}] [incoming-close] DISCONNECT sessionKey=${session_key.slice(0, 12)}\u2026`);
8295
+ interruptClient(session_key).catch((err) => {
8296
+ try {
8297
+ appendFileSync4(resolveTeeStreamLogPath(), `[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] interrupt-failed: ${err instanceof Error ? err.message : String(err)}
8298
+ `);
8299
+ } catch {
8300
+ }
8301
+ });
8302
+ }
8303
+ });
8304
+ } else {
8305
+ try {
8306
+ appendFileSync4(resolveTeeStreamLogPath(), `[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] UNAVAILABLE \u2014 c.env.incoming is not an EventEmitter
8307
+ `);
8308
+ } catch {
8309
+ }
8310
+ }
8311
+ const sseLog = {
8312
+ write(line) {
8313
+ try {
8314
+ sseLogStream.write(line);
8315
+ } catch {
8316
+ }
8317
+ try {
8318
+ appendFileSync4(resolveTeeStreamLogPath(), line);
8319
+ } catch {
8320
+ }
8321
+ return true;
8322
+ },
8323
+ end() {
8324
+ try {
8325
+ sseLogStream.end();
8326
+ } catch {
8327
+ }
8328
+ }
8329
+ };
8259
8330
  let tailer = null;
8260
8331
  const readable = new ReadableStream({
8332
+ // Task 606 — fires when the consumer (Hono's response writer / Node
8333
+ // adapter) cancels the stream because the client disconnected. This is
8334
+ // the only signal that arrives WHILE start()'s for-await is blocked
8335
+ // awaiting the SDK's next message — c.req.raw.signal didn't propagate
8336
+ // under @hono/node-server, and controller.enqueue throwing only
8337
+ // surfaces on the next yielded event (which never comes if the model
8338
+ // is mid-response when Cancel is pressed). cancel() is the load-bearing
8339
+ // hook for operator abort.
8340
+ //
8341
+ // Synchronous trace writes go to BOTH the per-conv stream log (where
8342
+ // operators read) AND console.error (server.log backstop). This lets
8343
+ // us prove definitively whether this callback is even being invoked
8344
+ // by @hono/node-server on disconnect.
8345
+ cancel(reason) {
8346
+ const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
8347
+ const reasonStr = typeof reason === "string" ? reason : reason instanceof Error ? reason.message : "consumer-cancelled";
8348
+ sseLog.write(`[${ts}] [${sk}] admin: CANCEL [stream-cancel] reason=${reasonStr}
8349
+ `);
8350
+ console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}] [stream-cancel-callback] sessionKey=${session_key.slice(0, 12)}\u2026 reason=${JSON.stringify(reasonStr)}`);
8351
+ interruptClient(session_key).catch((err) => {
8352
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${err instanceof Error ? err.message : String(err)}
8353
+ `);
8354
+ });
8355
+ },
8261
8356
  async start(controller) {
8262
8357
  let controllerOpen = true;
8263
8358
  const sseEntry = { controller, conversationId: sseConvId ?? null, sessionKey: session_key };
8359
+ try {
8360
+ const reqSignal = c.req.raw?.signal;
8361
+ if (reqSignal) {
8362
+ reqSignal.addEventListener("abort", () => {
8363
+ const abortLogKey = sseConvId ?? preflushStreamLogKey(session_key);
8364
+ const abortStreamLog = agentLogStream("claude-agent-stream", account.accountDir, abortLogKey);
8365
+ const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
8366
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [operator-cancel] interrupting pool client
8367
+ `);
8368
+ interruptClient(session_key, abortStreamLog).catch((err) => {
8369
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${err instanceof Error ? err.message : String(err)}
8370
+ `);
8371
+ });
8372
+ }, { once: true });
8373
+ }
8374
+ } catch {
8375
+ }
8264
8376
  try {
8265
8377
  registerAdminSSE(sseEntry);
8266
8378
  if (sseConvId) {
@@ -8308,6 +8420,10 @@ app11.post("/", requireAdminSession, async (c) => {
8308
8420
  if (controllerClosed) {
8309
8421
  sseLog.write(`[${ts}] [${sk}] admin: DISCONNECT [client_disconnect] ${rawMessage}
8310
8422
  `);
8423
+ interruptClient(session_key).catch((interruptErr) => {
8424
+ sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${interruptErr instanceof Error ? interruptErr.message : String(interruptErr)}
8425
+ `);
8426
+ });
8311
8427
  } else {
8312
8428
  const category = classifyAgentError(err);
8313
8429
  const errEvent = JSON.stringify({ type: "text", content: friendlyAgentError(err) });