@geminixiang/mikan 1.0.0-beta.80 → 1.0.0-beta.81
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/CHANGELOG.md +19 -0
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +3 -4
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/client.d.ts +4 -0
- package/dist/adapters/github/client.d.ts.map +1 -1
- package/dist/adapters/github/client.js +41 -23
- package/dist/adapters/github/client.js.map +1 -1
- package/dist/adapters/github/github-ops.js +16 -12
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +6 -3
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/web/server.d.ts +2 -0
- package/dist/adapters/web/server.d.ts.map +1 -1
- package/dist/adapters/web/server.js +11 -4
- package/dist/adapters/web/server.js.map +1 -1
- package/dist/adapters/web/session-view/portal.d.ts.map +1 -1
- package/dist/adapters/web/session-view/portal.js +84 -63
- package/dist/adapters/web/session-view/portal.js.map +1 -1
- package/dist/adapters/web/session-view/types.d.ts +2 -0
- package/dist/adapters/web/session-view/types.d.ts.map +1 -1
- package/dist/adapters/web/session-view/types.js.map +1 -1
- package/dist/env-manifest.d.ts +1 -0
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +7 -0
- package/dist/env-manifest.js.map +1 -1
- package/dist/harness/loop-guard.d.ts +10 -0
- package/dist/harness/loop-guard.d.ts.map +1 -0
- package/dist/harness/loop-guard.js +111 -0
- package/dist/harness/loop-guard.js.map +1 -0
- package/dist/harness/presenter.d.ts.map +1 -1
- package/dist/harness/presenter.js +143 -141
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/run-events.d.ts +10 -0
- package/dist/harness/run-events.d.ts.map +1 -0
- package/dist/harness/run-events.js +129 -0
- package/dist/harness/run-events.js.map +1 -0
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +78 -48
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +5 -0
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +71 -1
- package/dist/harness/session.js.map +1 -1
- package/dist/harness/types.d.ts +60 -0
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/main.js +11 -8
- package/dist/main.js.map +1 -1
- package/dist/runtime/conversation-runtime.js +1 -0
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +2 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -13,6 +13,7 @@ import type { Workspace } from "../../office/types.js";
|
|
|
13
13
|
import type { GithubWebhookOptions } from "../github/types.js";
|
|
14
14
|
interface StartWebServerOptions {
|
|
15
15
|
port: number;
|
|
16
|
+
host: string;
|
|
16
17
|
linkTokenStore: InMemoryLinkTokenStore;
|
|
17
18
|
vaultManager: VaultManager;
|
|
18
19
|
notify: NotifyFn;
|
|
@@ -29,5 +30,6 @@ interface StartWebServerOptions {
|
|
|
29
30
|
githubWebhook?: GithubWebhookOptions;
|
|
30
31
|
}
|
|
31
32
|
export declare function startWebServer(options: StartWebServerOptions): Server;
|
|
33
|
+
export declare function closeWebServer(server: Server, graceMs: number): Promise<void>;
|
|
32
34
|
export {};
|
|
33
35
|
//# sourceMappingURL=server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG/D,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,sBAAsB,CAAC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC;IACjB,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,sBAAsB,CAAC,EAAE,6BAA6B,CAAC;IACvD,YAAY,CAAC,EAAE;QACb,eAAe,EAAE,uBAAuB,CAAC;QACzC,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,kBAAkB,CAAC;QAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7D,cAAc,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;KACtD,CAAC;IACF,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG/D,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,sBAAsB,CAAC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC;IACjB,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,sBAAsB,CAAC,EAAE,6BAA6B,CAAC;IACvD,YAAY,CAAC,EAAE;QACb,eAAe,EAAE,uBAAuB,CAAC;QACzC,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,kBAAkB,CAAC;QAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7D,cAAc,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;KACtD,CAAC;IACF,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAuFrE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7E"}
|
|
@@ -55,11 +55,10 @@ export function startWebServer(options) {
|
|
|
55
55
|
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
log.logInfo(`Web server listening on ${bindHost ?? "0.0.0.0"}:${options.port}`);
|
|
58
|
+
server.listen(options.port, options.host, () => {
|
|
59
|
+
log.logInfo(`Web server listening on ${options.host}:${options.port}`);
|
|
61
60
|
if (!resolveLinkBaseUrl()) {
|
|
62
|
-
log.logWarning("MIKAN_LINK_URL is not set —
|
|
61
|
+
log.logWarning("MIKAN_LINK_URL is not set — OAuth redirect_uri will be " +
|
|
63
62
|
"derived from request headers (Host / X-Forwarded-*). Set " +
|
|
64
63
|
"MIKAN_LINK_URL=https://your-host.example.com for production.");
|
|
65
64
|
}
|
|
@@ -69,4 +68,12 @@ export function startWebServer(options) {
|
|
|
69
68
|
});
|
|
70
69
|
return server;
|
|
71
70
|
}
|
|
71
|
+
export function closeWebServer(server, graceMs) {
|
|
72
|
+
const closed = new Promise((resolve, reject) => {
|
|
73
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
74
|
+
});
|
|
75
|
+
server.closeIdleConnections();
|
|
76
|
+
const forceClose = setTimeout(() => server.closeAllConnections(), graceMs);
|
|
77
|
+
return closed.finally(() => clearTimeout(forceClose));
|
|
78
|
+
}
|
|
72
79
|
//# sourceMappingURL=server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA0D,MAAM,WAAW,CAAC;AAEjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAA0B,MAAM,uBAAuB,CAAC;AAEjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAIpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { MessagingBot, PlatformName } from \"../../types.js\";\nimport { resolveLinkBaseUrl } from \"../../env-manifest.js\";\nimport * as log from \"../../log.js\";\nimport type { SandboxConfig } from \"../../sandbox/types.js\";\nimport { OfficeEventStore, type EventScheduleSink } from \"../../events/index.js\";\nimport type { VaultManager } from \"../../vault/types.js\";\nimport { handleAdminRequest } from \"./admin/portal.js\";\nimport type { AdminRuntimeBridge } from \"./admin/types.js\";\nimport type { InMemoryAdminTokenStore } from \"./admin/portal.js\";\nimport { createLoginRequestHandler } from \"./login/portal.js\";\nimport { requestBaseUrl } from \"./portal-shell.js\";\nimport type { InMemoryLinkTokenStore } from \"./login/portal.js\";\nimport type { NotifyFn } from \"./login/types.js\";\nimport { handleSessionViewRequest } from \"./session-view/portal.js\";\nimport type { SessionViewInteractiveOptions } from \"./session-view/types.js\";\nimport type { InMemorySessionViewTokenStore } from \"./session-view/portal.js\";\nimport type { Office, Workspace } from \"../../office/types.js\";\nimport { handleGithubWebhookRequest } from \"../github/webhook.js\";\nimport type { GithubWebhookOptions } from \"../github/types.js\";\nimport { errorMessage } from \"../../unknown-values.js\";\n\ninterface StartWebServerOptions {\n port: number;\n host: string;\n linkTokenStore: InMemoryLinkTokenStore;\n vaultManager: VaultManager;\n notify: NotifyFn;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n sessionViewInteractive?: SessionViewInteractiveOptions;\n adminOptions?: {\n adminTokenStore: InMemoryAdminTokenStore;\n workspace?: Workspace;\n runtime?: AdminRuntimeBridge;\n sandbox?: SandboxConfig;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n eventScheduler?: () => EventScheduleSink | undefined;\n };\n githubWebhook?: GithubWebhookOptions;\n}\n\nexport function startWebServer(options: StartWebServerOptions): Server {\n const loginHandler = createLoginRequestHandler(\n options.linkTokenStore,\n options.vaultManager,\n options.notify,\n );\n\n const adminEventStore = (office: Office) =>\n new OfficeEventStore(office, options.adminOptions?.eventScheduler?.());\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const url = new URL(req.url ?? \"/\", requestBaseUrl(req));\n\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n if (\n options.githubWebhook &&\n (await handleGithubWebhookRequest(req, res, url, options.githubWebhook))\n ) {\n return;\n }\n\n const adminOptions = options.adminOptions;\n if (\n adminOptions?.adminTokenStore &&\n (await handleAdminRequest(req, res, url, {\n vaultManager: options.vaultManager,\n linkTokenStore: options.linkTokenStore,\n sessionViewTokenStore: options.sessionViewTokenStore,\n adminTokenStore: adminOptions.adminTokenStore,\n portalBaseUrl: resolveLinkBaseUrl() ?? undefined,\n workspace: adminOptions.workspace,\n eventStore: adminEventStore,\n runtime: adminOptions.runtime,\n sandbox: adminOptions.sandbox,\n botsByPlatform: adminOptions.botsByPlatform,\n }))\n ) {\n return;\n }\n\n if (\n await handleSessionViewRequest(\n req,\n res,\n url,\n options.sessionViewTokenStore,\n options.sessionViewInteractive,\n )\n ) {\n return;\n }\n\n if (loginHandler(req, res, url)) return;\n\n res.writeHead(404);\n res.end();\n } catch (err) {\n log.logWarning(\"Web server request error\", errorMessage(err));\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n });\n\n server.listen(options.port, options.host, () => {\n log.logInfo(`Web server listening on ${options.host}:${options.port}`);\n if (!resolveLinkBaseUrl()) {\n log.logWarning(\n \"MIKAN_LINK_URL is not set — OAuth redirect_uri will be \" +\n \"derived from request headers (Host / X-Forwarded-*). Set \" +\n \"MIKAN_LINK_URL=https://your-host.example.com for production.\",\n );\n }\n });\n\n server.on(\"error\", (err) => {\n log.logWarning(\"Web server error\", err.message);\n });\n\n return server;\n}\n\nexport function closeWebServer(server: Server, graceMs: number): Promise<void> {\n const closed = new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n server.closeIdleConnections();\n const forceClose = setTimeout(() => server.closeAllConnections(), graceMs);\n return closed.finally(() => clearTimeout(forceClose));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../../src/adapters/web/session-view/portal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAgBjE,OAAO,KAAK,EAGV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAGV,6BAA6B,EAC9B,MAAM,mBAAmB,CAAC;AAmB3B,qBAAa,6BAA8B,SAAQ,kBAAkB,CAAC,gBAAgB,CAAC;IACrF,MAAM,CAAC,OAAO,EAAE,6BAA6B,GAAG,gBAAgB,CAS/D;CACF;
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../../src/adapters/web/session-view/portal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAgBjE,OAAO,KAAK,EAGV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAGV,6BAA6B,EAC9B,MAAM,mBAAmB,CAAC;AAmB3B,qBAAa,6BAA8B,SAAQ,kBAAkB,CAAC,gBAAgB,CAAC;IACrF,MAAM,CAAC,OAAO,EAAE,6BAA6B,GAAG,gBAAgB,CAS/D;CACF;AA6DD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAIhE,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,GAAG,EACR,qBAAqB,CAAC,EAAE,6BAA6B,EACrD,WAAW,CAAC,EAAE,6BAA6B,GAC1C,OAAO,CAAC,OAAO,CAAC,CAuElB;AAwLD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG;IAC1C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CA4BA;AAm6CD,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAKf;AAED,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyDzF"}
|
|
@@ -415,15 +415,26 @@ async function handleSessionStreamRequest(req, res, url, sessionViewTokenStore,
|
|
|
415
415
|
type: "status",
|
|
416
416
|
running: interactive.handler.isRunning(createOfficeAddress(entry.platform, entry.conversationId), activeSessionKey),
|
|
417
417
|
})}\n\n`);
|
|
418
|
-
const
|
|
419
|
-
|
|
418
|
+
const send = (event) => res.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
419
|
+
const unsubscribe = sessionViewStreamHub.subscribe(streamKey, send);
|
|
420
|
+
const liveRun = createLiveRunProjection(send, async () => {
|
|
421
|
+
const model = await loadSessionViewModel(target.targetSessionFile);
|
|
422
|
+
return {
|
|
423
|
+
type: "refresh",
|
|
424
|
+
timelineHtml: renderTimelineItems(model.items, url.searchParams.get("token") ?? ""),
|
|
425
|
+
updatedAt: formatDate(model.updatedAt),
|
|
426
|
+
entryCount: model.entryCount,
|
|
427
|
+
running: false,
|
|
428
|
+
};
|
|
420
429
|
});
|
|
430
|
+
const unsubscribeRun = interactive.runEvents.subscribe(createOfficeAddress(entry.platform, entry.conversationId), activeSessionKey, liveRun);
|
|
421
431
|
const heartbeat = setInterval(() => {
|
|
422
432
|
res.write(": keep-alive\n\n");
|
|
423
433
|
}, 15000);
|
|
424
434
|
req.on("close", () => {
|
|
425
435
|
clearInterval(heartbeat);
|
|
426
436
|
unsubscribe();
|
|
437
|
+
unsubscribeRun();
|
|
427
438
|
});
|
|
428
439
|
}
|
|
429
440
|
async function handleSessionMessageRequest(req, res, sessionViewTokenStore, interactive) {
|
|
@@ -447,23 +458,15 @@ async function handleSessionMessageRequest(req, res, sessionViewTokenStore, inte
|
|
|
447
458
|
json(res, target.status, { ok: false, error: target.message });
|
|
448
459
|
return;
|
|
449
460
|
}
|
|
450
|
-
const { activeSessionKey, entry
|
|
461
|
+
const { activeSessionKey, entry } = target;
|
|
451
462
|
if (requestedSessionKey && requestedSessionKey !== activeSessionKey) {
|
|
452
463
|
json(res, 400, { ok: false, error: "Session target mismatch." });
|
|
453
464
|
return;
|
|
454
465
|
}
|
|
455
|
-
await dispatchSessionViewMessage({
|
|
456
|
-
res,
|
|
457
|
-
interactive,
|
|
458
|
-
token,
|
|
459
|
-
text,
|
|
460
|
-
activeSessionKey,
|
|
461
|
-
entry,
|
|
462
|
-
targetSessionFile,
|
|
463
|
-
});
|
|
466
|
+
await dispatchSessionViewMessage({ res, interactive, text, activeSessionKey, entry });
|
|
464
467
|
}
|
|
465
468
|
async function dispatchSessionViewMessage(input) {
|
|
466
|
-
const { res, interactive,
|
|
469
|
+
const { res, interactive, text, activeSessionKey, entry } = input;
|
|
467
470
|
const bot = interactive.botsByPlatform[entry.platform];
|
|
468
471
|
if (!bot) {
|
|
469
472
|
json(res, 503, { ok: false, error: `No bot configured for ${entry.platform}.` });
|
|
@@ -477,9 +480,7 @@ async function dispatchSessionViewMessage(input) {
|
|
|
477
480
|
platformInfo.users.find((user) => user.id === entry.platformUserId)?.userName ||
|
|
478
481
|
platformInfo.users.find((user) => user.id === entry.platformUserId)?.displayName ||
|
|
479
482
|
"unknown";
|
|
480
|
-
const responder =
|
|
481
|
-
sessionViewStreamHub.publish(streamKey, event);
|
|
482
|
-
});
|
|
483
|
+
const responder = createSilentResponder();
|
|
483
484
|
const event = createConversationEvent({
|
|
484
485
|
platform: entry.platform,
|
|
485
486
|
type: "session_view",
|
|
@@ -510,24 +511,7 @@ async function dispatchSessionViewMessage(input) {
|
|
|
510
511
|
responder,
|
|
511
512
|
platform: { ...platformInfo, diagnostics: { showUsageSummary: false } },
|
|
512
513
|
};
|
|
513
|
-
|
|
514
|
-
sessionViewStreamHub.publish(streamKey, {
|
|
515
|
-
type: "user",
|
|
516
|
-
html: renderLiveUserMessage(text, platformUserName),
|
|
517
|
-
});
|
|
518
|
-
void interactive.handler
|
|
519
|
-
.handleEvent(event, bot, context)
|
|
520
|
-
.then(async () => {
|
|
521
|
-
const model = await loadSessionViewModel(targetSessionFile);
|
|
522
|
-
sessionViewStreamHub.publish(streamKey, {
|
|
523
|
-
type: "refresh",
|
|
524
|
-
timelineHtml: renderTimelineItems(model.items, token),
|
|
525
|
-
updatedAt: formatDate(model.updatedAt),
|
|
526
|
-
entryCount: model.entryCount,
|
|
527
|
-
running: false,
|
|
528
|
-
});
|
|
529
|
-
})
|
|
530
|
-
.catch((error) => {
|
|
514
|
+
void interactive.handler.handleEvent(event, bot, context).catch((error) => {
|
|
531
515
|
log.logWarning(`[${entry.conversationId}] Session view message failed`, errorMessage(error));
|
|
532
516
|
reportUserFacingError(error, {
|
|
533
517
|
domain: "session_view",
|
|
@@ -550,36 +534,70 @@ async function dispatchSessionViewMessage(input) {
|
|
|
550
534
|
});
|
|
551
535
|
json(res, 202, { ok: true, accepted: true });
|
|
552
536
|
}
|
|
553
|
-
function
|
|
554
|
-
|
|
537
|
+
async function ignoreResponse() { }
|
|
538
|
+
function createSilentResponder() {
|
|
539
|
+
const ignore = ignoreResponse;
|
|
555
540
|
return {
|
|
556
|
-
respond:
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
541
|
+
respond: ignore,
|
|
542
|
+
replaceResponse: ignore,
|
|
543
|
+
respondDiagnostic: ignore,
|
|
544
|
+
respondToolResult: ignore,
|
|
545
|
+
setTyping: ignore,
|
|
546
|
+
setWorking: ignore,
|
|
547
|
+
uploadFile: ignore,
|
|
548
|
+
deleteResponse: ignore,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
function createLiveRunProjection(send, refresh) {
|
|
552
|
+
let answer = "";
|
|
553
|
+
return (event) => {
|
|
554
|
+
switch (event.type) {
|
|
555
|
+
case "run_started":
|
|
556
|
+
answer = "";
|
|
557
|
+
send({ type: "status", running: true });
|
|
558
|
+
send({ type: "user", html: renderLiveUserMessage(event.text, event.userName) });
|
|
559
|
+
return;
|
|
560
|
+
case "tool_ended":
|
|
561
|
+
send({
|
|
562
|
+
type: "tool",
|
|
563
|
+
html: renderLiveToolResult({
|
|
564
|
+
toolName: event.toolName,
|
|
565
|
+
result: event.resultText,
|
|
566
|
+
isError: event.isError,
|
|
567
|
+
}),
|
|
568
|
+
});
|
|
569
|
+
return;
|
|
570
|
+
case "assistant_delta":
|
|
571
|
+
answer += event.delta;
|
|
572
|
+
send({ type: "assistant", html: renderLiveAssistantMessage(answer) });
|
|
573
|
+
return;
|
|
574
|
+
case "assistant_message":
|
|
575
|
+
answer = "";
|
|
576
|
+
send({ type: "assistant_done" });
|
|
577
|
+
return;
|
|
578
|
+
case "compaction_started":
|
|
579
|
+
send({ type: "system", html: renderLiveSystemEvent("Compacting context…") });
|
|
580
|
+
return;
|
|
581
|
+
case "retry_started":
|
|
582
|
+
send({
|
|
583
|
+
type: "system",
|
|
584
|
+
html: renderLiveSystemEvent(`Retrying (${event.attempt}/${event.maxAttempts})…`),
|
|
585
|
+
});
|
|
586
|
+
return;
|
|
587
|
+
case "budget_exceeded":
|
|
588
|
+
send({
|
|
589
|
+
type: "system",
|
|
590
|
+
html: renderLiveSystemEvent(`Stopped: run budget exceeded (${event.reason})`, "err"),
|
|
591
|
+
});
|
|
592
|
+
return;
|
|
593
|
+
case "run_ended":
|
|
594
|
+
void refresh()
|
|
595
|
+
.then(send)
|
|
596
|
+
.catch((error) => send({ type: "error", message: errorMessage(error) }));
|
|
597
|
+
return;
|
|
598
|
+
default:
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
583
601
|
};
|
|
584
602
|
}
|
|
585
603
|
function renderStatusPage(title, message) {
|
|
@@ -722,6 +740,9 @@ const sessionViewScript = `
|
|
|
722
740
|
if (liveAssistant?.isConnected) liveAssistant.remove();
|
|
723
741
|
liveAssistant = null;
|
|
724
742
|
break;
|
|
743
|
+
case 'assistant_done':
|
|
744
|
+
liveAssistant = null;
|
|
745
|
+
break;
|
|
725
746
|
case 'refresh':
|
|
726
747
|
if (timelineList) timelineList.innerHTML = payload.timelineHtml;
|
|
727
748
|
liveAssistant = null;
|