chattercatcher 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1077,7 +1077,10 @@ declare class VectorRetriever implements Retriever {
1077
1077
  retrieve(question: string, scope?: RetrievalScope): Promise<EvidenceBlock[]>;
1078
1078
  }
1079
1079
 
1080
- declare function createWebApp(config: AppConfig): FastifyInstance;
1081
- declare function startWebServer(config: AppConfig): Promise<void>;
1080
+ interface WebAppOptions {
1081
+ version?: string;
1082
+ }
1083
+ declare function createWebApp(config: AppConfig, options?: WebAppOptions): FastifyInstance;
1084
+ declare function startWebServer(config: AppConfig, options?: WebAppOptions): Promise<void>;
1082
1085
 
1083
- export { type AppConfig, type AppSecrets, type AskWithRagInput, type BuildEvidencePromptOptions, type ChatMessage, type ChatModel, type ChatRecord, type ChatTool, type Citation, type CreateImageSummaryMessageInput, type CronJobRecord, CronJobRepository, type CronJobScheduler, type CronJobStatus, type CronJobTool, type DataExportResult, type DataRestoreResult, type DeleteLocalDataResult, type DeleteTargetType, type DoctorCheck, type DoctorOptions, type DoctorStatus, type EmbeddingModel, type EpisodeListItem, type EpisodeMessage, EpisodeRepository, type EpisodeSearchResult, type EpisodeSummaryRecord, type EpisodeWindow, type EvidenceBlock, type EvidencePrompt, type EvidenceSource, type FeishuAttachmentMetadata, type FeishuDownloadResourceInput, type FeishuDownloadedResource, type FeishuGatewayOptions, type FeishuGatewayRuntime, FeishuMessageSender, type FeishuQuestionDecision, FeishuQuestionHandler, type FeishuQuestionHandlerOptions, type FeishuReceiveMessageEvent, FeishuResourceDownloader, type FileJobRecord, FileJobRepository, type FileJobStatus, type FileRecord, type GatewayAttachmentIngestResult, type GatewayIngestAndDownloadResult, type GatewayIngestResult, GatewayIngestor, type GatewayPidRecord, type GatewayRuntimeState, type GroundedAnswer, HybridRetriever, type HybridRetrieverOptions, type IngestLocalFileResult, type IngestMessageInput, type LogFileInfo, type LogTailResult, type ManualMessageIndexResult, MemoryVectorStore, MessageFtsRetriever, type MessageRecord, MessageRepository, type MessageSearchResult, type MessageSearchScope, type MessageSender, OpenAICompatibleChatModel, type OpenAICompatibleChatOptions, OpenAICompatibleEmbeddingModel, type OpenAICompatibleEmbeddingOptions, type ParsedFile, type ProcessEpisodesResult, type SourceType, type SqliteDatabase, type StopGatewayResult, type TextChunk, type ToolCall, type ToolChatResult, type VectorIndexStats, type VectorRecord, VectorRetriever, type VectorSearchResult, type VectorStore, appConfigSchema, appSecretsSchema, applySecretInput, askWithRag, buildEvidencePrompt, chunkText, cosineSimilarity, createAgenticRagSearchTools, createChatModel, createCronJobScheduler, createCronJobTools, createDefaultConfig, createDefaultSecrets, createEmbeddingModel, createFeishuEventDispatcher, createFeishuGateway, createHybridRetriever, createWebApp, deleteLocalData, describeSupportedParseTypes, ensureConfigFiles, exportLocalData, extractFeishuAttachment, followLogFile, formatCitation, formatCitations, formatDoctorChecks, generateCronJobMessage, generateGroundedAnswer, getDatabasePath, getFeishuQuestionDecision, getGatewayLogPath, getGatewayPidPath, getGatewayRuntimeState, getLogsDirectory, getNextCronRun, hasEmbeddingConfig, indexMessageChunks, ingestLocalFile, isFeishuMessageAddressedToBot, isProcessRunning, isSupportedParseFile, isSupportedTextFile, isValidCronSchedule, listLogFiles, loadConfig, loadSecrets, mapDomain, maskSecret, matchesCronSchedule, migrateDatabase, normalizeFeishuReceiveMessageEvent, normalizeLineCount, openDatabase, parseFileToText, processEpisodesNow, processMessagesNow, rankEvidenceForPrompt, readGatewayPidRecord, readLatestLogTail, readLogTail, removeGatewayPidRecord, resetConfigFiles, resolveEmbeddingApiKey, resolveLogPath, restoreLocalData, runDoctor, sanitizeEpisodeSummary, saveConfig, saveSecrets, startWebServer, stopGatewayProcess, summarizeEpisodeWindow, writeGatewayPidRecord };
1086
+ export { type AppConfig, type AppSecrets, type AskWithRagInput, type BuildEvidencePromptOptions, type ChatMessage, type ChatModel, type ChatRecord, type ChatTool, type Citation, type CreateImageSummaryMessageInput, type CronJobRecord, CronJobRepository, type CronJobScheduler, type CronJobStatus, type CronJobTool, type DataExportResult, type DataRestoreResult, type DeleteLocalDataResult, type DeleteTargetType, type DoctorCheck, type DoctorOptions, type DoctorStatus, type EmbeddingModel, type EpisodeListItem, type EpisodeMessage, EpisodeRepository, type EpisodeSearchResult, type EpisodeSummaryRecord, type EpisodeWindow, type EvidenceBlock, type EvidencePrompt, type EvidenceSource, type FeishuAttachmentMetadata, type FeishuDownloadResourceInput, type FeishuDownloadedResource, type FeishuGatewayOptions, type FeishuGatewayRuntime, FeishuMessageSender, type FeishuQuestionDecision, FeishuQuestionHandler, type FeishuQuestionHandlerOptions, type FeishuReceiveMessageEvent, FeishuResourceDownloader, type FileJobRecord, FileJobRepository, type FileJobStatus, type FileRecord, type GatewayAttachmentIngestResult, type GatewayIngestAndDownloadResult, type GatewayIngestResult, GatewayIngestor, type GatewayPidRecord, type GatewayRuntimeState, type GroundedAnswer, HybridRetriever, type HybridRetrieverOptions, type IngestLocalFileResult, type IngestMessageInput, type LogFileInfo, type LogTailResult, type ManualMessageIndexResult, MemoryVectorStore, MessageFtsRetriever, type MessageRecord, MessageRepository, type MessageSearchResult, type MessageSearchScope, type MessageSender, OpenAICompatibleChatModel, type OpenAICompatibleChatOptions, OpenAICompatibleEmbeddingModel, type OpenAICompatibleEmbeddingOptions, type ParsedFile, type ProcessEpisodesResult, type SourceType, type SqliteDatabase, type StopGatewayResult, type TextChunk, type ToolCall, type ToolChatResult, type VectorIndexStats, type VectorRecord, VectorRetriever, type VectorSearchResult, type VectorStore, type WebAppOptions, appConfigSchema, appSecretsSchema, applySecretInput, askWithRag, buildEvidencePrompt, chunkText, cosineSimilarity, createAgenticRagSearchTools, createChatModel, createCronJobScheduler, createCronJobTools, createDefaultConfig, createDefaultSecrets, createEmbeddingModel, createFeishuEventDispatcher, createFeishuGateway, createHybridRetriever, createWebApp, deleteLocalData, describeSupportedParseTypes, ensureConfigFiles, exportLocalData, extractFeishuAttachment, followLogFile, formatCitation, formatCitations, formatDoctorChecks, generateCronJobMessage, generateGroundedAnswer, getDatabasePath, getFeishuQuestionDecision, getGatewayLogPath, getGatewayPidPath, getGatewayRuntimeState, getLogsDirectory, getNextCronRun, hasEmbeddingConfig, indexMessageChunks, ingestLocalFile, isFeishuMessageAddressedToBot, isProcessRunning, isSupportedParseFile, isSupportedTextFile, isValidCronSchedule, listLogFiles, loadConfig, loadSecrets, mapDomain, maskSecret, matchesCronSchedule, migrateDatabase, normalizeFeishuReceiveMessageEvent, normalizeLineCount, openDatabase, parseFileToText, processEpisodesNow, processMessagesNow, rankEvidenceForPrompt, readGatewayPidRecord, readLatestLogTail, readLogTail, removeGatewayPidRecord, resetConfigFiles, resolveEmbeddingApiKey, resolveLogPath, restoreLocalData, runDoctor, sanitizeEpisodeSummary, saveConfig, saveSecrets, startWebServer, stopGatewayProcess, summarizeEpisodeWindow, writeGatewayPidRecord };
package/dist/index.js CHANGED
@@ -4938,6 +4938,7 @@ function buildHtml() {
4938
4938
  const gatewayClass = status.gateway.configured ? "status-ok" : "status-warn";
4939
4939
  metrics.innerHTML = [
4940
4940
  ["Gateway", formatGatewayValue(status.gateway), formatGatewayNote(status.gateway), gatewayClass],
4941
+ ["\u7248\u672C", status.version || "unknown", "\u5F53\u524D\u8FD0\u884C\u7248\u672C", ""],
4941
4942
  ["\u7FA4\u804A", status.data.chats, "\u672C\u5730\u7FA4\u804A\u6570", ""],
4942
4943
  ["\u6D88\u606F", status.data.messages, "\u5DF2\u5165\u5E93\u6D88\u606F", ""],
4943
4944
  ["\u4F1A\u8BDD\u8BB0\u5FC6", status.data.episodes, "\u5DF2\u751F\u6210\u6458\u8981", ""],
@@ -5131,31 +5132,41 @@ function buildHtml() {
5131
5132
  ");
5132
5133
  }
5133
5134
 
5134
- async function load() {
5135
+ async function fetchJson(path) {
5136
+ const response = await fetch(path);
5137
+ if (!response.ok) {
5138
+ const body = await response.text();
5139
+ throw new Error(path + " " + response.status + " " + body);
5140
+ }
5141
+ return response.json();
5142
+ }
5143
+
5144
+ function renderLoadError(element, error) {
5145
+ element.className = "empty";
5146
+ element.textContent = "\u52A0\u8F7D\u5931\u8D25\uFF1A" + (error instanceof Error ? error.message : String(error));
5147
+ }
5148
+
5149
+ async function loadSection(path, element, render) {
5135
5150
  try {
5136
- const [status, recent, episodeList, chatList, fileList, jobList, qaLogList, cronJobList] = await Promise.all([
5137
- fetch("/api/status").then((response) => response.json()),
5138
- fetch("/api/messages/recent?limit=20").then((response) => response.json()),
5139
- fetch("/api/episodes?limit=10").then((response) => response.json()),
5140
- fetch("/api/chats").then((response) => response.json()),
5141
- fetch("/api/files").then((response) => response.json()),
5142
- fetch("/api/file-jobs").then((response) => response.json()),
5143
- fetch("/api/qa-logs?limit=10").then((response) => response.json()),
5144
- fetch("/api/cron-jobs").then((response) => response.json()),
5145
- ]);
5146
- renderMetrics(status);
5147
- renderMessages(recent.items);
5148
- renderEpisodes(episodeList.items);
5149
- renderChats(chatList.items);
5150
- renderFiles(fileList.items);
5151
- renderFileJobs(jobList.items);
5152
- renderQaLogs(qaLogList.items);
5153
- renderCronJobs(cronJobList.items);
5151
+ render(await fetchJson(path));
5154
5152
  } catch (error) {
5155
- metrics.innerHTML = '<div class="empty">\u6570\u636E\u52A0\u8F7D\u5931\u8D25\uFF1A' + escapeHtml(error instanceof Error ? error.message : String(error)) + '</div>';
5153
+ renderLoadError(element, error);
5156
5154
  }
5157
5155
  }
5158
5156
 
5157
+ async function load() {
5158
+ await Promise.all([
5159
+ loadSection("/api/status", metrics, renderMetrics),
5160
+ loadSection("/api/messages/recent?limit=20", messages, (data) => renderMessages(data.items)),
5161
+ loadSection("/api/episodes?limit=10", episodes, (data) => renderEpisodes(data.items)),
5162
+ loadSection("/api/chats", chats, (data) => renderChats(data.items)),
5163
+ loadSection("/api/files", files, (data) => renderFiles(data.items)),
5164
+ loadSection("/api/file-jobs", fileJobs, (data) => renderFileJobs(data.items)),
5165
+ loadSection("/api/qa-logs?limit=10", qaLogs, (data) => renderQaLogs(data.items)),
5166
+ loadSection("/api/cron-jobs", cronJobs, (data) => renderCronJobs(data.items)),
5167
+ ]);
5168
+ }
5169
+
5159
5170
  async function processNow() {
5160
5171
  processMessages.disabled = true;
5161
5172
  actionStatus.textContent = "\u6B63\u5728\u5904\u7406\u6D88\u606F\u7D22\u5F15...";
@@ -5230,9 +5241,10 @@ function isAuthorizedWebAction(request, token) {
5230
5241
  const provided = readHeader(request.headers["x-chattercatcher-web-token"]);
5231
5242
  return provided === token;
5232
5243
  }
5233
- function createWebApp(config) {
5244
+ function createWebApp(config, options = {}) {
5234
5245
  const app = Fastify({ logger: false });
5235
5246
  const database = openDatabase(config);
5247
+ const version = options.version ?? "unknown";
5236
5248
  const messages = new MessageRepository(database);
5237
5249
  const episodes = new EpisodeRepository(database);
5238
5250
  const fileJobs = new FileJobRepository(database);
@@ -5254,6 +5266,7 @@ function createWebApp(config) {
5254
5266
  await tokenReady;
5255
5267
  return {
5256
5268
  app: "ChatterCatcher",
5269
+ version,
5257
5270
  gateway: getGatewayStatus(config),
5258
5271
  data: {
5259
5272
  chats: messages.getChatCount(),
@@ -5358,12 +5371,13 @@ function createWebApp(config) {
5358
5371
  });
5359
5372
  return app;
5360
5373
  }
5361
- async function startWebServer(config) {
5362
- const app = createWebApp(config);
5374
+ async function startWebServer(config, options = {}) {
5375
+ const app = createWebApp(config, options);
5363
5376
  await app.listen({ host: config.web.host, port: config.web.port });
5364
5377
  const address = app.server.address();
5365
5378
  const url = typeof address === "string" ? address : `http://${config.web.host}:${address?.port ?? config.web.port}`;
5366
- console.log(`ChatterCatcher Web UI: ${url}`);
5379
+ const versionText = options.version ? ` ${options.version}` : "";
5380
+ console.log(`ChatterCatcher Web UI${versionText}: ${url}`);
5367
5381
  }
5368
5382
  export {
5369
5383
  CronJobRepository,