@shadowob/shared
Advanced tools
| // src/types/inbox.types.ts | ||
| var BUDDY_INBOX_TOPIC_PREFIX = "shadow:buddy-inbox:"; | ||
| var BUDDY_INBOX_DELIVERY_PERMISSION = "buddy_inbox:deliver"; | ||
| var BUDDY_INBOX_PLATFORM_PERMISSIONS = [BUDDY_INBOX_DELIVERY_PERMISSION]; | ||
| function isBuddyInboxPlatformPermission(value) { | ||
| return typeof value === "string" && BUDDY_INBOX_PLATFORM_PERMISSIONS.includes(value); | ||
| } | ||
| function buddyInboxTopic(agentId) { | ||
| return `${BUDDY_INBOX_TOPIC_PREFIX}${agentId}`; | ||
| } | ||
| function parseBuddyInboxAgentId(topic) { | ||
| if (!topic?.startsWith(BUDDY_INBOX_TOPIC_PREFIX)) return null; | ||
| const agentId = topic.slice(BUDDY_INBOX_TOPIC_PREFIX.length).trim(); | ||
| return agentId || null; | ||
| } | ||
| function isBuddyInboxTopic(topic) { | ||
| return parseBuddyInboxAgentId(topic) !== null; | ||
| } | ||
| var TASK_MESSAGE_CARD_STATUSES = [ | ||
| "queued", | ||
| "claimed", | ||
| "running", | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TERMINAL_TASK_MESSAGE_CARD_STATUSES = [ | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TASK_MESSAGE_CARD_STATUS_TRANSITIONS = { | ||
| queued: ["queued", "claimed", "running", "completed", "failed", "canceled"], | ||
| claimed: ["claimed", "running", "completed", "failed", "canceled"], | ||
| running: ["running", "completed", "failed", "canceled"], | ||
| completed: ["completed"], | ||
| failed: ["failed", "transferred"], | ||
| canceled: ["canceled"], | ||
| transferred: ["transferred"] | ||
| }; | ||
| function isTerminalTaskMessageCardStatus(status) { | ||
| return TERMINAL_TASK_MESSAGE_CARD_STATUSES.includes( | ||
| status | ||
| ); | ||
| } | ||
| function isTaskMessageCardStatus(value) { | ||
| return typeof value === "string" && TASK_MESSAGE_CARD_STATUSES.includes(value); | ||
| } | ||
| function canTransitionTaskMessageCardStatus(from, to) { | ||
| const allowed = TASK_MESSAGE_CARD_STATUS_TRANSITIONS[from]; | ||
| return allowed.includes(to); | ||
| } | ||
| function isRecord(value) { | ||
| return !!value && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isMessageReferenceCard(card) { | ||
| return card?.kind === "message_reference" && typeof card.title === "string" && isRecord(card.target) && typeof card.target.channelId === "string" && typeof card.target.messageId === "string"; | ||
| } | ||
| function getBuddyInboxTaskCards(message) { | ||
| const cards = message.metadata?.cards; | ||
| if (!Array.isArray(cards)) return []; | ||
| return cards.filter( | ||
| (card) => card?.kind === "task" && typeof card.id === "string" && isTaskMessageCardStatus(card.status) | ||
| ); | ||
| } | ||
| function hasBuddyInboxTaskCard(message) { | ||
| return getBuddyInboxTaskCards(message).length > 0; | ||
| } | ||
| function getBuddyInboxTaskStatuses(message) { | ||
| return getBuddyInboxTaskCards(message).map((card) => card.status); | ||
| } | ||
| function buildBuddyInboxViewMessages(messages, options) { | ||
| void options; | ||
| return [...messages]; | ||
| } | ||
| var DEFAULT_BUDDY_INBOX_ADMISSION_POLICY = { | ||
| defaultMode: "allow", | ||
| rules: [] | ||
| }; | ||
| function parseAdmissionMode(value, fallback) { | ||
| if (value === "allow" || value === "deny" || value === "first_time" || value === "every_time") { | ||
| return value; | ||
| } | ||
| if (value === void 0 || value === null) return fallback; | ||
| throw new Error("Invalid Buddy Inbox admission mode"); | ||
| } | ||
| function parseSubjectKind(value) { | ||
| if (value === "user" || value === "agent" || value === "server_app" || value === "system") { | ||
| return value; | ||
| } | ||
| throw new Error("Invalid Buddy Inbox admission subject kind"); | ||
| } | ||
| function parseOptionalString(value, field, maxLength) { | ||
| if (value === void 0 || value === null || value === "") return void 0; | ||
| if (typeof value !== "string" || value.length > maxLength) { | ||
| throw new Error(`Invalid Buddy Inbox admission ${field}`); | ||
| } | ||
| return value; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPolicy(value) { | ||
| if (value === void 0 || value === null) return { ...DEFAULT_BUDDY_INBOX_ADMISSION_POLICY }; | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox admission policy"); | ||
| const defaultMode = parseAdmissionMode(value.defaultMode, "allow"); | ||
| const rawRules = value.rules; | ||
| if (rawRules !== void 0 && !Array.isArray(rawRules)) { | ||
| throw new Error("Invalid Buddy Inbox admission rules"); | ||
| } | ||
| const rules = (rawRules ?? []).slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox admission rule"); | ||
| return { | ||
| subjectKind: parseSubjectKind(entry.subjectKind), | ||
| subjectId: parseOptionalString(entry.subjectId, "subjectId", 160), | ||
| appKey: parseOptionalString(entry.appKey, "appKey", 120), | ||
| mode: parseAdmissionMode(entry.mode, defaultMode), | ||
| ...entry.approved === true ? { approved: true } : {}, | ||
| note: parseOptionalString(entry.note, "note", 500), | ||
| createdAt: parseOptionalString(entry.createdAt, "createdAt", 64), | ||
| updatedAt: parseOptionalString(entry.updatedAt, "updatedAt", 64) | ||
| }; | ||
| }); | ||
| return { defaultMode, rules }; | ||
| } | ||
| function buddyInboxAdmissionRuleKey(rule) { | ||
| return [rule.subjectKind, rule.subjectId ?? "", rule.appKey ?? ""].join(":"); | ||
| } | ||
| function parsePendingTask(value) { | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox pending task"); | ||
| const title = parseOptionalString(value.title, "task.title", 180); | ||
| if (!title) throw new Error("Invalid Buddy Inbox pending task title"); | ||
| const body = parseOptionalString(value.body, "task.body", 8e3); | ||
| const priority = value.priority; | ||
| if (priority !== void 0 && priority !== "low" && priority !== "normal" && priority !== "medium" && priority !== "high") { | ||
| throw new Error("Invalid Buddy Inbox pending task priority"); | ||
| } | ||
| const idempotencyKey = parseOptionalString(value.idempotencyKey, "task.idempotencyKey", 240); | ||
| const source = isRecord(value.source) ? value.source : void 0; | ||
| const requirements = isRecord(value.requirements) ? value.requirements : void 0; | ||
| const outputContract = isRecord(value.outputContract) ? value.outputContract : void 0; | ||
| const privacy = isRecord(value.privacy) ? value.privacy : void 0; | ||
| const data = isRecord(value.data) ? value.data : void 0; | ||
| return { | ||
| title, | ||
| ...body ? { body } : {}, | ||
| ...priority ? { priority } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...source ? { source } : {}, | ||
| ...requirements ? { requirements } : {}, | ||
| ...outputContract ? { outputContract } : {}, | ||
| ...privacy ? { privacy } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPendingDeliveries(value) { | ||
| if (value === void 0 || value === null) return []; | ||
| if (!Array.isArray(value)) throw new Error("Invalid Buddy Inbox pending deliveries"); | ||
| return value.slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox pending delivery"); | ||
| const id = parseOptionalString(entry.id, "pending.id", 80); | ||
| const serverId = parseOptionalString(entry.serverId, "pending.serverId", 160); | ||
| const channelId = parseOptionalString(entry.channelId, "pending.channelId", 160); | ||
| const agentId = parseOptionalString(entry.agentId, "pending.agentId", 160); | ||
| const mode = parseAdmissionMode(entry.mode, "first_time"); | ||
| if (mode !== "first_time" && mode !== "every_time") { | ||
| throw new Error("Invalid Buddy Inbox pending mode"); | ||
| } | ||
| if (!isRecord(entry.subject)) throw new Error("Invalid Buddy Inbox pending subject"); | ||
| if (!isRecord(entry.requestedBy)) throw new Error("Invalid Buddy Inbox pending requester"); | ||
| if (!id || !serverId || !channelId || !agentId) { | ||
| throw new Error("Invalid Buddy Inbox pending delivery identifiers"); | ||
| } | ||
| const requestedAt = parseOptionalString(entry.requestedAt, "pending.requestedAt", 64); | ||
| if (!requestedAt) throw new Error("Invalid Buddy Inbox pending requestedAt"); | ||
| return { | ||
| id, | ||
| serverId, | ||
| channelId, | ||
| agentId, | ||
| mode, | ||
| subject: { | ||
| kind: parseSubjectKind(entry.subject.kind), | ||
| id: parseOptionalString(entry.subject.id, "subject.id", 160), | ||
| appKey: parseOptionalString(entry.subject.appKey, "subject.appKey", 120), | ||
| label: parseOptionalString(entry.subject.label, "subject.label", 160) | ||
| }, | ||
| task: parsePendingTask(entry.task), | ||
| requestedBy: entry.requestedBy, | ||
| requestedAt, | ||
| updatedAt: parseOptionalString(entry.updatedAt, "pending.updatedAt", 64) | ||
| }; | ||
| }); | ||
| } | ||
| // src/types/message.types.ts | ||
| var MESSAGE_COPILOT_CONTEXT_METADATA_KEY = "copilotContext"; | ||
| var MESSAGE_AGENT_CHAIN_METADATA_KEY = "agentChain"; | ||
| function isBoundedMetadataString(value, maxLength, required = false) { | ||
| if (typeof value !== "string") return !required && value == null; | ||
| const trimmed = value.trim(); | ||
| return trimmed.length > 0 && trimmed.length <= maxLength; | ||
| } | ||
| function isMessageCopilotContext(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| return record.kind === "server_app_copilot" && isBoundedMetadataString(record.appKey, 120, true) && isBoundedMetadataString(record.serverAppId, 160) && isBoundedMetadataString(record.appId, 160) && isBoundedMetadataString(record.appName, 160) && isBoundedMetadataString(record.serverId, 160) && isBoundedMetadataString(record.serverSlug, 160) && isBoundedMetadataString(record.channelId, 160) && isBoundedMetadataString(record.channelKind, 40); | ||
| } | ||
| function buildMessageCopilotContextMetadata(context) { | ||
| return context && isMessageCopilotContext(context) ? { copilotContext: context } : void 0; | ||
| } | ||
| function isMessageAgentChainMetadata(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| const startedAt = record.startedAt; | ||
| return isBoundedMetadataString(record.agentId, 160, true) && typeof record.depth === "number" && Number.isInteger(record.depth) && record.depth >= 0 && record.depth <= 100 && Array.isArray(record.participants) && record.participants.length <= 100 && record.participants.every((participant) => isBoundedMetadataString(participant, 160, true)) && (startedAt == null || typeof startedAt === "number" && Number.isInteger(startedAt) && startedAt >= 0 || isBoundedMetadataString(startedAt, 64, true)) && isBoundedMetadataString(record.rootMessageId, 160); | ||
| } | ||
| function buildMessageAgentChainMetadata(agentChain) { | ||
| return agentChain && isMessageAgentChainMetadata(agentChain) ? { agentChain } : void 0; | ||
| } | ||
| function metadataRecord(value) { | ||
| return value && typeof value === "object" && !Array.isArray(value) ? value : null; | ||
| } | ||
| function metadataString(value) { | ||
| return typeof value === "string" && value.trim() ? value.trim() : null; | ||
| } | ||
| function isMessageCardStatus(value) { | ||
| return value === "queued" || value === "claimed" || value === "running" || value === "completed" || value === "failed" || value === "canceled" || value === "transferred"; | ||
| } | ||
| function parseBuddyInboxTaskRef(value) { | ||
| const record = metadataRecord(value); | ||
| if (!record) return void 0; | ||
| const messageId = metadataString(record.messageId); | ||
| const cardId = metadataString(record.cardId); | ||
| const channelId = metadataString(record.channelId); | ||
| const threadId = metadataString(record.threadId); | ||
| const title = metadataString(record.title); | ||
| if (!messageId || !cardId || !channelId) return void 0; | ||
| const extra = { ...record }; | ||
| delete extra.messageId; | ||
| delete extra.cardId; | ||
| delete extra.channelId; | ||
| delete extra.threadId; | ||
| delete extra.title; | ||
| return { | ||
| ...extra, | ||
| messageId, | ||
| cardId, | ||
| channelId, | ||
| threadId, | ||
| ...title ? { title } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultCard(value) { | ||
| const result = metadataRecord(value); | ||
| if (!result || result.kind !== "task_result") return null; | ||
| const taskMessageId = metadataString(result.taskMessageId); | ||
| const taskCardId = metadataString(result.taskCardId); | ||
| const status = result.status; | ||
| if (!taskMessageId || !taskCardId || !isMessageCardStatus(status)) return null; | ||
| const id = metadataString(result.id) ?? `task-result:${taskMessageId}:${taskCardId}:${status}`; | ||
| const version = typeof result.version === "number" && Number.isFinite(result.version) ? Math.max(1, Math.trunc(result.version)) : 1; | ||
| const title = metadataString(result.title) ?? metadataString(metadataRecord(result.sourceTask)?.title) ?? metadataString(metadataRecord(result.parentTask)?.title) ?? "Task result"; | ||
| const body = metadataString(result.body); | ||
| const idempotencyKey = metadataString(result.idempotencyKey); | ||
| const delivery = metadataString(result.delivery); | ||
| const createdAt = metadataString(result.createdAt); | ||
| const updatedAt = metadataString(result.updatedAt); | ||
| const sourceTask = parseBuddyInboxTaskRef(result.sourceTask); | ||
| const parentTask = parseBuddyInboxTaskRef(result.parentTask); | ||
| const data = metadataRecord(result.data); | ||
| const extra = { ...result }; | ||
| delete extra.id; | ||
| delete extra.kind; | ||
| delete extra.version; | ||
| delete extra.title; | ||
| delete extra.body; | ||
| delete extra.idempotencyKey; | ||
| delete extra.taskMessageId; | ||
| delete extra.taskCardId; | ||
| delete extra.status; | ||
| delete extra.delivery; | ||
| delete extra.createdAt; | ||
| delete extra.updatedAt; | ||
| delete extra.sourceTask; | ||
| delete extra.parentTask; | ||
| delete extra.data; | ||
| return { | ||
| ...extra, | ||
| id, | ||
| kind: "task_result", | ||
| version, | ||
| title, | ||
| taskMessageId, | ||
| taskCardId, | ||
| status, | ||
| ...body ? { body } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...delivery ? { delivery } : {}, | ||
| ...createdAt ? { createdAt } : {}, | ||
| ...updatedAt ? { updatedAt } : {}, | ||
| ...sourceTask ? { sourceTask } : {}, | ||
| ...parentTask ? { parentTask } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultMetadata(metadata) { | ||
| const record = metadataRecord(metadata); | ||
| const cards = Array.isArray(record?.cards) ? record.cards : []; | ||
| for (const card of cards) { | ||
| const result = parseBuddyInboxTaskResultCard(card); | ||
| if (result) return result; | ||
| } | ||
| const custom = metadataRecord(record?.custom); | ||
| return parseBuddyInboxTaskResultCard(custom?.buddyInboxTaskResult); | ||
| } | ||
| function isMetadataRecord(value) { | ||
| return Boolean(value) && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isCommerceMessageCard(card) { | ||
| if (!isMetadataRecord(card)) return false; | ||
| const kind = card.kind; | ||
| return (kind === "offer" || kind === "product") && typeof card.id === "string" && typeof card.productId === "string" && typeof card.shopId === "string" && isMetadataRecord(card.snapshot) && isMetadataRecord(card.purchase); | ||
| } | ||
| function isPaidFileMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "paid_file" && typeof card.id === "string" && typeof card.fileId === "string" && isMetadataRecord(card.snapshot); | ||
| } | ||
| function isOAuthLinkMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "oauth_link" && typeof card.id === "string" && typeof card.appId === "string" && typeof card.title === "string" && typeof card.url === "string" && isMetadataRecord(card.action); | ||
| } | ||
| function getCommerceMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isCommerceMessageCard) : []; | ||
| } | ||
| function getPaidFileMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isPaidFileMessageCard) : []; | ||
| } | ||
| function getOAuthLinkMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isOAuthLinkMessageCard) : []; | ||
| } | ||
| // src/types/runtime-session.types.ts | ||
| var RUNTIME_SESSION_PET_REACTION_BY_STATE = { | ||
| idle: "idle", | ||
| running: "working", | ||
| streaming: "thinking", | ||
| tool_call: "working", | ||
| waiting_for_approval: "waiting", | ||
| blocked: "waiting", | ||
| completed: "success", | ||
| failed: "error", | ||
| stopped: "idle", | ||
| unknown: "idle" | ||
| }; | ||
| function runtimeSessionPetReactionForState(state) { | ||
| return RUNTIME_SESSION_PET_REACTION_BY_STATE[state] ?? "idle"; | ||
| } | ||
| function runtimeSessionSignalToPetReaction(signal) { | ||
| switch (signal) { | ||
| case "running": | ||
| return "working"; | ||
| case "streaming": | ||
| return "thinking"; | ||
| case "tool_call": | ||
| return "working"; | ||
| case "waiting_for_approval": | ||
| case "blocked": | ||
| return "waiting"; | ||
| case "completed": | ||
| return "success"; | ||
| case "failed": | ||
| return "error"; | ||
| case "stopped": | ||
| case "unknown": | ||
| return "idle"; | ||
| default: | ||
| return signal; | ||
| } | ||
| } | ||
| function runtimeSessionStateLooksActive(state) { | ||
| return state === "running" || state === "streaming" || state === "tool_call" || state === "waiting_for_approval" || state === "blocked"; | ||
| } | ||
| // src/types/user.types.ts | ||
| var USER_STATUSES = ["online", "idle", "dnd", "offline"]; | ||
| var BUDDY_PRESENCE_STATUSES = ["online", "busy", "idle", "dnd", "offline"]; | ||
| var BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS = 9e4; | ||
| function normalizeUserStatus(status) { | ||
| if (status === "online" || status === "idle" || status === "dnd" || status === "offline") { | ||
| return status; | ||
| } | ||
| return "offline"; | ||
| } | ||
| function normalizeBuddyPresenceStatus(status, options) { | ||
| if (options?.busy) { | ||
| return "busy"; | ||
| } | ||
| if (status === "busy") { | ||
| return "busy"; | ||
| } | ||
| return normalizeUserStatus(status); | ||
| } | ||
| function normalizePresenceStatus(status, options) { | ||
| return normalizeBuddyPresenceStatus(status, options); | ||
| } | ||
| function isBuddyHeartbeatActive(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return false; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return false; | ||
| const nowMs = options?.nowMs ?? Date.now(); | ||
| const thresholdMs = options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS; | ||
| return nowMs - heartbeatMs <= thresholdMs; | ||
| } | ||
| function normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy || agentStatus === "busy") return "busy"; | ||
| if (agentStatus === "running") { | ||
| return isBuddyHeartbeatActive(lastHeartbeat, { nowMs }) ? "online" : "offline"; | ||
| } | ||
| const normalizedAgentStatus = normalizeBuddyPresenceStatus(agentStatus); | ||
| if (normalizedAgentStatus !== "offline") return normalizedAgentStatus; | ||
| return "offline"; | ||
| } | ||
| function resolvePresenceStatus({ | ||
| userStatus, | ||
| isBot, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy) return "busy"; | ||
| if (isBot || agentStatus != null || lastHeartbeat != null) { | ||
| return normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| nowMs | ||
| }); | ||
| } | ||
| return normalizePresenceStatus(userStatus); | ||
| } | ||
| function getBuddyPresenceExpiresAt(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return null; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return null; | ||
| return new Date( | ||
| heartbeatMs + (options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS) | ||
| ).toISOString(); | ||
| } | ||
| function applyPresenceChangeToRuntime(current, update, options) { | ||
| const observedAt = update.observedAt ?? options?.observedAt ?? (/* @__PURE__ */ new Date()).toISOString(); | ||
| const userStatus = normalizeUserStatus(update.status); | ||
| const hasAgentPresence = current.isBot === true || current.agentStatus != null || current.lastHeartbeat != null || update.agentId != null || update.agentStatus !== void 0 || update.lastHeartbeat !== void 0; | ||
| if (!hasAgentPresence) return { userStatus }; | ||
| const agentStatus = update.agentStatus !== void 0 ? update.agentStatus : current.agentStatus ?? null; | ||
| let lastHeartbeat = current.lastHeartbeat ?? null; | ||
| if (update.lastHeartbeat !== void 0) { | ||
| lastHeartbeat = update.lastHeartbeat; | ||
| } else if (userStatus === "online" && (update.agentStatus === "running" || current.agentStatus === "running")) { | ||
| lastHeartbeat = observedAt; | ||
| } else if (userStatus === "offline") { | ||
| lastHeartbeat = null; | ||
| } | ||
| return { userStatus, agentStatus, lastHeartbeat }; | ||
| } | ||
| export { | ||
| BUDDY_INBOX_TOPIC_PREFIX, | ||
| BUDDY_INBOX_DELIVERY_PERMISSION, | ||
| BUDDY_INBOX_PLATFORM_PERMISSIONS, | ||
| isBuddyInboxPlatformPermission, | ||
| buddyInboxTopic, | ||
| parseBuddyInboxAgentId, | ||
| isBuddyInboxTopic, | ||
| TASK_MESSAGE_CARD_STATUSES, | ||
| TERMINAL_TASK_MESSAGE_CARD_STATUSES, | ||
| TASK_MESSAGE_CARD_STATUS_TRANSITIONS, | ||
| isTerminalTaskMessageCardStatus, | ||
| isTaskMessageCardStatus, | ||
| canTransitionTaskMessageCardStatus, | ||
| isMessageReferenceCard, | ||
| getBuddyInboxTaskCards, | ||
| hasBuddyInboxTaskCard, | ||
| getBuddyInboxTaskStatuses, | ||
| buildBuddyInboxViewMessages, | ||
| DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, | ||
| normalizeBuddyInboxAdmissionPolicy, | ||
| buddyInboxAdmissionRuleKey, | ||
| normalizeBuddyInboxAdmissionPendingDeliveries, | ||
| MESSAGE_COPILOT_CONTEXT_METADATA_KEY, | ||
| MESSAGE_AGENT_CHAIN_METADATA_KEY, | ||
| isMessageCopilotContext, | ||
| buildMessageCopilotContextMetadata, | ||
| isMessageAgentChainMetadata, | ||
| buildMessageAgentChainMetadata, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| isCommerceMessageCard, | ||
| isPaidFileMessageCard, | ||
| isOAuthLinkMessageCard, | ||
| getCommerceMessageCards, | ||
| getPaidFileMessageCards, | ||
| getOAuthLinkMessageCards, | ||
| RUNTIME_SESSION_PET_REACTION_BY_STATE, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive, | ||
| USER_STATUSES, | ||
| BUDDY_PRESENCE_STATUSES, | ||
| BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| normalizeUserStatus, | ||
| normalizeBuddyPresenceStatus, | ||
| normalizePresenceStatus, | ||
| isBuddyHeartbeatActive, | ||
| normalizeBuddyRuntimePresenceStatus, | ||
| resolvePresenceStatus, | ||
| getBuddyPresenceExpiresAt, | ||
| applyPresenceChangeToRuntime | ||
| }; |
+1
-1
@@ -115,3 +115,3 @@ import { | ||
| runtimeSessionStateLooksActive | ||
| } from "./chunk-7YMBXKQG.js"; | ||
| } from "./chunk-G7TRWZCK.js"; | ||
| import { | ||
@@ -118,0 +118,0 @@ CAT_AVATAR_COUNT, |
@@ -500,3 +500,3 @@ "use strict"; | ||
| if (normalizedAgentStatus !== "offline") return normalizedAgentStatus; | ||
| return normalizeUserStatus(userStatus); | ||
| return "offline"; | ||
| } | ||
@@ -535,7 +535,7 @@ function resolvePresenceStatus({ | ||
| if (!hasAgentPresence) return { userStatus }; | ||
| const agentStatus = update.agentStatus !== void 0 ? update.agentStatus : current.agentStatus ?? (userStatus === "online" ? "running" : null); | ||
| const agentStatus = update.agentStatus !== void 0 ? update.agentStatus : current.agentStatus ?? null; | ||
| let lastHeartbeat = current.lastHeartbeat ?? null; | ||
| if (update.lastHeartbeat !== void 0) { | ||
| lastHeartbeat = update.lastHeartbeat; | ||
| } else if (userStatus === "online") { | ||
| } else if (userStatus === "online" && (update.agentStatus === "running" || current.agentStatus === "running")) { | ||
| lastHeartbeat = observedAt; | ||
@@ -542,0 +542,0 @@ } else if (userStatus === "offline") { |
@@ -52,3 +52,3 @@ import { | ||
| runtimeSessionStateLooksActive | ||
| } from "../chunk-7YMBXKQG.js"; | ||
| } from "../chunk-G7TRWZCK.js"; | ||
| export { | ||
@@ -55,0 +55,0 @@ BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, |
+1
-1
| { | ||
| "name": "@shadowob/shared", | ||
| "version": "1.1.63", | ||
| "version": "1.1.64", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
| // src/types/inbox.types.ts | ||
| var BUDDY_INBOX_TOPIC_PREFIX = "shadow:buddy-inbox:"; | ||
| var BUDDY_INBOX_DELIVERY_PERMISSION = "buddy_inbox:deliver"; | ||
| var BUDDY_INBOX_PLATFORM_PERMISSIONS = [BUDDY_INBOX_DELIVERY_PERMISSION]; | ||
| function isBuddyInboxPlatformPermission(value) { | ||
| return typeof value === "string" && BUDDY_INBOX_PLATFORM_PERMISSIONS.includes(value); | ||
| } | ||
| function buddyInboxTopic(agentId) { | ||
| return `${BUDDY_INBOX_TOPIC_PREFIX}${agentId}`; | ||
| } | ||
| function parseBuddyInboxAgentId(topic) { | ||
| if (!topic?.startsWith(BUDDY_INBOX_TOPIC_PREFIX)) return null; | ||
| const agentId = topic.slice(BUDDY_INBOX_TOPIC_PREFIX.length).trim(); | ||
| return agentId || null; | ||
| } | ||
| function isBuddyInboxTopic(topic) { | ||
| return parseBuddyInboxAgentId(topic) !== null; | ||
| } | ||
| var TASK_MESSAGE_CARD_STATUSES = [ | ||
| "queued", | ||
| "claimed", | ||
| "running", | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TERMINAL_TASK_MESSAGE_CARD_STATUSES = [ | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TASK_MESSAGE_CARD_STATUS_TRANSITIONS = { | ||
| queued: ["queued", "claimed", "running", "completed", "failed", "canceled"], | ||
| claimed: ["claimed", "running", "completed", "failed", "canceled"], | ||
| running: ["running", "completed", "failed", "canceled"], | ||
| completed: ["completed"], | ||
| failed: ["failed", "transferred"], | ||
| canceled: ["canceled"], | ||
| transferred: ["transferred"] | ||
| }; | ||
| function isTerminalTaskMessageCardStatus(status) { | ||
| return TERMINAL_TASK_MESSAGE_CARD_STATUSES.includes( | ||
| status | ||
| ); | ||
| } | ||
| function isTaskMessageCardStatus(value) { | ||
| return typeof value === "string" && TASK_MESSAGE_CARD_STATUSES.includes(value); | ||
| } | ||
| function canTransitionTaskMessageCardStatus(from, to) { | ||
| const allowed = TASK_MESSAGE_CARD_STATUS_TRANSITIONS[from]; | ||
| return allowed.includes(to); | ||
| } | ||
| function isRecord(value) { | ||
| return !!value && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isMessageReferenceCard(card) { | ||
| return card?.kind === "message_reference" && typeof card.title === "string" && isRecord(card.target) && typeof card.target.channelId === "string" && typeof card.target.messageId === "string"; | ||
| } | ||
| function getBuddyInboxTaskCards(message) { | ||
| const cards = message.metadata?.cards; | ||
| if (!Array.isArray(cards)) return []; | ||
| return cards.filter( | ||
| (card) => card?.kind === "task" && typeof card.id === "string" && isTaskMessageCardStatus(card.status) | ||
| ); | ||
| } | ||
| function hasBuddyInboxTaskCard(message) { | ||
| return getBuddyInboxTaskCards(message).length > 0; | ||
| } | ||
| function getBuddyInboxTaskStatuses(message) { | ||
| return getBuddyInboxTaskCards(message).map((card) => card.status); | ||
| } | ||
| function buildBuddyInboxViewMessages(messages, options) { | ||
| void options; | ||
| return [...messages]; | ||
| } | ||
| var DEFAULT_BUDDY_INBOX_ADMISSION_POLICY = { | ||
| defaultMode: "allow", | ||
| rules: [] | ||
| }; | ||
| function parseAdmissionMode(value, fallback) { | ||
| if (value === "allow" || value === "deny" || value === "first_time" || value === "every_time") { | ||
| return value; | ||
| } | ||
| if (value === void 0 || value === null) return fallback; | ||
| throw new Error("Invalid Buddy Inbox admission mode"); | ||
| } | ||
| function parseSubjectKind(value) { | ||
| if (value === "user" || value === "agent" || value === "server_app" || value === "system") { | ||
| return value; | ||
| } | ||
| throw new Error("Invalid Buddy Inbox admission subject kind"); | ||
| } | ||
| function parseOptionalString(value, field, maxLength) { | ||
| if (value === void 0 || value === null || value === "") return void 0; | ||
| if (typeof value !== "string" || value.length > maxLength) { | ||
| throw new Error(`Invalid Buddy Inbox admission ${field}`); | ||
| } | ||
| return value; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPolicy(value) { | ||
| if (value === void 0 || value === null) return { ...DEFAULT_BUDDY_INBOX_ADMISSION_POLICY }; | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox admission policy"); | ||
| const defaultMode = parseAdmissionMode(value.defaultMode, "allow"); | ||
| const rawRules = value.rules; | ||
| if (rawRules !== void 0 && !Array.isArray(rawRules)) { | ||
| throw new Error("Invalid Buddy Inbox admission rules"); | ||
| } | ||
| const rules = (rawRules ?? []).slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox admission rule"); | ||
| return { | ||
| subjectKind: parseSubjectKind(entry.subjectKind), | ||
| subjectId: parseOptionalString(entry.subjectId, "subjectId", 160), | ||
| appKey: parseOptionalString(entry.appKey, "appKey", 120), | ||
| mode: parseAdmissionMode(entry.mode, defaultMode), | ||
| ...entry.approved === true ? { approved: true } : {}, | ||
| note: parseOptionalString(entry.note, "note", 500), | ||
| createdAt: parseOptionalString(entry.createdAt, "createdAt", 64), | ||
| updatedAt: parseOptionalString(entry.updatedAt, "updatedAt", 64) | ||
| }; | ||
| }); | ||
| return { defaultMode, rules }; | ||
| } | ||
| function buddyInboxAdmissionRuleKey(rule) { | ||
| return [rule.subjectKind, rule.subjectId ?? "", rule.appKey ?? ""].join(":"); | ||
| } | ||
| function parsePendingTask(value) { | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox pending task"); | ||
| const title = parseOptionalString(value.title, "task.title", 180); | ||
| if (!title) throw new Error("Invalid Buddy Inbox pending task title"); | ||
| const body = parseOptionalString(value.body, "task.body", 8e3); | ||
| const priority = value.priority; | ||
| if (priority !== void 0 && priority !== "low" && priority !== "normal" && priority !== "medium" && priority !== "high") { | ||
| throw new Error("Invalid Buddy Inbox pending task priority"); | ||
| } | ||
| const idempotencyKey = parseOptionalString(value.idempotencyKey, "task.idempotencyKey", 240); | ||
| const source = isRecord(value.source) ? value.source : void 0; | ||
| const requirements = isRecord(value.requirements) ? value.requirements : void 0; | ||
| const outputContract = isRecord(value.outputContract) ? value.outputContract : void 0; | ||
| const privacy = isRecord(value.privacy) ? value.privacy : void 0; | ||
| const data = isRecord(value.data) ? value.data : void 0; | ||
| return { | ||
| title, | ||
| ...body ? { body } : {}, | ||
| ...priority ? { priority } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...source ? { source } : {}, | ||
| ...requirements ? { requirements } : {}, | ||
| ...outputContract ? { outputContract } : {}, | ||
| ...privacy ? { privacy } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPendingDeliveries(value) { | ||
| if (value === void 0 || value === null) return []; | ||
| if (!Array.isArray(value)) throw new Error("Invalid Buddy Inbox pending deliveries"); | ||
| return value.slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox pending delivery"); | ||
| const id = parseOptionalString(entry.id, "pending.id", 80); | ||
| const serverId = parseOptionalString(entry.serverId, "pending.serverId", 160); | ||
| const channelId = parseOptionalString(entry.channelId, "pending.channelId", 160); | ||
| const agentId = parseOptionalString(entry.agentId, "pending.agentId", 160); | ||
| const mode = parseAdmissionMode(entry.mode, "first_time"); | ||
| if (mode !== "first_time" && mode !== "every_time") { | ||
| throw new Error("Invalid Buddy Inbox pending mode"); | ||
| } | ||
| if (!isRecord(entry.subject)) throw new Error("Invalid Buddy Inbox pending subject"); | ||
| if (!isRecord(entry.requestedBy)) throw new Error("Invalid Buddy Inbox pending requester"); | ||
| if (!id || !serverId || !channelId || !agentId) { | ||
| throw new Error("Invalid Buddy Inbox pending delivery identifiers"); | ||
| } | ||
| const requestedAt = parseOptionalString(entry.requestedAt, "pending.requestedAt", 64); | ||
| if (!requestedAt) throw new Error("Invalid Buddy Inbox pending requestedAt"); | ||
| return { | ||
| id, | ||
| serverId, | ||
| channelId, | ||
| agentId, | ||
| mode, | ||
| subject: { | ||
| kind: parseSubjectKind(entry.subject.kind), | ||
| id: parseOptionalString(entry.subject.id, "subject.id", 160), | ||
| appKey: parseOptionalString(entry.subject.appKey, "subject.appKey", 120), | ||
| label: parseOptionalString(entry.subject.label, "subject.label", 160) | ||
| }, | ||
| task: parsePendingTask(entry.task), | ||
| requestedBy: entry.requestedBy, | ||
| requestedAt, | ||
| updatedAt: parseOptionalString(entry.updatedAt, "pending.updatedAt", 64) | ||
| }; | ||
| }); | ||
| } | ||
| // src/types/message.types.ts | ||
| var MESSAGE_COPILOT_CONTEXT_METADATA_KEY = "copilotContext"; | ||
| var MESSAGE_AGENT_CHAIN_METADATA_KEY = "agentChain"; | ||
| function isBoundedMetadataString(value, maxLength, required = false) { | ||
| if (typeof value !== "string") return !required && value == null; | ||
| const trimmed = value.trim(); | ||
| return trimmed.length > 0 && trimmed.length <= maxLength; | ||
| } | ||
| function isMessageCopilotContext(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| return record.kind === "server_app_copilot" && isBoundedMetadataString(record.appKey, 120, true) && isBoundedMetadataString(record.serverAppId, 160) && isBoundedMetadataString(record.appId, 160) && isBoundedMetadataString(record.appName, 160) && isBoundedMetadataString(record.serverId, 160) && isBoundedMetadataString(record.serverSlug, 160) && isBoundedMetadataString(record.channelId, 160) && isBoundedMetadataString(record.channelKind, 40); | ||
| } | ||
| function buildMessageCopilotContextMetadata(context) { | ||
| return context && isMessageCopilotContext(context) ? { copilotContext: context } : void 0; | ||
| } | ||
| function isMessageAgentChainMetadata(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| const startedAt = record.startedAt; | ||
| return isBoundedMetadataString(record.agentId, 160, true) && typeof record.depth === "number" && Number.isInteger(record.depth) && record.depth >= 0 && record.depth <= 100 && Array.isArray(record.participants) && record.participants.length <= 100 && record.participants.every((participant) => isBoundedMetadataString(participant, 160, true)) && (startedAt == null || typeof startedAt === "number" && Number.isInteger(startedAt) && startedAt >= 0 || isBoundedMetadataString(startedAt, 64, true)) && isBoundedMetadataString(record.rootMessageId, 160); | ||
| } | ||
| function buildMessageAgentChainMetadata(agentChain) { | ||
| return agentChain && isMessageAgentChainMetadata(agentChain) ? { agentChain } : void 0; | ||
| } | ||
| function metadataRecord(value) { | ||
| return value && typeof value === "object" && !Array.isArray(value) ? value : null; | ||
| } | ||
| function metadataString(value) { | ||
| return typeof value === "string" && value.trim() ? value.trim() : null; | ||
| } | ||
| function isMessageCardStatus(value) { | ||
| return value === "queued" || value === "claimed" || value === "running" || value === "completed" || value === "failed" || value === "canceled" || value === "transferred"; | ||
| } | ||
| function parseBuddyInboxTaskRef(value) { | ||
| const record = metadataRecord(value); | ||
| if (!record) return void 0; | ||
| const messageId = metadataString(record.messageId); | ||
| const cardId = metadataString(record.cardId); | ||
| const channelId = metadataString(record.channelId); | ||
| const threadId = metadataString(record.threadId); | ||
| const title = metadataString(record.title); | ||
| if (!messageId || !cardId || !channelId) return void 0; | ||
| const extra = { ...record }; | ||
| delete extra.messageId; | ||
| delete extra.cardId; | ||
| delete extra.channelId; | ||
| delete extra.threadId; | ||
| delete extra.title; | ||
| return { | ||
| ...extra, | ||
| messageId, | ||
| cardId, | ||
| channelId, | ||
| threadId, | ||
| ...title ? { title } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultCard(value) { | ||
| const result = metadataRecord(value); | ||
| if (!result || result.kind !== "task_result") return null; | ||
| const taskMessageId = metadataString(result.taskMessageId); | ||
| const taskCardId = metadataString(result.taskCardId); | ||
| const status = result.status; | ||
| if (!taskMessageId || !taskCardId || !isMessageCardStatus(status)) return null; | ||
| const id = metadataString(result.id) ?? `task-result:${taskMessageId}:${taskCardId}:${status}`; | ||
| const version = typeof result.version === "number" && Number.isFinite(result.version) ? Math.max(1, Math.trunc(result.version)) : 1; | ||
| const title = metadataString(result.title) ?? metadataString(metadataRecord(result.sourceTask)?.title) ?? metadataString(metadataRecord(result.parentTask)?.title) ?? "Task result"; | ||
| const body = metadataString(result.body); | ||
| const idempotencyKey = metadataString(result.idempotencyKey); | ||
| const delivery = metadataString(result.delivery); | ||
| const createdAt = metadataString(result.createdAt); | ||
| const updatedAt = metadataString(result.updatedAt); | ||
| const sourceTask = parseBuddyInboxTaskRef(result.sourceTask); | ||
| const parentTask = parseBuddyInboxTaskRef(result.parentTask); | ||
| const data = metadataRecord(result.data); | ||
| const extra = { ...result }; | ||
| delete extra.id; | ||
| delete extra.kind; | ||
| delete extra.version; | ||
| delete extra.title; | ||
| delete extra.body; | ||
| delete extra.idempotencyKey; | ||
| delete extra.taskMessageId; | ||
| delete extra.taskCardId; | ||
| delete extra.status; | ||
| delete extra.delivery; | ||
| delete extra.createdAt; | ||
| delete extra.updatedAt; | ||
| delete extra.sourceTask; | ||
| delete extra.parentTask; | ||
| delete extra.data; | ||
| return { | ||
| ...extra, | ||
| id, | ||
| kind: "task_result", | ||
| version, | ||
| title, | ||
| taskMessageId, | ||
| taskCardId, | ||
| status, | ||
| ...body ? { body } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...delivery ? { delivery } : {}, | ||
| ...createdAt ? { createdAt } : {}, | ||
| ...updatedAt ? { updatedAt } : {}, | ||
| ...sourceTask ? { sourceTask } : {}, | ||
| ...parentTask ? { parentTask } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultMetadata(metadata) { | ||
| const record = metadataRecord(metadata); | ||
| const cards = Array.isArray(record?.cards) ? record.cards : []; | ||
| for (const card of cards) { | ||
| const result = parseBuddyInboxTaskResultCard(card); | ||
| if (result) return result; | ||
| } | ||
| const custom = metadataRecord(record?.custom); | ||
| return parseBuddyInboxTaskResultCard(custom?.buddyInboxTaskResult); | ||
| } | ||
| function isMetadataRecord(value) { | ||
| return Boolean(value) && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isCommerceMessageCard(card) { | ||
| if (!isMetadataRecord(card)) return false; | ||
| const kind = card.kind; | ||
| return (kind === "offer" || kind === "product") && typeof card.id === "string" && typeof card.productId === "string" && typeof card.shopId === "string" && isMetadataRecord(card.snapshot) && isMetadataRecord(card.purchase); | ||
| } | ||
| function isPaidFileMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "paid_file" && typeof card.id === "string" && typeof card.fileId === "string" && isMetadataRecord(card.snapshot); | ||
| } | ||
| function isOAuthLinkMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "oauth_link" && typeof card.id === "string" && typeof card.appId === "string" && typeof card.title === "string" && typeof card.url === "string" && isMetadataRecord(card.action); | ||
| } | ||
| function getCommerceMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isCommerceMessageCard) : []; | ||
| } | ||
| function getPaidFileMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isPaidFileMessageCard) : []; | ||
| } | ||
| function getOAuthLinkMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isOAuthLinkMessageCard) : []; | ||
| } | ||
| // src/types/runtime-session.types.ts | ||
| var RUNTIME_SESSION_PET_REACTION_BY_STATE = { | ||
| idle: "idle", | ||
| running: "working", | ||
| streaming: "thinking", | ||
| tool_call: "working", | ||
| waiting_for_approval: "waiting", | ||
| blocked: "waiting", | ||
| completed: "success", | ||
| failed: "error", | ||
| stopped: "idle", | ||
| unknown: "idle" | ||
| }; | ||
| function runtimeSessionPetReactionForState(state) { | ||
| return RUNTIME_SESSION_PET_REACTION_BY_STATE[state] ?? "idle"; | ||
| } | ||
| function runtimeSessionSignalToPetReaction(signal) { | ||
| switch (signal) { | ||
| case "running": | ||
| return "working"; | ||
| case "streaming": | ||
| return "thinking"; | ||
| case "tool_call": | ||
| return "working"; | ||
| case "waiting_for_approval": | ||
| case "blocked": | ||
| return "waiting"; | ||
| case "completed": | ||
| return "success"; | ||
| case "failed": | ||
| return "error"; | ||
| case "stopped": | ||
| case "unknown": | ||
| return "idle"; | ||
| default: | ||
| return signal; | ||
| } | ||
| } | ||
| function runtimeSessionStateLooksActive(state) { | ||
| return state === "running" || state === "streaming" || state === "tool_call" || state === "waiting_for_approval" || state === "blocked"; | ||
| } | ||
| // src/types/user.types.ts | ||
| var USER_STATUSES = ["online", "idle", "dnd", "offline"]; | ||
| var BUDDY_PRESENCE_STATUSES = ["online", "busy", "idle", "dnd", "offline"]; | ||
| var BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS = 9e4; | ||
| function normalizeUserStatus(status) { | ||
| if (status === "online" || status === "idle" || status === "dnd" || status === "offline") { | ||
| return status; | ||
| } | ||
| return "offline"; | ||
| } | ||
| function normalizeBuddyPresenceStatus(status, options) { | ||
| if (options?.busy) { | ||
| return "busy"; | ||
| } | ||
| if (status === "busy") { | ||
| return "busy"; | ||
| } | ||
| return normalizeUserStatus(status); | ||
| } | ||
| function normalizePresenceStatus(status, options) { | ||
| return normalizeBuddyPresenceStatus(status, options); | ||
| } | ||
| function isBuddyHeartbeatActive(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return false; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return false; | ||
| const nowMs = options?.nowMs ?? Date.now(); | ||
| const thresholdMs = options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS; | ||
| return nowMs - heartbeatMs <= thresholdMs; | ||
| } | ||
| function normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy || agentStatus === "busy") return "busy"; | ||
| if (agentStatus === "running") { | ||
| return isBuddyHeartbeatActive(lastHeartbeat, { nowMs }) ? "online" : "offline"; | ||
| } | ||
| const normalizedAgentStatus = normalizeBuddyPresenceStatus(agentStatus); | ||
| if (normalizedAgentStatus !== "offline") return normalizedAgentStatus; | ||
| return normalizeUserStatus(userStatus); | ||
| } | ||
| function resolvePresenceStatus({ | ||
| userStatus, | ||
| isBot, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy) return "busy"; | ||
| if (isBot || agentStatus != null || lastHeartbeat != null) { | ||
| return normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| nowMs | ||
| }); | ||
| } | ||
| return normalizePresenceStatus(userStatus); | ||
| } | ||
| function getBuddyPresenceExpiresAt(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return null; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return null; | ||
| return new Date( | ||
| heartbeatMs + (options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS) | ||
| ).toISOString(); | ||
| } | ||
| function applyPresenceChangeToRuntime(current, update, options) { | ||
| const observedAt = update.observedAt ?? options?.observedAt ?? (/* @__PURE__ */ new Date()).toISOString(); | ||
| const userStatus = normalizeUserStatus(update.status); | ||
| const hasAgentPresence = current.isBot === true || current.agentStatus != null || current.lastHeartbeat != null || update.agentId != null || update.agentStatus !== void 0 || update.lastHeartbeat !== void 0; | ||
| if (!hasAgentPresence) return { userStatus }; | ||
| const agentStatus = update.agentStatus !== void 0 ? update.agentStatus : current.agentStatus ?? (userStatus === "online" ? "running" : null); | ||
| let lastHeartbeat = current.lastHeartbeat ?? null; | ||
| if (update.lastHeartbeat !== void 0) { | ||
| lastHeartbeat = update.lastHeartbeat; | ||
| } else if (userStatus === "online") { | ||
| lastHeartbeat = observedAt; | ||
| } else if (userStatus === "offline") { | ||
| lastHeartbeat = null; | ||
| } | ||
| return { userStatus, agentStatus, lastHeartbeat }; | ||
| } | ||
| export { | ||
| BUDDY_INBOX_TOPIC_PREFIX, | ||
| BUDDY_INBOX_DELIVERY_PERMISSION, | ||
| BUDDY_INBOX_PLATFORM_PERMISSIONS, | ||
| isBuddyInboxPlatformPermission, | ||
| buddyInboxTopic, | ||
| parseBuddyInboxAgentId, | ||
| isBuddyInboxTopic, | ||
| TASK_MESSAGE_CARD_STATUSES, | ||
| TERMINAL_TASK_MESSAGE_CARD_STATUSES, | ||
| TASK_MESSAGE_CARD_STATUS_TRANSITIONS, | ||
| isTerminalTaskMessageCardStatus, | ||
| isTaskMessageCardStatus, | ||
| canTransitionTaskMessageCardStatus, | ||
| isMessageReferenceCard, | ||
| getBuddyInboxTaskCards, | ||
| hasBuddyInboxTaskCard, | ||
| getBuddyInboxTaskStatuses, | ||
| buildBuddyInboxViewMessages, | ||
| DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, | ||
| normalizeBuddyInboxAdmissionPolicy, | ||
| buddyInboxAdmissionRuleKey, | ||
| normalizeBuddyInboxAdmissionPendingDeliveries, | ||
| MESSAGE_COPILOT_CONTEXT_METADATA_KEY, | ||
| MESSAGE_AGENT_CHAIN_METADATA_KEY, | ||
| isMessageCopilotContext, | ||
| buildMessageCopilotContextMetadata, | ||
| isMessageAgentChainMetadata, | ||
| buildMessageAgentChainMetadata, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| isCommerceMessageCard, | ||
| isPaidFileMessageCard, | ||
| isOAuthLinkMessageCard, | ||
| getCommerceMessageCards, | ||
| getPaidFileMessageCards, | ||
| getOAuthLinkMessageCards, | ||
| RUNTIME_SESSION_PET_REACTION_BY_STATE, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive, | ||
| USER_STATUSES, | ||
| BUDDY_PRESENCE_STATUSES, | ||
| BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| normalizeUserStatus, | ||
| normalizeBuddyPresenceStatus, | ||
| normalizePresenceStatus, | ||
| isBuddyHeartbeatActive, | ||
| normalizeBuddyRuntimePresenceStatus, | ||
| resolvePresenceStatus, | ||
| getBuddyPresenceExpiresAt, | ||
| applyPresenceChangeToRuntime | ||
| }; |
Sorry, the diff of this file is too big to display
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
735188
0.01%