@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.
- package/README.md +205 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +12 -0
- package/dist/setup-entry.d.ts +73 -0
- package/dist/setup-entry.js +3 -0
- package/dist/src/account.d.ts +70 -0
- package/dist/src/account.js +182 -0
- package/dist/src/channel.d.ts +72 -0
- package/dist/src/channel.js +105 -0
- package/dist/src/config-schema.d.ts +98 -0
- package/dist/src/config-schema.js +55 -0
- package/dist/src/cursor-store.d.ts +86 -0
- package/dist/src/cursor-store.js +141 -0
- package/dist/src/doctor.d.ts +11 -0
- package/dist/src/doctor.js +29 -0
- package/dist/src/event-types.d.ts +113 -0
- package/dist/src/event-types.js +86 -0
- package/dist/src/loggie-client.d.ts +33 -0
- package/dist/src/loggie-client.js +74 -0
- package/dist/src/monitor/connection.d.ts +30 -0
- package/dist/src/monitor/connection.js +289 -0
- package/dist/src/monitor/event-handler.d.ts +27 -0
- package/dist/src/monitor/event-handler.js +90 -0
- package/dist/src/monitor/transcript-dispatch.d.ts +16 -0
- package/dist/src/monitor/transcript-dispatch.js +124 -0
- package/dist/src/monitor/transcript-format.d.ts +2 -0
- package/dist/src/monitor/transcript-format.js +41 -0
- package/dist/src/object.d.ts +4 -0
- package/dist/src/object.js +12 -0
- package/dist/src/routing.d.ts +11 -0
- package/dist/src/routing.js +13 -0
- package/dist/src/runtime.d.ts +3 -0
- package/dist/src/runtime.js +6 -0
- package/dist/src/status.d.ts +45 -0
- package/dist/src/status.js +45 -0
- package/index.ts +13 -0
- package/openclaw.plugin.json +71 -0
- package/package.json +93 -0
- package/plugin-inspector.config.json +15 -0
- package/setup-entry.ts +4 -0
- package/src/account.ts +265 -0
- package/src/channel.ts +148 -0
- package/src/config-schema.ts +57 -0
- package/src/cursor-store.ts +233 -0
- package/src/doctor.ts +39 -0
- package/src/event-types.ts +105 -0
- package/src/loggie-client.ts +111 -0
- package/src/monitor/connection.ts +349 -0
- package/src/monitor/event-handler.ts +133 -0
- package/src/monitor/transcript-dispatch.ts +145 -0
- package/src/monitor/transcript-format.ts +49 -0
- package/src/object.ts +15 -0
- package/src/routing.ts +27 -0
- package/src/runtime.ts +13 -0
- package/src/status.ts +72 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { ResolvedLoggieAccount } from "../account.js";
|
|
2
|
+
import {
|
|
3
|
+
advanceCursor,
|
|
4
|
+
deadLetterEvent,
|
|
5
|
+
decideCursor,
|
|
6
|
+
recordEventFailure,
|
|
7
|
+
type LoggieCursorStore,
|
|
8
|
+
} from "../cursor-store.js";
|
|
9
|
+
import {
|
|
10
|
+
isTranscriptReadyEvent,
|
|
11
|
+
parseLoggieEventEnvelope,
|
|
12
|
+
type LoggieEventEnvelope,
|
|
13
|
+
} from "../event-types.js";
|
|
14
|
+
import type { TranscriptDispatcher } from "./transcript-dispatch.js";
|
|
15
|
+
|
|
16
|
+
export type LoggieEventHandleResult =
|
|
17
|
+
| { status: "dispatched"; event: LoggieEventEnvelope }
|
|
18
|
+
| {
|
|
19
|
+
status: "skipped";
|
|
20
|
+
reason: string;
|
|
21
|
+
event?: LoggieEventEnvelope;
|
|
22
|
+
deadLettered?: {
|
|
23
|
+
attempts: number;
|
|
24
|
+
reason: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
| { status: "failed"; reason: string; retryable: boolean };
|
|
28
|
+
|
|
29
|
+
const MAX_EVENT_DISPATCH_ATTEMPTS = 3;
|
|
30
|
+
|
|
31
|
+
export async function handleLoggieEvent(params: {
|
|
32
|
+
raw: unknown;
|
|
33
|
+
account: ResolvedLoggieAccount;
|
|
34
|
+
cursorStore: LoggieCursorStore;
|
|
35
|
+
dispatcher: TranscriptDispatcher;
|
|
36
|
+
now?: Date;
|
|
37
|
+
}): Promise<LoggieEventHandleResult> {
|
|
38
|
+
const parsed = parseLoggieEventEnvelope(params.raw);
|
|
39
|
+
if (!parsed.ok) {
|
|
40
|
+
return { status: "failed", reason: parsed.reason, retryable: false };
|
|
41
|
+
}
|
|
42
|
+
const event = parsed.event;
|
|
43
|
+
const cursor = await params.cursorStore.load(params.account.accountId, params.account.agentProfileId);
|
|
44
|
+
if (event.agentProfileId && event.agentProfileId !== params.account.agentProfileId) {
|
|
45
|
+
const reason = `event agentProfileId does not match configured account`;
|
|
46
|
+
await params.cursorStore.save(
|
|
47
|
+
deadLetterEvent({
|
|
48
|
+
record: cursor,
|
|
49
|
+
event,
|
|
50
|
+
accountId: params.account.accountId,
|
|
51
|
+
agentProfileId: params.account.agentProfileId,
|
|
52
|
+
reason,
|
|
53
|
+
attempts: 1,
|
|
54
|
+
now: params.now,
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
return {
|
|
58
|
+
status: "skipped",
|
|
59
|
+
reason: `dead_lettered_non_retryable:${reason}`,
|
|
60
|
+
event,
|
|
61
|
+
deadLettered: {
|
|
62
|
+
attempts: 1,
|
|
63
|
+
reason,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const decision = decideCursor(cursor, event);
|
|
69
|
+
if (decision.action === "skip") {
|
|
70
|
+
return { status: "skipped", reason: decision.reason, event };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!isTranscriptReadyEvent(event)) {
|
|
74
|
+
await params.cursorStore.save(
|
|
75
|
+
advanceCursor({
|
|
76
|
+
record: cursor,
|
|
77
|
+
event,
|
|
78
|
+
accountId: params.account.accountId,
|
|
79
|
+
agentProfileId: params.account.agentProfileId,
|
|
80
|
+
now: params.now,
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
return { status: "skipped", reason: `unsupported_event:${event.eventType}`, event };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await params.dispatcher.dispatchTranscriptReady(event);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
90
|
+
const failure = recordEventFailure({
|
|
91
|
+
record: cursor,
|
|
92
|
+
event,
|
|
93
|
+
accountId: params.account.accountId,
|
|
94
|
+
agentProfileId: params.account.agentProfileId,
|
|
95
|
+
reason,
|
|
96
|
+
now: params.now,
|
|
97
|
+
});
|
|
98
|
+
if (failure.attempts < MAX_EVENT_DISPATCH_ATTEMPTS) {
|
|
99
|
+
await params.cursorStore.save(failure.record);
|
|
100
|
+
return { status: "failed", reason, retryable: true };
|
|
101
|
+
}
|
|
102
|
+
await params.cursorStore.save(
|
|
103
|
+
deadLetterEvent({
|
|
104
|
+
record: failure.record,
|
|
105
|
+
event,
|
|
106
|
+
accountId: params.account.accountId,
|
|
107
|
+
agentProfileId: params.account.agentProfileId,
|
|
108
|
+
reason,
|
|
109
|
+
attempts: failure.attempts,
|
|
110
|
+
now: params.now,
|
|
111
|
+
}),
|
|
112
|
+
);
|
|
113
|
+
return {
|
|
114
|
+
status: "skipped",
|
|
115
|
+
reason: `dead_lettered_after_${failure.attempts}_attempts:${reason}`,
|
|
116
|
+
event,
|
|
117
|
+
deadLettered: {
|
|
118
|
+
attempts: failure.attempts,
|
|
119
|
+
reason,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
await params.cursorStore.save(
|
|
124
|
+
advanceCursor({
|
|
125
|
+
record: cursor,
|
|
126
|
+
event,
|
|
127
|
+
accountId: params.account.accountId,
|
|
128
|
+
agentProfileId: params.account.agentProfileId,
|
|
129
|
+
now: params.now,
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
132
|
+
return { status: "dispatched", event };
|
|
133
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk/channel-core";
|
|
2
|
+
import type { ResolvedLoggieAccount } from "../account.js";
|
|
3
|
+
import type { LoggieTranscriptReadyEvent } from "../event-types.js";
|
|
4
|
+
import { fetchLoggieTranscriptDetail } from "../loggie-client.js";
|
|
5
|
+
import { buildLoggieRouteSessionKey, buildLoggieSessionId, meetingConversationId } from "../routing.js";
|
|
6
|
+
import { formatTranscriptReadyPrompt } from "./transcript-format.js";
|
|
7
|
+
|
|
8
|
+
export type TranscriptDispatcher = {
|
|
9
|
+
dispatchTranscriptReady(event: LoggieTranscriptReadyEvent): Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type ChannelRuntime = PluginRuntime["channel"];
|
|
13
|
+
|
|
14
|
+
export function createOpenClawTranscriptDispatcher(params: {
|
|
15
|
+
account: ResolvedLoggieAccount;
|
|
16
|
+
cfg: OpenClawConfig;
|
|
17
|
+
runtime: PluginRuntime;
|
|
18
|
+
channelRuntime: ChannelRuntime;
|
|
19
|
+
abortSignal?: AbortSignal;
|
|
20
|
+
fetchImpl?: typeof fetch;
|
|
21
|
+
}): TranscriptDispatcher {
|
|
22
|
+
const agentRuntime = params.runtime.agent;
|
|
23
|
+
return {
|
|
24
|
+
async dispatchTranscriptReady(event) {
|
|
25
|
+
const routeSessionKey = buildLoggieRouteSessionKey({ account: params.account, event });
|
|
26
|
+
const conversationId = meetingConversationId(event);
|
|
27
|
+
const detail = event.payload.detailPath
|
|
28
|
+
? await fetchLoggieTranscriptDetail({
|
|
29
|
+
account: params.account,
|
|
30
|
+
detailPath: event.payload.detailPath,
|
|
31
|
+
fetchImpl: params.fetchImpl,
|
|
32
|
+
})
|
|
33
|
+
: undefined;
|
|
34
|
+
const body = formatTranscriptReadyPrompt(event, detail);
|
|
35
|
+
const title = event.payload.title?.trim() || "Loggie meeting";
|
|
36
|
+
const timestamp = Date.parse(event.occurredAt);
|
|
37
|
+
const ctxPayload = await params.channelRuntime.inbound.buildContext({
|
|
38
|
+
channel: "loggie",
|
|
39
|
+
accountId: params.account.accountId,
|
|
40
|
+
provider: "loggie",
|
|
41
|
+
surface: "loggie",
|
|
42
|
+
messageId: event.eventId,
|
|
43
|
+
messageIdFull: `loggie:${event.eventId}`,
|
|
44
|
+
timestamp,
|
|
45
|
+
from: `loggie:${event.workspaceId}:${params.account.agentProfileId}`,
|
|
46
|
+
sender: {
|
|
47
|
+
id: params.account.agentProfileId,
|
|
48
|
+
name: "Loggie",
|
|
49
|
+
displayLabel: "Loggie",
|
|
50
|
+
},
|
|
51
|
+
conversation: {
|
|
52
|
+
kind: "group",
|
|
53
|
+
id: conversationId,
|
|
54
|
+
label: title,
|
|
55
|
+
nativeChannelId: conversationId,
|
|
56
|
+
},
|
|
57
|
+
route: {
|
|
58
|
+
routeSessionKey,
|
|
59
|
+
dispatchSessionKey: routeSessionKey,
|
|
60
|
+
accountId: params.account.accountId,
|
|
61
|
+
agentId: params.account.agentId,
|
|
62
|
+
},
|
|
63
|
+
reply: {
|
|
64
|
+
to: conversationId,
|
|
65
|
+
originatingTo: conversationId,
|
|
66
|
+
nativeChannelId: conversationId,
|
|
67
|
+
},
|
|
68
|
+
message: {
|
|
69
|
+
rawBody: body,
|
|
70
|
+
body,
|
|
71
|
+
bodyForAgent: body,
|
|
72
|
+
commandBody: body,
|
|
73
|
+
inboundEventKind: "user_request",
|
|
74
|
+
sourceModality: "text",
|
|
75
|
+
},
|
|
76
|
+
extra: {
|
|
77
|
+
LoggieEventId: event.eventId,
|
|
78
|
+
LoggieCursor: event.cursor,
|
|
79
|
+
LoggieSequence: event.sequence,
|
|
80
|
+
LoggieMeetingId: event.meetingId,
|
|
81
|
+
LoggieMeetingScheduleId: event.meetingScheduleId,
|
|
82
|
+
LoggieDetailPath: event.payload.detailPath,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const storePath = params.channelRuntime.session.resolveStorePath(undefined, {
|
|
87
|
+
agentId: params.account.agentId,
|
|
88
|
+
});
|
|
89
|
+
const sessionId = buildLoggieSessionId({ account: params.account, event });
|
|
90
|
+
await params.channelRuntime.inbound.runPreparedReply({
|
|
91
|
+
channel: "loggie",
|
|
92
|
+
accountId: params.account.accountId,
|
|
93
|
+
routeSessionKey,
|
|
94
|
+
storePath,
|
|
95
|
+
ctxPayload,
|
|
96
|
+
recordInboundSession: params.channelRuntime.session.recordInboundSession,
|
|
97
|
+
record: {
|
|
98
|
+
createIfMissing: true,
|
|
99
|
+
updateLastRoute: {
|
|
100
|
+
sessionKey: routeSessionKey,
|
|
101
|
+
channel: "loggie",
|
|
102
|
+
to: conversationId,
|
|
103
|
+
accountId: params.account.accountId,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
runDispatch: async () => {
|
|
107
|
+
const workspaceDir = agentRuntime.resolveAgentWorkspaceDir(
|
|
108
|
+
params.cfg,
|
|
109
|
+
params.account.agentId,
|
|
110
|
+
);
|
|
111
|
+
await agentRuntime.ensureAgentWorkspace?.({ dir: workspaceDir });
|
|
112
|
+
return agentRuntime.runEmbeddedAgent({
|
|
113
|
+
sessionId,
|
|
114
|
+
sessionKey: routeSessionKey,
|
|
115
|
+
agentId: params.account.agentId,
|
|
116
|
+
messageChannel: "loggie",
|
|
117
|
+
messageProvider: "loggie",
|
|
118
|
+
chatType: "group",
|
|
119
|
+
agentAccountId: params.account.accountId,
|
|
120
|
+
trigger: "user",
|
|
121
|
+
messageTo: conversationId,
|
|
122
|
+
messageThreadId: conversationId,
|
|
123
|
+
groupId: conversationId,
|
|
124
|
+
groupChannel: title,
|
|
125
|
+
senderId: params.account.agentProfileId,
|
|
126
|
+
senderName: "Loggie",
|
|
127
|
+
currentChannelId: conversationId,
|
|
128
|
+
currentMessageId: event.eventId,
|
|
129
|
+
chatId: conversationId,
|
|
130
|
+
workspaceDir,
|
|
131
|
+
agentDir: agentRuntime.resolveAgentDir(params.cfg, params.account.agentId),
|
|
132
|
+
config: params.cfg,
|
|
133
|
+
prompt: body,
|
|
134
|
+
transcriptPrompt: body,
|
|
135
|
+
currentInboundEventKind: "user_request",
|
|
136
|
+
currentInboundContext: { text: body },
|
|
137
|
+
timeoutMs: agentRuntime.resolveAgentTimeoutMs({ cfg: params.cfg }),
|
|
138
|
+
runId: `loggie-${event.eventId}`,
|
|
139
|
+
abortSignal: params.abortSignal,
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { LoggieTranscriptReadyEvent } from "../event-types.js";
|
|
2
|
+
|
|
3
|
+
const MAX_DETAIL_CHARS = 60_000;
|
|
4
|
+
|
|
5
|
+
export function formatTranscriptReadyPrompt(
|
|
6
|
+
event: LoggieTranscriptReadyEvent,
|
|
7
|
+
detail?: unknown,
|
|
8
|
+
): string {
|
|
9
|
+
const title = event.payload.title?.trim() || "Untitled meeting";
|
|
10
|
+
const meetingDate = event.payload.meetingDate ?? event.occurredAt;
|
|
11
|
+
const lines = [
|
|
12
|
+
`Loggie meeting transcript ready: ${title}`,
|
|
13
|
+
`Meeting ID: ${event.meetingScheduleId ?? event.meetingId}`,
|
|
14
|
+
`Workspace ID: ${event.workspaceId}`,
|
|
15
|
+
`Occurred At: ${event.occurredAt}`,
|
|
16
|
+
`Meeting Date: ${meetingDate}`,
|
|
17
|
+
];
|
|
18
|
+
if (event.payload.source) {
|
|
19
|
+
lines.push(`Source: ${event.payload.source}`);
|
|
20
|
+
}
|
|
21
|
+
if (event.payload.externalId) {
|
|
22
|
+
lines.push(`External Transcript ID: ${event.payload.externalId}`);
|
|
23
|
+
}
|
|
24
|
+
if (event.payload.detailPath) {
|
|
25
|
+
lines.push(`Transcript Detail Path: ${event.payload.detailPath}`);
|
|
26
|
+
}
|
|
27
|
+
const formattedDetail = formatTranscriptDetail(detail);
|
|
28
|
+
if (formattedDetail) {
|
|
29
|
+
lines.push("", "Transcript Detail:", formattedDetail);
|
|
30
|
+
}
|
|
31
|
+
return lines.join("\n");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function formatTranscriptDetail(detail: unknown): string | undefined {
|
|
35
|
+
if (detail === undefined || detail === null) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
const text =
|
|
39
|
+
typeof detail === "string"
|
|
40
|
+
? detail
|
|
41
|
+
: JSON.stringify(detail, null, 2);
|
|
42
|
+
const trimmed = text.trim();
|
|
43
|
+
if (!trimmed) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
return trimmed.length > MAX_DETAIL_CHARS
|
|
47
|
+
? `${trimmed.slice(0, MAX_DETAIL_CHARS)}\n[truncated]`
|
|
48
|
+
: trimmed;
|
|
49
|
+
}
|
package/src/object.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function isRecord(value: unknown): value is Record<string, unknown> {
|
|
2
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function readString(value: unknown): string | undefined {
|
|
6
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function readBoolean(value: unknown, fallback: boolean): boolean {
|
|
10
|
+
return typeof value === "boolean" ? value : fallback;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function readInteger(value: unknown, fallback: number): number {
|
|
14
|
+
return Number.isInteger(value) ? (value as number) : fallback;
|
|
15
|
+
}
|
package/src/routing.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ResolvedLoggieAccount } from "./account.js";
|
|
2
|
+
import type { LoggieEventEnvelope } from "./event-types.js";
|
|
3
|
+
|
|
4
|
+
const UNSAFE_SESSION_CHARS_RE = /[^a-zA-Z0-9._-]+/g;
|
|
5
|
+
|
|
6
|
+
export function meetingConversationId(event: LoggieEventEnvelope): string {
|
|
7
|
+
return event.meetingScheduleId ?? event.meetingId ?? event.eventId;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function buildLoggieRouteSessionKey(params: {
|
|
11
|
+
account: Pick<ResolvedLoggieAccount, "accountId" | "agentId">;
|
|
12
|
+
event: LoggieEventEnvelope;
|
|
13
|
+
}): string {
|
|
14
|
+
return `agent:${params.account.agentId}:loggie:${params.account.accountId}:meeting:${meetingConversationId(
|
|
15
|
+
params.event,
|
|
16
|
+
)}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function buildLoggieSessionId(params: {
|
|
20
|
+
account: Pick<ResolvedLoggieAccount, "accountId">;
|
|
21
|
+
event: LoggieEventEnvelope;
|
|
22
|
+
}): string {
|
|
23
|
+
return `loggie-${params.account.accountId}-${meetingConversationId(params.event)}`
|
|
24
|
+
.replace(UNSAFE_SESSION_CHARS_RE, "-")
|
|
25
|
+
.replace(/^-+|-+$/g, "")
|
|
26
|
+
.slice(0, 128);
|
|
27
|
+
}
|
package/src/runtime.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PluginRuntime } from "openclaw/plugin-sdk/channel-core";
|
|
2
|
+
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
setRuntime: setLoggieRuntime,
|
|
6
|
+
clearRuntime: clearLoggieRuntime,
|
|
7
|
+
tryGetRuntime: getOptionalLoggieRuntime,
|
|
8
|
+
} = createPluginRuntimeStore<PluginRuntime>({
|
|
9
|
+
pluginId: "loggie",
|
|
10
|
+
errorMessage: "Loggie runtime not initialized",
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export { clearLoggieRuntime, getOptionalLoggieRuntime, setLoggieRuntime };
|
package/src/status.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { buildBaseAccountStatusSnapshot, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
2
|
+
import type { ResolvedLoggieAccount } from "./account.js";
|
|
3
|
+
|
|
4
|
+
export type LoggieRuntimeExtra = {
|
|
5
|
+
connected?: boolean;
|
|
6
|
+
authenticated?: boolean;
|
|
7
|
+
caughtUp?: boolean;
|
|
8
|
+
lastEventId?: string | null;
|
|
9
|
+
lastCursor?: string | null;
|
|
10
|
+
lastSequence?: number | null;
|
|
11
|
+
lastDispatchAt?: number | null;
|
|
12
|
+
lastDeadLetterAt?: number | null;
|
|
13
|
+
lastDeadLetteredEventId?: string | null;
|
|
14
|
+
lastDeadLetteredCursor?: string | null;
|
|
15
|
+
lastDeadLetterReason?: string | null;
|
|
16
|
+
lastDeadLetterAttempts?: number | null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const defaultLoggieRuntimeState = createDefaultChannelRuntimeState<LoggieRuntimeExtra>(
|
|
20
|
+
"default",
|
|
21
|
+
{
|
|
22
|
+
connected: false,
|
|
23
|
+
authenticated: false,
|
|
24
|
+
caughtUp: false,
|
|
25
|
+
lastEventId: null,
|
|
26
|
+
lastCursor: null,
|
|
27
|
+
lastSequence: null,
|
|
28
|
+
lastDispatchAt: null,
|
|
29
|
+
lastDeadLetterAt: null,
|
|
30
|
+
lastDeadLetteredEventId: null,
|
|
31
|
+
lastDeadLetteredCursor: null,
|
|
32
|
+
lastDeadLetterReason: null,
|
|
33
|
+
lastDeadLetterAttempts: null,
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export function buildLoggieAccountStatusSnapshot(params: {
|
|
38
|
+
account: ResolvedLoggieAccount;
|
|
39
|
+
runtime?: Record<string, unknown> | null;
|
|
40
|
+
}) {
|
|
41
|
+
return buildBaseAccountStatusSnapshot(
|
|
42
|
+
{
|
|
43
|
+
account: {
|
|
44
|
+
accountId: params.account.accountId,
|
|
45
|
+
name: params.account.name,
|
|
46
|
+
enabled: params.account.enabled,
|
|
47
|
+
configured: params.account.configured,
|
|
48
|
+
},
|
|
49
|
+
runtime: params.runtime,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
mode: "websocket",
|
|
53
|
+
baseUrl: params.account.baseUrl,
|
|
54
|
+
agentId: params.account.agentId,
|
|
55
|
+
agentProfileId: params.account.agentProfileId,
|
|
56
|
+
tokenStatus: params.account.tokenStatus.status,
|
|
57
|
+
tokenSource: params.account.tokenStatus.source,
|
|
58
|
+
connected: params.runtime?.connected ?? false,
|
|
59
|
+
authenticated: params.runtime?.authenticated ?? false,
|
|
60
|
+
caughtUp: params.runtime?.caughtUp ?? false,
|
|
61
|
+
lastEventId: params.runtime?.lastEventId ?? null,
|
|
62
|
+
lastCursor: params.runtime?.lastCursor ?? null,
|
|
63
|
+
lastSequence: params.runtime?.lastSequence ?? null,
|
|
64
|
+
lastDispatchAt: params.runtime?.lastDispatchAt ?? null,
|
|
65
|
+
lastDeadLetterAt: params.runtime?.lastDeadLetterAt ?? null,
|
|
66
|
+
lastDeadLetteredEventId: params.runtime?.lastDeadLetteredEventId ?? null,
|
|
67
|
+
lastDeadLetteredCursor: params.runtime?.lastDeadLetteredCursor ?? null,
|
|
68
|
+
lastDeadLetterReason: params.runtime?.lastDeadLetterReason ?? null,
|
|
69
|
+
lastDeadLetterAttempts: params.runtime?.lastDeadLetterAttempts ?? null,
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
}
|