@geminixiang/mikan 1.0.0-beta.94 → 1.0.0-beta.95

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.
Files changed (92) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/adapters/commands/login.js +1 -1
  3. package/dist/adapters/commands/login.js.map +1 -1
  4. package/dist/adapters/commands/registry.d.ts +1 -1
  5. package/dist/adapters/commands/registry.d.ts.map +1 -1
  6. package/dist/adapters/commands/registry.js +1 -2
  7. package/dist/adapters/commands/registry.js.map +1 -1
  8. package/dist/adapters/commands/types.d.ts +2 -4
  9. package/dist/adapters/commands/types.d.ts.map +1 -1
  10. package/dist/adapters/commands/types.js.map +1 -1
  11. package/dist/adapters/web/admin/portal.d.ts.map +1 -1
  12. package/dist/adapters/web/admin/portal.js +92 -173
  13. package/dist/adapters/web/admin/portal.js.map +1 -1
  14. package/dist/adapters/web/admin/types.d.ts +3 -8
  15. package/dist/adapters/web/admin/types.d.ts.map +1 -1
  16. package/dist/adapters/web/admin/types.js.map +1 -1
  17. package/dist/adapters/web/server.d.ts +1 -1
  18. package/dist/adapters/web/server.d.ts.map +1 -1
  19. package/dist/adapters/web/server.js.map +1 -1
  20. package/dist/cli/arg-grammar.d.ts +0 -1
  21. package/dist/cli/arg-grammar.d.ts.map +1 -1
  22. package/dist/cli/arg-grammar.js +0 -3
  23. package/dist/cli/arg-grammar.js.map +1 -1
  24. package/dist/env-manifest.d.ts +0 -1
  25. package/dist/env-manifest.d.ts.map +1 -1
  26. package/dist/env-manifest.js +0 -4
  27. package/dist/env-manifest.js.map +1 -1
  28. package/dist/harness/execution-resolver.js +1 -1
  29. package/dist/harness/execution-resolver.js.map +1 -1
  30. package/dist/harness/models.d.ts +2 -2
  31. package/dist/harness/models.d.ts.map +1 -1
  32. package/dist/harness/models.js +4 -6
  33. package/dist/harness/models.js.map +1 -1
  34. package/dist/harness/runner.js +1 -2
  35. package/dist/harness/runner.js.map +1 -1
  36. package/dist/harness/types.d.ts +1 -1
  37. package/dist/harness/types.d.ts.map +1 -1
  38. package/dist/harness/types.js.map +1 -1
  39. package/dist/main.js +3 -5
  40. package/dist/main.js.map +1 -1
  41. package/dist/migrations/index.d.ts.map +1 -1
  42. package/dist/migrations/index.js +0 -6
  43. package/dist/migrations/index.js.map +1 -1
  44. package/dist/migrations/session-v3.d.ts +57 -0
  45. package/dist/migrations/session-v3.d.ts.map +1 -0
  46. package/dist/migrations/session-v3.js +93 -0
  47. package/dist/migrations/session-v3.js.map +1 -0
  48. package/dist/migrations/sessions-sqlite.d.ts.map +1 -1
  49. package/dist/migrations/sessions-sqlite.js +98 -54
  50. package/dist/migrations/sessions-sqlite.js.map +1 -1
  51. package/dist/observability/instrument.js +1 -3
  52. package/dist/observability/instrument.js.map +1 -1
  53. package/dist/runtime/conversation-runtime.js +9 -14
  54. package/dist/runtime/conversation-runtime.js.map +1 -1
  55. package/dist/runtime/types.d.ts +2 -7
  56. package/dist/runtime/types.d.ts.map +1 -1
  57. package/dist/runtime/types.js.map +1 -1
  58. package/dist/settings/apply.d.ts +1 -1
  59. package/dist/settings/apply.d.ts.map +1 -1
  60. package/dist/settings/apply.js +4 -5
  61. package/dist/settings/apply.js.map +1 -1
  62. package/dist/settings/index.d.ts +4 -4
  63. package/dist/settings/index.d.ts.map +1 -1
  64. package/dist/settings/index.js +21 -20
  65. package/dist/settings/index.js.map +1 -1
  66. package/dist/types.d.ts +2 -3
  67. package/dist/types.d.ts.map +1 -1
  68. package/dist/types.js.map +1 -1
  69. package/dist/vault/index.d.ts.map +1 -1
  70. package/dist/vault/index.js +1 -14
  71. package/dist/vault/index.js.map +1 -1
  72. package/package.json +1 -1
  73. package/dist/migrations/dream-checkpoints.d.ts +0 -3
  74. package/dist/migrations/dream-checkpoints.d.ts.map +0 -1
  75. package/dist/migrations/dream-checkpoints.js +0 -23
  76. package/dist/migrations/dream-checkpoints.js.map +0 -1
  77. package/dist/migrations/private-office-dirs.d.ts +0 -3
  78. package/dist/migrations/private-office-dirs.d.ts.map +0 -1
  79. package/dist/migrations/private-office-dirs.js +0 -24
  80. package/dist/migrations/private-office-dirs.js.map +0 -1
  81. package/dist/migrations/session-files.d.ts +0 -28
  82. package/dist/migrations/session-files.d.ts.map +0 -1
  83. package/dist/migrations/session-files.js +0 -80
  84. package/dist/migrations/session-files.js.map +0 -1
  85. package/dist/migrations/session-v4.d.ts +0 -77
  86. package/dist/migrations/session-v4.d.ts.map +0 -1
  87. package/dist/migrations/session-v4.js +0 -177
  88. package/dist/migrations/session-v4.js.map +0 -1
  89. package/dist/migrations/sessions-v3.d.ts +0 -8
  90. package/dist/migrations/sessions-v3.d.ts.map +0 -1
  91. package/dist/migrations/sessions-v3.js +0 -350
  92. package/dist/migrations/sessions-v3.js.map +0 -1
@@ -4,14 +4,50 @@ import { OfficeRegistry, officeStateDir } from "../office/index.js";
4
4
  import { earlierSessionKey, importOfficeSessions, readImportedContexts, } from "../sessions/session-store.js";
5
5
  import { makeThreadSessionKey } from "../sessions/session-key.js";
6
6
  import { readTextFileIfExists } from "../file-guards.js";
7
- import { branchSummaryMessage, isContextMessage, readV4Header, readV4Session, toModelMessage, } from "./session-v4.js";
8
- const V4_SESSIONS_DIR = "sessions";
9
- const ARCHIVE_DIR = "sessions-v4";
7
+ import { epochMillis, isV3SessionFile, pathTo, readV3Session, } from "./session-v3.js";
8
+ const SESSIONS_DIR = "sessions";
9
+ const ARCHIVE_DIR = "sessions-v3";
10
10
  const STORAGE_FILENAME = "sessions.db";
11
11
  const TEMP_SUFFIX = ".importing";
12
12
  const MAIN_SESSION_FILENAME = /^\d{4}-\d{2}-\d{2}T.+_[0-9a-f]{8}\.jsonl$/i;
13
- const ARCHIVED_THREAD_PREFIX = "scoped-archive-";
14
13
  const INTERRUPTED_RESULT = "This tool call was interrupted by the upgrade to Pi 1.0; its outcome is unknown.";
14
+ const BRANCH_SUMMARY_PREFIX = "The following is a summary of a branch that this conversation came back from:\n\n<summary>\n";
15
+ const BRANCH_SUMMARY_SUFFIX = "</summary>";
16
+ const LEGACY_SETTING_TYPES = new Set([
17
+ "thinking_level_change",
18
+ "model_change",
19
+ ]);
20
+ function isModelMessage(value) {
21
+ return value.role === "user" || value.role === "assistant" || value.role === "toolResult";
22
+ }
23
+ function isContextMessage(message) {
24
+ return (message.role !== "assistant" ||
25
+ (message.stopReason !== "error" &&
26
+ message.stopReason !== "aborted" &&
27
+ message.stopReason !== "deferred"));
28
+ }
29
+ function userMessage(content, timestamp) {
30
+ return {
31
+ role: "user",
32
+ content: typeof content === "string" ? [{ type: "text", text: content }] : content,
33
+ timestamp,
34
+ };
35
+ }
36
+ function messageOf(entry) {
37
+ const timestamp = epochMillis(entry.timestamp);
38
+ switch (entry.type) {
39
+ case "message":
40
+ return isModelMessage(entry.message) ? entry.message : undefined;
41
+ case "custom_message":
42
+ return userMessage(entry.content, timestamp);
43
+ case "branch_summary":
44
+ return entry.summary
45
+ ? userMessage(BRANCH_SUMMARY_PREFIX + entry.summary + BRANCH_SUMMARY_SUFFIX, timestamp)
46
+ : undefined;
47
+ default:
48
+ return undefined;
49
+ }
50
+ }
15
51
  class EntryCollector {
16
52
  constructor() {
17
53
  this.entries = [];
@@ -20,11 +56,8 @@ class EntryCollector {
20
56
  get messageCount() {
21
57
  return this.entries.filter((entry) => entry.type !== "custom").length;
22
58
  }
23
- message(v4) {
24
- if (!isContextMessage(v4))
25
- return;
26
- const message = toModelMessage(v4);
27
- if (!message)
59
+ message(message) {
60
+ if (!isContextMessage(message))
28
61
  return;
29
62
  if (message.role === "toolResult") {
30
63
  if (!this.openCalls.delete(message.toolCallId))
@@ -33,7 +66,7 @@ class EntryCollector {
33
66
  else {
34
67
  this.closeOpenCalls();
35
68
  }
36
- this.push(message);
69
+ this.entries.push({ type: "message", message });
37
70
  if (message.role === "assistant")
38
71
  this.trackCalls(message);
39
72
  }
@@ -46,20 +79,20 @@ class EntryCollector {
46
79
  }
47
80
  closeOpenCalls() {
48
81
  for (const [toolCallId, call] of this.openCalls) {
49
- this.push({
50
- role: "toolResult",
51
- toolCallId,
52
- toolName: call.name,
53
- content: [{ type: "text", text: INTERRUPTED_RESULT }],
54
- isError: true,
55
- timestamp: call.timestamp,
82
+ this.entries.push({
83
+ type: "message",
84
+ message: {
85
+ role: "toolResult",
86
+ toolCallId,
87
+ toolName: call.name,
88
+ content: [{ type: "text", text: INTERRUPTED_RESULT }],
89
+ isError: true,
90
+ timestamp: call.timestamp,
91
+ },
56
92
  });
57
93
  }
58
94
  this.openCalls.clear();
59
95
  }
60
- push(message) {
61
- this.entries.push({ type: "message", message });
62
- }
63
96
  trackCalls(message) {
64
97
  for (const part of message.content) {
65
98
  if (part.type === "toolCall") {
@@ -68,33 +101,43 @@ class EntryCollector {
68
101
  }
69
102
  }
70
103
  }
104
+ function keptMessages(session, entry) {
105
+ const ancestors = pathTo(session.entriesById, entry.parentId);
106
+ const kept = ancestors.findIndex((ancestor) => ancestor.id === entry.firstKeptEntryId);
107
+ if (kept === -1)
108
+ return [];
109
+ return ancestors
110
+ .slice(kept)
111
+ .filter((ancestor) => ancestor.type === "message" || ancestor.type === "custom_message");
112
+ }
71
113
  function collectEntries(session) {
72
114
  const collector = new EntryCollector();
73
115
  const visibleStart = session.branch.findLastIndex((entry) => entry.type === "compaction");
74
116
  for (const [index, entry] of session.branch.entries()) {
117
+ const timestamp = epochMillis(entry.timestamp);
75
118
  if (entry.type === "custom") {
76
- collector.custom(entry.customType, entry.data, entry.timestamp);
119
+ collector.custom(entry.customType, entry.data, timestamp);
120
+ continue;
121
+ }
122
+ if (LEGACY_SETTING_TYPES.has(entry.type)) {
123
+ const { id: _id, parentId: _parentId, timestamp: _timestamp, type, ...data } = entry;
124
+ collector.custom(`mikan.legacy.${type}`, data, timestamp);
77
125
  continue;
78
126
  }
79
127
  if (index < visibleStart)
80
128
  continue;
81
- switch (entry.type) {
82
- case "compaction":
83
- collector.compaction(entry.summary, entry.timestamp);
84
- for (const message of entry.retainedTail)
129
+ if (entry.type === "compaction") {
130
+ collector.compaction(entry.summary, timestamp);
131
+ for (const kept of keptMessages(session, entry)) {
132
+ const message = messageOf(kept);
133
+ if (message)
85
134
  collector.message(message);
86
- break;
87
- case "message":
88
- collector.message(entry.message);
89
- break;
90
- case "branch_summary":
91
- if (entry.summary) {
92
- collector.message(branchSummaryMessage(entry.summary, entry.fromId, entry.timestamp));
93
- }
94
- break;
95
- default:
96
- entry;
135
+ }
136
+ continue;
97
137
  }
138
+ const message = messageOf(entry);
139
+ if (message)
140
+ collector.message(message);
98
141
  }
99
142
  collector.closeOpenCalls();
100
143
  return collector;
@@ -102,31 +145,32 @@ function collectEntries(session) {
102
145
  function sessionKeyFor(conversationId, fileName, current) {
103
146
  if (fileName === current)
104
147
  return { key: conversationId, root: true };
105
- const stem = fileName.slice(0, -".jsonl".length);
106
- if (MAIN_SESSION_FILENAME.test(fileName) || fileName.startsWith(ARCHIVED_THREAD_PREFIX)) {
148
+ if (MAIN_SESSION_FILENAME.test(fileName))
107
149
  return { key: undefined, root: false };
108
- }
109
- return { key: makeThreadSessionKey(conversationId, stem), root: false };
150
+ return {
151
+ key: makeThreadSessionKey(conversationId, fileName.slice(0, -".jsonl".length)),
152
+ root: false,
153
+ };
110
154
  }
111
155
  function planOfficeImport(conversationId, sessionsDir) {
112
156
  const current = readTextFileIfExists(join(sessionsDir, "current"))?.trim() || undefined;
113
157
  return readdirSync(sessionsDir, { withFileTypes: true })
114
158
  .filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl"))
115
- .filter((entry) => readV4Header(join(sessionsDir, entry.name)) !== undefined)
159
+ .filter((entry) => isV3SessionFile(join(sessionsDir, entry.name)))
116
160
  .map((entry) => {
117
161
  const file = join(sessionsDir, entry.name);
118
- const v4 = readV4Session(file);
119
- const collected = collectEntries(v4);
162
+ const v3 = readV3Session(file);
163
+ const collected = collectEntries(v3);
120
164
  const { key, root } = sessionKeyFor(conversationId, entry.name, current);
121
165
  return {
122
166
  file,
123
167
  expectedMessages: collected.messageCount,
124
168
  session: {
125
- key: key ?? earlierSessionKey(v4.header.id),
126
- id: v4.header.id,
127
- createdAt: v4.header.createdAt,
169
+ key: key ?? earlierSessionKey(v3.id),
170
+ id: v3.id,
171
+ createdAt: v3.createdAt,
128
172
  root,
129
- name: v4.name,
173
+ name: v3.name,
130
174
  entries: collected.entries,
131
175
  },
132
176
  };
@@ -141,15 +185,15 @@ async function verifyImport(temp, planned) {
141
185
  }
142
186
  }
143
187
  }
144
- function hasV4Sessions(sessionsDir) {
188
+ function hasV3Sessions(sessionsDir) {
145
189
  if (!existsSync(sessionsDir))
146
190
  return false;
147
191
  return readdirSync(sessionsDir, { withFileTypes: true }).some((entry) => entry.isFile() &&
148
192
  entry.name.endsWith(".jsonl") &&
149
- readV4Header(join(sessionsDir, entry.name)) !== undefined);
193
+ isV3SessionFile(join(sessionsDir, entry.name)));
150
194
  }
151
195
  async function migrateOffice(conversationId, officeDir, context) {
152
- const sessionsDir = join(officeDir, V4_SESSIONS_DIR);
196
+ const sessionsDir = join(officeDir, SESSIONS_DIR);
153
197
  const archive = join(officeDir, ARCHIVE_DIR);
154
198
  const storage = join(officeDir, STORAGE_FILENAME);
155
199
  const temp = `${storage}${TEMP_SUFFIX}`;
@@ -159,12 +203,12 @@ async function migrateOffice(conversationId, officeDir, context) {
159
203
  renameSync(temp, storage);
160
204
  return;
161
205
  }
162
- if (!hasV4Sessions(sessionsDir))
206
+ if (!hasV3Sessions(sessionsDir))
163
207
  return;
164
208
  if (existsSync(storage))
165
209
  throw new Error(`Session storage already exists: ${storage}`);
166
210
  if (existsSync(archive))
167
- throw new Error(`Archived v4 sessions already exist: ${archive}`);
211
+ throw new Error(`Archived session files already exist: ${archive}`);
168
212
  const planned = planOfficeImport(conversationId, sessionsDir);
169
213
  context.report(` ${planned.length} sessions -> ${storage}`);
170
214
  if (context.dryRun)
@@ -196,14 +240,14 @@ function assertEveryOfficeRegistered(stateDir, registered) {
196
240
  if (!entry.isDirectory())
197
241
  continue;
198
242
  const dir = join(root, entry.name);
199
- if (!registered.has(dir) && hasV4Sessions(join(dir, V4_SESSIONS_DIR))) {
243
+ if (!registered.has(dir) && hasV3Sessions(join(dir, SESSIONS_DIR))) {
200
244
  throw new Error(`Sessions in ${dir} belong to no office in office-registry.json; record the office before migrating`);
201
245
  }
202
246
  }
203
247
  }
204
248
  export const sessionsSqliteMigration = Object.freeze({
205
249
  id: "0009-sessions-sqlite",
206
- summary: "import v4 session files into one pi-durable SQLite storage per office, keeping originals under sessions-v4/",
250
+ summary: "import 0.5.3 session files into one pi-durable SQLite storage per office, keeping originals under sessions-v3/",
207
251
  async run(context) {
208
252
  const offices = registeredOffices(context.stateDir);
209
253
  assertEveryOfficeRegistered(context.stateDir, new Set(offices.map((office) => office.dir)));
@@ -1 +1 @@
1
- {"version":3,"file":"sessions-sqlite.js","sourceRoot":"","sources":["../../src/migrations/sessions-sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync, renameSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AssistantMessage, Message } from \"@earendil-works/pi-ai\";\nimport { OfficeRegistry, officeStateDir } from \"../office/index.js\";\nimport {\n earlierSessionKey,\n importOfficeSessions,\n readImportedContexts,\n} from \"../sessions/session-store.js\";\nimport { makeThreadSessionKey } from \"../sessions/session-key.js\";\nimport type { ImportedSession, ImportedSessionEntry } from \"../sessions/types.js\";\nimport { readTextFileIfExists } from \"../file-guards.js\";\nimport {\n branchSummaryMessage,\n isContextMessage,\n readV4Header,\n readV4Session,\n toModelMessage,\n type V4Message,\n type V4Session,\n} from \"./session-v4.js\";\nimport type { Migration, MigrationContext } from \"./types.js\";\n\nconst V4_SESSIONS_DIR = \"sessions\";\nconst ARCHIVE_DIR = \"sessions-v4\";\nconst STORAGE_FILENAME = \"sessions.db\";\nconst TEMP_SUFFIX = \".importing\";\nconst MAIN_SESSION_FILENAME = /^\\d{4}-\\d{2}-\\d{2}T.+_[0-9a-f]{8}\\.jsonl$/i;\nconst ARCHIVED_THREAD_PREFIX = \"scoped-archive-\";\nconst INTERRUPTED_RESULT =\n \"This tool call was interrupted by the upgrade to Pi 1.0; its outcome is unknown.\";\n\nclass EntryCollector {\n readonly entries: ImportedSessionEntry[] = [];\n private readonly openCalls = new Map<string, { name: string; timestamp: number }>();\n\n get messageCount(): number {\n return this.entries.filter((entry) => entry.type !== \"custom\").length;\n }\n\n message(v4: V4Message): void {\n if (!isContextMessage(v4)) return;\n const message = toModelMessage(v4);\n if (!message) return;\n if (message.role === \"toolResult\") {\n if (!this.openCalls.delete(message.toolCallId)) return;\n } else {\n this.closeOpenCalls();\n }\n this.push(message);\n if (message.role === \"assistant\") this.trackCalls(message);\n }\n\n compaction(summary: string, timestamp: number): void {\n this.closeOpenCalls();\n this.entries.push({ type: \"compaction\", summary, timestamp });\n }\n\n custom(customType: string, data: unknown, timestamp: number): void {\n this.entries.push({ type: \"custom\", customType, data, timestamp });\n }\n\n closeOpenCalls(): void {\n for (const [toolCallId, call] of this.openCalls) {\n this.push({\n role: \"toolResult\",\n toolCallId,\n toolName: call.name,\n content: [{ type: \"text\", text: INTERRUPTED_RESULT }],\n isError: true,\n timestamp: call.timestamp,\n });\n }\n this.openCalls.clear();\n }\n\n private push(message: Message): void {\n this.entries.push({ type: \"message\", message });\n }\n\n private trackCalls(message: AssistantMessage): void {\n for (const part of message.content) {\n if (part.type === \"toolCall\") {\n this.openCalls.set(part.id, { name: part.name, timestamp: message.timestamp });\n }\n }\n }\n}\n\nfunction collectEntries(session: V4Session): EntryCollector {\n const collector = new EntryCollector();\n const visibleStart = session.branch.findLastIndex((entry) => entry.type === \"compaction\");\n for (const [index, entry] of session.branch.entries()) {\n if (entry.type === \"custom\") {\n collector.custom(entry.customType, entry.data, entry.timestamp);\n continue;\n }\n if (index < visibleStart) continue;\n switch (entry.type) {\n case \"compaction\":\n collector.compaction(entry.summary, entry.timestamp);\n for (const message of entry.retainedTail) collector.message(message);\n break;\n case \"message\":\n collector.message(entry.message);\n break;\n case \"branch_summary\":\n if (entry.summary) {\n collector.message(branchSummaryMessage(entry.summary, entry.fromId, entry.timestamp));\n }\n break;\n default:\n entry satisfies never;\n }\n }\n collector.closeOpenCalls();\n return collector;\n}\n\ninterface PlannedSession {\n file: string;\n session: ImportedSession;\n expectedMessages: number;\n}\n\nfunction sessionKeyFor(conversationId: string, fileName: string, current: string | undefined) {\n if (fileName === current) return { key: conversationId, root: true };\n const stem = fileName.slice(0, -\".jsonl\".length);\n if (MAIN_SESSION_FILENAME.test(fileName) || fileName.startsWith(ARCHIVED_THREAD_PREFIX)) {\n return { key: undefined, root: false };\n }\n return { key: makeThreadSessionKey(conversationId, stem), root: false };\n}\n\nfunction planOfficeImport(conversationId: string, sessionsDir: string): PlannedSession[] {\n const current = readTextFileIfExists(join(sessionsDir, \"current\"))?.trim() || undefined;\n return readdirSync(sessionsDir, { withFileTypes: true })\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".jsonl\"))\n .filter((entry) => readV4Header(join(sessionsDir, entry.name)) !== undefined)\n .map((entry) => {\n const file = join(sessionsDir, entry.name);\n const v4 = readV4Session(file);\n const collected = collectEntries(v4);\n const { key, root } = sessionKeyFor(conversationId, entry.name, current);\n return {\n file,\n expectedMessages: collected.messageCount,\n session: {\n key: key ?? earlierSessionKey(v4.header.id),\n id: v4.header.id,\n createdAt: v4.header.createdAt,\n root,\n name: v4.name,\n entries: collected.entries,\n },\n };\n });\n}\n\nasync function verifyImport(temp: string, planned: readonly PlannedSession[]): Promise<void> {\n const contexts = await readImportedContexts(temp);\n for (const { file, session, expectedMessages } of planned) {\n const imported = contexts.get(session.key)?.length ?? 0;\n if (imported < expectedMessages) {\n throw new Error(\n `Imported context of ${file} has ${imported} messages; expected at least ${expectedMessages}`,\n );\n }\n }\n}\n\nfunction hasV4Sessions(sessionsDir: string): boolean {\n if (!existsSync(sessionsDir)) return false;\n return readdirSync(sessionsDir, { withFileTypes: true }).some(\n (entry) =>\n entry.isFile() &&\n entry.name.endsWith(\".jsonl\") &&\n readV4Header(join(sessionsDir, entry.name)) !== undefined,\n );\n}\n\nasync function migrateOffice(\n conversationId: string,\n officeDir: string,\n context: MigrationContext,\n): Promise<void> {\n const sessionsDir = join(officeDir, V4_SESSIONS_DIR);\n const archive = join(officeDir, ARCHIVE_DIR);\n const storage = join(officeDir, STORAGE_FILENAME);\n const temp = `${storage}${TEMP_SUFFIX}`;\n if (!existsSync(sessionsDir) && existsSync(temp) && existsSync(archive)) {\n context.report(` finish ${storage}`);\n if (!context.dryRun) renameSync(temp, storage);\n return;\n }\n if (!hasV4Sessions(sessionsDir)) return;\n if (existsSync(storage)) throw new Error(`Session storage already exists: ${storage}`);\n if (existsSync(archive)) throw new Error(`Archived v4 sessions already exist: ${archive}`);\n const planned = planOfficeImport(conversationId, sessionsDir);\n context.report(` ${planned.length} sessions -> ${storage}`);\n if (context.dryRun) return;\n rmSync(temp, { force: true });\n try {\n await importOfficeSessions(\n temp,\n planned.map((plan) => plan.session),\n );\n await verifyImport(temp, planned);\n } catch (error) {\n for (const file of [temp, `${temp}-wal`, `${temp}-shm`]) rmSync(file, { force: true });\n throw new Error(`Session migration failed for ${sessionsDir}`, { cause: error });\n }\n renameSync(sessionsDir, archive);\n renameSync(temp, storage);\n}\n\nfunction registeredOffices(stateDir: string): Array<{ conversationId: string; dir: string }> {\n return new OfficeRegistry(stateDir).getOffices().map((record) => ({\n conversationId: record.conversationId,\n dir: officeStateDir(stateDir, record),\n }));\n}\n\nfunction assertEveryOfficeRegistered(stateDir: string, registered: ReadonlySet<string>): void {\n const root = join(stateDir, \"conversations\");\n if (!existsSync(root)) return;\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const dir = join(root, entry.name);\n if (!registered.has(dir) && hasV4Sessions(join(dir, V4_SESSIONS_DIR))) {\n throw new Error(\n `Sessions in ${dir} belong to no office in office-registry.json; record the office before migrating`,\n );\n }\n }\n}\n\nexport const sessionsSqliteMigration: Migration = Object.freeze({\n id: \"0009-sessions-sqlite\",\n summary:\n \"import v4 session files into one pi-durable SQLite storage per office, keeping originals under sessions-v4/\",\n async run(context: MigrationContext): Promise<void> {\n const offices = registeredOffices(context.stateDir);\n assertEveryOfficeRegistered(context.stateDir, new Set(offices.map((office) => office.dir)));\n for (const office of offices) {\n await migrateOffice(office.conversationId, office.dir, context);\n }\n },\n});\n"]}
1
+ {"version":3,"file":"sessions-sqlite.js","sourceRoot":"","sources":["../../src/migrations/sessions-sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync, renameSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AssistantMessage, Message } from \"@earendil-works/pi-ai\";\nimport { OfficeRegistry, officeStateDir } from \"../office/index.js\";\nimport {\n earlierSessionKey,\n importOfficeSessions,\n readImportedContexts,\n} from \"../sessions/session-store.js\";\nimport { makeThreadSessionKey } from \"../sessions/session-key.js\";\nimport type { ImportedSession, ImportedSessionEntry } from \"../sessions/types.js\";\nimport { readTextFileIfExists } from \"../file-guards.js\";\nimport {\n epochMillis,\n isV3SessionFile,\n pathTo,\n readV3Session,\n type V3Entry,\n type V3Session,\n} from \"./session-v3.js\";\nimport type { Migration, MigrationContext } from \"./types.js\";\n\nconst SESSIONS_DIR = \"sessions\";\nconst ARCHIVE_DIR = \"sessions-v3\";\nconst STORAGE_FILENAME = \"sessions.db\";\nconst TEMP_SUFFIX = \".importing\";\nconst MAIN_SESSION_FILENAME = /^\\d{4}-\\d{2}-\\d{2}T.+_[0-9a-f]{8}\\.jsonl$/i;\nconst INTERRUPTED_RESULT =\n \"This tool call was interrupted by the upgrade to Pi 1.0; its outcome is unknown.\";\nconst BRANCH_SUMMARY_PREFIX =\n \"The following is a summary of a branch that this conversation came back from:\\n\\n<summary>\\n\";\nconst BRANCH_SUMMARY_SUFFIX = \"</summary>\";\nconst LEGACY_SETTING_TYPES: ReadonlySet<string> = new Set([\n \"thinking_level_change\",\n \"model_change\",\n]);\n\nfunction isModelMessage(value: { role: unknown }): value is Message {\n return value.role === \"user\" || value.role === \"assistant\" || value.role === \"toolResult\";\n}\n\nfunction isContextMessage(message: Message): boolean {\n return (\n message.role !== \"assistant\" ||\n (message.stopReason !== \"error\" &&\n message.stopReason !== \"aborted\" &&\n message.stopReason !== \"deferred\")\n );\n}\n\nfunction userMessage(content: Extract<Message, { role: \"user\" }>[\"content\"], timestamp: number) {\n return {\n role: \"user\" as const,\n content: typeof content === \"string\" ? [{ type: \"text\" as const, text: content }] : content,\n timestamp,\n };\n}\n\nfunction messageOf(entry: V3Entry): Message | undefined {\n const timestamp = epochMillis(entry.timestamp);\n switch (entry.type) {\n case \"message\":\n return isModelMessage(entry.message) ? entry.message : undefined;\n case \"custom_message\":\n return userMessage(entry.content, timestamp);\n case \"branch_summary\":\n return entry.summary\n ? userMessage(BRANCH_SUMMARY_PREFIX + entry.summary + BRANCH_SUMMARY_SUFFIX, timestamp)\n : undefined;\n default:\n return undefined;\n }\n}\n\nclass EntryCollector {\n readonly entries: ImportedSessionEntry[] = [];\n private readonly openCalls = new Map<string, { name: string; timestamp: number }>();\n\n get messageCount(): number {\n return this.entries.filter((entry) => entry.type !== \"custom\").length;\n }\n\n message(message: Message): void {\n if (!isContextMessage(message)) return;\n if (message.role === \"toolResult\") {\n if (!this.openCalls.delete(message.toolCallId)) return;\n } else {\n this.closeOpenCalls();\n }\n this.entries.push({ type: \"message\", message });\n if (message.role === \"assistant\") this.trackCalls(message);\n }\n\n compaction(summary: string, timestamp: number): void {\n this.closeOpenCalls();\n this.entries.push({ type: \"compaction\", summary, timestamp });\n }\n\n custom(customType: string, data: unknown, timestamp: number): void {\n this.entries.push({ type: \"custom\", customType, data, timestamp });\n }\n\n closeOpenCalls(): void {\n for (const [toolCallId, call] of this.openCalls) {\n this.entries.push({\n type: \"message\",\n message: {\n role: \"toolResult\",\n toolCallId,\n toolName: call.name,\n content: [{ type: \"text\", text: INTERRUPTED_RESULT }],\n isError: true,\n timestamp: call.timestamp,\n },\n });\n }\n this.openCalls.clear();\n }\n\n private trackCalls(message: AssistantMessage): void {\n for (const part of message.content) {\n if (part.type === \"toolCall\") {\n this.openCalls.set(part.id, { name: part.name, timestamp: message.timestamp });\n }\n }\n }\n}\n\nfunction keptMessages(session: V3Session, entry: Extract<V3Entry, { type: \"compaction\" }>) {\n const ancestors = pathTo(session.entriesById, entry.parentId);\n const kept = ancestors.findIndex((ancestor) => ancestor.id === entry.firstKeptEntryId);\n if (kept === -1) return [];\n return ancestors\n .slice(kept)\n .filter((ancestor) => ancestor.type === \"message\" || ancestor.type === \"custom_message\");\n}\n\nfunction collectEntries(session: V3Session): EntryCollector {\n const collector = new EntryCollector();\n const visibleStart = session.branch.findLastIndex((entry) => entry.type === \"compaction\");\n for (const [index, entry] of session.branch.entries()) {\n const timestamp = epochMillis(entry.timestamp);\n if (entry.type === \"custom\") {\n collector.custom(entry.customType, entry.data, timestamp);\n continue;\n }\n if (LEGACY_SETTING_TYPES.has(entry.type)) {\n const { id: _id, parentId: _parentId, timestamp: _timestamp, type, ...data } = entry;\n collector.custom(`mikan.legacy.${type}`, data, timestamp);\n continue;\n }\n if (index < visibleStart) continue;\n if (entry.type === \"compaction\") {\n collector.compaction(entry.summary, timestamp);\n for (const kept of keptMessages(session, entry)) {\n const message = messageOf(kept);\n if (message) collector.message(message);\n }\n continue;\n }\n const message = messageOf(entry);\n if (message) collector.message(message);\n }\n collector.closeOpenCalls();\n return collector;\n}\n\ninterface PlannedSession {\n file: string;\n session: ImportedSession;\n expectedMessages: number;\n}\n\nfunction sessionKeyFor(conversationId: string, fileName: string, current: string | undefined) {\n if (fileName === current) return { key: conversationId, root: true };\n if (MAIN_SESSION_FILENAME.test(fileName)) return { key: undefined, root: false };\n return {\n key: makeThreadSessionKey(conversationId, fileName.slice(0, -\".jsonl\".length)),\n root: false,\n };\n}\n\nfunction planOfficeImport(conversationId: string, sessionsDir: string): PlannedSession[] {\n const current = readTextFileIfExists(join(sessionsDir, \"current\"))?.trim() || undefined;\n return readdirSync(sessionsDir, { withFileTypes: true })\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".jsonl\"))\n .filter((entry) => isV3SessionFile(join(sessionsDir, entry.name)))\n .map((entry) => {\n const file = join(sessionsDir, entry.name);\n const v3 = readV3Session(file);\n const collected = collectEntries(v3);\n const { key, root } = sessionKeyFor(conversationId, entry.name, current);\n return {\n file,\n expectedMessages: collected.messageCount,\n session: {\n key: key ?? earlierSessionKey(v3.id),\n id: v3.id,\n createdAt: v3.createdAt,\n root,\n name: v3.name,\n entries: collected.entries,\n },\n };\n });\n}\n\nasync function verifyImport(temp: string, planned: readonly PlannedSession[]): Promise<void> {\n const contexts = await readImportedContexts(temp);\n for (const { file, session, expectedMessages } of planned) {\n const imported = contexts.get(session.key)?.length ?? 0;\n if (imported < expectedMessages) {\n throw new Error(\n `Imported context of ${file} has ${imported} messages; expected at least ${expectedMessages}`,\n );\n }\n }\n}\n\nfunction hasV3Sessions(sessionsDir: string): boolean {\n if (!existsSync(sessionsDir)) return false;\n return readdirSync(sessionsDir, { withFileTypes: true }).some(\n (entry) =>\n entry.isFile() &&\n entry.name.endsWith(\".jsonl\") &&\n isV3SessionFile(join(sessionsDir, entry.name)),\n );\n}\n\nasync function migrateOffice(\n conversationId: string,\n officeDir: string,\n context: MigrationContext,\n): Promise<void> {\n const sessionsDir = join(officeDir, SESSIONS_DIR);\n const archive = join(officeDir, ARCHIVE_DIR);\n const storage = join(officeDir, STORAGE_FILENAME);\n const temp = `${storage}${TEMP_SUFFIX}`;\n if (!existsSync(sessionsDir) && existsSync(temp) && existsSync(archive)) {\n context.report(` finish ${storage}`);\n if (!context.dryRun) renameSync(temp, storage);\n return;\n }\n if (!hasV3Sessions(sessionsDir)) return;\n if (existsSync(storage)) throw new Error(`Session storage already exists: ${storage}`);\n if (existsSync(archive)) throw new Error(`Archived session files already exist: ${archive}`);\n const planned = planOfficeImport(conversationId, sessionsDir);\n context.report(` ${planned.length} sessions -> ${storage}`);\n if (context.dryRun) return;\n rmSync(temp, { force: true });\n try {\n await importOfficeSessions(\n temp,\n planned.map((plan) => plan.session),\n );\n await verifyImport(temp, planned);\n } catch (error) {\n for (const file of [temp, `${temp}-wal`, `${temp}-shm`]) rmSync(file, { force: true });\n throw new Error(`Session migration failed for ${sessionsDir}`, { cause: error });\n }\n renameSync(sessionsDir, archive);\n renameSync(temp, storage);\n}\n\nfunction registeredOffices(stateDir: string): Array<{ conversationId: string; dir: string }> {\n return new OfficeRegistry(stateDir).getOffices().map((record) => ({\n conversationId: record.conversationId,\n dir: officeStateDir(stateDir, record),\n }));\n}\n\nfunction assertEveryOfficeRegistered(stateDir: string, registered: ReadonlySet<string>): void {\n const root = join(stateDir, \"conversations\");\n if (!existsSync(root)) return;\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const dir = join(root, entry.name);\n if (!registered.has(dir) && hasV3Sessions(join(dir, SESSIONS_DIR))) {\n throw new Error(\n `Sessions in ${dir} belong to no office in office-registry.json; record the office before migrating`,\n );\n }\n }\n}\n\nexport const sessionsSqliteMigration: Migration = Object.freeze({\n id: \"0009-sessions-sqlite\",\n summary:\n \"import 0.5.3 session files into one pi-durable SQLite storage per office, keeping originals under sessions-v3/\",\n async run(context: MigrationContext): Promise<void> {\n const offices = registeredOffices(context.stateDir);\n assertEveryOfficeRegistered(context.stateDir, new Set(offices.map((office) => office.dir)));\n for (const office of offices) {\n await migrateOffice(office.conversationId, office.dir, context);\n }\n },\n});\n"]}
@@ -1,11 +1,9 @@
1
1
  import * as Sentry from "@sentry/node";
2
2
  import { resolveStateDir } from "../cli/arg-grammar.js";
3
3
  import { resolveSentryDsn } from "../settings/index.js";
4
- import { setEnvAliases } from "../env-manifest.js";
5
4
  import { initializeOpenTelemetry, resolveOpenTelemetryConfiguration } from "./otel.js";
6
5
  import { createSentryInitOptions } from "./sentry.js";
7
- setEnvAliases("STATE_DIR", resolveStateDir());
8
- const sentryDsn = resolveSentryDsn();
6
+ const sentryDsn = resolveSentryDsn(resolveStateDir());
9
7
  const otel = resolveOpenTelemetryConfiguration();
10
8
  const customOpenTelemetry = otel.traces;
11
9
  Sentry.init(createSentryInitOptions(sentryDsn, customOpenTelemetry));
@@ -1 +1 @@
1
- {"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../src/observability/instrument.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,iCAAiC,EAAE,MAAM,WAAW,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,aAAa,CAAC,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC;AAC9C,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;AACrC,MAAM,IAAI,GAAG,iCAAiC,EAAE,CAAC;AACjD,MAAM,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC;AACxC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC;AACrE,uBAAuB,EAAE,CAAC","sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport { resolveStateDir } from \"../cli/arg-grammar.js\";\nimport { resolveSentryDsn } from \"../settings/index.js\";\nimport { setEnvAliases } from \"../env-manifest.js\";\nimport { initializeOpenTelemetry, resolveOpenTelemetryConfiguration } from \"./otel.js\";\nimport { createSentryInitOptions } from \"./sentry.js\";\n\nsetEnvAliases(\"STATE_DIR\", resolveStateDir());\nconst sentryDsn = resolveSentryDsn();\nconst otel = resolveOpenTelemetryConfiguration();\nconst customOpenTelemetry = otel.traces;\nSentry.init(createSentryInitOptions(sentryDsn, customOpenTelemetry));\ninitializeOpenTelemetry();\n"]}
1
+ {"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../src/observability/instrument.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,iCAAiC,EAAE,MAAM,WAAW,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,SAAS,GAAG,gBAAgB,CAAC,eAAe,EAAE,CAAC,CAAC;AACtD,MAAM,IAAI,GAAG,iCAAiC,EAAE,CAAC;AACjD,MAAM,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC;AACxC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC;AACrE,uBAAuB,EAAE,CAAC","sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport { resolveStateDir } from \"../cli/arg-grammar.js\";\nimport { resolveSentryDsn } from \"../settings/index.js\";\nimport { initializeOpenTelemetry, resolveOpenTelemetryConfiguration } from \"./otel.js\";\nimport { createSentryInitOptions } from \"./sentry.js\";\n\nconst sentryDsn = resolveSentryDsn(resolveStateDir());\nconst otel = resolveOpenTelemetryConfiguration();\nconst customOpenTelemetry = otel.traces;\nSentry.init(createSentryInitOptions(sentryDsn, customOpenTelemetry));\ninitializeOpenTelemetry();\n"]}
@@ -1,5 +1,5 @@
1
1
  import { createRunner } from "../harness/runner.js";
2
- import { MikanModels } from "../harness/models.js";
2
+ import { defaultModelsJsonPath, MikanModels } from "../harness/models.js";
3
3
  import { isCommandText } from "../adapters/commands/manifest.js";
4
4
  import { defaultCommandHandlers, dispatchCommand } from "../adapters/commands/registry.js";
5
5
  import { isPrivateConversation } from "../adapters/commands/utils.js";
@@ -50,7 +50,9 @@ class ConversationRuntimeImpl {
50
50
  this.sessions = new SessionLifecycle();
51
51
  this.chatSessionManager = new ChatHistorySync({ isCommandText });
52
52
  this.isShuttingDown = false;
53
- this.resolvedModels = options.models ?? MikanModels.create();
53
+ this.resolvedModels =
54
+ options.models ??
55
+ MikanModels.create({ modelsJsonPath: defaultModelsJsonPath(options.workspace.stateDir) });
54
56
  this.memoryCapture = options.memoryCapture?.(this.resolvedModels);
55
57
  this.commandServices = {
56
58
  ...options,
@@ -346,11 +348,11 @@ class ConversationRuntimeImpl {
346
348
  }
347
349
  });
348
350
  }
349
- switchConversationModel(address, _provider, _model) {
350
- return this.invalidateOffice(address, "Model switched");
351
- }
352
- refreshConversationEnvironment(address) {
353
- return this.invalidateOffice(address, "Environment refreshed");
351
+ refreshConversation(address) {
352
+ const cleared = this.sessions.invalidateConversation(address);
353
+ if (cleared)
354
+ log.logInfo(`[${address.conversationId}] Cleared cached session runners`);
355
+ return cleared;
354
356
  }
355
357
  refreshAllConversations() {
356
358
  const offices = this.sessions.offices();
@@ -363,13 +365,6 @@ class ConversationRuntimeImpl {
363
365
  }
364
366
  return result;
365
367
  }
366
- invalidateOffice(address, reason) {
367
- const cleared = this.sessions.invalidateConversation(address);
368
- if (cleared) {
369
- log.logInfo(`[${address.conversationId}] ${reason}; cleared cached session runners`);
370
- }
371
- return cleared;
372
- }
373
368
  async createCurrentRunner(options, sessionScope, signal) {
374
369
  const runnerFactory = this.options.runnerFactory ?? createRunner;
375
370
  return runnerFactory({
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-runtime.js","sourceRoot":"","sources":["../../src/runtime/conversation-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n MessagingBot,\n ConversationContext,\n ConversationMessage,\n ConversationEvent,\n HandleNewCommandOptions,\n OfficeAddress,\n PlatformName,\n RunningSession,\n} from \"../types.js\";\nimport type { Office } from \"../office/types.js\";\nimport { createRunner } from \"../harness/runner.js\";\nimport type { PiAgentWrapper } from \"../types.js\";\nimport type { RunMemoryCapture } from \"../memory-capture/types.js\";\nimport { MikanModels } from \"../harness/models.js\";\nimport { isCommandText } from \"../adapters/commands/manifest.js\";\nimport { defaultCommandHandlers, dispatchCommand } from \"../adapters/commands/registry.js\";\nimport type { CommandHandler, CommandServices } from \"../adapters/commands/types.js\";\nimport { isPrivateConversation } from \"../adapters/commands/utils.js\";\nimport * as log from \"../log.js\";\nimport {\n addLifecycleEvent,\n createRunAttributionAttributes,\n recordCounter,\n recordDistribution,\n recordGauge,\n reportUserFacingError,\n withRunSpan,\n} from \"../observability/index.js\";\nimport {\n ChatHistorySync,\n hasMaterializedChatSession,\n waitForThreadSessionBootstrap,\n} from \"../sessions/chat-history-sync.js\";\nimport {\n assertSessionKeyBelongsToConversation,\n deriveSessionKey,\n threadSuffixOf,\n} from \"../sessions/session-key.js\";\nimport {\n formatNothingRunning,\n formatRestarting,\n formatStopped,\n formatStopping,\n} from \"../adapters/messages.js\";\nimport { disabledVaultManager } from \"../vault/index.js\";\nimport type { ConversationRuntimeState } from \"./types.js\";\nimport { SessionLifecycle } from \"./session-lifecycle.js\";\n\ntype ConversationState = ConversationRuntimeState;\n\nimport type {\n RunSessionOptions,\n ConversationRuntime,\n ConversationRuntimeOptions,\n SessionStateOptions,\n} from \"./types.js\";\nimport { errorMessage } from \"../unknown-values.js\";\n\ntype RunResult = Awaited<ReturnType<PiAgentWrapper[\"run\"]>>;\n\nfunction portalNotConfiguredTokenStore(portal: string): { create: () => never } {\n return {\n create: () => {\n throw new Error(`${portal} portal not configured`);\n },\n };\n}\n\nfunction requestStop(state: ConversationRuntimeState): void {\n state.stopRequested = true;\n state.runner.abort();\n}\n\nasync function postAbortNotice(\n state: ConversationRuntimeState,\n bot: MessagingBot,\n conversationId: string,\n platformName: string,\n): Promise<void> {\n if (state.shutdownAborted) {\n recordCounter(\"agent.run.shutdown_aborted\", 1, { platform: platformName });\n const text = formatRestarting(bot);\n const ts = await bot.postMessage(conversationId, text);\n bot.logBotResponse?.(conversationId, text, ts);\n return;\n }\n if (!state.stopRequested) return;\n if (state.stopNoticeOwned) return;\n const thread = threadSuffixOf(state.sessionKey) ?? undefined;\n const text = formatStopped(bot);\n const ts =\n thread && bot.postInThread\n ? await bot.postInThread(conversationId, thread, text)\n : await bot.postMessage(conversationId, text);\n bot.logBotResponse?.(conversationId, text, ts, thread);\n}\n\nexport function createConversationRuntime(\n options: ConversationRuntimeOptions,\n): ConversationRuntime {\n return new ConversationRuntimeImpl(options);\n}\n\nclass ConversationRuntimeImpl implements ConversationRuntime {\n private readonly sessions = new SessionLifecycle();\n private readonly chatSessionManager = new ChatHistorySync({ isCommandText });\n private readonly commandServices: CommandServices;\n private readonly commandHandlers: readonly CommandHandler[];\n private readonly resolvedModels: MikanModels;\n private readonly memoryCapture: RunMemoryCapture | undefined;\n private isShuttingDown = false;\n\n constructor(private readonly options: ConversationRuntimeOptions) {\n this.resolvedModels = options.models ?? MikanModels.create();\n this.memoryCapture = options.memoryCapture?.(this.resolvedModels);\n this.commandServices = {\n ...options,\n resourceController: options.resourceController ?? options.provisioner,\n vaultManager: options.vaultManager ?? disabledVaultManager,\n linkTokenStore: options.linkTokenStore ?? portalNotConfiguredTokenStore(\"Login\"),\n sessionViewTokenStore:\n options.sessionViewTokenStore ?? portalNotConfiguredTokenStore(\"Session viewer\"),\n adminTokenStore: options.adminTokenStore ?? portalNotConfiguredTokenStore(\"Admin\"),\n runtime: this,\n };\n this.commandHandlers = options.commandHandlers ?? defaultCommandHandlers(this.resolvedModels);\n }\n\n isRunning(address: OfficeAddress, sessionKey: string): boolean {\n return this.sessions.get(address, sessionKey)?.running === true;\n }\n\n getRunningSessions(): RunningSession[] {\n const sessions: RunningSession[] = [];\n for (const state of this.sessions.runningStates()) {\n if (state.startedAt) {\n const currentStep = state.runner.getCurrentStep();\n sessions.push({\n address: state.address,\n sessionKey: state.sessionKey,\n startedAt: state.startedAt,\n lastActivityAt: state.lastActivityAt,\n currentTool: currentStep?.label || currentStep?.toolName,\n stopping: state.stopRequested ? true : undefined,\n });\n }\n }\n return sessions;\n }\n\n async steer(message: ConversationMessage): Promise<boolean> {\n const state = this.sessions.get(message.address, message.sessionKey);\n if (!state?.running) return false;\n return state.runner.steer ? state.runner.steer(message) : false;\n }\n\n async handleStop(\n address: OfficeAddress,\n sessionKey: string,\n bot: MessagingBot,\n replyThreadTs?: string,\n ): Promise<void> {\n assertSessionKeyBelongsToConversation(sessionKey, address.conversationId);\n const post = async (text: string) => {\n const ts =\n replyThreadTs && bot.postInThread\n ? await bot.postInThread(address.conversationId, replyThreadTs, text)\n : await bot.postMessage(address.conversationId, text);\n bot.logBotResponse?.(address.conversationId, text, ts, replyThreadTs);\n return ts;\n };\n const state = this.sessions.get(address, sessionKey);\n if (!state?.running) {\n await post(formatNothingRunning(bot));\n return;\n }\n const settlement = state.runSettlement;\n state.stopNoticeOwned = true;\n requestStop(state);\n try {\n const ts = await post(formatStopping(bot));\n await settlement;\n const stoppedText = formatStopped(bot);\n await bot.updateMessage(address.conversationId, ts, stoppedText);\n bot.logBotResponse?.(address.conversationId, stoppedText, ts, replyThreadTs);\n } finally {\n state.stopNoticeOwned = false;\n }\n }\n\n forceStop(address: OfficeAddress, sessionKey: string): void {\n const state = this.sessions.get(address, sessionKey);\n if (state?.running) {\n log.logInfo(`[Force Stop] Force stopping session: ${sessionKey}`);\n requestStop(state);\n }\n }\n\n async handleNewCommand({ bot, message }: HandleNewCommandOptions): Promise<void> {\n const { address, sessionKey } = message;\n assertSessionKeyBelongsToConversation(sessionKey, address.conversationId);\n\n const activeState = this.sessions.get(address, sessionKey);\n if (activeState?.runSettlement) {\n if (activeState.running) requestStop(activeState);\n await activeState.runSettlement;\n }\n\n await this.sessions.runConversationMaintenance(address, async () => {\n await this.resetSession(address, sessionKey, bot);\n });\n }\n\n private async resetSession(\n address: OfficeAddress,\n sessionKey: string,\n bot: MessagingBot,\n ): Promise<void> {\n const conversationId = address.conversationId;\n const office = this.options.workspace.office(address);\n await this.sessions.discardAndWait(address, sessionKey);\n await this.chatSessionManager.resetSession({ office, sessionKey });\n\n log.logInfo(`[${conversationId}] Session reset: ${sessionKey}`);\n await bot.postMessage(conversationId, \"Conversation reset. Send a new message to start fresh.\");\n }\n\n async handleEvent(\n event: ConversationEvent,\n bot: MessagingBot,\n context: ConversationContext,\n ): Promise<void> {\n const sessionKey = deriveSessionKey(event);\n await this.sessions.enqueue(event.address, sessionKey, () =>\n this.runSession({ event, bot, context }),\n );\n }\n\n async runSession(options: RunSessionOptions): Promise<void> {\n const { event } = options;\n const conversationId = event.address.conversationId;\n if (this.isShuttingDown) {\n log.logInfo(\n `[${conversationId}] Rejected event during shutdown: ${event.text.substring(0, 50)}`,\n );\n return;\n }\n\n const sessionKey = deriveSessionKey(event);\n if (await this.handledBeforeRun(options, sessionKey)) return;\n\n const address = event.address;\n const releaseConversationWork = await this.sessions.acquireConversationWork(address);\n try {\n await this.waitForParentSession(address, sessionKey);\n\n const lease = await this.acquireRunLease(options, sessionKey);\n const { state } = lease;\n log.logInfo(`[${conversationId}] Starting run: ${event.text.substring(0, 50)}`);\n const runPromise = this.sessions.settle(state, () =>\n this.executeRun(options, sessionKey, state),\n );\n lease.release();\n recordGauge(\"agent.sessions.active\", this.sessions.settlementCount());\n await runPromise;\n } finally {\n releaseConversationWork();\n }\n }\n\n private async handledBeforeRun(options: RunSessionOptions, sessionKey: string): Promise<boolean> {\n const { event } = options;\n if (await this.dispatchSessionCommand(options, sessionKey)) return true;\n\n const activeSettlement = this.sessions.get(event.address, sessionKey)?.runSettlement;\n if (activeSettlement) await activeSettlement;\n return false;\n }\n\n private async acquireRunLease(\n { event, context }: RunSessionOptions,\n sessionKey: string,\n ): Promise<{ state: ConversationState; release: () => void }> {\n let lease: { state: ConversationState; release: () => void } | undefined;\n try {\n lease = await this.acquireState({\n address: event.address,\n sessionKey,\n currentMessageId: event.ts,\n trustModel: context.platform.trustModel ?? \"membership\",\n platformWorkspaceId: context.platform.workspaceId,\n });\n await lease.state.runner.syncChatHistory(event.ts);\n return lease;\n } catch (err) {\n lease?.release();\n reportUserFacingError(err, {\n domain: \"mikan\",\n surface: \"session_setup\",\n operation: \"get_or_create_state\",\n severity: \"error\",\n platform: context.platform.name,\n context: {\n conversationId: event.address.conversationId,\n sessionKey,\n messageId: context.message.id,\n threadTs: context.message.threadTs,\n attachmentCount: context.message.attachments?.length ?? 0,\n },\n });\n throw err;\n }\n }\n\n private async executeRun(\n { event, bot, context }: RunSessionOptions,\n sessionKey: string,\n state: ConversationState,\n ): Promise<void> {\n const conversationId = event.address.conversationId;\n try {\n const result = await this.runWithInstrumentation(\n context,\n { conversationId, sessionKey, startedAt: state.startedAt },\n async () => {\n await context.responder.setTyping(true);\n await context.responder.setWorking(true);\n try {\n return await state.runner.run(context.message, context.responder, context.platform);\n } finally {\n await context.responder.setWorking(false);\n }\n },\n );\n\n if (result?.stopReason === \"aborted\") {\n await postAbortNotice(state, bot, conversationId, context.platform.name);\n }\n if (result) {\n this.memoryCapture?.capture({\n office: this.options.workspace.office(event.address),\n message: context.message,\n stopReason: result.stopReason,\n reply: result.finalText ?? \"\",\n });\n }\n } finally {\n recordGauge(\"agent.sessions.active\", this.sessions.settlementCount() - 1);\n }\n }\n\n private async waitForParentSession(address: OfficeAddress, sessionKey: string): Promise<void> {\n const conversationId = address.conversationId;\n const office = this.options.workspace.office(address);\n const waited = await waitForThreadSessionBootstrap({\n parentSessionKey: conversationId,\n sessionKey,\n hasThreadSession: () => hasMaterializedChatSession({ office, sessionKey }),\n isParentRunning: () => this.sessions.get(address, conversationId)?.running === true,\n });\n if (waited) {\n log.logInfo(\n `[${conversationId}] Delayed thread bootstrap until parent session sealed: ${sessionKey}`,\n );\n }\n }\n\n private async dispatchSessionCommand(\n { event, bot, context }: RunSessionOptions,\n sessionKey: string,\n ): Promise<boolean> {\n return dispatchCommand(this.commandHandlers, {\n bot,\n responder: context.responder,\n platform: context.platform.name as PlatformName,\n address: event.address,\n platformUserId: event.user,\n platformUserName: context.message.userName,\n conversationId: event.address.conversationId,\n vaultConversationId: event.vaultConversationId,\n sessionKey,\n commandText: event.text,\n privateConversation: isPrivateConversation(event),\n services: this.commandServices,\n });\n }\n\n private async runWithInstrumentation(\n context: ConversationContext,\n meta: {\n conversationId: string;\n sessionKey: string;\n startedAt: number;\n },\n body: () => Promise<RunResult>,\n ): Promise<RunResult | undefined> {\n const { conversationId, sessionKey, startedAt } = meta;\n const { message, platform } = context;\n\n const attribution = createRunAttributionAttributes({\n conversationId,\n sessionKey,\n messageId: message.id,\n platform: platform.name,\n conversationKind: message.conversationKind,\n userId: message.userId,\n threadTs: message.threadTs,\n });\n\n recordCounter(\"agent.run.started\", 1, attribution);\n\n return withRunSpan(\n {\n conversationId,\n sessionKey,\n messageId: message.id,\n platform: platform.name,\n conversationKind: message.conversationKind,\n userId: message.userId,\n threadTs: message.threadTs,\n },\n async () => {\n addLifecycleEvent(\"agent.run.started\", {\n channel_id: attribution.channel_id,\n platform: platform.name,\n conversation_kind: message.conversationKind,\n has_attachments: (message.attachments?.length ?? 0) > 0,\n });\n\n try {\n const result = await body();\n const durationMs = Date.now() - startedAt;\n const completionAttrs = {\n ...attribution,\n stop_reason: result.stopReason,\n };\n recordDistribution(\"agent.run.duration\", durationMs, {\n unit: \"millisecond\",\n attributes: completionAttrs,\n });\n recordCounter(\"agent.run.completed\", 1, completionAttrs);\n addLifecycleEvent(\"agent.run.completed\", {\n channel_id: attribution.channel_id,\n platform: platform.name,\n stop_reason: result.stopReason,\n duration_ms: durationMs,\n });\n return result;\n } catch (err) {\n reportUserFacingError(err, {\n domain: \"mikan\",\n surface: \"agent_run\",\n operation: \"run\",\n severity: \"error\",\n platform: platform.name,\n context: {\n conversationId,\n sessionKey,\n messageId: message.id,\n threadTs: message.threadTs,\n attachmentCount: message.attachments?.length ?? 0,\n },\n });\n recordCounter(\"agent.run.errors\", 1, attribution);\n log.logWarning(`[${conversationId}] Run error`, errorMessage(err));\n await context.responder\n .replaceResponse(\"Could not complete the request. Please reply to retry or revise it.\")\n .catch(() => {});\n return undefined;\n }\n },\n );\n }\n\n switchConversationModel(address: OfficeAddress, _provider: string, _model: string): boolean {\n return this.invalidateOffice(address, \"Model switched\");\n }\n\n refreshConversationEnvironment(address: OfficeAddress): boolean {\n return this.invalidateOffice(address, \"Environment refreshed\");\n }\n\n refreshAllConversations(): { busy: OfficeAddress[] } {\n const offices = this.sessions.offices();\n const result = this.sessions.invalidateAll();\n const busyKeys = new Set(\n result.busy.map((address) => `${address.platform}:${address.conversationId}`),\n );\n for (const address of offices) {\n if (busyKeys.has(`${address.platform}:${address.conversationId}`)) continue;\n log.logInfo(\n `[${address.conversationId}] Global settings changed; cleared cached session runners`,\n );\n }\n return result;\n }\n\n private invalidateOffice(address: OfficeAddress, reason: string): boolean {\n const cleared = this.sessions.invalidateConversation(address);\n if (cleared) {\n log.logInfo(`[${address.conversationId}] ${reason}; cleared cached session runners`);\n }\n return cleared;\n }\n\n private async createCurrentRunner(\n options: SessionStateOptions,\n sessionScope: Awaited<ReturnType<ChatHistorySync[\"resolveSessionScope\"]>>,\n signal: AbortSignal,\n ): Promise<PiAgentWrapper> {\n const runnerFactory = this.options.runnerFactory ?? createRunner;\n return runnerFactory({\n sandboxConfig: this.options.sandbox,\n sessionKey: options.sessionKey,\n office: this.options.workspace.office(options.address),\n trustModel: options.trustModel,\n platformWorkspaceId: options.platformWorkspaceId,\n openConnector: this.options.openConnector,\n eventScheduler: this.options.eventScheduler?.(),\n sessionScope,\n chatHistory: this.chatSessionManager,\n signal,\n vaultManager: this.options.vaultManager,\n provisioner: this.options.provisioner,\n resourceController: this.options.resourceController,\n sessionView: this.options.sessionViewTokenStore\n ? {\n tokenStore: this.options.sessionViewTokenStore,\n portalBaseUrl: this.options.portalBaseUrl,\n }\n : undefined,\n platformToolPackFactories: this.options.platformToolPackFactories,\n models: this.resolvedModels,\n runEvents: this.options.runEvents,\n });\n }\n\n private acquireState(options: SessionStateOptions & { currentMessageId?: string }) {\n const { address, sessionKey } = options;\n const office = this.options.workspace.office(address);\n return this.sessions.acquire(address, sessionKey, (signal) =>\n this.materializeState(options, office, signal),\n );\n }\n\n private async materializeState(\n options: SessionStateOptions & { currentMessageId?: string },\n office: Office,\n signal: AbortSignal,\n ): Promise<ConversationState> {\n signal.throwIfAborted();\n const { address, sessionKey, currentMessageId } = options;\n const sessionScope = await this.chatSessionManager.resolveSessionScope({\n office,\n sessionKey,\n currentMessageId,\n });\n signal.throwIfAborted();\n return {\n address,\n sessionKey,\n running: false,\n runner: await this.createCurrentRunner(options, sessionScope, signal),\n stopRequested: false,\n lastAccessedAt: Date.now(),\n startedAt: 0,\n };\n }\n\n async shutdown(timeoutMs = 30_000): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n log.logInfo(\"Shutting down gracefully...\");\n await this.sessions.shutdown(timeoutMs);\n }\n}\n"]}
1
+ {"version":3,"file":"conversation-runtime.js","sourceRoot":"","sources":["../../src/runtime/conversation-runtime.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAE3F,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,8BAA8B,EAC9B,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,WAAW,GACZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,eAAe,EACf,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,qCAAqC,EACrC,gBAAgB,EAChB,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAU1D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIpD,SAAS,6BAA6B,CAAC,MAAc;IACnD,OAAO;QACL,MAAM,EAAE,GAAG,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,wBAAwB,CAAC,CAAC;QACrD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,KAA+B;IAClD,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,KAA+B,EAC/B,GAAiB,EACjB,cAAsB,EACtB,YAAoB;IAEpB,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,aAAa,CAAC,4BAA4B,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACvD,GAAG,CAAC,cAAc,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,OAAO;IACjC,IAAI,KAAK,CAAC,eAAe;QAAE,OAAO;IAClC,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC;IAC7D,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,EAAE,GACN,MAAM,IAAI,GAAG,CAAC,YAAY;QACxB,CAAC,CAAC,MAAM,GAAG,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC;QACtD,CAAC,CAAC,MAAM,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAClD,GAAG,CAAC,cAAc,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,OAAmC;IAEnC,OAAO,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,uBAAuB;IAS3B,YAA6B,OAAmC;QAAnC,YAAO,GAAP,OAAO,CAA4B;QAR/C,aAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAClC,uBAAkB,GAAG,IAAI,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;QAKrE,mBAAc,GAAG,KAAK,CAAC;QAG7B,IAAI,CAAC,cAAc;YACjB,OAAO,CAAC,MAAM;gBACd,WAAW,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,qBAAqB,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC5F,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,CAAC,eAAe,GAAG;YACrB,GAAG,OAAO;YACV,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,OAAO,CAAC,WAAW;YACrE,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,oBAAoB;YAC1D,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,6BAA6B,CAAC,OAAO,CAAC;YAChF,qBAAqB,EACnB,OAAO,CAAC,qBAAqB,IAAI,6BAA6B,CAAC,gBAAgB,CAAC;YAClF,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,6BAA6B,CAAC,OAAO,CAAC;YAClF,OAAO,EAAE,IAAI;SACd,CAAC;QACF,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAChG,CAAC;IAED,SAAS,CAAC,OAAsB,EAAE,UAAkB;QAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAClE,CAAC;IAED,kBAAkB;QAChB,MAAM,QAAQ,GAAqB,EAAE,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC;YAClD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpB,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBAClD,QAAQ,CAAC,IAAI,CAAC;oBACZ,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;oBACpC,WAAW,EAAE,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,QAAQ;oBACxD,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;iBACjD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAA4B;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK,EAAE,OAAO;YAAE,OAAO,KAAK,CAAC;QAClC,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,UAAU,CACd,OAAsB,EACtB,UAAkB,EAClB,GAAiB,EACjB,aAAsB;QAEtB,qCAAqC,CAAC,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;QAC1E,MAAM,IAAI,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;YAClC,MAAM,EAAE,GACN,aAAa,IAAI,GAAG,CAAC,YAAY;gBAC/B,CAAC,CAAC,MAAM,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,EAAE,IAAI,CAAC;gBACrE,CAAC,CAAC,MAAM,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAC1D,GAAG,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;YACtE,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC;QACvC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC;QAC7B,WAAW,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3C,MAAM,UAAU,CAAC;YACjB,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;YACjE,GAAG,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,WAAW,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;QAC/E,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC;QAChC,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAAsB,EAAE,UAAkB;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,KAAK,EAAE,OAAO,EAAE,CAAC;YACnB,GAAG,CAAC,OAAO,CAAC,wCAAwC,UAAU,EAAE,CAAC,CAAC;YAClE,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,OAAO,EAA2B;QAC9D,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QACxC,qCAAqC,CAAC,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;QAE1E,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC3D,IAAI,WAAW,EAAE,aAAa,EAAE,CAAC;YAC/B,IAAI,WAAW,CAAC,OAAO;gBAAE,WAAW,CAAC,WAAW,CAAC,CAAC;YAClD,MAAM,WAAW,CAAC,aAAa,CAAC;QAClC,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,OAAsB,EACtB,UAAkB,EAClB,GAAiB;QAEjB,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACxD,MAAM,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAEnE,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,oBAAoB,UAAU,EAAE,CAAC,CAAC;QAChE,MAAM,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,wDAAwD,CAAC,CAAC;IAClG,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAwB,EACxB,GAAiB,EACjB,OAA4B;QAE5B,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,CAC1D,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CACzC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAA0B;QACzC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QAC1B,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;QACpD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,GAAG,CAAC,OAAO,CACT,IAAI,cAAc,qCAAqC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CACrF,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC;YAAE,OAAO;QAE7D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,MAAM,uBAAuB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACrF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAErD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAC9D,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;YACxB,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,mBAAmB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAChF,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,CAClD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAC5C,CAAC;YACF,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,WAAW,CAAC,uBAAuB,EAAE,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;YACtE,MAAM,UAAU,CAAC;QACnB,CAAC;gBAAS,CAAC;YACT,uBAAuB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,OAA0B,EAAE,UAAkB;QAC3E,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QAC1B,IAAI,MAAM,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QAExE,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC;QACrF,IAAI,gBAAgB;YAAE,MAAM,gBAAgB,CAAC;QAC7C,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,eAAe,CAC3B,EAAE,KAAK,EAAE,OAAO,EAAqB,EACrC,UAAkB;QAElB,IAAI,KAAoE,CAAC;QACzE,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC;gBAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,UAAU;gBACV,gBAAgB,EAAE,KAAK,CAAC,EAAE;gBAC1B,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,UAAU,IAAI,YAAY;gBACvD,mBAAmB,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW;aAClD,CAAC,CAAC;YACH,MAAM,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,EAAE,OAAO,EAAE,CAAC;YACjB,qBAAqB,CAAC,GAAG,EAAE;gBACzB,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,eAAe;gBACxB,SAAS,EAAE,qBAAqB;gBAChC,QAAQ,EAAE,OAAO;gBACjB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAC/B,OAAO,EAAE;oBACP,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc;oBAC5C,UAAU;oBACV,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC7B,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ;oBAClC,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC;iBAC1D;aACF,CAAC,CAAC;YACH,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU,CACtB,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAqB,EAC1C,UAAkB,EAClB,KAAwB;QAExB,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAC9C,OAAO,EACP,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,EAC1D,KAAK,IAAI,EAAE;gBACT,MAAM,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBACzC,IAAI,CAAC;oBACH,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACtF,CAAC;wBAAS,CAAC;oBACT,MAAM,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC,CACF,CAAC;YAEF,IAAI,MAAM,EAAE,UAAU,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC;oBAC1B,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;oBACpD,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,KAAK,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,WAAW,CAAC,uBAAuB,EAAE,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,OAAsB,EAAE,UAAkB;QAC3E,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,6BAA6B,CAAC;YACjD,gBAAgB,EAAE,cAAc;YAChC,UAAU;YACV,gBAAgB,EAAE,GAAG,EAAE,CAAC,0BAA0B,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;YAC1E,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI;SACpF,CAAC,CAAC;QACH,IAAI,MAAM,EAAE,CAAC;YACX,GAAG,CAAC,OAAO,CACT,IAAI,cAAc,2DAA2D,UAAU,EAAE,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAClC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAqB,EAC1C,UAAkB;QAElB,OAAO,eAAe,CAAC,IAAI,CAAC,eAAe,EAAE;YAC3C,GAAG;YACH,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAoB;YAC/C,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,cAAc,EAAE,KAAK,CAAC,IAAI;YAC1B,gBAAgB,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ;YAC1C,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc;YAC5C,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;YAC9C,UAAU;YACV,WAAW,EAAE,KAAK,CAAC,IAAI;YACvB,mBAAmB,EAAE,qBAAqB,CAAC,KAAK,CAAC;YACjD,QAAQ,EAAE,IAAI,CAAC,eAAe;SAC/B,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAClC,OAA4B,EAC5B,IAIC,EACD,IAA8B;QAE9B,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;QACvD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAEtC,MAAM,WAAW,GAAG,8BAA8B,CAAC;YACjD,cAAc;YACd,UAAU;YACV,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,QAAQ,EAAE,QAAQ,CAAC,IAAI;YACvB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;QAEH,aAAa,CAAC,mBAAmB,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAEnD,OAAO,WAAW,CAChB;YACE,cAAc;YACd,UAAU;YACV,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,QAAQ,EAAE,QAAQ,CAAC,IAAI;YACvB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,EACD,KAAK,IAAI,EAAE;YACT,iBAAiB,CAAC,mBAAmB,EAAE;gBACrC,UAAU,EAAE,WAAW,CAAC,UAAU;gBAClC,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBACvB,iBAAiB,EAAE,OAAO,CAAC,gBAAgB;gBAC3C,eAAe,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;gBAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAC1C,MAAM,eAAe,GAAG;oBACtB,GAAG,WAAW;oBACd,WAAW,EAAE,MAAM,CAAC,UAAU;iBAC/B,CAAC;gBACF,kBAAkB,CAAC,oBAAoB,EAAE,UAAU,EAAE;oBACnD,IAAI,EAAE,aAAa;oBACnB,UAAU,EAAE,eAAe;iBAC5B,CAAC,CAAC;gBACH,aAAa,CAAC,qBAAqB,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC;gBACzD,iBAAiB,CAAC,qBAAqB,EAAE;oBACvC,UAAU,EAAE,WAAW,CAAC,UAAU;oBAClC,QAAQ,EAAE,QAAQ,CAAC,IAAI;oBACvB,WAAW,EAAE,MAAM,CAAC,UAAU;oBAC9B,WAAW,EAAE,UAAU;iBACxB,CAAC,CAAC;gBACH,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,qBAAqB,CAAC,GAAG,EAAE;oBACzB,MAAM,EAAE,OAAO;oBACf,OAAO,EAAE,WAAW;oBACpB,SAAS,EAAE,KAAK;oBAChB,QAAQ,EAAE,OAAO;oBACjB,QAAQ,EAAE,QAAQ,CAAC,IAAI;oBACvB,OAAO,EAAE;wBACP,cAAc;wBACd,UAAU;wBACV,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,QAAQ,EAAE,OAAO,CAAC,QAAQ;wBAC1B,eAAe,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC;qBAClD;iBACF,CAAC,CAAC;gBACH,aAAa,CAAC,kBAAkB,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;gBAClD,GAAG,CAAC,UAAU,CAAC,IAAI,cAAc,aAAa,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;gBACnE,MAAM,OAAO,CAAC,SAAS;qBACpB,eAAe,CAAC,qEAAqE,CAAC;qBACtF,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACnB,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IAED,mBAAmB,CAAC,OAAsB;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,OAAO;YAAE,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,cAAc,kCAAkC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,uBAAuB;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAC9E,CAAC;QACF,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;gBAAE,SAAS;YAC5E,GAAG,CAAC,OAAO,CACT,IAAI,OAAO,CAAC,cAAc,2DAA2D,CACtF,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAC/B,OAA4B,EAC5B,YAAyE,EACzE,MAAmB;QAEnB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,YAAY,CAAC;QACjE,OAAO,aAAa,CAAC;YACnB,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YACnC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;YACtD,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;YAChD,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;YACzC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE;YAC/C,YAAY;YACZ,WAAW,EAAE,IAAI,CAAC,kBAAkB;YACpC,MAAM;YACN,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;YACvC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;YACrC,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB;YACnD,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB;gBAC7C,CAAC,CAAC;oBACE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB;oBAC9C,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;iBAC1C;gBACH,CAAC,CAAC,SAAS;YACb,yBAAyB,EAAE,IAAI,CAAC,OAAO,CAAC,yBAAyB;YACjE,MAAM,EAAE,IAAI,CAAC,cAAc;YAC3B,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;SAClC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,OAA4D;QAC/E,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAC3D,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAC/C,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,OAA4D,EAC5D,MAAc,EACd,MAAmB;QAEnB,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;QAC1D,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC;YACrE,MAAM;YACN,UAAU;YACV,gBAAgB;SACjB,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO;YACL,OAAO;YACP,UAAU;YACV,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC;YACrE,aAAa,EAAE,KAAK;YACpB,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE;YAC1B,SAAS,EAAE,CAAC;SACb,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAS,GAAG,MAAM;QAC/B,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,GAAG,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import type {\n MessagingBot,\n ConversationContext,\n ConversationMessage,\n ConversationEvent,\n HandleNewCommandOptions,\n OfficeAddress,\n PlatformName,\n RunningSession,\n} from \"../types.js\";\nimport type { Office } from \"../office/types.js\";\nimport { createRunner } from \"../harness/runner.js\";\nimport type { PiAgentWrapper } from \"../types.js\";\nimport type { RunMemoryCapture } from \"../memory-capture/types.js\";\nimport { defaultModelsJsonPath, MikanModels } from \"../harness/models.js\";\nimport { isCommandText } from \"../adapters/commands/manifest.js\";\nimport { defaultCommandHandlers, dispatchCommand } from \"../adapters/commands/registry.js\";\nimport type { CommandHandler, CommandServices } from \"../adapters/commands/types.js\";\nimport { isPrivateConversation } from \"../adapters/commands/utils.js\";\nimport * as log from \"../log.js\";\nimport {\n addLifecycleEvent,\n createRunAttributionAttributes,\n recordCounter,\n recordDistribution,\n recordGauge,\n reportUserFacingError,\n withRunSpan,\n} from \"../observability/index.js\";\nimport {\n ChatHistorySync,\n hasMaterializedChatSession,\n waitForThreadSessionBootstrap,\n} from \"../sessions/chat-history-sync.js\";\nimport {\n assertSessionKeyBelongsToConversation,\n deriveSessionKey,\n threadSuffixOf,\n} from \"../sessions/session-key.js\";\nimport {\n formatNothingRunning,\n formatRestarting,\n formatStopped,\n formatStopping,\n} from \"../adapters/messages.js\";\nimport { disabledVaultManager } from \"../vault/index.js\";\nimport type { ConversationRuntimeState } from \"./types.js\";\nimport { SessionLifecycle } from \"./session-lifecycle.js\";\n\ntype ConversationState = ConversationRuntimeState;\n\nimport type {\n RunSessionOptions,\n ConversationRuntime,\n ConversationRuntimeOptions,\n SessionStateOptions,\n} from \"./types.js\";\nimport { errorMessage } from \"../unknown-values.js\";\n\ntype RunResult = Awaited<ReturnType<PiAgentWrapper[\"run\"]>>;\n\nfunction portalNotConfiguredTokenStore(portal: string): { create: () => never } {\n return {\n create: () => {\n throw new Error(`${portal} portal not configured`);\n },\n };\n}\n\nfunction requestStop(state: ConversationRuntimeState): void {\n state.stopRequested = true;\n state.runner.abort();\n}\n\nasync function postAbortNotice(\n state: ConversationRuntimeState,\n bot: MessagingBot,\n conversationId: string,\n platformName: string,\n): Promise<void> {\n if (state.shutdownAborted) {\n recordCounter(\"agent.run.shutdown_aborted\", 1, { platform: platformName });\n const text = formatRestarting(bot);\n const ts = await bot.postMessage(conversationId, text);\n bot.logBotResponse?.(conversationId, text, ts);\n return;\n }\n if (!state.stopRequested) return;\n if (state.stopNoticeOwned) return;\n const thread = threadSuffixOf(state.sessionKey) ?? undefined;\n const text = formatStopped(bot);\n const ts =\n thread && bot.postInThread\n ? await bot.postInThread(conversationId, thread, text)\n : await bot.postMessage(conversationId, text);\n bot.logBotResponse?.(conversationId, text, ts, thread);\n}\n\nexport function createConversationRuntime(\n options: ConversationRuntimeOptions,\n): ConversationRuntime {\n return new ConversationRuntimeImpl(options);\n}\n\nclass ConversationRuntimeImpl implements ConversationRuntime {\n private readonly sessions = new SessionLifecycle();\n private readonly chatSessionManager = new ChatHistorySync({ isCommandText });\n private readonly commandServices: CommandServices;\n private readonly commandHandlers: readonly CommandHandler[];\n private readonly resolvedModels: MikanModels;\n private readonly memoryCapture: RunMemoryCapture | undefined;\n private isShuttingDown = false;\n\n constructor(private readonly options: ConversationRuntimeOptions) {\n this.resolvedModels =\n options.models ??\n MikanModels.create({ modelsJsonPath: defaultModelsJsonPath(options.workspace.stateDir) });\n this.memoryCapture = options.memoryCapture?.(this.resolvedModels);\n this.commandServices = {\n ...options,\n resourceController: options.resourceController ?? options.provisioner,\n vaultManager: options.vaultManager ?? disabledVaultManager,\n linkTokenStore: options.linkTokenStore ?? portalNotConfiguredTokenStore(\"Login\"),\n sessionViewTokenStore:\n options.sessionViewTokenStore ?? portalNotConfiguredTokenStore(\"Session viewer\"),\n adminTokenStore: options.adminTokenStore ?? portalNotConfiguredTokenStore(\"Admin\"),\n runtime: this,\n };\n this.commandHandlers = options.commandHandlers ?? defaultCommandHandlers(this.resolvedModels);\n }\n\n isRunning(address: OfficeAddress, sessionKey: string): boolean {\n return this.sessions.get(address, sessionKey)?.running === true;\n }\n\n getRunningSessions(): RunningSession[] {\n const sessions: RunningSession[] = [];\n for (const state of this.sessions.runningStates()) {\n if (state.startedAt) {\n const currentStep = state.runner.getCurrentStep();\n sessions.push({\n address: state.address,\n sessionKey: state.sessionKey,\n startedAt: state.startedAt,\n lastActivityAt: state.lastActivityAt,\n currentTool: currentStep?.label || currentStep?.toolName,\n stopping: state.stopRequested ? true : undefined,\n });\n }\n }\n return sessions;\n }\n\n async steer(message: ConversationMessage): Promise<boolean> {\n const state = this.sessions.get(message.address, message.sessionKey);\n if (!state?.running) return false;\n return state.runner.steer ? state.runner.steer(message) : false;\n }\n\n async handleStop(\n address: OfficeAddress,\n sessionKey: string,\n bot: MessagingBot,\n replyThreadTs?: string,\n ): Promise<void> {\n assertSessionKeyBelongsToConversation(sessionKey, address.conversationId);\n const post = async (text: string) => {\n const ts =\n replyThreadTs && bot.postInThread\n ? await bot.postInThread(address.conversationId, replyThreadTs, text)\n : await bot.postMessage(address.conversationId, text);\n bot.logBotResponse?.(address.conversationId, text, ts, replyThreadTs);\n return ts;\n };\n const state = this.sessions.get(address, sessionKey);\n if (!state?.running) {\n await post(formatNothingRunning(bot));\n return;\n }\n const settlement = state.runSettlement;\n state.stopNoticeOwned = true;\n requestStop(state);\n try {\n const ts = await post(formatStopping(bot));\n await settlement;\n const stoppedText = formatStopped(bot);\n await bot.updateMessage(address.conversationId, ts, stoppedText);\n bot.logBotResponse?.(address.conversationId, stoppedText, ts, replyThreadTs);\n } finally {\n state.stopNoticeOwned = false;\n }\n }\n\n forceStop(address: OfficeAddress, sessionKey: string): void {\n const state = this.sessions.get(address, sessionKey);\n if (state?.running) {\n log.logInfo(`[Force Stop] Force stopping session: ${sessionKey}`);\n requestStop(state);\n }\n }\n\n async handleNewCommand({ bot, message }: HandleNewCommandOptions): Promise<void> {\n const { address, sessionKey } = message;\n assertSessionKeyBelongsToConversation(sessionKey, address.conversationId);\n\n const activeState = this.sessions.get(address, sessionKey);\n if (activeState?.runSettlement) {\n if (activeState.running) requestStop(activeState);\n await activeState.runSettlement;\n }\n\n await this.sessions.runConversationMaintenance(address, async () => {\n await this.resetSession(address, sessionKey, bot);\n });\n }\n\n private async resetSession(\n address: OfficeAddress,\n sessionKey: string,\n bot: MessagingBot,\n ): Promise<void> {\n const conversationId = address.conversationId;\n const office = this.options.workspace.office(address);\n await this.sessions.discardAndWait(address, sessionKey);\n await this.chatSessionManager.resetSession({ office, sessionKey });\n\n log.logInfo(`[${conversationId}] Session reset: ${sessionKey}`);\n await bot.postMessage(conversationId, \"Conversation reset. Send a new message to start fresh.\");\n }\n\n async handleEvent(\n event: ConversationEvent,\n bot: MessagingBot,\n context: ConversationContext,\n ): Promise<void> {\n const sessionKey = deriveSessionKey(event);\n await this.sessions.enqueue(event.address, sessionKey, () =>\n this.runSession({ event, bot, context }),\n );\n }\n\n async runSession(options: RunSessionOptions): Promise<void> {\n const { event } = options;\n const conversationId = event.address.conversationId;\n if (this.isShuttingDown) {\n log.logInfo(\n `[${conversationId}] Rejected event during shutdown: ${event.text.substring(0, 50)}`,\n );\n return;\n }\n\n const sessionKey = deriveSessionKey(event);\n if (await this.handledBeforeRun(options, sessionKey)) return;\n\n const address = event.address;\n const releaseConversationWork = await this.sessions.acquireConversationWork(address);\n try {\n await this.waitForParentSession(address, sessionKey);\n\n const lease = await this.acquireRunLease(options, sessionKey);\n const { state } = lease;\n log.logInfo(`[${conversationId}] Starting run: ${event.text.substring(0, 50)}`);\n const runPromise = this.sessions.settle(state, () =>\n this.executeRun(options, sessionKey, state),\n );\n lease.release();\n recordGauge(\"agent.sessions.active\", this.sessions.settlementCount());\n await runPromise;\n } finally {\n releaseConversationWork();\n }\n }\n\n private async handledBeforeRun(options: RunSessionOptions, sessionKey: string): Promise<boolean> {\n const { event } = options;\n if (await this.dispatchSessionCommand(options, sessionKey)) return true;\n\n const activeSettlement = this.sessions.get(event.address, sessionKey)?.runSettlement;\n if (activeSettlement) await activeSettlement;\n return false;\n }\n\n private async acquireRunLease(\n { event, context }: RunSessionOptions,\n sessionKey: string,\n ): Promise<{ state: ConversationState; release: () => void }> {\n let lease: { state: ConversationState; release: () => void } | undefined;\n try {\n lease = await this.acquireState({\n address: event.address,\n sessionKey,\n currentMessageId: event.ts,\n trustModel: context.platform.trustModel ?? \"membership\",\n platformWorkspaceId: context.platform.workspaceId,\n });\n await lease.state.runner.syncChatHistory(event.ts);\n return lease;\n } catch (err) {\n lease?.release();\n reportUserFacingError(err, {\n domain: \"mikan\",\n surface: \"session_setup\",\n operation: \"get_or_create_state\",\n severity: \"error\",\n platform: context.platform.name,\n context: {\n conversationId: event.address.conversationId,\n sessionKey,\n messageId: context.message.id,\n threadTs: context.message.threadTs,\n attachmentCount: context.message.attachments?.length ?? 0,\n },\n });\n throw err;\n }\n }\n\n private async executeRun(\n { event, bot, context }: RunSessionOptions,\n sessionKey: string,\n state: ConversationState,\n ): Promise<void> {\n const conversationId = event.address.conversationId;\n try {\n const result = await this.runWithInstrumentation(\n context,\n { conversationId, sessionKey, startedAt: state.startedAt },\n async () => {\n await context.responder.setTyping(true);\n await context.responder.setWorking(true);\n try {\n return await state.runner.run(context.message, context.responder, context.platform);\n } finally {\n await context.responder.setWorking(false);\n }\n },\n );\n\n if (result?.stopReason === \"aborted\") {\n await postAbortNotice(state, bot, conversationId, context.platform.name);\n }\n if (result) {\n this.memoryCapture?.capture({\n office: this.options.workspace.office(event.address),\n message: context.message,\n stopReason: result.stopReason,\n reply: result.finalText ?? \"\",\n });\n }\n } finally {\n recordGauge(\"agent.sessions.active\", this.sessions.settlementCount() - 1);\n }\n }\n\n private async waitForParentSession(address: OfficeAddress, sessionKey: string): Promise<void> {\n const conversationId = address.conversationId;\n const office = this.options.workspace.office(address);\n const waited = await waitForThreadSessionBootstrap({\n parentSessionKey: conversationId,\n sessionKey,\n hasThreadSession: () => hasMaterializedChatSession({ office, sessionKey }),\n isParentRunning: () => this.sessions.get(address, conversationId)?.running === true,\n });\n if (waited) {\n log.logInfo(\n `[${conversationId}] Delayed thread bootstrap until parent session sealed: ${sessionKey}`,\n );\n }\n }\n\n private async dispatchSessionCommand(\n { event, bot, context }: RunSessionOptions,\n sessionKey: string,\n ): Promise<boolean> {\n return dispatchCommand(this.commandHandlers, {\n bot,\n responder: context.responder,\n platform: context.platform.name as PlatformName,\n address: event.address,\n platformUserId: event.user,\n platformUserName: context.message.userName,\n conversationId: event.address.conversationId,\n vaultConversationId: event.vaultConversationId,\n sessionKey,\n commandText: event.text,\n privateConversation: isPrivateConversation(event),\n services: this.commandServices,\n });\n }\n\n private async runWithInstrumentation(\n context: ConversationContext,\n meta: {\n conversationId: string;\n sessionKey: string;\n startedAt: number;\n },\n body: () => Promise<RunResult>,\n ): Promise<RunResult | undefined> {\n const { conversationId, sessionKey, startedAt } = meta;\n const { message, platform } = context;\n\n const attribution = createRunAttributionAttributes({\n conversationId,\n sessionKey,\n messageId: message.id,\n platform: platform.name,\n conversationKind: message.conversationKind,\n userId: message.userId,\n threadTs: message.threadTs,\n });\n\n recordCounter(\"agent.run.started\", 1, attribution);\n\n return withRunSpan(\n {\n conversationId,\n sessionKey,\n messageId: message.id,\n platform: platform.name,\n conversationKind: message.conversationKind,\n userId: message.userId,\n threadTs: message.threadTs,\n },\n async () => {\n addLifecycleEvent(\"agent.run.started\", {\n channel_id: attribution.channel_id,\n platform: platform.name,\n conversation_kind: message.conversationKind,\n has_attachments: (message.attachments?.length ?? 0) > 0,\n });\n\n try {\n const result = await body();\n const durationMs = Date.now() - startedAt;\n const completionAttrs = {\n ...attribution,\n stop_reason: result.stopReason,\n };\n recordDistribution(\"agent.run.duration\", durationMs, {\n unit: \"millisecond\",\n attributes: completionAttrs,\n });\n recordCounter(\"agent.run.completed\", 1, completionAttrs);\n addLifecycleEvent(\"agent.run.completed\", {\n channel_id: attribution.channel_id,\n platform: platform.name,\n stop_reason: result.stopReason,\n duration_ms: durationMs,\n });\n return result;\n } catch (err) {\n reportUserFacingError(err, {\n domain: \"mikan\",\n surface: \"agent_run\",\n operation: \"run\",\n severity: \"error\",\n platform: platform.name,\n context: {\n conversationId,\n sessionKey,\n messageId: message.id,\n threadTs: message.threadTs,\n attachmentCount: message.attachments?.length ?? 0,\n },\n });\n recordCounter(\"agent.run.errors\", 1, attribution);\n log.logWarning(`[${conversationId}] Run error`, errorMessage(err));\n await context.responder\n .replaceResponse(\"Could not complete the request. Please reply to retry or revise it.\")\n .catch(() => {});\n return undefined;\n }\n },\n );\n }\n\n refreshConversation(address: OfficeAddress): boolean {\n const cleared = this.sessions.invalidateConversation(address);\n if (cleared) log.logInfo(`[${address.conversationId}] Cleared cached session runners`);\n return cleared;\n }\n\n refreshAllConversations(): { busy: OfficeAddress[] } {\n const offices = this.sessions.offices();\n const result = this.sessions.invalidateAll();\n const busyKeys = new Set(\n result.busy.map((address) => `${address.platform}:${address.conversationId}`),\n );\n for (const address of offices) {\n if (busyKeys.has(`${address.platform}:${address.conversationId}`)) continue;\n log.logInfo(\n `[${address.conversationId}] Global settings changed; cleared cached session runners`,\n );\n }\n return result;\n }\n\n private async createCurrentRunner(\n options: SessionStateOptions,\n sessionScope: Awaited<ReturnType<ChatHistorySync[\"resolveSessionScope\"]>>,\n signal: AbortSignal,\n ): Promise<PiAgentWrapper> {\n const runnerFactory = this.options.runnerFactory ?? createRunner;\n return runnerFactory({\n sandboxConfig: this.options.sandbox,\n sessionKey: options.sessionKey,\n office: this.options.workspace.office(options.address),\n trustModel: options.trustModel,\n platformWorkspaceId: options.platformWorkspaceId,\n openConnector: this.options.openConnector,\n eventScheduler: this.options.eventScheduler?.(),\n sessionScope,\n chatHistory: this.chatSessionManager,\n signal,\n vaultManager: this.options.vaultManager,\n provisioner: this.options.provisioner,\n resourceController: this.options.resourceController,\n sessionView: this.options.sessionViewTokenStore\n ? {\n tokenStore: this.options.sessionViewTokenStore,\n portalBaseUrl: this.options.portalBaseUrl,\n }\n : undefined,\n platformToolPackFactories: this.options.platformToolPackFactories,\n models: this.resolvedModels,\n runEvents: this.options.runEvents,\n });\n }\n\n private acquireState(options: SessionStateOptions & { currentMessageId?: string }) {\n const { address, sessionKey } = options;\n const office = this.options.workspace.office(address);\n return this.sessions.acquire(address, sessionKey, (signal) =>\n this.materializeState(options, office, signal),\n );\n }\n\n private async materializeState(\n options: SessionStateOptions & { currentMessageId?: string },\n office: Office,\n signal: AbortSignal,\n ): Promise<ConversationState> {\n signal.throwIfAborted();\n const { address, sessionKey, currentMessageId } = options;\n const sessionScope = await this.chatSessionManager.resolveSessionScope({\n office,\n sessionKey,\n currentMessageId,\n });\n signal.throwIfAborted();\n return {\n address,\n sessionKey,\n running: false,\n runner: await this.createCurrentRunner(options, sessionScope, signal),\n stopRequested: false,\n lastAccessedAt: Date.now(),\n startedAt: 0,\n };\n }\n\n async shutdown(timeoutMs = 30_000): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n log.logInfo(\"Shutting down gracefully...\");\n await this.sessions.shutdown(timeoutMs);\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { McpServerConfig, RunEventPublisher } from "../harness/types.js";
2
2
  import type { EventScheduleSink } from "../events/index.js";
3
3
  import type { CreateRunnerOptions, PiAgentWrapper, PlatformTrustModel } from "../types.js";
4
- import type { MessagingBot, ConversationContext, ConversationEvent, MessagingEventHandler, OfficeAddress } from "../types.js";
4
+ import type { MessagingBot, ConversationContext, ConversationEvent, GlobalRunnerCacheControl, MessagingEventHandler, OfficeAddress, RunnerCacheControl } from "../types.js";
5
5
  import type { AdminTokenStoreLike, CommandHandler, CommandServices, LinkTokenStoreLike } from "../adapters/commands/types.js";
6
6
  import type { SessionViewTokenStoreLike } from "../types.js";
7
7
  import type { MikanModels } from "../harness/models.js";
@@ -52,13 +52,8 @@ export interface ConversationRuntimeOptions extends Omit<CommandServices, "runti
52
52
  runnerFactory?: RunnerFactory;
53
53
  runEvents?: RunEventPublisher;
54
54
  }
55
- export interface ConversationRuntime extends MessagingEventHandler {
55
+ export interface ConversationRuntime extends MessagingEventHandler, RunnerCacheControl, GlobalRunnerCacheControl {
56
56
  runSession(options: RunSessionOptions): Promise<void>;
57
- switchConversationModel(address: OfficeAddress, provider: string, model: string): boolean;
58
- refreshConversationEnvironment(address: OfficeAddress): boolean;
59
- refreshAllConversations(): {
60
- busy: OfficeAddress[];
61
- };
62
57
  shutdown(timeoutMs?: number): Promise<void>;
63
58
  }
64
59
  //# sourceMappingURL=types.d.ts.map