@loggie-ai/openclaw-plugin 0.1.0

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 (55) hide show
  1. package/README.md +205 -0
  2. package/dist/index.d.ts +8 -0
  3. package/dist/index.js +12 -0
  4. package/dist/setup-entry.d.ts +73 -0
  5. package/dist/setup-entry.js +3 -0
  6. package/dist/src/account.d.ts +70 -0
  7. package/dist/src/account.js +182 -0
  8. package/dist/src/channel.d.ts +72 -0
  9. package/dist/src/channel.js +105 -0
  10. package/dist/src/config-schema.d.ts +98 -0
  11. package/dist/src/config-schema.js +55 -0
  12. package/dist/src/cursor-store.d.ts +86 -0
  13. package/dist/src/cursor-store.js +141 -0
  14. package/dist/src/doctor.d.ts +11 -0
  15. package/dist/src/doctor.js +29 -0
  16. package/dist/src/event-types.d.ts +113 -0
  17. package/dist/src/event-types.js +86 -0
  18. package/dist/src/loggie-client.d.ts +33 -0
  19. package/dist/src/loggie-client.js +74 -0
  20. package/dist/src/monitor/connection.d.ts +30 -0
  21. package/dist/src/monitor/connection.js +289 -0
  22. package/dist/src/monitor/event-handler.d.ts +27 -0
  23. package/dist/src/monitor/event-handler.js +90 -0
  24. package/dist/src/monitor/transcript-dispatch.d.ts +16 -0
  25. package/dist/src/monitor/transcript-dispatch.js +124 -0
  26. package/dist/src/monitor/transcript-format.d.ts +2 -0
  27. package/dist/src/monitor/transcript-format.js +41 -0
  28. package/dist/src/object.d.ts +4 -0
  29. package/dist/src/object.js +12 -0
  30. package/dist/src/routing.d.ts +11 -0
  31. package/dist/src/routing.js +13 -0
  32. package/dist/src/runtime.d.ts +3 -0
  33. package/dist/src/runtime.js +6 -0
  34. package/dist/src/status.d.ts +45 -0
  35. package/dist/src/status.js +45 -0
  36. package/index.ts +13 -0
  37. package/openclaw.plugin.json +71 -0
  38. package/package.json +93 -0
  39. package/plugin-inspector.config.json +15 -0
  40. package/setup-entry.ts +4 -0
  41. package/src/account.ts +265 -0
  42. package/src/channel.ts +148 -0
  43. package/src/config-schema.ts +57 -0
  44. package/src/cursor-store.ts +233 -0
  45. package/src/doctor.ts +39 -0
  46. package/src/event-types.ts +105 -0
  47. package/src/loggie-client.ts +111 -0
  48. package/src/monitor/connection.ts +349 -0
  49. package/src/monitor/event-handler.ts +133 -0
  50. package/src/monitor/transcript-dispatch.ts +145 -0
  51. package/src/monitor/transcript-format.ts +49 -0
  52. package/src/object.ts +15 -0
  53. package/src/routing.ts +27 -0
  54. package/src/runtime.ts +13 -0
  55. package/src/status.ts +72 -0
@@ -0,0 +1,105 @@
1
+ import { createChannelPluginBase, } from "openclaw/plugin-sdk/channel-core";
2
+ import { applyLoggieAccountConfig, inspectLoggieAccount, listLoggieAccountIds, resolveDefaultLoggieAccountId, resolveLoggieAccount, } from "./account.js";
3
+ import { loggieChannelConfigSchema } from "./config-schema.js";
4
+ import { loggieDoctor } from "./doctor.js";
5
+ import { buildLoggieAccountStatusSnapshot, defaultLoggieRuntimeState, } from "./status.js";
6
+ const base = createChannelPluginBase({
7
+ id: "loggie",
8
+ meta: {
9
+ label: "Loggie",
10
+ selectionLabel: "Loggie",
11
+ blurb: "Receives durable Loggie meeting transcript events over WebSocket.",
12
+ docsPath: "/plugins/loggie",
13
+ },
14
+ capabilities: {
15
+ chatTypes: ["group"],
16
+ threads: false,
17
+ media: false,
18
+ reply: false,
19
+ },
20
+ configSchema: loggieChannelConfigSchema,
21
+ setup: {
22
+ resolveAccountId: ({ accountId }) => accountId ?? "default",
23
+ applyAccountConfig: ({ cfg, accountId, input, }) => applyLoggieAccountConfig({
24
+ cfg,
25
+ accountId,
26
+ input: input,
27
+ }),
28
+ },
29
+ config: {
30
+ listAccountIds: listLoggieAccountIds,
31
+ resolveAccount: (cfg, accountId) => resolveLoggieAccount(cfg, accountId),
32
+ inspectAccount: inspectLoggieAccount,
33
+ defaultAccountId: resolveDefaultLoggieAccountId,
34
+ isEnabled: (account) => account.enabled,
35
+ isConfigured: (account) => account.configured,
36
+ unconfiguredReason: (account) => account.tokenStatus.status !== "available"
37
+ ? `Loggie token ${account.tokenStatus.status}`
38
+ : "Loggie baseUrl and agentProfileId are required",
39
+ describeAccount: (account) => ({
40
+ accountId: account.accountId,
41
+ name: account.name,
42
+ enabled: account.enabled,
43
+ configured: account.configured,
44
+ tokenStatus: account.tokenStatus.status,
45
+ tokenSource: account.tokenStatus.source,
46
+ extra: {
47
+ baseUrl: account.baseUrl,
48
+ agentId: account.agentId,
49
+ agentProfileId: account.agentProfileId,
50
+ },
51
+ }),
52
+ },
53
+ });
54
+ export const loggiePlugin = {
55
+ ...base,
56
+ status: {
57
+ defaultRuntime: defaultLoggieRuntimeState,
58
+ buildAccountSnapshot: ({ account, runtime, }) => buildLoggieAccountStatusSnapshot({
59
+ account,
60
+ runtime: runtime,
61
+ }),
62
+ },
63
+ doctor: loggieDoctor,
64
+ secrets: {
65
+ secretTargetRegistryEntries: [
66
+ {
67
+ id: "channels.loggie.credentialRef",
68
+ targetType: "channels.loggie.credentialRef",
69
+ configFile: "openclaw.json",
70
+ pathPattern: "channels.loggie.credentialRef",
71
+ secretShape: "secret_input",
72
+ expectedResolvedValue: "string",
73
+ includeInPlan: true,
74
+ includeInConfigure: true,
75
+ includeInAudit: true,
76
+ },
77
+ {
78
+ id: "channels.loggie.accounts.*.credentialRef",
79
+ targetType: "channels.loggie.accounts.*.credentialRef",
80
+ configFile: "openclaw.json",
81
+ pathPattern: "channels.loggie.accounts.*.credentialRef",
82
+ secretShape: "secret_input",
83
+ expectedResolvedValue: "string",
84
+ includeInPlan: true,
85
+ includeInConfigure: true,
86
+ includeInAudit: true,
87
+ },
88
+ ],
89
+ },
90
+ gateway: {
91
+ startAccount: async (ctx) => {
92
+ const { monitorLoggieAccount } = await import("./monitor/connection.js");
93
+ return monitorLoggieAccount({
94
+ account: ctx.account,
95
+ cfg: ctx.cfg,
96
+ runtime: ctx.runtime,
97
+ channelRuntime: ctx.channelRuntime,
98
+ abortSignal: ctx.abortSignal,
99
+ setStatus: ctx.setStatus,
100
+ getStatus: ctx.getStatus,
101
+ log: ctx.log,
102
+ });
103
+ },
104
+ },
105
+ };
@@ -0,0 +1,98 @@
1
+ export declare const LOGGIE_CHANNEL_ID = "loggie";
2
+ export declare const DEFAULT_LOGGIE_ACCOUNT_ID = "default";
3
+ export declare const DEFAULT_LOGGIE_AGENT_ID = "main";
4
+ export declare const DEFAULT_LOGGIE_SOCKET_PATH = "/api/events/socket";
5
+ export declare const DEFAULT_LOGGIE_TOKEN_ENV = "LOGGIE_AGENT_TOKEN";
6
+ export declare const DEFAULT_LOGGIE_BASE_URL_ENV = "LOGGIE_BASE_URL";
7
+ export declare const DEFAULT_LOGGIE_HEARTBEAT_TIMEOUT_MS = 120000;
8
+ export declare const loggieEntryConfigSchema: {
9
+ readonly type: "object";
10
+ readonly additionalProperties: false;
11
+ readonly properties: {};
12
+ };
13
+ export declare const loggieChannelConfigSchema: {
14
+ readonly type: "object";
15
+ readonly additionalProperties: true;
16
+ readonly properties: {
17
+ readonly enabled: {
18
+ readonly type: "boolean";
19
+ readonly default: true;
20
+ };
21
+ readonly baseUrl: {
22
+ readonly type: "string";
23
+ };
24
+ readonly socketPath: {
25
+ readonly type: "string";
26
+ readonly default: "/api/events/socket";
27
+ };
28
+ readonly accountId: {
29
+ readonly type: "string";
30
+ readonly default: "default";
31
+ };
32
+ readonly agentId: {
33
+ readonly type: "string";
34
+ readonly default: "main";
35
+ };
36
+ readonly agentProfileId: {
37
+ readonly type: "string";
38
+ };
39
+ readonly credentialRef: {};
40
+ readonly token: {
41
+ readonly type: "string";
42
+ };
43
+ readonly authHeader: {
44
+ readonly type: "string";
45
+ readonly enum: readonly ["authorization", "x-api-key"];
46
+ readonly default: "authorization";
47
+ };
48
+ readonly accounts: {
49
+ readonly type: "object";
50
+ readonly additionalProperties: {
51
+ readonly type: "object";
52
+ };
53
+ };
54
+ readonly reconnect: {
55
+ readonly type: "object";
56
+ readonly additionalProperties: false;
57
+ readonly properties: {
58
+ readonly minMs: {
59
+ readonly type: "integer";
60
+ readonly minimum: 100;
61
+ readonly default: 1000;
62
+ };
63
+ readonly maxMs: {
64
+ readonly type: "integer";
65
+ readonly minimum: 1000;
66
+ readonly default: 60000;
67
+ };
68
+ };
69
+ };
70
+ readonly heartbeat: {
71
+ readonly type: "object";
72
+ readonly additionalProperties: false;
73
+ readonly properties: {
74
+ readonly timeoutMs: {
75
+ readonly type: "integer";
76
+ readonly minimum: 1000;
77
+ readonly default: 120000;
78
+ };
79
+ };
80
+ };
81
+ readonly transcript: {
82
+ readonly type: "object";
83
+ readonly additionalProperties: false;
84
+ readonly properties: {
85
+ readonly activation: {
86
+ readonly type: "string";
87
+ readonly enum: readonly ["final-only"];
88
+ readonly default: "final-only";
89
+ };
90
+ readonly debounceMs: {
91
+ readonly type: "integer";
92
+ readonly minimum: 0;
93
+ readonly default: 5000;
94
+ };
95
+ };
96
+ };
97
+ };
98
+ };
@@ -0,0 +1,55 @@
1
+ export const LOGGIE_CHANNEL_ID = "loggie";
2
+ export const DEFAULT_LOGGIE_ACCOUNT_ID = "default";
3
+ export const DEFAULT_LOGGIE_AGENT_ID = "main";
4
+ export const DEFAULT_LOGGIE_SOCKET_PATH = "/api/events/socket";
5
+ export const DEFAULT_LOGGIE_TOKEN_ENV = "LOGGIE_AGENT_TOKEN";
6
+ export const DEFAULT_LOGGIE_BASE_URL_ENV = "LOGGIE_BASE_URL";
7
+ export const DEFAULT_LOGGIE_HEARTBEAT_TIMEOUT_MS = 120_000;
8
+ export const loggieEntryConfigSchema = {
9
+ type: "object",
10
+ additionalProperties: false,
11
+ properties: {},
12
+ };
13
+ export const loggieChannelConfigSchema = {
14
+ type: "object",
15
+ additionalProperties: true,
16
+ properties: {
17
+ enabled: { type: "boolean", default: true },
18
+ baseUrl: { type: "string" },
19
+ socketPath: { type: "string", default: DEFAULT_LOGGIE_SOCKET_PATH },
20
+ accountId: { type: "string", default: DEFAULT_LOGGIE_ACCOUNT_ID },
21
+ agentId: { type: "string", default: DEFAULT_LOGGIE_AGENT_ID },
22
+ agentProfileId: { type: "string" },
23
+ credentialRef: {},
24
+ token: { type: "string" },
25
+ authHeader: { type: "string", enum: ["authorization", "x-api-key"], default: "authorization" },
26
+ accounts: { type: "object", additionalProperties: { type: "object" } },
27
+ reconnect: {
28
+ type: "object",
29
+ additionalProperties: false,
30
+ properties: {
31
+ minMs: { type: "integer", minimum: 100, default: 1000 },
32
+ maxMs: { type: "integer", minimum: 1000, default: 60000 },
33
+ },
34
+ },
35
+ heartbeat: {
36
+ type: "object",
37
+ additionalProperties: false,
38
+ properties: {
39
+ timeoutMs: {
40
+ type: "integer",
41
+ minimum: 1000,
42
+ default: DEFAULT_LOGGIE_HEARTBEAT_TIMEOUT_MS,
43
+ },
44
+ },
45
+ },
46
+ transcript: {
47
+ type: "object",
48
+ additionalProperties: false,
49
+ properties: {
50
+ activation: { type: "string", enum: ["final-only"], default: "final-only" },
51
+ debounceMs: { type: "integer", minimum: 0, default: 5000 },
52
+ },
53
+ },
54
+ },
55
+ };
@@ -0,0 +1,86 @@
1
+ import type { LoggieEventEnvelope } from "./event-types.js";
2
+ export type LoggieCursorRecord = {
3
+ accountId: string;
4
+ agentProfileId: string;
5
+ lastEventId?: string;
6
+ lastCursor?: string;
7
+ lastSequence?: number;
8
+ lastConnectedAt?: number;
9
+ lastCaughtUpAt?: number;
10
+ lastError?: string;
11
+ failedEvents?: LoggieFailedEvent[];
12
+ deadLetteredEvents?: LoggieDeadLetteredEvent[];
13
+ seenEventIds: string[];
14
+ updatedAt: string;
15
+ };
16
+ export type LoggieFailedEvent = {
17
+ eventId: string;
18
+ cursor?: string;
19
+ eventType: string;
20
+ attempts: number;
21
+ firstFailedAt: string;
22
+ lastFailedAt: string;
23
+ lastReason: string;
24
+ };
25
+ export type LoggieDeadLetteredEvent = {
26
+ eventId: string;
27
+ cursor?: string;
28
+ eventType: string;
29
+ attempts: number;
30
+ reason: string;
31
+ deadLetteredAt: string;
32
+ };
33
+ export type LoggieCursorDecision = {
34
+ action: "process";
35
+ } | {
36
+ action: "skip";
37
+ reason: "duplicate_event" | "cursor_regression";
38
+ };
39
+ export type LoggieCursorStore = {
40
+ load(accountId: string, agentProfileId: string): Promise<LoggieCursorRecord | undefined>;
41
+ save(record: LoggieCursorRecord): Promise<void>;
42
+ };
43
+ export declare function createEmptyCursorRecord(params: {
44
+ accountId: string;
45
+ agentProfileId: string;
46
+ }): LoggieCursorRecord;
47
+ export declare function decideCursor(record: LoggieCursorRecord | undefined, event: LoggieEventEnvelope): LoggieCursorDecision;
48
+ export declare function advanceCursor(params: {
49
+ record: LoggieCursorRecord | undefined;
50
+ event: LoggieEventEnvelope;
51
+ accountId: string;
52
+ agentProfileId: string;
53
+ now?: Date;
54
+ }): LoggieCursorRecord;
55
+ export declare function recordEventFailure(params: {
56
+ record: LoggieCursorRecord | undefined;
57
+ event: LoggieEventEnvelope;
58
+ accountId: string;
59
+ agentProfileId: string;
60
+ reason: string;
61
+ now?: Date;
62
+ }): {
63
+ record: LoggieCursorRecord;
64
+ attempts: number;
65
+ };
66
+ export declare function deadLetterEvent(params: {
67
+ record: LoggieCursorRecord | undefined;
68
+ event: LoggieEventEnvelope;
69
+ accountId: string;
70
+ agentProfileId: string;
71
+ reason: string;
72
+ attempts: number;
73
+ now?: Date;
74
+ }): LoggieCursorRecord;
75
+ export declare function createMemoryCursorStore(initial?: LoggieCursorRecord[]): LoggieCursorStore;
76
+ export declare function createRuntimeCursorStore(runtime: {
77
+ state?: {
78
+ openKeyedStore?: <T>(opts: {
79
+ namespace: string;
80
+ maxEntries: number;
81
+ }) => {
82
+ lookup(key: string): Promise<T | undefined>;
83
+ register(key: string, value: T): Promise<void>;
84
+ };
85
+ };
86
+ }): LoggieCursorStore;
@@ -0,0 +1,141 @@
1
+ const MAX_SEEN_EVENT_IDS = 500;
2
+ const MAX_FAILED_EVENTS = 50;
3
+ const MAX_DEAD_LETTERED_EVENTS = 100;
4
+ export function createEmptyCursorRecord(params) {
5
+ return {
6
+ accountId: params.accountId,
7
+ agentProfileId: params.agentProfileId,
8
+ seenEventIds: [],
9
+ updatedAt: new Date(0).toISOString(),
10
+ };
11
+ }
12
+ export function decideCursor(record, event) {
13
+ if (record?.seenEventIds.includes(event.eventId)) {
14
+ return { action: "skip", reason: "duplicate_event" };
15
+ }
16
+ const eventCursor = parseCursor(event.cursor);
17
+ const recordCursor = parseCursor(readStoredCursor(record));
18
+ if (eventCursor !== undefined && recordCursor !== undefined && eventCursor < recordCursor) {
19
+ return { action: "skip", reason: "cursor_regression" };
20
+ }
21
+ return { action: "process" };
22
+ }
23
+ export function advanceCursor(params) {
24
+ const base = params.record ??
25
+ createEmptyCursorRecord({
26
+ accountId: params.accountId,
27
+ agentProfileId: params.agentProfileId,
28
+ });
29
+ const seen = [params.event.eventId, ...base.seenEventIds.filter((id) => id !== params.event.eventId)].slice(0, MAX_SEEN_EVENT_IDS);
30
+ const failedEvents = base.failedEvents?.filter((entry) => entry.eventId !== params.event.eventId);
31
+ return {
32
+ ...base,
33
+ lastEventId: params.event.eventId,
34
+ lastCursor: params.event.cursor ?? base.lastCursor,
35
+ lastSequence: typeof params.event.sequence === "number"
36
+ ? params.event.sequence
37
+ : base.lastSequence,
38
+ lastCaughtUpAt: (params.now ?? new Date()).getTime(),
39
+ lastError: undefined,
40
+ failedEvents: failedEvents?.length ? failedEvents : undefined,
41
+ seenEventIds: seen,
42
+ updatedAt: (params.now ?? new Date()).toISOString(),
43
+ };
44
+ }
45
+ export function recordEventFailure(params) {
46
+ const now = (params.now ?? new Date()).toISOString();
47
+ const base = params.record ??
48
+ createEmptyCursorRecord({
49
+ accountId: params.accountId,
50
+ agentProfileId: params.agentProfileId,
51
+ });
52
+ const existing = base.failedEvents?.find((entry) => entry.eventId === params.event.eventId);
53
+ const nextFailure = {
54
+ eventId: params.event.eventId,
55
+ cursor: params.event.cursor,
56
+ eventType: params.event.eventType,
57
+ attempts: (existing?.attempts ?? 0) + 1,
58
+ firstFailedAt: existing?.firstFailedAt ?? now,
59
+ lastFailedAt: now,
60
+ lastReason: params.reason,
61
+ };
62
+ const failedEvents = [
63
+ nextFailure,
64
+ ...(base.failedEvents ?? []).filter((entry) => entry.eventId !== params.event.eventId),
65
+ ].slice(0, MAX_FAILED_EVENTS);
66
+ return {
67
+ attempts: nextFailure.attempts,
68
+ record: {
69
+ ...base,
70
+ lastError: params.reason,
71
+ failedEvents,
72
+ updatedAt: now,
73
+ },
74
+ };
75
+ }
76
+ export function deadLetterEvent(params) {
77
+ const now = params.now ?? new Date();
78
+ const advanced = advanceCursor({
79
+ record: params.record,
80
+ event: params.event,
81
+ accountId: params.accountId,
82
+ agentProfileId: params.agentProfileId,
83
+ now,
84
+ });
85
+ return {
86
+ ...advanced,
87
+ deadLetteredEvents: [
88
+ {
89
+ eventId: params.event.eventId,
90
+ cursor: params.event.cursor,
91
+ eventType: params.event.eventType,
92
+ attempts: params.attempts,
93
+ reason: params.reason,
94
+ deadLetteredAt: now.toISOString(),
95
+ },
96
+ ...(advanced.deadLetteredEvents ?? []),
97
+ ].slice(0, MAX_DEAD_LETTERED_EVENTS),
98
+ };
99
+ }
100
+ export function createMemoryCursorStore(initial) {
101
+ const records = new Map();
102
+ for (const record of initial ?? []) {
103
+ records.set(cursorKey(record.accountId, record.agentProfileId), record);
104
+ }
105
+ return {
106
+ async load(accountId, agentProfileId) {
107
+ return records.get(cursorKey(accountId, agentProfileId));
108
+ },
109
+ async save(record) {
110
+ records.set(cursorKey(record.accountId, record.agentProfileId), record);
111
+ },
112
+ };
113
+ }
114
+ export function createRuntimeCursorStore(runtime) {
115
+ const store = runtime.state?.openKeyedStore?.({
116
+ namespace: "loggie-cursors",
117
+ maxEntries: 1000,
118
+ });
119
+ if (!store) {
120
+ throw new Error("Loggie durable cursor store is unavailable");
121
+ }
122
+ return {
123
+ load: (accountId, agentProfileId) => store.lookup(cursorKey(accountId, agentProfileId)),
124
+ save: (record) => store.register(cursorKey(record.accountId, record.agentProfileId), record),
125
+ };
126
+ }
127
+ function cursorKey(accountId, agentProfileId) {
128
+ return `${accountId}:${agentProfileId}`;
129
+ }
130
+ function parseCursor(value) {
131
+ if (!value || !/^\d+$/.test(value)) {
132
+ return undefined;
133
+ }
134
+ return BigInt(value);
135
+ }
136
+ function readStoredCursor(record) {
137
+ if (!record) {
138
+ return undefined;
139
+ }
140
+ return record.lastCursor ?? (typeof record.lastSequence === "number" ? String(record.lastSequence) : undefined);
141
+ }
@@ -0,0 +1,11 @@
1
+ import type { OpenClawConfig } from "openclaw/plugin-sdk/channel-core";
2
+ export declare function collectLoggieDoctorWarnings(params: {
3
+ cfg: OpenClawConfig;
4
+ env?: NodeJS.ProcessEnv;
5
+ }): string[];
6
+ export declare const loggieDoctor: {
7
+ collectPreviewWarnings: (params: {
8
+ cfg: OpenClawConfig;
9
+ env?: NodeJS.ProcessEnv;
10
+ }) => string[];
11
+ };
@@ -0,0 +1,29 @@
1
+ import { listLoggieAccountIds, resolveLoggieAccount } from "./account.js";
2
+ export function collectLoggieDoctorWarnings(params) {
3
+ const warnings = [];
4
+ const accountIds = listLoggieAccountIds(params.cfg);
5
+ if (accountIds.length === 0) {
6
+ return ["channels.loggie has no configured accounts."];
7
+ }
8
+ for (const accountId of accountIds) {
9
+ const account = resolveLoggieAccount(params.cfg, accountId, params.env);
10
+ const prefix = `channels.loggie account ${account.accountId}`;
11
+ if (!account.enabled) {
12
+ warnings.push(`${prefix} is disabled.`);
13
+ continue;
14
+ }
15
+ if (!account.baseUrl) {
16
+ warnings.push(`${prefix} is missing baseUrl or LOGGIE_BASE_URL.`);
17
+ }
18
+ if (!account.agentProfileId) {
19
+ warnings.push(`${prefix} is missing agentProfileId.`);
20
+ }
21
+ if (account.tokenStatus.status !== "available") {
22
+ warnings.push(`${prefix} token is ${account.tokenStatus.status} (${account.tokenStatus.source}).`);
23
+ }
24
+ }
25
+ return warnings;
26
+ }
27
+ export const loggieDoctor = {
28
+ collectPreviewWarnings: (params) => collectLoggieDoctorWarnings(params),
29
+ };
@@ -0,0 +1,113 @@
1
+ import { z } from "zod";
2
+ export declare const LOGGIE_TRANSCRIPT_READY_EVENT = "meeting.transcript.ready";
3
+ declare const transcriptPayloadSchema: z.ZodObject<{
4
+ eventId: z.ZodOptional<z.ZodString>;
5
+ cursor: z.ZodOptional<z.ZodString>;
6
+ type: z.ZodOptional<z.ZodString>;
7
+ workspaceId: z.ZodOptional<z.ZodString>;
8
+ meetingId: z.ZodOptional<z.ZodString>;
9
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
10
+ title: z.ZodOptional<z.ZodString>;
11
+ source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
12
+ externalId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
+ meetingDate: z.ZodOptional<z.ZodString>;
14
+ hasTranscript: z.ZodOptional<z.ZodBoolean>;
15
+ detailPath: z.ZodOptional<z.ZodString>;
16
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
17
+ eventId: z.ZodOptional<z.ZodString>;
18
+ cursor: z.ZodOptional<z.ZodString>;
19
+ type: z.ZodOptional<z.ZodString>;
20
+ workspaceId: z.ZodOptional<z.ZodString>;
21
+ meetingId: z.ZodOptional<z.ZodString>;
22
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
23
+ title: z.ZodOptional<z.ZodString>;
24
+ source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
25
+ externalId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
26
+ meetingDate: z.ZodOptional<z.ZodString>;
27
+ hasTranscript: z.ZodOptional<z.ZodBoolean>;
28
+ detailPath: z.ZodOptional<z.ZodString>;
29
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
30
+ eventId: z.ZodOptional<z.ZodString>;
31
+ cursor: z.ZodOptional<z.ZodString>;
32
+ type: z.ZodOptional<z.ZodString>;
33
+ workspaceId: z.ZodOptional<z.ZodString>;
34
+ meetingId: z.ZodOptional<z.ZodString>;
35
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
36
+ title: z.ZodOptional<z.ZodString>;
37
+ source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
38
+ externalId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
39
+ meetingDate: z.ZodOptional<z.ZodString>;
40
+ hasTranscript: z.ZodOptional<z.ZodBoolean>;
41
+ detailPath: z.ZodOptional<z.ZodString>;
42
+ }, z.ZodTypeAny, "passthrough">>;
43
+ export declare const loggieEventEnvelopeSchema: z.ZodEffects<z.ZodObject<{
44
+ eventId: z.ZodString;
45
+ cursor: z.ZodOptional<z.ZodString>;
46
+ workspaceId: z.ZodString;
47
+ agentProfileId: z.ZodOptional<z.ZodString>;
48
+ meetingId: z.ZodOptional<z.ZodString>;
49
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
50
+ eventType: z.ZodString;
51
+ occurredAt: z.ZodString;
52
+ sequence: z.ZodOptional<z.ZodNumber>;
53
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
54
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
55
+ eventId: z.ZodString;
56
+ cursor: z.ZodOptional<z.ZodString>;
57
+ workspaceId: z.ZodString;
58
+ agentProfileId: z.ZodOptional<z.ZodString>;
59
+ meetingId: z.ZodOptional<z.ZodString>;
60
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
61
+ eventType: z.ZodString;
62
+ occurredAt: z.ZodString;
63
+ sequence: z.ZodOptional<z.ZodNumber>;
64
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
65
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
66
+ eventId: z.ZodString;
67
+ cursor: z.ZodOptional<z.ZodString>;
68
+ workspaceId: z.ZodString;
69
+ agentProfileId: z.ZodOptional<z.ZodString>;
70
+ meetingId: z.ZodOptional<z.ZodString>;
71
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
72
+ eventType: z.ZodString;
73
+ occurredAt: z.ZodString;
74
+ sequence: z.ZodOptional<z.ZodNumber>;
75
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
76
+ }, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
77
+ eventId: z.ZodString;
78
+ cursor: z.ZodOptional<z.ZodString>;
79
+ workspaceId: z.ZodString;
80
+ agentProfileId: z.ZodOptional<z.ZodString>;
81
+ meetingId: z.ZodOptional<z.ZodString>;
82
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
83
+ eventType: z.ZodString;
84
+ occurredAt: z.ZodString;
85
+ sequence: z.ZodOptional<z.ZodNumber>;
86
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
87
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
88
+ eventId: z.ZodString;
89
+ cursor: z.ZodOptional<z.ZodString>;
90
+ workspaceId: z.ZodString;
91
+ agentProfileId: z.ZodOptional<z.ZodString>;
92
+ meetingId: z.ZodOptional<z.ZodString>;
93
+ meetingScheduleId: z.ZodOptional<z.ZodString>;
94
+ eventType: z.ZodString;
95
+ occurredAt: z.ZodString;
96
+ sequence: z.ZodOptional<z.ZodNumber>;
97
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
98
+ }, z.ZodTypeAny, "passthrough">>;
99
+ export type LoggieEventEnvelope = z.infer<typeof loggieEventEnvelopeSchema>;
100
+ export type LoggieTranscriptReadyEvent = LoggieEventEnvelope & {
101
+ eventType: typeof LOGGIE_TRANSCRIPT_READY_EVENT;
102
+ payload: z.infer<typeof transcriptPayloadSchema>;
103
+ };
104
+ export type ParseLoggieEventResult = {
105
+ ok: true;
106
+ event: LoggieEventEnvelope;
107
+ } | {
108
+ ok: false;
109
+ reason: string;
110
+ };
111
+ export declare function parseLoggieEventEnvelope(raw: unknown): ParseLoggieEventResult;
112
+ export declare function isTranscriptReadyEvent(event: LoggieEventEnvelope): event is LoggieTranscriptReadyEvent;
113
+ export {};