@mgamadeus/ddd-agents 0.1.0-alpha.23 → 0.1.0-alpha.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.js +71 -827
- package/dist/chat.js.map +1 -1
- package/dist/chunks/ConversationMessageInputComposerWidgets-BxyaFBA6.js +631 -0
- package/dist/chunks/ConversationMessageInputComposerWidgets-BxyaFBA6.js.map +1 -0
- package/dist/chunks/{WebSearchResultsConversationWidget-DRBQvycE.js → WebSearchResultsConversationWidget-as3p5bHw.js} +92 -85
- package/dist/chunks/WebSearchResultsConversationWidget-as3p5bHw.js.map +1 -0
- package/dist/chunks/{decide-canvas-open-DBWoWtAC.js → canvas-behaviours-AvzKSYyv.js} +3 -19
- package/dist/chunks/canvas-behaviours-AvzKSYyv.js.map +1 -0
- package/dist/chunks/canvas-reducers-Bfp_i7lc.js +88 -0
- package/dist/chunks/canvas-reducers-Bfp_i7lc.js.map +1 -0
- package/dist/chunks/{canvasBodies-DLjDkviP.js → canvasBodies-Cvu3l38p.js} +6 -3
- package/dist/chunks/{canvasBodies-DLjDkviP.js.map → canvasBodies-Cvu3l38p.js.map} +1 -1
- package/dist/chunks/canvasStorage-EvQsGdto.js +65 -0
- package/dist/chunks/canvasStorage-EvQsGdto.js.map +1 -0
- package/dist/chunks/contract-BxmMxYPF.js +96 -0
- package/dist/chunks/contract-BxmMxYPF.js.map +1 -0
- package/dist/chunks/conversation-BEF0aesf.js +31 -0
- package/dist/chunks/conversation-BEF0aesf.js.map +1 -0
- package/dist/chunks/{ConversationMarkdown-CJhAnuVa.js → widget-click-signal-sources-DulRkNvZ.js} +22 -77
- package/dist/chunks/widget-click-signal-sources-DulRkNvZ.js.map +1 -0
- package/dist/chunks/{widget-name-resolver-C8SfpiR5.js → widget-name-resolver-BGN3HpoG.js} +61 -30
- package/dist/chunks/widget-name-resolver-BGN3HpoG.js.map +1 -0
- package/dist/chunks/{withPollingChangeSubscription-BLDAWF-o.js → withPollingChangeSubscription-B16htQGd.js} +2 -2
- package/dist/chunks/{withPollingChangeSubscription-BLDAWF-o.js.map → withPollingChangeSubscription-B16htQGd.js.map} +1 -1
- package/dist/client-testing.js +28 -6
- package/dist/client-testing.js.map +1 -1
- package/dist/client.js +1 -1
- package/dist/contract.js +8 -27
- package/dist/contract.js.map +1 -1
- package/dist/image-render.js +8 -8
- package/dist/index.js +6 -5
- package/dist/kit.js +2 -2
- package/dist/preview.js +44 -16
- package/dist/preview.js.map +1 -1
- package/dist/renderer.js +62 -57
- package/dist/renderer.js.map +1 -1
- package/dist/styles.css +55 -22
- package/dist/types/client/testing/widget-hydration-stand-ins.d.ts +12 -3
- package/dist/types/entries/chat.d.ts +2 -0
- package/dist/types/entries/client-testing.d.ts +2 -0
- package/dist/types/entries/contract.d.ts +1 -0
- package/dist/types/entries/index.d.ts +1 -1
- package/dist/types/entries/preview.d.ts +1 -0
- package/dist/types/entries/renderer.d.ts +3 -1
- package/dist/types/kit/components/data/chart-model.d.ts +2 -2
- package/dist/types/kit/components/data/use-chart-palette.d.ts +2 -2
- package/dist/types/kit/components/map/use-google-maps-auth-failure.d.ts +18 -0
- package/dist/types/kit/entity-detail/entity-detail-bodies.d.ts +2 -0
- package/dist/types/renderer/canvas/entity-detail-instance.d.ts +5 -3
- package/dist/types/renderer/widget-hydration/use-widget-hydration.d.ts +5 -0
- package/dist/types/widgets/EntityMentionConversationWidget/stories/EntityMentionAskFlowStory.d.ts +8 -0
- package/dist/widgets.js +33 -33
- package/package.json +1 -1
- package/public-api.json +19 -1
- package/dist/chunks/ConversationMarkdown-CJhAnuVa.js.map +0 -1
- package/dist/chunks/WebSearchResultsConversationWidget-DRBQvycE.js.map +0 -1
- package/dist/chunks/decide-canvas-open-DBWoWtAC.js.map +0 -1
- package/dist/chunks/widget-name-resolver-C8SfpiR5.js.map +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION = [
|
|
3
|
+
"COMPLETED",
|
|
4
|
+
"CANCELLED"
|
|
5
|
+
];
|
|
6
|
+
const readConversationRunStatusOfRunState = (runState) => {
|
|
7
|
+
if (!runState) return null;
|
|
8
|
+
if (runState === "FAILED") return "failed";
|
|
9
|
+
if (runState === "RUNNING" || runState === "AWAITING_DELEGATES" || runState === "QUEUED") return "running";
|
|
10
|
+
return "idle";
|
|
11
|
+
};
|
|
12
|
+
const AGENTS_CLIENT_ERROR_CODE_REQUEST_ABORTED = "REQUEST_ABORTED";
|
|
13
|
+
class AgentsClientError extends Error {
|
|
14
|
+
constructor(kind, details = {}) {
|
|
15
|
+
super(details.message ?? kind);
|
|
16
|
+
this.name = "AgentsClientError";
|
|
17
|
+
this.kind = kind;
|
|
18
|
+
this.code = details.code ?? null;
|
|
19
|
+
this.retryAfterSeconds = kind === "rateLimit" ? details.retryAfterSeconds ?? null : null;
|
|
20
|
+
this.httpStatus = details.httpStatus ?? null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const isAgentsClientError = (value) => value instanceof AgentsClientError;
|
|
24
|
+
export {
|
|
25
|
+
AgentsClientError as A,
|
|
26
|
+
CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION as C,
|
|
27
|
+
AGENTS_CLIENT_ERROR_CODE_REQUEST_ABORTED as a,
|
|
28
|
+
isAgentsClientError as i,
|
|
29
|
+
readConversationRunStatusOfRunState as r
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=conversation-BEF0aesf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-BEF0aesf.js","sources":["../../src/contract/conversation.ts"],"sourcesContent":["/**\n * The conversation contract of the package: plain TypeScript types the conversation client port\n * (`client/AgentsConversationClient.ts`) returns and the chat reads. Every field is derived from what the chat files and\n * the chat controller read from the server today (the host application's generated `AIConversation`, `AIConversationMessage`,\n * `AgentActivityLine`, `SemanticSearchHit`, `AIConversationSearchGroup`, `AgentCustomerSelectableModel`); nothing the\n * chat does not read is here.\n *\n * Naming: a field keeps the wire name where the name is neutral (`message`, `indexInConversation`, `role`, `status`,\n * `toolCall`); a name that carries an app's vocabulary is renamed (`aiConversationId` → `conversationId`,\n * the app's own key of the thing the agent works for → `agentSpaceKey`, `summary.title` → `title`). Each field carries a\n * one-line note:\n * - `generic` — every app that runs the agent conversation backend has it;\n * - `app extension` — read by the chat today but specific to one app's backend or debug surface; optional, and a\n * binding may leave it out.\n *\n * Client-side state is NOT part of the contract: the `fresh` tag of a live-arrived message, the optimistic user\n * message without an id and the `isNewConversation` / `isReopenedConversation` flags belong to the package store.\n */\n\n// ── Vocabulary ───────────────────────────────────────────────────────────────────────────────────────────────────\n\n/** The run state of a conversation as the server stores it (`AIConversationRunState`). */\nexport type ConversationRunState =\n | \"IDLE\"\n | \"QUEUED\"\n | \"RUNNING\"\n | \"AWAITING_DELEGATES\"\n | \"FAILED\"\n | \"COMPLETED\"\n | \"CANCELLED\";\n\n/** The three-value run status the live-update signal speaks; the chat keys its indicator and error card off it. */\nexport type ConversationRunStatus = \"running\" | \"idle\" | \"failed\";\n\nexport type ConversationMessageRole = \"SYSTEM\" | \"USER\" | \"ASSISTANT\";\n\nexport type ConversationMessageType = \"TEXT\" | \"TOOL_CALL\" | \"CHECKPOINT\" | \"ERROR\" | \"SIGNAL\" | \"TOOL_MESSAGE\";\n\nexport type ConversationMessageStatus =\n | \"PENDING\"\n | \"RUNNING\"\n | \"CANCEL_REQUESTED\"\n | \"CANCELLED\"\n | \"COMPLETED\"\n | \"FAILED\";\n\nexport type ConversationMessageAuthorType = \"USER\" | \"ASSISTANT\" | \"AGENT\" | \"TOOL\";\n\n/** Run states after which nothing runs any more and the server refuses further customer input. */\nexport const CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION: readonly ConversationRunState[] = [\n \"COMPLETED\",\n \"CANCELLED\",\n];\n\n/** Maps a stored run state onto the signal's three-value status (`runStateToSignalStatus` of the live-update hook). */\nexport const readConversationRunStatusOfRunState = (\n runState: string | null | undefined,\n): ConversationRunStatus | null => {\n if (!runState) return null;\n if (runState === \"FAILED\") return \"failed\";\n if (runState === \"RUNNING\" || runState === \"AWAITING_DELEGATES\" || runState === \"QUEUED\") return \"running\";\n return \"idle\";\n};\n\n// ── Conversation ─────────────────────────────────────────────────────────────────────────────────────────────────\n\n/** One step of the progress stepper a purposed conversation declares (`CustomerProgressStep`). */\nexport interface ConversationProgressStep {\n /** generic */\n key: string;\n /** generic — already in the owner's language */\n label: string;\n /** generic */\n status: \"done\" | \"active\" | \"upcoming\";\n}\n\n/** A conversation as the chat, the conversation list and the window around the chat read it. */\nexport interface AgentsConversation {\n /** generic */\n id: number;\n /** generic — the key of the agent space the conversation belongs to */\n agentSpaceKey: number | null;\n /** generic */\n runState: ConversationRunState | null;\n /**\n * generic — set while the server owes a turn on an IDLE conversation (a failed hand-over the recovery re-drives);\n * an IDLE conversation with this set counts as running (`effectiveRunState`)\n */\n agentTurnOwedAt: string | null;\n /** generic — the display title (`summary.title`); null until the first title was generated */\n title: string | null;\n /** generic — the owner set the title by hand; the generated title never replaces it then */\n titleManuallyEdited: boolean;\n /** generic — the generated summary of what the conversation is about (`summary.text`); null until generated */\n summary: string | null;\n /** generic — when the conversation was created, in the server's date-time format */\n created: string | null;\n /** generic — when the conversation was last modified, in the server's date-time format */\n updated: string | null;\n /** generic — the purpose of a purposed conversation (e.g. `Example.Build`, a first-run setup purpose); null otherwise */\n purposeName: string | null;\n /** generic — who started the conversation (`SCHEDULE` for a run of a scheduled task) */\n initiatorType: string | null;\n /** generic — the scheduled task a `SCHEDULE` conversation is a run of */\n scheduleId: number | null;\n /** generic — the entry point a start came from; a start from the same entry point reopens this conversation */\n entryPointKey: string | null;\n /** generic — empty unless the purpose declares a progress stepper */\n progressSteps: ConversationProgressStep[];\n /**\n * generic — the id of the newest stored message; null before the first. The polling default of the live updates\n * (`client/polling/`) reads it to see a new message while the run status stays the same, and hands it to the rules as\n * the signal's `lastMessageId`. Optional: a binding with a push transport may leave it out (the host application's metadata\n * read does not carry it); without it the poller treats every poll of a running turn as a change.\n */\n lastMessageId?: number | null;\n /** app extension — the prompt extension of the host application's older AI-Extensions chat */\n promptExtensionId?: number | null;\n /** app extension — the category of that prompt extension (its colour and product name in the conversation list) */\n promptExtensionCategory?: { alias: string | null; name: string | null } | null;\n}\n\n// ── Messages ─────────────────────────────────────────────────────────────────────────────────────────────────────\n\n/** A sub-agent conversation a delegation started, as far as the chat reads it (`delegatedConversations(select=id,runState)`). */\nexport interface ConversationDelegatedConversation {\n /** generic */\n id: number;\n /** generic */\n runState: ConversationRunState | null;\n}\n\n/** One run of a sub-agent, as the activity derivation reads it (`DelegationSubAgentRun`). */\nexport interface ConversationSubAgentRun {\n /** generic */\n runNumber: number | null;\n /** generic */\n status: string | null;\n}\n\n/** The sub-agent record a newer `delegate` call row carries instead of expanded children (`DelegationSubAgentRecord`). */\nexport interface ConversationSubAgent {\n /** generic */\n currentRunNumber: number | null;\n /** generic */\n runs: ConversationSubAgentRun[];\n}\n\n/** The tool call a `TOOL_CALL` row carries, as far as the chat reads it. */\nexport interface ConversationToolCall {\n /** generic */\n toolCallId: string | null;\n /** generic */\n name: string | null;\n /** generic — the call's arguments as the model wrote them (the `delegate` call's `tasks` is read) */\n arguments: unknown;\n /** generic — the call's own progress; a row's `status` says nothing about it */\n status: string | null;\n}\n\n/** The admin debug numbers of one message (the message forensics panel). */\nexport interface ConversationMessageForensics {\n /** app extension */\n inputTokens: number | null;\n /** app extension */\n outputTokens: number | null;\n /** app extension */\n costInUSD: number | null;\n /** app extension — the stored request snapshot of the model call (model name, reasoning effort, sent at) */\n requestSnapshot: unknown;\n}\n\n/** One stored message of a conversation. */\nexport interface AgentsConversationMessage {\n /** generic */\n id: number;\n /** generic */\n conversationId: number | null;\n /** generic — the position in the conversation; the merge key of every page */\n indexInConversation: number | null;\n /** generic */\n role: ConversationMessageRole | null;\n /** generic */\n messageType: ConversationMessageType | null;\n /** generic — non-final only on a waiting signal row */\n status: ConversationMessageStatus | null;\n /** generic */\n authorType: ConversationMessageAuthorType | null;\n /** generic — the source of a SIGNAL or ERROR row (`AI_BUDGET_REACHED`, `FRONTEND_WIDGET_CLICK`, …) */\n signalSource: string | null;\n /** generic — the text in markdown, widget blocks included */\n message: string;\n /** generic */\n createdDate: string | null;\n /** generic */\n toolCall: ConversationToolCall | null;\n /** generic — the sub-agent conversations a `delegate` call started (older rows) */\n delegatedConversations: ConversationDelegatedConversation[];\n /** generic — the sub-agent record of a `delegate` call (newer rows) */\n subAgent: ConversationSubAgent | null;\n /** app extension — admin debug numbers; absent outside the admin surfaces */\n forensics?: ConversationMessageForensics;\n}\n\n/** A file from the app's media library that rides along with a message. */\nexport interface ConversationAttachmentReference {\n /** generic — the app's id of the file (host application: the media manager file id) */\n fileId: string | number | null;\n /** generic */\n fileName: string | null;\n /** generic — a URL the model and the tools can fetch */\n publicUrl: string | null;\n}\n\n// ── Pages and results of the port ────────────────────────────────────────────────────────────────────────────────\n\n/** A page of messages read newest first (the newest page on open, an older page on scroll-up). */\nexport interface ConversationMessagesPage {\n /** generic — in any order; the store merges by `indexInConversation` */\n messages: AgentsConversationMessage[];\n /** generic — an older page exists */\n hasMoreOlder: boolean;\n}\n\n/**\n * What a live update reads: every message written since the newest known id, plus every message from the lowest\n * loaded index that can still change (`build-live-refetch-query.ts`). The package computes both values.\n */\nexport interface ChangedMessagesRequest {\n /** generic — the highest message id loaded */\n highestKnownId: number;\n /** generic — the lowest index that can still change, never below the newest page */\n fromIndex: number;\n /** generic — the page size of the read; the binding's default (host application: 50, as the chat sends) when omitted */\n pageSize?: number;\n}\n\n/** The answer of a changed-messages read; it says nothing about older pages (the store keeps `hasMoreOlder`). */\nexport interface ChangedConversationMessages {\n /** generic */\n messages: AgentsConversationMessage[];\n}\n\n/** The answer of a start: the new conversation with what it holds so far, or the reopened one of the entry point. */\nexport interface StartedConversation {\n /** generic */\n conversation: AgentsConversation;\n /** generic — the stored messages of a new conversation; empty for a reopened one (the chat reads its newest page) */\n messages: AgentsConversationMessage[];\n /** generic — the start returned the recent conversation of its entry point; nothing was appended, no turn started */\n reopenedExisting: boolean;\n}\n\n/** The answer of a post: the conversation's messages so far (the reply arrives through live updates). */\nexport interface PostedMessage {\n /** generic */\n messages: AgentsConversationMessage[];\n}\n\n/** A model-visible, owner-invisible note into a conversation (a widget click, a render report, a correction). */\nexport interface ConversationSignal {\n /** generic */\n text: string;\n /** generic — the signal source; the server's default applies when omitted (a widget click) */\n source?: string;\n}\n\n/** How a list read pages and which conversations it includes. */\nexport interface ConversationListQueryOptions {\n /** generic — include conversations that have no summary (title) yet, e.g. a just-started one */\n includeUnsummarized?: boolean;\n /** generic — the host application's history reads the newest 50 */\n paging?: { top?: number; skip?: number };\n}\n\n/** The size of a search answer. */\nexport interface ConversationSearchOptions {\n /** generic — the most groups (or hits) returned; the host application's chat asks for 10 */\n limit?: number;\n /** generic — the excerpt length in characters; the host application's chat asks for 420 */\n excerptLength?: number;\n}\n\n/** app extension — the reconstructed request a model call was sent with (the admin details panel); opaque data. */\nexport type ConversationMessageSentPayload = unknown[];\n\n/** One matched message of a message search (`SemanticSearchHit`). */\nexport interface ConversationMessageSearchHit {\n /** generic */\n messageId: number | null;\n /** generic */\n conversationId: number | null;\n /** generic */\n indexInConversation: number | null;\n /** generic */\n role: string | null;\n /** generic */\n excerpt: string;\n /** generic */\n relevance: number;\n /** generic */\n created: string | null;\n /** generic */\n updated: string | null;\n /** generic — the conversation's title */\n title: string | null;\n}\n\n/** One conversation of a search across conversations, with its matched messages (`AIConversationSearchGroup`). */\nexport interface ConversationSearchGroup {\n /** generic */\n conversationId: number | null;\n /** generic */\n title: string | null;\n /** generic */\n summary: string | null;\n /** generic */\n created: string | null;\n /** generic */\n updated: string | null;\n /** generic */\n relevance: number;\n /** generic */\n hits: ConversationMessageSearchHit[];\n}\n\n/** One generated line of what the agent is doing (`AgentActivityLine`). */\nexport interface ConversationActivityElement {\n /** generic — the row the line narrates; the merge key */\n toolCallMessageId: number;\n /** generic */\n batchId: string | null;\n /** generic */\n state: \"queued\" | \"running\" | \"finished\" | \"failed\" | \"skipped\" | null;\n /** generic */\n kind: \"tool\" | \"delegation\" | \"background\" | \"long\" | \"turnStart\" | null;\n /** generic */\n childCount: number | null;\n /** generic — the 1-based delegation helper that ran the step; null for the assistant's own steps */\n helperIndex: number | null;\n /** generic — the sentence; null while the narrator has not answered */\n line: string | null;\n}\n\n/** The activity of one turn (`GET …/activity`). */\nexport interface ConversationActivity {\n /** generic — the message that started the narrated turn */\n turnMessageId: number | null;\n /** generic */\n turnRunning: boolean;\n /** generic */\n elements: ConversationActivityElement[];\n}\n\n/** A model the owner (host application: an impersonating admin) may pick for the next turns (`AgentCustomerSelectableModel`). */\nexport interface SelectableModel {\n /** generic — the name a send carries */\n name: string;\n /** generic */\n displayName: string;\n /** generic */\n description: string;\n /** generic */\n strengthLevel: number | null;\n /** generic */\n speedLevel: number | null;\n /** app extension — the host application's credit multiplier of the model */\n creditsMultiplier?: number | null;\n}\n\n// ── Live updates ─────────────────────────────────────────────────────────────────────────────────────────────────\n\n/**\n * What a live update carries: a claim check, never content. The chat reads the conversation again when\n * `changeCounter` advances, at once on a terminal status, and until `lastMessageId` is loaded.\n */\nexport interface ConversationChangeSignal {\n /** generic — advances on every change of the conversation */\n changeCounter: number;\n /** generic — the newest message the server wrote; null before the first */\n lastMessageId: number | null;\n /** generic */\n runStatus: ConversationRunStatus | null;\n /** generic — advances when the title or summary was generated again (a light metadata read is enough then) */\n summaryUpdatedAt: number | null;\n /**\n * generic — the binding produced this emission from a run-state read, not from a pushed change (a binding without\n * push, or a push transport whose path is not proven readable, or a check that corrects a stale status). It carries\n * only `runStatus` as news: `changeCounter`, `lastMessageId` and `summaryUpdatedAt` repeat the last pushed values\n * (before any push: a counter that counts down from -1, never equal to a pushed one). The package sets the status\n * from it and reads the conversation again on a status change while the push path is not alive (`isPushPathAlive`).\n */\n isStatusCheck?: boolean;\n /**\n * generic, on a status-check emission — the binding's push path delivers: a pushed change arrived and the path was not\n * denied since. False after a denied read until a push arrives again; then the status checks are the live path and a\n * status change reads the conversation again. A binding without push leaves it out: the package then counts the\n * pushed changes it saw itself.\n */\n isPushPathAlive?: boolean;\n}\n\n/** Why a subscription ended for good: the conversation was deleted or is no longer readable, or the account lost access. */\nexport type ConversationSubscriptionEndReason = \"gone\" | \"forbidden\";\n\n// ── Errors ───────────────────────────────────────────────────────────────────────────────────────────────────────\n\n/**\n * What went wrong, as the chat tells the owner. The codes the chat's error handling reads today map\n * onto it: `AI_BUDGET_REACHED` → `budget`, HTTP 429 / `RATE_LIMIT_EXCEEDED` → `rateLimit`, `CONVERSATION_CLOSED` →\n * `closed`, the not-found and no-access answers → `notFound` / `forbidden` (`conversation-not-found.ts`), no answer or a\n * server failure → `network`, everything else (a refused retry, a cancelled request) → `other` with its `code`.\n */\nexport type AgentsClientErrorKind = \"budget\" | \"rateLimit\" | \"closed\" | \"notFound\" | \"forbidden\" | \"network\" | \"other\";\n\n/** The code `other` carries for a request the client cancelled; the chat shows no error card for it. */\nexport const AGENTS_CLIENT_ERROR_CODE_REQUEST_ABORTED = \"REQUEST_ABORTED\";\n\n/** The one error shape every port function rejects with. */\nexport class AgentsClientError extends Error {\n readonly kind: AgentsClientErrorKind;\n /** The server's stable error code, or the client's own code (`REQUEST_ABORTED`); null when none arrived. */\n readonly code: string | null;\n /** Seconds until a quota frees up again; set only for `rateLimit`. */\n readonly retryAfterSeconds: number | null;\n /** The HTTP status when one arrived (not part of the contract's shape; kept for diagnostics). */\n readonly httpStatus: number | null;\n\n constructor(\n kind: AgentsClientErrorKind,\n details: { message?: string; code?: string | null; retryAfterSeconds?: number | null; httpStatus?: number | null } = {},\n ) {\n super(details.message ?? kind);\n this.name = \"AgentsClientError\";\n this.kind = kind;\n this.code = details.code ?? null;\n this.retryAfterSeconds = kind === \"rateLimit\" ? (details.retryAfterSeconds ?? null) : null;\n this.httpStatus = details.httpStatus ?? null;\n }\n}\n\nexport const isAgentsClientError = (value: unknown): value is AgentsClientError => value instanceof AgentsClientError;\n"],"names":[],"mappings":";AAiDO,MAAM,oDAAqF;AAAA,EAChG;AAAA,EACA;AACF;AAGO,MAAM,sCAAsC,CACjD,aACiC;AACjC,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,aAAa,SAAU,QAAO;AAClC,MAAI,aAAa,aAAa,aAAa,wBAAwB,aAAa,SAAU,QAAO;AACjG,SAAO;AACT;AAkWO,MAAM,2CAA2C;AAGjD,MAAM,0BAA0B,MAAM;AAAA,EAS3C,YACE,MACA,UAAqH,IACrH;AACA,UAAM,QAAQ,WAAW,IAAI;AAC7B,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,oBAAoB,SAAS,cAAe,QAAQ,qBAAqB,OAAQ;AACtF,SAAK,aAAa,QAAQ,cAAc;AAAA,EAC1C;AACF;AAEO,MAAM,sBAAsB,CAAC,UAA+C,iBAAiB;"}
|
package/dist/chunks/{ConversationMarkdown-CJhAnuVa.js → widget-click-signal-sources-DulRkNvZ.js}
RENAMED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { j as conversationWidgetRegistry,
|
|
3
|
-
import { f as decideCanvasOpen, d as canvasBehaviourOf } from "./decide-canvas-open-DBWoWtAC.js";
|
|
4
|
-
import { s as sameCanvasIdentity, z as readWidgetAgentSpaceKeyAttribute, W as WidgetRenderReportContext } from "./WebSearchResultsConversationWidget-DRBQvycE.js";
|
|
2
|
+
import { j as conversationWidgetRegistry, F as resolveCanonicalWidgetName, I as exceedsJsonContainerDepth, p as ConversationWidgetFeatureGate, o as ConversationWidgetErrorBoundary, J as remarkWidgetFencePlugin, y as getConversationWidgetRegistryRevision } from "./widget-name-resolver-BGN3HpoG.js";
|
|
5
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
4
|
import React, { createContext, useContext, useState, useEffect, useRef, useMemo } from "react";
|
|
7
|
-
import { f as InteractiveSurface, q as Text, $ as translateText, h as Markdown } from "./index-7Qc_3GbG.js";
|
|
5
|
+
import { f as InteractiveSurface, q as Text, $ as translateText, h as Markdown, N as getFurtherWidgetClickSignalSources } from "./index-7Qc_3GbG.js";
|
|
8
6
|
import remarkDirective from "remark-directive";
|
|
9
7
|
import { visit } from "unist-util-visit";
|
|
8
|
+
import { A as readWidgetAgentSpaceKeyAttribute, W as WidgetRenderReportContext } from "./WebSearchResultsConversationWidget-as3p5bHw.js";
|
|
10
9
|
const resolveDeepLinkableWidget = (widgetName) => {
|
|
11
10
|
if (!widgetName) return null;
|
|
12
11
|
return conversationWidgetRegistry.widgets.find((entry) => entry.name === widgetName && entry.deepLinkable === true) ?? null;
|
|
@@ -17,68 +16,6 @@ const deepLinkableWidgetNameForCanvas = (canvasId) => {
|
|
|
17
16
|
(entry) => entry.deepLinkable === true && entry.opensCanvases?.includes(canvasId)
|
|
18
17
|
)?.name ?? null;
|
|
19
18
|
};
|
|
20
|
-
const toLastClosed = (canvas, closedByCustomer) => ({
|
|
21
|
-
canvasId: canvas.canvasId,
|
|
22
|
-
instanceId: canvas.instanceId,
|
|
23
|
-
anchor: canvas.anchor,
|
|
24
|
-
mountGeneration: canvas.mountGeneration,
|
|
25
|
-
closedByCustomer,
|
|
26
|
-
...canvas.createdEntityId !== void 0 ? { createdEntityId: canvas.createdEntityId } : {}
|
|
27
|
-
});
|
|
28
|
-
const nextMountGeneration = (state) => {
|
|
29
|
-
state.canvasMountCount += 1;
|
|
30
|
-
return state.canvasMountCount;
|
|
31
|
-
};
|
|
32
|
-
const applyOpenCanvas = (state, request) => {
|
|
33
|
-
const decision = decideCanvasOpen(canvasBehaviourOf(request.canvasId), state.canvas, state.lastClosedCanvas, request);
|
|
34
|
-
if (decision.kind === "ignore") return decision;
|
|
35
|
-
const previous = state.canvas;
|
|
36
|
-
const mountGeneration = nextMountGeneration(state);
|
|
37
|
-
const carriedCreatedEntityId = request.createdEntityId ?? (previous !== null && sameCanvasIdentity(previous, request) ? previous.createdEntityId : void 0) ?? (state.lastClosedCanvas !== null && sameCanvasIdentity(state.lastClosedCanvas, request) ? state.lastClosedCanvas.createdEntityId : void 0);
|
|
38
|
-
if (previous !== null && !sameCanvasIdentity(previous, request)) {
|
|
39
|
-
state.lastClosedCanvas = toLastClosed(previous, false);
|
|
40
|
-
} else if (state.lastClosedCanvas !== null && sameCanvasIdentity(state.lastClosedCanvas, request)) {
|
|
41
|
-
state.lastClosedCanvas = null;
|
|
42
|
-
}
|
|
43
|
-
state.canvas = {
|
|
44
|
-
canvasId: request.canvasId,
|
|
45
|
-
instanceId: request.instanceId,
|
|
46
|
-
anchor: request.anchor,
|
|
47
|
-
origin: request.origin,
|
|
48
|
-
mountGeneration,
|
|
49
|
-
...carriedCreatedEntityId !== void 0 ? { createdEntityId: carriedCreatedEntityId } : {}
|
|
50
|
-
};
|
|
51
|
-
return decision;
|
|
52
|
-
};
|
|
53
|
-
const applyCloseCanvas = (state, byCustomer) => {
|
|
54
|
-
if (state.canvas === null) return;
|
|
55
|
-
state.lastClosedCanvas = toLastClosed(state.canvas, byCustomer);
|
|
56
|
-
state.canvas = null;
|
|
57
|
-
};
|
|
58
|
-
const applyResetCanvasForNewTurn = (state) => {
|
|
59
|
-
if (state.canvas !== null && canvasBehaviourOf(state.canvas.canvasId)?.lifetime === "turn") {
|
|
60
|
-
state.canvas = null;
|
|
61
|
-
}
|
|
62
|
-
if (state.lastClosedCanvas !== null) {
|
|
63
|
-
if (canvasBehaviourOf(state.lastClosedCanvas.canvasId)?.lifetime === "turn") {
|
|
64
|
-
state.lastClosedCanvas = null;
|
|
65
|
-
} else if (state.lastClosedCanvas.closedByCustomer) {
|
|
66
|
-
state.lastClosedCanvas = { ...state.lastClosedCanvas, closedByCustomer: false };
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const applyClearCanvas = (state) => {
|
|
71
|
-
state.canvas = null;
|
|
72
|
-
state.lastClosedCanvas = null;
|
|
73
|
-
};
|
|
74
|
-
const applySetCanvasCreatedEntityId = (state, created) => {
|
|
75
|
-
const canvas = state.canvas;
|
|
76
|
-
if (canvas === null || !sameCanvasIdentity(canvas, created) || canvas.mountGeneration !== created.mountGeneration) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
state.canvas = { ...canvas, createdEntityId: created.createdEntityId };
|
|
80
|
-
return true;
|
|
81
|
-
};
|
|
82
19
|
const createWidgetRenderReportCollector = (options) => {
|
|
83
20
|
const { onSettled, settleMs = 1500, maxWaitMs = 2e4 } = options;
|
|
84
21
|
const reportsByMessageId = /* @__PURE__ */ new Map();
|
|
@@ -481,21 +418,29 @@ const ConversationMarkdown = (props) => {
|
|
|
481
418
|
);
|
|
482
419
|
return /* @__PURE__ */ jsx(ConversationWidgetRenderContext.Provider, { value: renderContext, children: /* @__PURE__ */ jsx(Markdown, { remarkPlugins, components: getMarkdownComponents(), markdown }) });
|
|
483
420
|
};
|
|
421
|
+
const FRONTEND_WIDGET_CLICK_SIGNAL_SOURCE = "FRONTEND_WIDGET_CLICK";
|
|
422
|
+
const OWNER_ACTION_CONFIRM_SIGNAL_SOURCE = "OWNER_ACTION_CONFIRM";
|
|
423
|
+
const PACKAGE_WIDGET_CLICK_SIGNAL_SOURCES = [
|
|
424
|
+
FRONTEND_WIDGET_CLICK_SIGNAL_SOURCE,
|
|
425
|
+
OWNER_ACTION_CONFIRM_SIGNAL_SOURCE
|
|
426
|
+
];
|
|
427
|
+
const getWidgetClickSignalSources = () => [
|
|
428
|
+
...PACKAGE_WIDGET_CLICK_SIGNAL_SOURCES,
|
|
429
|
+
...getFurtherWidgetClickSignalSources()
|
|
430
|
+
];
|
|
431
|
+
const isWidgetClickSignalSource = (signalSource) => signalSource != null && getWidgetClickSignalSources().includes(signalSource);
|
|
484
432
|
export {
|
|
485
433
|
ConversationMarkdown as C,
|
|
486
434
|
WIDGET_RENDER_REPORT_SIGNAL_SOURCE as W,
|
|
487
435
|
ConversationWidgetHost as a,
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
WidgetWindowRootContext as i,
|
|
496
|
-
createWidgetRenderReportCollector as j,
|
|
497
|
-
WidgetRenderReportCollectorContext as k,
|
|
436
|
+
buildWidgetRenderReportSignal as b,
|
|
437
|
+
WidgetWindowRootContext as c,
|
|
438
|
+
deepLinkableWidgetNameForCanvas as d,
|
|
439
|
+
createWidgetRenderReportCollector as e,
|
|
440
|
+
WidgetRenderReportCollectorContext as f,
|
|
441
|
+
getWidgetClickSignalSources as g,
|
|
442
|
+
isWidgetClickSignalSource as i,
|
|
498
443
|
parseWidgetRenderReportSignal as p,
|
|
499
444
|
resolveDeepLinkableWidget as r
|
|
500
445
|
};
|
|
501
|
-
//# sourceMappingURL=
|
|
446
|
+
//# sourceMappingURL=widget-click-signal-sources-DulRkNvZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-click-signal-sources-DulRkNvZ.js","sources":["../../src/renderer/resolve-deep-linkable-widget.ts","../../src/renderer/render-report/widget-render-report-collector.ts","../../src/renderer/widget-windowing.tsx","../../src/renderer/conversationWidgetAstPlugin.ts","../../src/renderer/restoreTextDirectivesPlugin.ts","../../src/renderer/WindowedWidget/WindowedWidget.tsx","../../src/renderer/ConversationWidgetHost.tsx","../../src/renderer/MarkdownLink.tsx","../../src/renderer/ConversationMarkdown.tsx","../../src/renderer/widget-click-signal-sources.ts"],"sourcesContent":["import type { CanvasId } from \"./canvas/canvas-behaviours\";\nimport { ConversationWidgetEntry, conversationWidgetRegistry } from \"./conversationWidgetRegistry\";\n\n/**\n * Resolves the widget a `?agentWidget=<name>` deep-link (or a restored pinned canvas) may mount, by its CANONICAL\n * registry wire name.\n *\n * A URL is untrusted input, so this is an allow-list rather than a registry lookup: only an entry that declares\n * `deepLinkable: true` can be opened this way. Every other widget is emitted by the agent inside a message, where the\n * conversation itself is the authorisation — a link must not be able to mount an arbitrary widget (some carry\n * mount-time side effects) just because its name was typed into the address bar.\n *\n * Returns the entry (the caller renders its `component`, applying the feature gate the entry declares) or null when the\n * name is empty, unknown, or not deep-linkable.\n */\nexport const resolveDeepLinkableWidget = (widgetName?: string | null): ConversationWidgetEntry | null => {\n if (!widgetName) return null;\n return (\n conversationWidgetRegistry.widgets.find((entry) => entry.name === widgetName && entry.deepLinkable === true) ?? null\n );\n};\n\n/**\n * The reverse direction: which deep-linkable widget re-opens THIS canvas. The open canvas of the agent chat is\n * mirrored into `?agentWidget=` (AgentTrigger) so a reload brings the customer back to the surface they were working\n * on — an editor a cold chat opened has no conversation id yet, so the canvas model's own pointer storage\n * has nothing to restore from.\n *\n * Null for every canvas no deep-linkable widget declares: it is the agent's to open inside a message, and a URL must\n * not be able to mount it (the allow-list above).\n */\nexport const deepLinkableWidgetNameForCanvas = (canvasId: CanvasId | null | undefined): string | null => {\n if (!canvasId) return null;\n return (\n conversationWidgetRegistry.widgets.find(\n (entry) => entry.deepLinkable === true && entry.opensCanvases?.includes(canvasId),\n )?.name ?? null\n );\n};\n","import { createContext } from \"react\";\nimport type { WidgetRenderReporter, WidgetRenderReportEntry } from \"./widget-render-report\";\n\n/**\n * The render reports of the widget blocks of live messages, collected per message. The chat host\n * (`AgentChat`) owns one collector and hands it down; `ConversationWidgetHost` registers every block of a JUST-DELIVERED\n * message (never a replayed one) and gives the widget a reporter for it. A block that reports nothing counts as\n * `mounted`. Once a message's blocks have settled — none `pending` for `settleMs`, or `maxWaitMs` after the first block\n * at the latest — the collector calls `onSettled` ONCE for that message with its blocks in document order; the host\n * sends the signal only when a block is not `mounted` or rendered with a note (a `mounted` entry with a code: figures\n * without a source), so a clean render costs nothing.\n */\n\nexport interface WidgetRenderBlockReport {\n widgetName: string;\n /** The block's offset in the message's markdown — document order, and the block's identity in the message. */\n sourceOffset: number;\n entry: WidgetRenderReportEntry;\n}\n\nexport interface WidgetRenderReportCollector {\n /** Counts one block of one live message as `mounted` unless it already reported (a child reports before its host mounts). */\n registerBlock: (messageId: string | number, widgetName: string, sourceOffset: number) => void;\n /** The reporter of one block of one live message. */\n reporterForBlock: (messageId: string | number, widgetName: string, sourceOffset: number) => WidgetRenderReporter;\n /** Forget every pending timer (the host unmounts or the conversation switches). */\n dispose: () => void;\n}\n\nexport interface WidgetRenderReportCollectorOptions {\n onSettled: (messageId: string, blocks: WidgetRenderBlockReport[]) => void;\n settleMs?: number;\n maxWaitMs?: number;\n}\n\ninterface MessageReports {\n blocksByKey: Map<string, WidgetRenderBlockReport>;\n firstReportAt: number;\n settleTimer: ReturnType<typeof setTimeout> | null;\n isSent: boolean;\n}\n\nexport const createWidgetRenderReportCollector = (\n options: WidgetRenderReportCollectorOptions,\n): WidgetRenderReportCollector => {\n const { onSettled, settleMs = 1500, maxWaitMs = 20000 } = options;\n const reportsByMessageId = new Map<string, MessageReports>();\n\n const scheduleSettleCheck = (messageId: string) => {\n const messageReports = reportsByMessageId.get(messageId);\n if (!messageReports || messageReports.isSent) return;\n if (messageReports.settleTimer !== null) clearTimeout(messageReports.settleTimer);\n const hasPendingBlock = [...messageReports.blocksByKey.values()].some((block) => block.entry.status === \"pending\");\n const waitedMs = Date.now() - messageReports.firstReportAt;\n const delayMs = hasPendingBlock ? Math.max(0, Math.min(settleMs * 4, maxWaitMs - waitedMs)) : settleMs;\n messageReports.settleTimer = setTimeout(() => {\n messageReports.settleTimer = null;\n const isStillPending = [...messageReports.blocksByKey.values()].some((block) => block.entry.status === \"pending\");\n if (isStillPending && Date.now() - messageReports.firstReportAt < maxWaitMs) {\n scheduleSettleCheck(messageId);\n return;\n }\n messageReports.isSent = true;\n onSettled(\n messageId,\n [...messageReports.blocksByKey.values()].sort((first, second) => first.sourceOffset - second.sourceOffset),\n );\n }, delayMs);\n };\n\n const recordBlock = (\n messageId: string,\n widgetName: string,\n sourceOffset: number,\n entry: WidgetRenderReportEntry | null,\n ) => {\n let messageReports = reportsByMessageId.get(messageId);\n if (!messageReports) {\n messageReports = { blocksByKey: new Map(), firstReportAt: Date.now(), settleTimer: null, isSent: false };\n reportsByMessageId.set(messageId, messageReports);\n }\n if (messageReports.isSent) return;\n const blockKey = `${widgetName}@${sourceOffset}`;\n const knownBlock = messageReports.blocksByKey.get(blockKey);\n if (entry === null && knownBlock) return;\n messageReports.blocksByKey.set(blockKey, { widgetName, sourceOffset, entry: entry ?? { status: \"mounted\" } });\n scheduleSettleCheck(messageId);\n };\n\n return {\n registerBlock: (messageId, widgetName, sourceOffset) =>\n recordBlock(String(messageId), widgetName, sourceOffset, null),\n reporterForBlock: (messageId, widgetName, sourceOffset) => ({\n report: (entry: WidgetRenderReportEntry) => recordBlock(String(messageId), widgetName, sourceOffset, entry),\n }),\n dispose: () => {\n for (const messageReports of reportsByMessageId.values()) {\n if (messageReports.settleTimer !== null) clearTimeout(messageReports.settleTimer);\n }\n reportsByMessageId.clear();\n },\n };\n};\n\n/** The collector of the chat the widget lives in; absent = nobody listens (another host, a story, the e-mail capture). */\nexport const WidgetRenderReportCollectorContext = createContext<WidgetRenderReportCollector | null>(null);\n\n/** The stored prefix of a render-report signal — the inspector and the tests read it; never reworded. */\nexport const WIDGET_RENDER_REPORT_SIGNAL_PREFIX = \"Widget render report for message\";\n\n/** The signal source (backend `AIConversationSignalSource::FRONTEND_WIDGET_RENDER_REPORT`). */\nexport const WIDGET_RENDER_REPORT_SIGNAL_SOURCE = \"FRONTEND_WIDGET_RENDER_REPORT\";\n\nconst MAX_DETAIL_CHARACTERS = 400;\n\n/** The backend's cap on a signal text (`AIConversationMessage::MAX_SIGNAL_TEXT_CHARS`). */\nconst MAX_SIGNAL_TEXT_CHARS = 2000;\n/** Room kept for the \"… and N more\" line. */\nconst OMITTED_LINE_RESERVE = 80;\n\n/**\n * The model-visible signal for a settled message — null when every block mounted cleanly (nothing to tell). One line\n * per block that is not `mounted`, or that mounted with a note (a code: `INLINE_VALUE_WITHOUT_SOURCE`): its position\n * among the message's widgets, its name and its occurrence among widgets of that name, its status and code, the\n * detail. The closing sentence asks for the honest answer about a block the owner did not see, and for\n * a note that the next widget fixes it.\n */\nexport const buildWidgetRenderReportSignal = (messageId: string, blocks: WidgetRenderBlockReport[]): string | null => {\n const occurrenceByName = new Map<string, number>();\n const blockLines: string[] = [];\n blocks.forEach((block, blockPosition) => {\n const occurrence = (occurrenceByName.get(block.widgetName) ?? 0) + 1;\n occurrenceByName.set(block.widgetName, occurrence);\n if (block.entry.status === \"mounted\" && !block.entry.code) return;\n const status = block.entry.status === \"pending\" ? \"pending (did not finish loading)\" : block.entry.status;\n const code = block.entry.code ? ` ${block.entry.code}` : \"\";\n const detail = block.entry.detail ? ` — ${block.entry.detail.slice(0, MAX_DETAIL_CHARACTERS)}` : \"\";\n blockLines.push(`- widget ${blockPosition + 1} (${block.widgetName} #${occurrence}): ${status}${code}${detail}`);\n });\n if (blockLines.length === 0) return null;\n const header = `${WIDGET_RENDER_REPORT_SIGNAL_PREFIX} ${messageId}:`;\n const hasBlockNotShown = blocks.some((block) => block.entry.status !== \"mounted\");\n const hasNote = blocks.some((block) => block.entry.status === \"mounted\" && block.entry.code);\n const closing = [\n hasBlockNotShown\n ? \"The owner did not see these widgets as intended. In your next answer say so in one line where it matters and \" +\n 'give the content in prose; never refer to \"the widget above\" for them.'\n : \"\",\n hasNote\n ? \"The widgets marked mounted were shown; fix the noted part in every widget you write from now on (a figure you \" +\n \"researched names its publisher and page in `source`). Do not resend the widget for the note alone.\"\n : \"\",\n ]\n .filter((sentence) => sentence !== \"\")\n .join(\" \");\n // The backend keeps the first MAX_SIGNAL_TEXT_CHARS of a signal: whole lines only, the rest counted in one line.\n const keptLines: string[] = [];\n let signalLength = header.length + 1 + closing.length + OMITTED_LINE_RESERVE;\n for (const blockLine of blockLines) {\n if (signalLength + blockLine.length + 1 > MAX_SIGNAL_TEXT_CHARS) break;\n keptLines.push(blockLine);\n signalLength += blockLine.length + 1;\n }\n const omittedCount = blockLines.length - keptLines.length;\n if (omittedCount > 0) keptLines.push(`- … and ${omittedCount} more widget(s) that did not render as intended`);\n return `${header}\\n${keptLines.join(\"\\n\")}\\n${closing}`;\n};\n\nexport interface ParsedWidgetRenderReport {\n messageId: string;\n blocks: Array<{\n position: number;\n widgetName: string;\n occurrence: number;\n status: string;\n code: string | null;\n detail: string | null;\n }>;\n}\n\nconst REPORT_LINE =\n /^- widget (\\d+) \\(([A-Za-z]+) #(\\d+)\\): (mounted|empty|failed|pending)(?: \\(did not finish loading\\))?(?: ([A-Z_]+))?(?: — (.*))?$/;\n\n/** The report a stored signal text carries, or null for another text — the admin inspector's reader. */\nexport const parseWidgetRenderReportSignal = (signalText: string): ParsedWidgetRenderReport | null => {\n const lines = signalText.split(\"\\n\");\n const header = new RegExp(`^${WIDGET_RENDER_REPORT_SIGNAL_PREFIX} (\\\\S+):$`).exec(lines[0] ?? \"\");\n if (!header) return null;\n const blocks: ParsedWidgetRenderReport[\"blocks\"] = [];\n for (const line of lines.slice(1)) {\n const match = REPORT_LINE.exec(line);\n if (!match) continue;\n blocks.push({\n position: Number(match[1]),\n widgetName: match[2],\n occurrence: Number(match[3]),\n status: match[4],\n code: match[5] ?? null,\n detail: match[6] ?? null,\n });\n }\n return { messageId: header[1], blocks };\n};\n","import React, { createContext, RefObject, useContext, useEffect, useState } from \"react\";\n\n/**\n * Viewport-windowing for chat widgets. Heavy interactive widgets (maps, lists, hydrating components) are mounted ONLY\n * while near the viewport and unmounted back to a placeholder when far away — so a long conversation keeps a CONSTANT\n * number of widgets mounted no matter how far you scroll. Two thresholds give hysteresis (reveal early, hide late) so a\n * small scroll wobble never thrashes mount/unmount.\n *\n * The IntersectionObserver root is the chat scroll container, supplied via {@link WidgetWindowRootContext} by the chat\n * host (ConversationViewBody). Observers are POOLED per (root, margin): all placeholders share two observers, not two each.\n */\nexport const WidgetWindowRootContext = createContext<HTMLElement | null>(null);\n\n/** Mount when the widget is within this margin of the viewport. */\nconst REVEAL_MARGIN_PX = 600;\n/** Unmount only once it is beyond this (larger) margin — the gap to REVEAL is the hysteresis band. */\nconst HIDE_MARGIN_PX = 2000;\n\ntype Pool = { observer: IntersectionObserver; callbacks: Map<Element, (entry: IntersectionObserverEntry) => void> };\n// Keyed by root (null = viewport) → margin string → the shared observer + its per-element callbacks.\nconst poolsByRoot = new Map<Element | null, Map<string, Pool>>();\n\n/** Register `element` with the shared observer for (root, rootMargin); returns a disposer. */\nconst observeShared = (\n root: Element | null,\n rootMargin: string,\n element: Element,\n onEntry: (entry: IntersectionObserverEntry) => void,\n): (() => void) => {\n let byMargin = poolsByRoot.get(root);\n if (!byMargin) {\n byMargin = new Map();\n poolsByRoot.set(root, byMargin);\n }\n let pool = byMargin.get(rootMargin);\n if (!pool) {\n const callbacks = new Map<Element, (entry: IntersectionObserverEntry) => void>();\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n callbacks.get(entry.target)?.(entry);\n }\n },\n { root, rootMargin },\n );\n pool = { observer, callbacks };\n byMargin.set(rootMargin, pool);\n }\n pool.callbacks.set(element, onEntry);\n pool.observer.observe(element);\n\n return () => {\n const currentByMargin = poolsByRoot.get(root);\n const currentPool = currentByMargin?.get(rootMargin);\n if (!currentPool) return;\n currentPool.observer.unobserve(element);\n currentPool.callbacks.delete(element);\n if (currentPool.callbacks.size === 0) {\n currentPool.observer.disconnect();\n currentByMargin!.delete(rootMargin);\n if (currentByMargin!.size === 0) poolsByRoot.delete(root);\n }\n };\n};\n\n/**\n * Drives a widget's mounted/unmounted state from its viewport proximity.\n *\n * - `pinned` (the freshly-delivered widget) → always revealed, never observed: a live widget must not unmount while its\n * one-shot effects (canvas auto-open) are in play, and re-mounting it later would re-fire them.\n * - otherwise: starts at `initialRevealed` (the cheap index-window guess for first paint), then the reveal observer\n * mounts it when it scrolls within REVEAL_MARGIN and the hide observer unmounts it past HIDE_MARGIN.\n *\n * Returns `[revealed, reveal]` — `reveal` lets the placeholder force a manual mount (the \"Show\" affordance).\n */\nexport const useWidgetWindow = (\n targetRef: RefObject<HTMLElement | null>,\n options: { initialRevealed: boolean; pinned: boolean },\n): [boolean, () => void] => {\n const { initialRevealed, pinned } = options;\n const root = useContext(WidgetWindowRootContext);\n const [revealed, setRevealed] = useState(initialRevealed || pinned);\n\n useEffect(() => {\n if (pinned) {\n setRevealed(true);\n return undefined;\n }\n const element = targetRef.current;\n if (!element || typeof IntersectionObserver === \"undefined\") return undefined;\n\n const disposeReveal = observeShared(root, `${REVEAL_MARGIN_PX}px 0px`, element, (entry) => {\n if (entry.isIntersecting) setRevealed(true);\n });\n const disposeHide = observeShared(root, `${HIDE_MARGIN_PX}px 0px`, element, (entry) => {\n if (!entry.isIntersecting) setRevealed(false);\n });\n return () => {\n disposeReveal();\n disposeHide();\n };\n // Re-attach when the scroll root resolves (it is null on the first frame, then the container element).\n }, [root, pinned, targetRef]);\n\n return [revealed, () => setRevealed(true)];\n};\n","import { visit } from \"unist-util-visit\";\nimport { conversationWidgetRegistry, type ConversationWidgetEntry } from \"./conversationWidgetRegistry\";\nimport { resolveCanonicalWidgetName } from \"./widget-name-resolver\";\nimport { exceedsJsonContainerDepth } from \"./widget-tree/bounded-json\";\n\n/** Whether a `::Name{payload='…'}` payload nests deeper than the backend decodes — MALFORMED there, dropped here. */\nconst isPayloadTooDeep = (payload: unknown): boolean => {\n if (typeof payload !== \"string\") return false;\n try {\n return exceedsJsonContainerDepth(JSON.parse(payload));\n } catch {\n return false;\n }\n};\n\n/**\n * Maps the `::Name` nodes a message carries onto the registered components by rewriting `data.hName` to the CANONICAL\n * registry name — which is what `ConversationMarkdown` keys its component map by.\n *\n * The name on the node is whatever the message contains, so a stored conversation delivers the legacy\n * `::ExampleWidgetDirective{payload='…'}` form (and stored server `component` parts carry `\"name\":\"<Canonical>Directive\"`,\n * which `normalize-server-message-to-markdown` turns into exactly that). Resolution therefore goes\n * through `resolveCanonicalWidgetName` — the one legacy rule — never a direct set lookup, or every old message would\n * degrade to the `:name` plain-text fallback.\n */\nexport default function conversationWidgetAstPlugin() {\n const canonicalNames = new Set(conversationWidgetRegistry.widgets.map((w: ConversationWidgetEntry) => w.name));\n\n return (tree: any) => {\n // `\"leafDirective\"` is remark-directive's node type — its contract, not our vocabulary. It is the only form a\n // widget ever travels in: `remarkWidgetFencePlugin` produces it from a ```widget fence, and the stored `::Name`\n // syntax parses into it.\n visit(tree, [\"leafDirective\"], (node, index, parent) => {\n const canonicalName = resolveCanonicalWidgetName(node.name, canonicalNames);\n\n if (\n canonicalName &&\n index !== undefined &&\n index !== null &&\n parent &&\n isPayloadTooDeep(node.attributes?.payload)\n ) {\n parent.children[index] = { type: \"text\", value: \"\" };\n return;\n }\n\n if (canonicalName) {\n // Map properties to attributes for react-markdown\n node.data = {\n hName: canonicalName,\n hProperties: node.attributes || {},\n ...node.data,\n };\n return node;\n }\n\n // `index === 0` is falsy — a plain `!index` check would skip the text\n // fallback for a node that is its parent's first child.\n if (index === undefined || index === null || !parent) {\n return node;\n }\n\n // An unknown name becomes plain text. Keep the node's children so a `::Unknown[label]` form degrades to its\n // label instead of silently swallowing it.\n const asText = { type: \"text\", value: `:${node.name}` };\n parent.children.splice(index, 1, asText, ...(node.children ?? []));\n const prev = parent.children[index - 1];\n if (prev?.type === \"text\") {\n prev.value += asText.value;\n parent.children.splice(index, 1);\n }\n });\n };\n}\n","import { visit } from \"unist-util-visit\";\n\n/**\n * remark-directive parses EVERY `:name` run as a text directive — including the `:00` / `:30` inside a time such as\n * `08:00–16:30` (digits are valid directive names). Text directives are not part of our widget vocabulary (widgets\n * travel as leaf directives only, see `conversationWidgetAstPlugin`), so a text directive is always prose that the\n * parser misread: without this pass the customer chat rendered \"Montag: 08:00–16:30\" as \"08\" / \"–16\" (the `:00`\n * and `:30` swallowed, the unknown nodes rendered as breaks) while the admin inspector, which does not load\n * remark-directive, showed the line intact.\n *\n * Restores every text directive to the exact source slice it was parsed from, merging it into the neighbouring text\n * nodes so the paragraph reads as one run again.\n */\nexport default function restoreTextDirectivesPlugin() {\n return (tree: any, file: any) => {\n const source = String(file?.value ?? \"\");\n visit(tree, \"textDirective\", (node: any, index: number | undefined, parent: any) => {\n if (index === undefined || index === null || !parent) {\n return;\n }\n const start = node.position?.start?.offset;\n const end = node.position?.end?.offset;\n const literal =\n typeof start === \"number\" && typeof end === \"number\" && end > start\n ? source.slice(start, end)\n : `:${node.name}${node.children?.length ? `[${node.children.map((c: any) => c.value ?? \"\").join(\"\")}]` : \"\"}`;\n const asText = { type: \"text\", value: literal };\n parent.children.splice(index, 1, asText);\n // Merge with the neighbours so \"08\" + \":00\" + \"–16\" becomes one text node again.\n const prev = parent.children[index - 1];\n if (prev?.type === \"text\") {\n prev.value += asText.value;\n parent.children.splice(index, 1);\n const next = parent.children[index];\n if (next?.type === \"text\") {\n prev.value += next.value;\n parent.children.splice(index, 1);\n }\n return index - 1;\n }\n const next = parent.children[index + 1];\n if (next?.type === \"text\") {\n asText.value += next.value;\n parent.children.splice(index + 1, 1);\n }\n return index;\n });\n };\n}\n","import { InteractiveSurface, Text } from \"../../provider/components\";\nimport React, { useEffect, useRef } from \"react\";\nimport { translateText } from \"../../provider/environment\";\nimport { useWidgetWindow } from \"../widget-windowing\";\nimport styles from \"../HiddenWidgetPlaceholder/HiddenWidgetPlaceholder.module.scss\";\n\nexport interface WindowedWidgetProps {\n children: React.ReactNode;\n /** First-paint guess from the index window: recent messages start mounted, older ones start as a placeholder. */\n initialRevealed: boolean;\n /** The freshly-delivered widget — kept mounted (never windowed out) so its one-shot effects don't re-fire. */\n pinned: boolean;\n}\n\n/** Default reserved height for a widget that has never been measured (an old one that has not been scrolled to yet). */\nconst DEFAULT_PLACEHOLDER_MIN_HEIGHT = 80;\n\n/**\n * Mounts a chat widget only while it is near the viewport (see {@link useWidgetWindow}); far from the viewport it\n * collapses to a lightweight placeholder. The wrapper element is STABLE across the toggle so the shared\n * IntersectionObserver keeps tracking it. The placeholder reserves the widget's last measured height, so re-hiding it\n * causes ZERO layout shift (no scroll jump); revealing again restores the real widget (self-hydrating widgets re-fetch\n * with a brief skeleton).\n */\nexport const WindowedWidget = ({ children, initialRevealed, pinned }: WindowedWidgetProps) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const [revealed, reveal] = useWidgetWindow(wrapperRef, { initialRevealed, pinned });\n // Remembered so the placeholder can reserve exactly the height the widget occupied.\n const lastHeightRef = useRef<number | undefined>(undefined);\n\n useEffect(() => {\n const element = wrapperRef.current;\n if (!revealed || !element || typeof ResizeObserver === \"undefined\") return undefined;\n const measure = () => {\n if (wrapperRef.current) lastHeightRef.current = wrapperRef.current.offsetHeight;\n };\n measure();\n const resizeObserver = new ResizeObserver(measure);\n resizeObserver.observe(element);\n return () => resizeObserver.disconnect();\n }, [revealed]);\n\n return (\n <div ref={wrapperRef}>\n {revealed ? (\n children\n ) : (\n <InteractiveSurface\n hoverable\n className={styles.placeholder}\n style={{ minHeight: lastHeightRef.current ?? DEFAULT_PLACEHOLDER_MIN_HEIGHT }}\n >\n <button\n type=\"button\"\n className={styles.placeholderButton}\n onClick={reveal}\n aria-label={translateText(\"Show hidden widget\")}\n >\n <Text>Older interactive content is hidden.</Text>\n <span className={styles.cta}>\n <Text>Show</Text>\n </span>\n </button>\n </InteractiveSurface>\n )}\n </div>\n );\n};\n","import React, { useContext, useEffect, useMemo } from \"react\";\nimport styles from \"./ConversationMarkdown.module.scss\";\nimport { ConversationWidgetEntry } from \"./conversationWidgetRegistry\";\nimport { ConversationWidgetFeatureGate } from \"./_access/ConversationWidgetFeatureGate\";\nimport { readWidgetAgentSpaceKeyAttribute } from \"./_agent-space/widget-agent-space-key-attribute\";\nimport { ConversationWidgetErrorBoundary } from \"./ConversationWidgetErrorBoundary\";\nimport { WindowedWidget } from \"./WindowedWidget/WindowedWidget\";\nimport { WidgetRenderReportContext } from \"./render-report/widget-render-report\";\nimport { WidgetRenderReportCollectorContext } from \"./render-report/widget-render-report-collector\";\n\nexport type ConversationWidgetRenderProps = Record<string, unknown> & {\n children?: React.ReactNode;\n fresh?: boolean;\n interactive?: boolean;\n justDelivered?: boolean;\n messageId?: string | number;\n};\n\ninterface ConversationWidgetHostProps {\n widget: ConversationWidgetEntry;\n /** Forwarded into the widget (and as its deprecated alias `fresh`): the widget's controls may be used. */\n interactive: boolean;\n /** Forwarded into the widget: the host message was delivered live right now — the one-shot side-effect gate. */\n justDelivered: boolean;\n /** Id of the host message, forwarded so a widget can identify the canvas it opens. */\n messageId?: string | number;\n /** When true, the widget renders as a lightweight placeholder (cheap scroll). */\n hideWidgets: boolean;\n /** Parsed markdown attributes for this widget instance. */\n conversationWidgetRenderProps: ConversationWidgetRenderProps;\n}\n\n/**\n * Single render path for every widget. Each concern is applied as a sequential gate\n * (innermost → outermost):\n * 1. the widget itself, with `interactive` / `justDelivered`\n * 2. feature-flag gate\n * 3. viewport-windowing (mount near the viewport, placeholder when far — WindowedWidget)\n * 4. block spacing wrapper\n *\n * A block of a JUST-DELIVERED message is also registered with the chat's render-report collector: it\n * counts as `mounted` unless the widget reports otherwise through `useReportWidgetRenderStatus`, and a crash caught by\n * the error boundary reports `failed` (`RENDER_FAILED`). A replayed message reports nothing.\n */\nexport const ConversationWidgetHost = ({\n widget,\n interactive,\n justDelivered,\n messageId,\n hideWidgets,\n conversationWidgetRenderProps,\n}: ConversationWidgetHostProps) => {\n const { component: Component, featureFlag, upsellTrigger } = widget;\n const renderReportCollector = useContext(WidgetRenderReportCollectorContext);\n // The block's offset in the message markdown (react-markdown hands every component its hast node) — its identity and\n // its document order in the render report.\n const sourceOffset = (\n conversationWidgetRenderProps.node as { position?: { start?: { offset?: number } } } | undefined\n )?.position?.start?.offset;\n const isReported = renderReportCollector !== null && justDelivered && messageId !== undefined;\n const renderReporter = useMemo(\n () =>\n isReported && messageId !== undefined\n ? renderReportCollector.reporterForBlock(messageId, widget.name, sourceOffset ?? 0)\n : null,\n [isReported, renderReportCollector, messageId, widget.name, sourceOffset],\n );\n useEffect(() => {\n if (isReported && messageId !== undefined)\n renderReportCollector.registerBlock(messageId, widget.name, sourceOffset ?? 0);\n }, [isReported, renderReportCollector, messageId, widget.name, sourceOffset]);\n\n let node = (\n <Component\n {...conversationWidgetRenderProps}\n fresh={interactive}\n interactive={interactive}\n justDelivered={justDelivered}\n messageId={messageId}\n />\n );\n\n if (featureFlag) {\n node = (\n <ConversationWidgetFeatureGate\n featureFlag={featureFlag}\n UpsellTrigger={upsellTrigger}\n agentSpaceKeyAttribute={readWidgetAgentSpaceKeyAttribute(conversationWidgetRenderProps)}\n >\n {node}\n </ConversationWidgetFeatureGate>\n );\n }\n\n // Viewport-windowing: a widget is mounted only while near the viewport and collapses to a height-preserving\n // placeholder when far away — so a long conversation keeps a constant number of widgets mounted. The INTERACTIVE\n // widget (the live reply, and the newest reply after a reload) is pinned — never unmounted, so its controls stay\n // and its one-shot effects don't re-fire; older widgets start from the cheap index-window guess and reveal/hide as\n // they scroll in and out. The feature gate lives INSIDE, so it only runs once the widget is actually mounted.\n node = (\n // Pinned on delivery as well as on controls: a just-delivered widget that lost its controls (a newer widget of the\n // same type superseded it) must not unmount when scrolled past, or its remount re-fires the one-shot canvas open.\n <WindowedWidget initialRevealed={!hideWidgets} pinned={interactive || justDelivered}>\n {node}\n </WindowedWidget>\n );\n\n // Outermost gate: widget props come from LLM output, so any throw inside the\n // widget (or its gates) must not unmount the whole chat message.\n node = (\n <ConversationWidgetErrorBoundary\n widgetName={widget.name}\n onCrash={() =>\n renderReporter?.report({ status: \"failed\", code: \"RENDER_FAILED\", detail: \"the widget threw while rendering\" })\n }\n >\n <WidgetRenderReportContext.Provider value={renderReporter}>{node}</WidgetRenderReportContext.Provider>\n </ConversationWidgetErrorBoundary>\n );\n\n return <div className={styles.conversationWidgetWrapper}>{node}</div>;\n};\n","import React from \"react\";\nimport styles from \"./ConversationMarkdown.module.scss\";\n\nexport type MarkdownLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n /** The hast node react-markdown passes to every custom component; not a valid DOM attribute. */\n node?: unknown;\n};\n\n// Render every markdown link as a new-tab anchor with a dashed underline. `node` is dropped before the\n// rest is spread onto <a> so react-markdown's hast node never lands on the DOM element.\nexport const MarkdownLink = ({ node, children, ...anchorProps }: MarkdownLinkProps) => (\n <a {...anchorProps} target=\"_blank\" rel=\"noopener noreferrer\" className={styles.markdownLink}>\n {children}\n </a>\n);\n","import React, { useContext, useMemo } from \"react\";\nimport { type AgentsMarkdownProps, Markdown } from \"../provider/components\";\nimport remarkDirective from \"remark-directive\";\nimport remarkWidgetFencePlugin from \"./remarkWidgetFencePlugin\";\nimport conversationWidgetAstPlugin from \"./conversationWidgetAstPlugin\";\nimport restoreTextDirectivesPlugin from \"./restoreTextDirectivesPlugin\";\nimport { conversationWidgetRegistry, getConversationWidgetRegistryRevision } from \"./conversationWidgetRegistry\";\nimport { ConversationWidgetHost, ConversationWidgetRenderProps } from \"./ConversationWidgetHost\";\nimport { MarkdownLink } from \"./MarkdownLink\";\n\nexport interface ConversationMarkdownProps {\n markdown: string;\n /**\n * Forwarded into every widget instance as `interactive` (and its deprecated alias `fresh`): the widget's controls\n * may be used. True for a live-delivered message and for the newest assistant reply after a reload.\n */\n interactive?: boolean;\n /**\n * Forwarded into every widget instance as `justDelivered`: the message was delivered live right now. The only gate\n * for one-shot side effects (canvas open, draft creation); never true after a reload or on replay.\n */\n justDelivered?: boolean;\n /** Id of the host message, forwarded so a widget can identify the canvas it opens. */\n messageId?: string | number;\n /**\n * When true, widgets are replaced with a lightweight placeholder.\n * Used for old messages to keep the chat scroll cheap.\n */\n hideWidgets?: boolean;\n}\n\n/**\n * Render flags delivered via context so the widget component map can live at module\n * scope. The map must keep stable component identities across renders: react-markdown\n * reconciles by element type, so a per-render `Wrapped` closure makes React unmount and\n * remount every widget on each streaming tick — resetting one-shot refs (duplicate\n * drawer opens / POSTs) and re-triggering hydration.\n */\nconst ConversationWidgetRenderContext = React.createContext<{\n interactive: boolean;\n justDelivered: boolean;\n hideWidgets: boolean;\n messageId?: string | number;\n}>({\n interactive: false,\n justDelivered: false,\n hideWidgets: false,\n});\n\n// Map every widget name to a component that delegates rendering to ConversationWidgetHost,\n// which owns the per-widget concerns (interactive / justDelivered, feature-flag gate, hidden placeholder, block spacing).\n// Built lazily: the registry imports every widget and a widget can import AgentChat, which renders this file.\nconst buildConversationWidgetComponents = () =>\n conversationWidgetRegistry.widgets.reduce<Record<string, React.ComponentType<ConversationWidgetRenderProps>>>(\n (acc, widget) => {\n const Wrapped: React.ComponentType<ConversationWidgetRenderProps> = (innerProps) => {\n const { interactive, justDelivered, hideWidgets, messageId } = useContext(ConversationWidgetRenderContext);\n\n return (\n <ConversationWidgetHost\n widget={widget}\n interactive={interactive}\n justDelivered={justDelivered}\n messageId={messageId}\n hideWidgets={hideWidgets}\n conversationWidgetRenderProps={innerProps}\n />\n );\n };\n Wrapped.displayName = `ConversationWidget(${widget.name})`;\n acc[widget.name] = Wrapped;\n return acc;\n },\n {},\n );\n\nlet markdownComponents: AgentsMarkdownProps[\"components\"] | undefined;\nlet markdownComponentsRevision = -1;\n\n// Rebuilt only when an app registered more widgets since (`registerConversationWidgets`): the identities stay stable.\nconst getMarkdownComponents = (): AgentsMarkdownProps[\"components\"] => {\n if (markdownComponents === undefined || markdownComponentsRevision !== getConversationWidgetRegistryRevision()) {\n markdownComponents = {\n ...buildConversationWidgetComponents(),\n a: MarkdownLink,\n } as AgentsMarkdownProps[\"components\"];\n markdownComponentsRevision = getConversationWidgetRegistryRevision();\n }\n return markdownComponents;\n};\n\n// remarkWidgetFencePlugin rewrites ```widget fenced blocks into the node type remark-directive parses `::Name{}` into,\n// BEFORE conversationWidgetAstPlugin maps them to components — so the model's ```widget egress and the legacy\n// `::Name{}` egress share one render path (ConversationWidgetHost + feature-gate + hydration).\n// restoreTextDirectivesPlugin runs LAST: remark-directive also parses the `:00` inside \"08:00–16:30\" as a text\n// directive (digits are valid names) and swallowed it in the customer chat — text directives are never widgets.\nconst remarkPlugins = [\n remarkDirective,\n remarkWidgetFencePlugin,\n conversationWidgetAstPlugin,\n restoreTextDirectivesPlugin,\n];\n\nexport const ConversationMarkdown = (props: ConversationMarkdownProps) => {\n const { markdown, interactive = false, justDelivered = false, hideWidgets = false, messageId } = props;\n\n const renderContext = useMemo(\n () => ({ interactive, justDelivered, hideWidgets, messageId }),\n [interactive, justDelivered, hideWidgets, messageId],\n );\n\n return (\n <ConversationWidgetRenderContext.Provider value={renderContext}>\n <Markdown remarkPlugins={remarkPlugins} components={getMarkdownComponents()} markdown={markdown} />\n </ConversationWidgetRenderContext.Provider>\n );\n};\n","import { getFurtherWidgetClickSignalSources } from \"../provider/environment\";\n\n/**\n * The `signalSource`s a widget CLICK posts into the conversation (`injectSignal`): the generic widget click and the\n * dedicated source the former owner-action consent widget sent (no component posts it any more; stored rows keep it),\n * plus the further sources an app's own widgets post (`AgentsEnvironment.furtherWidgetClickSignalSources`, e.g. a form\n * submit that starts its own owner turn). The message list reads them to tell an answered widget from an open one after\n * a reload — a widget the owner already clicked must never come back interactive (a consent widget re-armed is a second\n * confirmation for a destructive tool). Add a source here when a widget of the package starts posting a new one.\n */\nexport const FRONTEND_WIDGET_CLICK_SIGNAL_SOURCE = \"FRONTEND_WIDGET_CLICK\";\nexport const OWNER_ACTION_CONFIRM_SIGNAL_SOURCE = \"OWNER_ACTION_CONFIRM\";\n\n/** The package's own widget click sources (the backend's sources of the package that carry an owner statement). */\nexport const PACKAGE_WIDGET_CLICK_SIGNAL_SOURCES: readonly string[] = [\n FRONTEND_WIDGET_CLICK_SIGNAL_SOURCE,\n OWNER_ACTION_CONFIRM_SIGNAL_SOURCE,\n];\n\n/** Every widget click source: the package's own and the app's further ones. */\nexport const getWidgetClickSignalSources = (): readonly string[] => [\n ...PACKAGE_WIDGET_CLICK_SIGNAL_SOURCES,\n ...getFurtherWidgetClickSignalSources(),\n];\n\nexport const isWidgetClickSignalSource = (signalSource: string | undefined | null): boolean =>\n signalSource != null && getWidgetClickSignalSources().includes(signalSource);\n"],"names":["next","styles"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
3
|
import React, { useReducer, useRef, useCallback, useMemo, useEffect, useState, useContext, createContext, useLayoutEffect, useId, useSyncExternalStore, Fragment as Fragment$1 } from "react";
|
|
4
|
-
import { b as registerWidgetHydrator,
|
|
4
|
+
import { b as registerWidgetHydrator, X as SkeletonLine, U as WidgetSurface, ac as WidgetKpiValue, A as readWidgetAgentSpaceKeyAttribute, W as WidgetRenderReportContext, j as buildWidgetAgentSpaceKeyProps, aB as readTextNodeContent, aC as readAllowedValue, E as useConversationWidgetContext, M as ModelText, a3 as DonePill, aA as ConversationWidgetButton, D as shortStringHash, K as WidgetImageReadinessContext, y as messageAnchor, C as ConversationWidgetActions, aD as useReportTextNodeRenderState, aE as readTextNodeRenderState, a7 as SkeletonPill, aF as buildFaviconUrl, aG as readSiteHostname, V as SkeletonCircle, aH as readSafeHttpUrl, H as useWidgetHydration, F as useIsEmailWidgetRender, G as useReportWidgetRenderStatus, _ as ClockConversationWidget, $ as ConceptExplainerConversationWidget, a1 as CurrencyConverterConversationWidget, a2 as CustomVisualizationConversationWidget, aw as normalizeEntityMentionFields, a4 as EntityMentionConversationWidget, ad as WritingDraftConversationWidget, a9 as SuggestedActions, a5 as MultiChoiceConversationWidget, a6 as QuickRepliesConversationWidget, aa as ToolTraceConversationWidget, a0 as ConversationSearchResultsConversationWidget, ab as WebSearchResultsConversationWidget } from "./WebSearchResultsConversationWidget-as3p5bHw.js";
|
|
5
5
|
import { V as getWidgetSelfHydrationKeyFieldName, J as getAgentsEnvironment, E as escapePlainTextForText, q as Text, I as Icon, a5 as useAgentsOwnerSettings, z as classNames, B as Button, S as SegmentBar, u as TrendDelta, v as WidgetText, $ as translateText, Z as reportWidgetCrash, W as WidgetFeatureGate, f as InteractiveSurface, C as Checkbox, d as DateInput, s as TextInput, R as RadioGroup, k as Select, j as RangeSlider, T as Tabs, r as TextArea, M as Map$1, g as MapMarker, a4 as useAgentsMapsLoader, l as Skeleton, X as openImageGallery, o as StatusBadge, h as Markdown } from "./index-7Qc_3GbG.js";
|
|
6
6
|
import ReactApexChartImport from "react-apexcharts";
|
|
7
7
|
import { i as isAgentsIconName } from "./icon-names-Di6c4zLo.js";
|
|
@@ -1134,6 +1134,30 @@ const measureComposedViewSourceBytes = (widgetFields) => {
|
|
|
1134
1134
|
const { type: unusedType, writtenSyntax: unusedWrittenSyntax, ...fieldsWithoutType } = widgetFields;
|
|
1135
1135
|
return utf8ByteLength(JSON.stringify(normalizeToPhpArrays(fieldsWithoutType)));
|
|
1136
1136
|
};
|
|
1137
|
+
const composedViewNodeToWire = (node) => {
|
|
1138
|
+
const wireNode = { type: node.type };
|
|
1139
|
+
if (node.id !== null) wireNode.id = node.id;
|
|
1140
|
+
Object.assign(wireNode, node.props);
|
|
1141
|
+
const namedSlots = {};
|
|
1142
|
+
for (const [slotName, slotNodes] of Object.entries(node.nodesBySlotName)) {
|
|
1143
|
+
if (slotNodes.length === 0) continue;
|
|
1144
|
+
const slotWireNodes = slotNodes.map(composedViewNodeToWire);
|
|
1145
|
+
if (slotName === DEFAULT_SLOT_NAME) wireNode.children = slotWireNodes;
|
|
1146
|
+
else namedSlots[slotName] = slotWireNodes;
|
|
1147
|
+
}
|
|
1148
|
+
if (Object.keys(namedSlots).length > 0) wireNode.slots = namedSlots;
|
|
1149
|
+
return wireNode;
|
|
1150
|
+
};
|
|
1151
|
+
const composedViewTreeToWire = (tree) => {
|
|
1152
|
+
const wireFields = {};
|
|
1153
|
+
if (tree.title !== null) wireFields.title = tree.title;
|
|
1154
|
+
if (Object.keys(tree.state).length > 0) wireFields.state = tree.state;
|
|
1155
|
+
if (Object.keys(tree.data).length > 0) wireFields.data = tree.data;
|
|
1156
|
+
if (Object.keys(tree.computed).length > 0) wireFields.computed = tree.computed;
|
|
1157
|
+
if (tree.view !== null) wireFields.view = composedViewNodeToWire(tree.view);
|
|
1158
|
+
if (Object.keys(tree.actions).length > 0) wireFields.actions = tree.actions;
|
|
1159
|
+
return wireFields;
|
|
1160
|
+
};
|
|
1137
1161
|
const getComposedViewSubtreeNodesByPath = (node, path) => [
|
|
1138
1162
|
[path, node],
|
|
1139
1163
|
...Object.entries(node.nodesBySlotName).flatMap(([slotName, slotNodes]) => {
|
|
@@ -6301,6 +6325,10 @@ const subscribeToAuthFailure = (listener) => {
|
|
|
6301
6325
|
const readAuthFailure = () => hasGoogleMapsAuthFailed;
|
|
6302
6326
|
const readAuthFailureOnServer = () => false;
|
|
6303
6327
|
const useGoogleMapsAuthFailure = () => useSyncExternalStore(subscribeToAuthFailure, readAuthFailure, readAuthFailureOnServer);
|
|
6328
|
+
const resetGoogleMapsAuthFailureForTests = () => {
|
|
6329
|
+
hasGoogleMapsAuthFailed = false;
|
|
6330
|
+
};
|
|
6331
|
+
const simulateGoogleMapsAuthFailure = () => markGoogleMapsAuthFailed();
|
|
6304
6332
|
const buildMapRenderReport = (mapView, loadState) => {
|
|
6305
6333
|
if (loadState.isPending) return { status: "pending" };
|
|
6306
6334
|
if (loadState.hasLoadError || loadState.hasAuthFailed) {
|
|
@@ -9620,23 +9648,26 @@ const closestWidgetNames = (type, limit = 3) => {
|
|
|
9620
9648
|
};
|
|
9621
9649
|
export {
|
|
9622
9650
|
ApexChart as A,
|
|
9623
|
-
|
|
9651
|
+
readConversationWidgetRegistrations as B,
|
|
9624
9652
|
COMPOSED_VIEW_TONES as C,
|
|
9625
|
-
|
|
9653
|
+
readOpenEntityActionTarget as D,
|
|
9626
9654
|
EmbeddedConversationWidget as E,
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
|
|
9639
|
-
|
|
9655
|
+
resolveCanonicalWidgetName as F,
|
|
9656
|
+
resolveWidgetName as G,
|
|
9657
|
+
readComposedViewDataTimes as H,
|
|
9658
|
+
exceedsJsonContainerDepth as I,
|
|
9659
|
+
remarkWidgetFencePlugin as J,
|
|
9660
|
+
readEntityDetailInstanceId as K,
|
|
9661
|
+
readMapNodeKeyOfInstanceId as L,
|
|
9662
|
+
findMapNodeInMarkdown as M,
|
|
9663
|
+
canvasInstanceIdForEntityDetail as N,
|
|
9664
|
+
mapStyles as O,
|
|
9665
|
+
MapPresentationContext as P,
|
|
9666
|
+
buildComposedViewComponentRegistry as Q,
|
|
9667
|
+
composedViewComponents as R,
|
|
9668
|
+
ComposedViewComponentsContext as S,
|
|
9669
|
+
parseWidgetJsonObject as T,
|
|
9670
|
+
BARE_WIDGET_LINE_GLOBAL as U,
|
|
9640
9671
|
WIDGET_FENCE_LANG as W,
|
|
9641
9672
|
COMPOSED_VIEW_TONE_ALIASES as a,
|
|
9642
9673
|
COMPOSED_VIEW_TONE_GRAPHIC_COLOR as b,
|
|
@@ -9649,20 +9680,20 @@ export {
|
|
|
9649
9680
|
registerConversationWidgets as i,
|
|
9650
9681
|
conversationWidgetRegistry as j,
|
|
9651
9682
|
replaceConversationWidgetRegistryEntries as k,
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9683
|
+
resetGoogleMapsAuthFailureForTests as l,
|
|
9684
|
+
findWidgetFenceByPayloadHash as m,
|
|
9685
|
+
findWidgetFencesInMarkdown as n,
|
|
9686
|
+
ConversationWidgetErrorBoundary as o,
|
|
9687
|
+
ConversationWidgetFeatureGate as p,
|
|
9688
|
+
addComposedNodeSchemaApplicationPart as q,
|
|
9658
9689
|
readComposedViewTone as r,
|
|
9659
|
-
|
|
9660
|
-
|
|
9690
|
+
simulateGoogleMapsAuthFailure as s,
|
|
9691
|
+
closestWidgetNames as t,
|
|
9661
9692
|
useChartPalette as u,
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
|
|
9693
|
+
composedNodeSchema as v,
|
|
9694
|
+
composedViewTreeToWire as w,
|
|
9695
|
+
getComposedNodeSchema as x,
|
|
9696
|
+
getConversationWidgetRegistryRevision as y,
|
|
9697
|
+
readComposedViewTree as z
|
|
9667
9698
|
};
|
|
9668
|
-
//# sourceMappingURL=widget-name-resolver-
|
|
9699
|
+
//# sourceMappingURL=widget-name-resolver-BGN3HpoG.js.map
|