@bikdotai/bik-component-library 0.0.862 → 0.0.863-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +2 -2
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/mentionSerialization.d.ts +3 -1
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js +22 -14
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("../constants/tools.js"),d=(e,t="Manifest")=>e?i.TOOL_SOURCE_LABELS[e]??e:t,L=e=>{const t=e?String(e):"";return t==="BIK"?"BIK":t==="BSP"?"BSP":"Manifest"}
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("../constants/tools.js"),d=(e,t="Manifest")=>e?i.TOOL_SOURCE_LABELS[e]??e:t,L=e=>{const t=e?String(e):"";return t==="BIK"?"BIK":t==="BSP"?"BSP":"Manifest"},f=(e,t,n="Manifest")=>[...e.map(a=>({id:a.tool_id,label:`${d(a.source,n)} : ${a.display_name}`,meta:{kind:"tool",plainLabel:a.display_name,source:a.source,authRequired:a.auth_required}})),...t.map(a=>({id:a.id,label:`sub-agent: ${a.name}`,meta:{kind:"subagent",plainLabel:a.name}}))],p=e=>e.replace(/^\{\{|\}\}$/g,""),$=(e=[])=>{const t=[],n=a=>{const o=a.actualValue;if(o){const l=p(o);t.push({id:l,label:`{{${l}}}`,meta:{kind:"variable",plainLabel:a.displayName}})}Object.values(a.variables??{}).forEach(n)};return e.forEach(n),t},b=e=>{if(e.tool_key==="send_slack_message")return String(e.params.channelId?.value??"").trim()||"Send Slack message";if(e.tool_key==="send_email"){const t=String(e.params.name?.value??"").trim();return t||String(e.params.sendTo?.value??"").split(",").map(n=>n.trim()).filter(Boolean)[0]||"Send email"}return e.tool_key},g=e=>e.name||"Rest API",S=e=>{const t=g(e);return{id:e.id,label:`${i.TOOL_SOURCE_LABELS[i.ToolSource.RestApi]} : ${t}`,meta:{kind:"tool",plainLabel:t,source:i.ToolSource.RestApi}}},T=e=>{const t=e.tool_key==="send_slack_message"?i.ToolSource.Slack:i.ToolSource.EmailHandover,n=b(e);return{id:e.id,label:`${i.TOOL_SOURCE_LABELS[t]} : ${n}`,meta:{kind:"tool",plainLabel:n,source:t}}},_=(e=[],t=[])=>[...t.map(S),...e.map(T)],r=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),s=e=>r(e).replace(/"/g,"""),k=(e,t,n,a)=>`<span data-type="mentionAgent" class="bik-mention bik-mention--agent" data-id="${s(e)}" data-label="${s(t)}" data-kind="${s(n)}"`+(a?` data-source="${s(a)}"`:"")+`>${r(t)}</span>`,E=(e,t,n,a)=>k(e,t,n,a),O=e=>{const t=new Map;for(const n of e){const a=n.meta;a?.kind==="tool"?t.set(`tool:${String(n.id)}`,n):a?.kind==="subagent"?t.set(`subagent:${String(n.id)}`,n):a?.kind==="variable"&&t.set(`variable:${String(n.id)}`,n)}return t},c=/\{\{((?:tool|subagent|variable):[^{}]+)\}\}/g,v=(e,t)=>{let n="",a=0;c.lastIndex=0;let o;for(;(o=c.exec(e))!==null;){n+=r(e.slice(a,o.index));const l=t.get(o[1]);if(l){const m=l.meta;n+=k(String(l.id),l.label,m.kind,m.source)}else n+=r(o[0]);a=c.lastIndex}return n+=r(e.slice(a)),n.replace(/\n/g,"<br>")},I=(e,t=[])=>{if(!e)return"";const n=O(t);return e.split(/\n{2,}/).map(a=>`<p>${v(a,n)}</p>`).join("")},M=(e,t,n)=>t==="variable"?`{{variable:${e}}}`:(t??(n.has(e)?"tool":"subagent"))==="tool"?`{{tool:${e}}}`:`{{subagent:${e}}}`,u=(e,t)=>{switch(e.type){case"text":return e.text??"";case"mentionAgent":case"mentionTeam":{const n=e.attrs?.id;if(n==null)return"";const a=e.attrs?.kind;return M(String(n),a==null?null:String(a),t)}case"variable":return`{{${String(e.attrs?.variableName??"")}}}`;case"hardBreak":return`
|
|
2
2
|
`;case"orderedList":case"bulletList":{const n=e.type==="orderedList";return(e.content??[]).map((a,o)=>`${n?`${o+1}.`:"-"} ${u(a,t).replace(/\n+$/,"")}`).join(`
|
|
3
3
|
`)+`
|
|
4
4
|
`}default:{const n=(e.content??[]).map(o=>u(o,t)).join("");return["paragraph","heading","listItem","blockquote"].includes(e.type)?`${n}
|
|
5
|
-
`:n}}},A=(e,t)=>{if(!e)return"";const n=new Set(t.map(a=>a.tool_id));return u(e,n).replace(/\n+$/,"")};exports.TOOL_SOURCE_LABELS=i.TOOL_SOURCE_LABELS;exports.appTypeLabel=L;exports.buildAgentMentionItems
|
|
5
|
+
`:n}}},A=(e,t)=>{if(!e)return"";const n=new Set(t.map(a=>a.tool_id));return u(e,n).replace(/\n+$/,"")};exports.TOOL_SOURCE_LABELS=i.TOOL_SOURCE_LABELS;exports.appTypeLabel=L;exports.buildAgentMentionItems=f;exports.buildCustomToolMentionItems=_;exports.buildMentionHtml=E;exports.buildVariableMentionItems=$;exports.configToolMentionItem=T;exports.configToolName=b;exports.editorDocToInstructions=A;exports.instructionsToEditorHtml=I;exports.restApiMentionItem=S;exports.restApiToolName=g;exports.toolSourceLabel=d;exports.variableTokenName=p;
|
|
6
6
|
//# sourceMappingURL=mentionSerialization.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mentionSerialization.js","sources":["../../../../../src/components/agent-builder/utils/mentionSerialization.ts"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport { MentionItem } from '@src/editor';\nimport type {\n\tSubHeader,\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport {\n\tAgentTool,\n\tConfigToolConfig,\n\tRestApiToolConfig,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport { TOOL_SOURCE_LABELS, ToolSource } from '../constants/tools';\n\n/**\n * Serialization helpers between the BikEditor document and the firebase\n * `instructions` string.\n *\n * Firebase stores `instructions` as PLAIN TEXT with inline reference tokens:\n * - `{{subagent:<agentId>}}` — hand-off to another agent\n * - `{{tool:<tool_id>}}` — an action the agent can call\n * - `{{variable:<name>}}` — a template variable picked from the catalog\n *\n * In the editor those references are inserted via the `@` mention menu (which we\n * populate with BOTH tools and sub-agents). Mention nodes keep their `id` in the\n * ProseMirror doc JSON (the rendered HTML drops it), so we serialize from the doc\n * JSON — not from HTML.\n */\n\nexport interface MentionKindMeta {\n\t/** Distinguishes a tool / sub-agent / variable reference. */\n\tkind: 'tool' | 'subagent' | 'variable';\n\t/** Plain item name (no prefix) shown in the picker dropdown rows. */\n\tplainLabel?: string;\n\t/** For tools: the source bucket (manifest / shopify / …) the picker groups by. */\n\tsource?: string;\n\t/** For tools: touches customer-private data → shows a shield in the picker. */\n\tauthRequired?: boolean;\n}\n\n// Source labels moved to constants/tools.ts; re-exported for existing importers.\nexport { TOOL_SOURCE_LABELS };\n\n/** Human label for a tool source; falls back to the host-app label, then the raw key. */\nexport const toolSourceLabel = (\n\tsource: string | undefined,\n\tfallback = 'Manifest',\n): string => {\n\tif (!source) {\n\t\treturn fallback;\n\t}\n\treturn TOOL_SOURCE_LABELS[source as ToolSource] ?? source;\n};\n\n/** Human label for the host application, used as the tool-chip prefix. */\nexport const appTypeLabel = (applicationType?: ApplicationType): string => {\n\tconst key = applicationType ? String(applicationType) : '';\n\tif (key === 'BIK') {\n\t\treturn 'BIK';\n\t}\n\tif (key === 'BSP') {\n\t\treturn 'BSP';\n\t}\n\treturn 'Manifest';\n};\n\n/**\n * Build the combined `@` mention list from the available tools + sub-agents.\n *\n * The `label` is the CHIP text shown once inserted — tools read\n * `\"<App> : <tool name>\"` (e.g. \"Manifest : Look up order\"), sub-agents read\n * `\"sub-agent: <name>\"`. `meta.plainLabel` is the un-prefixed name for the\n * picker rows, and `meta.kind` drives the `{{tool}}` / `{{subagent}}` colour.\n */\nexport const buildAgentMentionItems = (\n\ttools: AgentTool[],\n\tsubAgents: SubAgentRef[],\n\tappLabel = 'Manifest',\n): MentionItem[] => [\n\t...tools.map(\n\t\t(t): MentionItem => ({\n\t\t\tid: t.tool_id,\n\t\t\tlabel: `${toolSourceLabel(t.source, appLabel)} : ${t.display_name}`,\n\t\t\tmeta: {\n\t\t\t\tkind: 'tool',\n\t\t\t\tplainLabel: t.display_name,\n\t\t\t\tsource: t.source,\n\t\t\t\tauthRequired: t.auth_required,\n\t\t\t},\n\t\t}),\n\t),\n\t...subAgents.map(\n\t\t(s): MentionItem => ({\n\t\t\tid: s.id,\n\t\t\tlabel: `sub-agent: ${s.name}`,\n\t\t\tmeta: { kind: 'subagent', plainLabel: s.name },\n\t\t}),\n\t),\n];\n\n/** Strip the `{{ }}` wrapper from a variable token (`{{a.b}}` → `a.b`). */\nexport const variableTokenName = (actualValue: string): string =>\n\tactualValue.replace(/^\\{\\{|\\}\\}$/g, '');\n\n/**\n * Flatten the (nested) variable catalog into mention items, so stored\n * `{{<name>}}` tokens rehydrate as `Variable: <display name>` chips. The item\n * id is the BARE token name (no braces) — `resolveMentionToken` re-wraps it on\n * save. Merge alongside {@link buildAgentMentionItems} for serialization.\n */\nexport const buildVariableMentionItems = (\n\tvariablesData: VariableListInterfaceV3[] = [],\n): MentionItem[] => {\n\tconst items: MentionItem[] = [];\n\tconst walk = (entry: VariableListInterfaceV3 | SubHeader | VariableV3) => {\n\t\tconst actual = (entry as VariableV3).actualValue;\n\t\tif (actual) {\n\t\t\tconst name = variableTokenName(actual);\n\t\t\titems.push({\n\t\t\t\tid: name,\n\t\t\t\t// Chip text is the raw token — designers want variables to read as\n\t\t\t\t// {{a.b.c}} (styled purple by the editor), not a labelled chip.\n\t\t\t\tlabel: `{{${name}}}`,\n\t\t\t\tmeta: { kind: 'variable', plainLabel: entry.displayName },\n\t\t\t});\n\t\t}\n\t\tObject.values(entry.variables ?? {}).forEach(walk);\n\t};\n\tvariablesData.forEach(walk);\n\treturn items;\n};\n\n/** Display name for a shared config tool: first recipient / channel, else generic. */\nexport const configToolName = (t: ConfigToolConfig): string => {\n\tif (t.tool_key === 'send_slack_message') {\n\t\treturn (\n\t\t\tString(t.params['channelId']?.value ?? '').trim() || 'Send Slack message'\n\t\t);\n\t}\n\treturn (\n\t\tString(t.params['sendTo']?.value ?? '')\n\t\t\t.split(',')\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean)[0] || 'Send email'\n\t);\n};\n\n/** Display name for a Rest API tool row / chip. */\nexport const restApiToolName = (t: RestApiToolConfig): string =>\n\tt.name || 'Rest API';\n\n/** The `@`-mention chip item for a Rest API tool (kind 'tool', restapi source). */\nexport const restApiMentionItem = (t: RestApiToolConfig): MentionItem => {\n\tconst name = restApiToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[ToolSource.RestApi]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source: ToolSource.RestApi },\n\t};\n};\n\n/** The `@`-mention chip item for a shared config tool (email / Slack). */\nexport const configToolMentionItem = (t: ConfigToolConfig): MentionItem => {\n\tconst source =\n\t\tt.tool_key === 'send_slack_message'\n\t\t\t? ToolSource.Slack\n\t\t\t: ToolSource.EmailHandover;\n\tconst name = configToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[source]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source },\n\t};\n};\n\n/**\n * Mention items for the inline-configured custom tools (Rest API + email / Slack)\n * so their `{{tool:<id>}}` tokens rehydrate as chips — they live on the agent\n * value, not in the catalog `availableTools`. Merge alongside\n * {@link buildAgentMentionItems} in the editor's mention list.\n */\nexport const buildCustomToolMentionItems = (\n\tconfigTools: ConfigToolConfig[] = [],\n\trestApiTools: RestApiToolConfig[] = [],\n): MentionItem[] => [\n\t...restApiTools.map(restApiMentionItem),\n\t...configTools.map(configToolMentionItem),\n];\n\nconst escapeHtml = (raw: string): string =>\n\traw.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nconst escapeAttr = (raw: string): string =>\n\tescapeHtml(raw).replace(/\"/g, '"');\n\n/**\n * The HTML for a single mention chip. Must round-trip through the TipTap mention\n * extension's `parseHTML` (`span[data-type=\"mentionAgent\"]`, reading\n * `data-id`/`data-label`/`data-kind`) — see MentionExtension.ts. `normalizeHtml`\n * is taught to keep `data-type=\"mention…\"` spans so this survives to the parser.\n */\nconst mentionSpanHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: string,\n\tsource?: string,\n): string =>\n\t`<span data-type=\"mentionAgent\" class=\"bik-mention bik-mention--agent\"` +\n\t` data-id=\"${escapeAttr(id)}\" data-label=\"${escapeAttr(label)}\"` +\n\t` data-kind=\"${escapeAttr(kind)}\"` +\n\t(source ? ` data-source=\"${escapeAttr(source)}\"` : '') +\n\t`>${escapeHtml(label)}</span>`;\n\n/**\n * Public: HTML for one mention chip, for inserting at the cursor (e.g. when a\n * tool / sub-agent is added from the Step-3 side panel). Round-trips through the\n * same parser path as the rehydrated chips. `source` (tool source bucket) drives\n * the chip's leading icon.\n */\nexport const buildMentionHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: 'tool' | 'subagent' | 'variable',\n\tsource?: string,\n): string => mentionSpanHtml(id, label, kind, source);\n\n/**\n * `{{tool:<id>}}` / `{{subagent:<id>}}` / `{{<variableName>}}` → the mention\n * item that produced them. The map key is the token's INNER text.\n */\nconst buildTokenLookup = (\n\tmentionItems: MentionItem[],\n): Map<string, MentionItem> => {\n\tconst byToken = new Map<string, MentionItem>();\n\tfor (const item of mentionItems) {\n\t\tconst meta = item.meta as unknown as MentionKindMeta | undefined;\n\t\t// Everything is keyed by its kind-prefixed id (a tool's id is its tool_id).\n\t\tif (meta?.kind === 'tool') {\n\t\t\tbyToken.set(`tool:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'subagent') {\n\t\t\tbyToken.set(`subagent:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'variable') {\n\t\t\tbyToken.set(`variable:${String(item.id)}`, item);\n\t\t}\n\t}\n\treturn byToken;\n};\n\n// Matches the kind-prefixed reference tokens we render as chips. Other\n// `{{var}}` tokens fall through untouched (left as literal text for the\n// variable decoration).\nconst REFERENCE_TOKEN = /\\{\\{((?:tool|subagent|variable):[^{}]+)\\}\\}/g;\n\n/** Escape plain text, swapping recognised reference tokens for mention spans. */\nconst inlineToHtml = (\n\tsegment: string,\n\tbyToken: Map<string, MentionItem>,\n): string => {\n\tlet out = '';\n\tlet lastIndex = 0;\n\tREFERENCE_TOKEN.lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\twhile ((match = REFERENCE_TOKEN.exec(segment)) !== null) {\n\t\tout += escapeHtml(segment.slice(lastIndex, match.index));\n\t\tconst item = byToken.get(match[1]);\n\t\tif (item) {\n\t\t\tconst meta = item.meta as unknown as MentionKindMeta;\n\t\t\tout += mentionSpanHtml(\n\t\t\t\tString(item.id),\n\t\t\t\titem.label,\n\t\t\t\tmeta.kind,\n\t\t\t\tmeta.source,\n\t\t\t);\n\t\t} else {\n\t\t\t// Not in any available list (removed tool / unknown variable) → keep the\n\t\t\t// raw token as literal text.\n\t\t\tout += escapeHtml(match[0]);\n\t\t}\n\t\tlastIndex = REFERENCE_TOKEN.lastIndex;\n\t}\n\tout += escapeHtml(segment.slice(lastIndex));\n\treturn out.replace(/\\n/g, '<br>');\n};\n\n/**\n * Convert the stored instructions string into HTML for `BikEditor.initialContent`.\n * `{{tool:KEY}}` / `{{subagent:ID}}` tokens are rehydrated into mention chips\n * (resolved via `mentionItems`); any other `{{…}}` token is left as literal text\n * for the editor's variable decoration. Newlines become paragraph / line breaks.\n */\nexport const instructionsToEditorHtml = (\n\ttext: string,\n\tmentionItems: MentionItem[] = [],\n): string => {\n\tif (!text) {\n\t\treturn '';\n\t}\n\tconst byToken = buildTokenLookup(mentionItems);\n\treturn text\n\t\t.split(/\\n{2,}/)\n\t\t.map((para) => `<p>${inlineToHtml(para, byToken)}</p>`)\n\t\t.join('');\n};\n\ninterface ProseMirrorNode {\n\ttype: string;\n\ttext?: string;\n\tattrs?: Record<string, unknown>;\n\tcontent?: ProseMirrorNode[];\n}\n\n/**\n * The token for a mention node. All kinds store their id in the node, so the\n * token value is just that id — the kind only picks the prefix. The node's\n * `kind` attr is authoritative; `toolIds` is a fallback for older content\n * saved before the kind attr existed.\n */\nconst resolveMentionToken = (\n\tid: string,\n\tkind: string | null,\n\ttoolIds: Set<string>,\n): string => {\n\tif (kind === 'variable') {\n\t\treturn `{{variable:${id}}}`;\n\t}\n\tconst resolved = kind ?? (toolIds.has(id) ? 'tool' : 'subagent');\n\treturn resolved === 'tool' ? `{{tool:${id}}}` : `{{subagent:${id}}}`;\n};\n\nconst nodeToText = (node: ProseMirrorNode, toolIds: Set<string>): string => {\n\tswitch (node.type) {\n\t\tcase 'text':\n\t\t\treturn node.text ?? '';\n\t\tcase 'mentionAgent':\n\t\tcase 'mentionTeam': {\n\t\t\tconst id = node.attrs?.['id'];\n\t\t\tif (id == null) {\n\t\t\t\treturn '';\n\t\t\t}\n\t\t\tconst kind = node.attrs?.['kind'];\n\t\t\treturn resolveMentionToken(\n\t\t\t\tString(id),\n\t\t\t\tkind == null ? null : String(kind),\n\t\t\t\ttoolIds,\n\t\t\t);\n\t\t}\n\t\tcase 'variable':\n\t\t\treturn `{{${String(node.attrs?.['variableName'] ?? '')}}}`;\n\t\tcase 'hardBreak':\n\t\t\treturn '\\n';\n\t\tcase 'orderedList':\n\t\tcase 'bulletList': {\n\t\t\t// Flattening to plain text otherwise drops the list markers, so a\n\t\t\t// numbered / bulleted list looks \"removed\" after publish. Emit an\n\t\t\t// ordinal (\"1. \") / bullet (\"- \") prefix per item to preserve it.\n\t\t\tconst ordered = node.type === 'orderedList';\n\t\t\treturn (\n\t\t\t\t(node.content ?? [])\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(item, i) =>\n\t\t\t\t\t\t\t`${ordered ? `${i + 1}.` : '-'} ${nodeToText(\n\t\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\t\ttoolIds,\n\t\t\t\t\t\t\t).replace(/\\n+$/, '')}`,\n\t\t\t\t\t)\n\t\t\t\t\t.join('\\n') + '\\n'\n\t\t\t);\n\t\t}\n\t\tdefault: {\n\t\t\tconst inner = (node.content ?? [])\n\t\t\t\t.map((child) => nodeToText(child, toolIds))\n\t\t\t\t.join('');\n\t\t\t// Block nodes terminate with a newline so paragraphs stay separated.\n\t\t\tconst BLOCK_NODES = ['paragraph', 'heading', 'listItem', 'blockquote'];\n\t\t\treturn BLOCK_NODES.includes(node.type) ? `${inner}\\n` : inner;\n\t\t}\n\t}\n};\n\n/**\n * Convert a BikEditor document (from `ref.getJSON()`) into the firebase\n * instructions string, replacing mention nodes with `{{subagent:<id>}}` /\n * `{{tool:<tool_id>}}` tokens.\n */\nexport const editorDocToInstructions = (\n\tdoc: Record<string, unknown> | null,\n\ttools: AgentTool[],\n): string => {\n\tif (!doc) {\n\t\treturn '';\n\t}\n\tconst toolIds = new Set(tools.map((t) => t.tool_id));\n\treturn nodeToText(doc as unknown as ProseMirrorNode, toolIds).replace(\n\t\t/\\n+$/,\n\t\t'',\n\t);\n};\n"],"names":["toolSourceLabel","source","fallback","TOOL_SOURCE_LABELS","appTypeLabel","applicationType","key","buildAgentMentionItems","tools","subAgents","appLabel","t","s","variableTokenName","actualValue","buildVariableMentionItems","variablesData","items","walk","entry","actual","name","configToolName","restApiToolName","restApiMentionItem","ToolSource","configToolMentionItem","buildCustomToolMentionItems","configTools","restApiTools","escapeHtml","raw","escapeAttr","mentionSpanHtml","id","label","kind","buildMentionHtml","buildTokenLookup","mentionItems","byToken","item","meta","REFERENCE_TOKEN","inlineToHtml","segment","out","lastIndex","match","instructionsToEditorHtml","text","para","resolveMentionToken","toolIds","nodeToText","node","ordered","i","inner","child","editorDocToInstructions","doc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mentionSerialization.js","sources":["../../../../../src/components/agent-builder/utils/mentionSerialization.ts"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport { MentionItem } from '@src/editor';\nimport type {\n\tSubHeader,\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport {\n\tAgentTool,\n\tConfigToolConfig,\n\tRestApiToolConfig,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport { TOOL_SOURCE_LABELS, ToolSource } from '../constants/tools';\n\n/**\n * Serialization helpers between the BikEditor document and the firebase\n * `instructions` string.\n *\n * Firebase stores `instructions` as PLAIN TEXT with inline reference tokens:\n * - `{{subagent:<agentId>}}` — hand-off to another agent\n * - `{{tool:<tool_id>}}` — an action the agent can call\n * - `{{variable:<name>}}` — a template variable picked from the catalog\n *\n * In the editor those references are inserted via the `@` mention menu (which we\n * populate with BOTH tools and sub-agents). Mention nodes keep their `id` in the\n * ProseMirror doc JSON (the rendered HTML drops it), so we serialize from the doc\n * JSON — not from HTML.\n */\n\nexport interface MentionKindMeta {\n\t/** Distinguishes a tool / sub-agent / variable reference. */\n\tkind: 'tool' | 'subagent' | 'variable';\n\t/** Plain item name (no prefix) shown in the picker dropdown rows. */\n\tplainLabel?: string;\n\t/** For tools: the source bucket (manifest / shopify / …) the picker groups by. */\n\tsource?: string;\n\t/** For tools: touches customer-private data → shows a shield in the picker. */\n\tauthRequired?: boolean;\n}\n\n// Source labels moved to constants/tools.ts; re-exported for existing importers.\nexport { TOOL_SOURCE_LABELS };\n\n/** Human label for a tool source; falls back to the host-app label, then the raw key. */\nexport const toolSourceLabel = (\n\tsource: string | undefined,\n\tfallback = 'Manifest',\n): string => {\n\tif (!source) {\n\t\treturn fallback;\n\t}\n\treturn TOOL_SOURCE_LABELS[source as ToolSource] ?? source;\n};\n\n/** Human label for the host application, used as the tool-chip prefix. */\nexport const appTypeLabel = (applicationType?: ApplicationType): string => {\n\tconst key = applicationType ? String(applicationType) : '';\n\tif (key === 'BIK') {\n\t\treturn 'BIK';\n\t}\n\tif (key === 'BSP') {\n\t\treturn 'BSP';\n\t}\n\treturn 'Manifest';\n};\n\n/**\n * Build the combined `@` mention list from the available tools + sub-agents.\n *\n * The `label` is the CHIP text shown once inserted — tools read\n * `\"<App> : <tool name>\"` (e.g. \"Manifest : Look up order\"), sub-agents read\n * `\"sub-agent: <name>\"`. `meta.plainLabel` is the un-prefixed name for the\n * picker rows, and `meta.kind` drives the `{{tool}}` / `{{subagent}}` colour.\n */\nexport const buildAgentMentionItems = (\n\ttools: AgentTool[],\n\tsubAgents: SubAgentRef[],\n\tappLabel = 'Manifest',\n): MentionItem[] => [\n\t...tools.map(\n\t\t(t): MentionItem => ({\n\t\t\tid: t.tool_id,\n\t\t\tlabel: `${toolSourceLabel(t.source, appLabel)} : ${t.display_name}`,\n\t\t\tmeta: {\n\t\t\t\tkind: 'tool',\n\t\t\t\tplainLabel: t.display_name,\n\t\t\t\tsource: t.source,\n\t\t\t\tauthRequired: t.auth_required,\n\t\t\t},\n\t\t}),\n\t),\n\t...subAgents.map(\n\t\t(s): MentionItem => ({\n\t\t\tid: s.id,\n\t\t\tlabel: `sub-agent: ${s.name}`,\n\t\t\tmeta: { kind: 'subagent', plainLabel: s.name },\n\t\t}),\n\t),\n];\n\n/** Strip the `{{ }}` wrapper from a variable token (`{{a.b}}` → `a.b`). */\nexport const variableTokenName = (actualValue: string): string =>\n\tactualValue.replace(/^\\{\\{|\\}\\}$/g, '');\n\n/**\n * Flatten the (nested) variable catalog into mention items, so stored\n * `{{<name>}}` tokens rehydrate as `Variable: <display name>` chips. The item\n * id is the BARE token name (no braces) — `resolveMentionToken` re-wraps it on\n * save. Merge alongside {@link buildAgentMentionItems} for serialization.\n */\nexport const buildVariableMentionItems = (\n\tvariablesData: VariableListInterfaceV3[] = [],\n): MentionItem[] => {\n\tconst items: MentionItem[] = [];\n\tconst walk = (entry: VariableListInterfaceV3 | SubHeader | VariableV3) => {\n\t\tconst actual = (entry as VariableV3).actualValue;\n\t\tif (actual) {\n\t\t\tconst name = variableTokenName(actual);\n\t\t\titems.push({\n\t\t\t\tid: name,\n\t\t\t\t// Chip text is the raw token — designers want variables to read as\n\t\t\t\t// {{a.b.c}} (styled purple by the editor), not a labelled chip.\n\t\t\t\tlabel: `{{${name}}}`,\n\t\t\t\tmeta: { kind: 'variable', plainLabel: entry.displayName },\n\t\t\t});\n\t\t}\n\t\tObject.values(entry.variables ?? {}).forEach(walk);\n\t};\n\tvariablesData.forEach(walk);\n\treturn items;\n};\n\n/** Display name for a shared config tool: the merchant's action name when set\n * (MAP-7245), else first recipient / channel (pre-action-name tools), else\n * generic. */\nexport const configToolName = (t: ConfigToolConfig): string => {\n\tif (t.tool_key === 'send_slack_message') {\n\t\treturn (\n\t\t\tString(t.params['channelId']?.value ?? '').trim() || 'Send Slack message'\n\t\t);\n\t}\n\tif (t.tool_key === 'send_email') {\n\t\tconst actionName = String(t.params['name']?.value ?? '').trim();\n\t\tif (actionName) {\n\t\t\treturn actionName;\n\t\t}\n\t\treturn (\n\t\t\tString(t.params['sendTo']?.value ?? '')\n\t\t\t\t.split(',')\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter(Boolean)[0] || 'Send email'\n\t\t);\n\t}\n\t// Future config-tool keys: no bespoke naming yet — fall back to the key.\n\treturn t.tool_key;\n};\n\n/** Display name for a Rest API tool row / chip. */\nexport const restApiToolName = (t: RestApiToolConfig): string =>\n\tt.name || 'Rest API';\n\n/** The `@`-mention chip item for a Rest API tool (kind 'tool', restapi source). */\nexport const restApiMentionItem = (t: RestApiToolConfig): MentionItem => {\n\tconst name = restApiToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[ToolSource.RestApi]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source: ToolSource.RestApi },\n\t};\n};\n\n/** The `@`-mention chip item for a shared config tool (email / Slack). */\nexport const configToolMentionItem = (t: ConfigToolConfig): MentionItem => {\n\tconst source =\n\t\tt.tool_key === 'send_slack_message'\n\t\t\t? ToolSource.Slack\n\t\t\t: ToolSource.EmailHandover;\n\tconst name = configToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[source]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source },\n\t};\n};\n\n/**\n * Mention items for the inline-configured custom tools (Rest API + email / Slack)\n * so their `{{tool:<id>}}` tokens rehydrate as chips — they live on the agent\n * value, not in the catalog `availableTools`. Merge alongside\n * {@link buildAgentMentionItems} in the editor's mention list.\n */\nexport const buildCustomToolMentionItems = (\n\tconfigTools: ConfigToolConfig[] = [],\n\trestApiTools: RestApiToolConfig[] = [],\n): MentionItem[] => [\n\t...restApiTools.map(restApiMentionItem),\n\t...configTools.map(configToolMentionItem),\n];\n\nconst escapeHtml = (raw: string): string =>\n\traw.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nconst escapeAttr = (raw: string): string =>\n\tescapeHtml(raw).replace(/\"/g, '"');\n\n/**\n * The HTML for a single mention chip. Must round-trip through the TipTap mention\n * extension's `parseHTML` (`span[data-type=\"mentionAgent\"]`, reading\n * `data-id`/`data-label`/`data-kind`) — see MentionExtension.ts. `normalizeHtml`\n * is taught to keep `data-type=\"mention…\"` spans so this survives to the parser.\n */\nconst mentionSpanHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: string,\n\tsource?: string,\n): string =>\n\t`<span data-type=\"mentionAgent\" class=\"bik-mention bik-mention--agent\"` +\n\t` data-id=\"${escapeAttr(id)}\" data-label=\"${escapeAttr(label)}\"` +\n\t` data-kind=\"${escapeAttr(kind)}\"` +\n\t(source ? ` data-source=\"${escapeAttr(source)}\"` : '') +\n\t`>${escapeHtml(label)}</span>`;\n\n/**\n * Public: HTML for one mention chip, for inserting at the cursor (e.g. when a\n * tool / sub-agent is added from the Step-3 side panel). Round-trips through the\n * same parser path as the rehydrated chips. `source` (tool source bucket) drives\n * the chip's leading icon.\n */\nexport const buildMentionHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: 'tool' | 'subagent' | 'variable',\n\tsource?: string,\n): string => mentionSpanHtml(id, label, kind, source);\n\n/**\n * `{{tool:<id>}}` / `{{subagent:<id>}}` / `{{<variableName>}}` → the mention\n * item that produced them. The map key is the token's INNER text.\n */\nconst buildTokenLookup = (\n\tmentionItems: MentionItem[],\n): Map<string, MentionItem> => {\n\tconst byToken = new Map<string, MentionItem>();\n\tfor (const item of mentionItems) {\n\t\tconst meta = item.meta as unknown as MentionKindMeta | undefined;\n\t\t// Everything is keyed by its kind-prefixed id (a tool's id is its tool_id).\n\t\tif (meta?.kind === 'tool') {\n\t\t\tbyToken.set(`tool:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'subagent') {\n\t\t\tbyToken.set(`subagent:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'variable') {\n\t\t\tbyToken.set(`variable:${String(item.id)}`, item);\n\t\t}\n\t}\n\treturn byToken;\n};\n\n// Matches the kind-prefixed reference tokens we render as chips. Other\n// `{{var}}` tokens fall through untouched (left as literal text for the\n// variable decoration).\nconst REFERENCE_TOKEN = /\\{\\{((?:tool|subagent|variable):[^{}]+)\\}\\}/g;\n\n/** Escape plain text, swapping recognised reference tokens for mention spans. */\nconst inlineToHtml = (\n\tsegment: string,\n\tbyToken: Map<string, MentionItem>,\n): string => {\n\tlet out = '';\n\tlet lastIndex = 0;\n\tREFERENCE_TOKEN.lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\twhile ((match = REFERENCE_TOKEN.exec(segment)) !== null) {\n\t\tout += escapeHtml(segment.slice(lastIndex, match.index));\n\t\tconst item = byToken.get(match[1]);\n\t\tif (item) {\n\t\t\tconst meta = item.meta as unknown as MentionKindMeta;\n\t\t\tout += mentionSpanHtml(\n\t\t\t\tString(item.id),\n\t\t\t\titem.label,\n\t\t\t\tmeta.kind,\n\t\t\t\tmeta.source,\n\t\t\t);\n\t\t} else {\n\t\t\t// Not in any available list (removed tool / unknown variable) → keep the\n\t\t\t// raw token as literal text.\n\t\t\tout += escapeHtml(match[0]);\n\t\t}\n\t\tlastIndex = REFERENCE_TOKEN.lastIndex;\n\t}\n\tout += escapeHtml(segment.slice(lastIndex));\n\treturn out.replace(/\\n/g, '<br>');\n};\n\n/**\n * Convert the stored instructions string into HTML for `BikEditor.initialContent`.\n * `{{tool:KEY}}` / `{{subagent:ID}}` tokens are rehydrated into mention chips\n * (resolved via `mentionItems`); any other `{{…}}` token is left as literal text\n * for the editor's variable decoration. Newlines become paragraph / line breaks.\n */\nexport const instructionsToEditorHtml = (\n\ttext: string,\n\tmentionItems: MentionItem[] = [],\n): string => {\n\tif (!text) {\n\t\treturn '';\n\t}\n\tconst byToken = buildTokenLookup(mentionItems);\n\treturn text\n\t\t.split(/\\n{2,}/)\n\t\t.map((para) => `<p>${inlineToHtml(para, byToken)}</p>`)\n\t\t.join('');\n};\n\ninterface ProseMirrorNode {\n\ttype: string;\n\ttext?: string;\n\tattrs?: Record<string, unknown>;\n\tcontent?: ProseMirrorNode[];\n}\n\n/**\n * The token for a mention node. All kinds store their id in the node, so the\n * token value is just that id — the kind only picks the prefix. The node's\n * `kind` attr is authoritative; `toolIds` is a fallback for older content\n * saved before the kind attr existed.\n */\nconst resolveMentionToken = (\n\tid: string,\n\tkind: string | null,\n\ttoolIds: Set<string>,\n): string => {\n\tif (kind === 'variable') {\n\t\treturn `{{variable:${id}}}`;\n\t}\n\tconst resolved = kind ?? (toolIds.has(id) ? 'tool' : 'subagent');\n\treturn resolved === 'tool' ? `{{tool:${id}}}` : `{{subagent:${id}}}`;\n};\n\nconst nodeToText = (node: ProseMirrorNode, toolIds: Set<string>): string => {\n\tswitch (node.type) {\n\t\tcase 'text':\n\t\t\treturn node.text ?? '';\n\t\tcase 'mentionAgent':\n\t\tcase 'mentionTeam': {\n\t\t\tconst id = node.attrs?.['id'];\n\t\t\tif (id == null) {\n\t\t\t\treturn '';\n\t\t\t}\n\t\t\tconst kind = node.attrs?.['kind'];\n\t\t\treturn resolveMentionToken(\n\t\t\t\tString(id),\n\t\t\t\tkind == null ? null : String(kind),\n\t\t\t\ttoolIds,\n\t\t\t);\n\t\t}\n\t\tcase 'variable':\n\t\t\treturn `{{${String(node.attrs?.['variableName'] ?? '')}}}`;\n\t\tcase 'hardBreak':\n\t\t\treturn '\\n';\n\t\tcase 'orderedList':\n\t\tcase 'bulletList': {\n\t\t\t// Flattening to plain text otherwise drops the list markers, so a\n\t\t\t// numbered / bulleted list looks \"removed\" after publish. Emit an\n\t\t\t// ordinal (\"1. \") / bullet (\"- \") prefix per item to preserve it.\n\t\t\tconst ordered = node.type === 'orderedList';\n\t\t\treturn (\n\t\t\t\t(node.content ?? [])\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(item, i) =>\n\t\t\t\t\t\t\t`${ordered ? `${i + 1}.` : '-'} ${nodeToText(\n\t\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\t\ttoolIds,\n\t\t\t\t\t\t\t).replace(/\\n+$/, '')}`,\n\t\t\t\t\t)\n\t\t\t\t\t.join('\\n') + '\\n'\n\t\t\t);\n\t\t}\n\t\tdefault: {\n\t\t\tconst inner = (node.content ?? [])\n\t\t\t\t.map((child) => nodeToText(child, toolIds))\n\t\t\t\t.join('');\n\t\t\t// Block nodes terminate with a newline so paragraphs stay separated.\n\t\t\tconst BLOCK_NODES = ['paragraph', 'heading', 'listItem', 'blockquote'];\n\t\t\treturn BLOCK_NODES.includes(node.type) ? `${inner}\\n` : inner;\n\t\t}\n\t}\n};\n\n/**\n * Convert a BikEditor document (from `ref.getJSON()`) into the firebase\n * instructions string, replacing mention nodes with `{{subagent:<id>}}` /\n * `{{tool:<tool_id>}}` tokens.\n */\nexport const editorDocToInstructions = (\n\tdoc: Record<string, unknown> | null,\n\ttools: AgentTool[],\n): string => {\n\tif (!doc) {\n\t\treturn '';\n\t}\n\tconst toolIds = new Set(tools.map((t) => t.tool_id));\n\treturn nodeToText(doc as unknown as ProseMirrorNode, toolIds).replace(\n\t\t/\\n+$/,\n\t\t'',\n\t);\n};\n"],"names":["toolSourceLabel","source","fallback","TOOL_SOURCE_LABELS","appTypeLabel","applicationType","key","buildAgentMentionItems","tools","subAgents","appLabel","t","s","variableTokenName","actualValue","buildVariableMentionItems","variablesData","items","walk","entry","actual","name","configToolName","actionName","restApiToolName","restApiMentionItem","ToolSource","configToolMentionItem","buildCustomToolMentionItems","configTools","restApiTools","escapeHtml","raw","escapeAttr","mentionSpanHtml","id","label","kind","buildMentionHtml","buildTokenLookup","mentionItems","byToken","item","meta","REFERENCE_TOKEN","inlineToHtml","segment","out","lastIndex","match","instructionsToEditorHtml","text","para","resolveMentionToken","toolIds","nodeToText","node","ordered","i","inner","child","editorDocToInstructions","doc"],"mappings":"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"}
|
|
@@ -50,7 +50,9 @@ export declare const variableTokenName: (actualValue: string) => string;
|
|
|
50
50
|
* save. Merge alongside {@link buildAgentMentionItems} for serialization.
|
|
51
51
|
*/
|
|
52
52
|
export declare const buildVariableMentionItems: (variablesData?: VariableListInterfaceV3[]) => MentionItem[];
|
|
53
|
-
/** Display name for a shared config tool:
|
|
53
|
+
/** Display name for a shared config tool: the merchant's action name when set
|
|
54
|
+
* (MAP-7245), else first recipient / channel (pre-action-name tools), else
|
|
55
|
+
* generic. */
|
|
54
56
|
export declare const configToolName: (t: ConfigToolConfig) => string;
|
|
55
57
|
/** Display name for a Rest API tool row / chip. */
|
|
56
58
|
export declare const restApiToolName: (t: RestApiToolConfig) => string;
|
|
@@ -38,7 +38,15 @@ const b = (e, t = "Manifest") => e ? m[e] ?? e : t, h = (e) => {
|
|
|
38
38
|
Object.values(a.variables ?? {}).forEach(n);
|
|
39
39
|
};
|
|
40
40
|
return e.forEach(n), t;
|
|
41
|
-
}, k = (e) =>
|
|
41
|
+
}, k = (e) => {
|
|
42
|
+
if (e.tool_key === "send_slack_message")
|
|
43
|
+
return String(e.params.channelId?.value ?? "").trim() || "Send Slack message";
|
|
44
|
+
if (e.tool_key === "send_email") {
|
|
45
|
+
const t = String(e.params.name?.value ?? "").trim();
|
|
46
|
+
return t || String(e.params.sendTo?.value ?? "").split(",").map((n) => n.trim()).filter(Boolean)[0] || "Send email";
|
|
47
|
+
}
|
|
48
|
+
return e.tool_key;
|
|
49
|
+
}, $ = (e) => e.name || "Rest API", f = (e) => {
|
|
42
50
|
const t = $(e);
|
|
43
51
|
return {
|
|
44
52
|
id: e.id,
|
|
@@ -52,22 +60,22 @@ const b = (e, t = "Manifest") => e ? m[e] ?? e : t, h = (e) => {
|
|
|
52
60
|
label: `${m[t]} : ${n}`,
|
|
53
61
|
meta: { kind: "tool", plainLabel: n, source: t }
|
|
54
62
|
};
|
|
55
|
-
},
|
|
63
|
+
}, y = (e = [], t = []) => [
|
|
56
64
|
...t.map(f),
|
|
57
65
|
...e.map(S)
|
|
58
|
-
],
|
|
66
|
+
], r = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"), l = (e) => r(e).replace(/"/g, """), p = (e, t, n, a) => `<span data-type="mentionAgent" class="bik-mention bik-mention--agent" data-id="${l(e)}" data-label="${l(t)}" data-kind="${l(n)}"` + (a ? ` data-source="${l(a)}"` : "") + `>${r(t)}</span>`, M = (e, t, n, a) => p(e, t, n, a), T = (e) => {
|
|
59
67
|
const t = /* @__PURE__ */ new Map();
|
|
60
68
|
for (const n of e) {
|
|
61
69
|
const a = n.meta;
|
|
62
70
|
a?.kind === "tool" ? t.set(`tool:${String(n.id)}`, n) : a?.kind === "subagent" ? t.set(`subagent:${String(n.id)}`, n) : a?.kind === "variable" && t.set(`variable:${String(n.id)}`, n);
|
|
63
71
|
}
|
|
64
72
|
return t;
|
|
65
|
-
}, c = /\{\{((?:tool|subagent|variable):[^{}]+)\}\}/g,
|
|
73
|
+
}, c = /\{\{((?:tool|subagent|variable):[^{}]+)\}\}/g, _ = (e, t) => {
|
|
66
74
|
let n = "", a = 0;
|
|
67
75
|
c.lastIndex = 0;
|
|
68
76
|
let o;
|
|
69
77
|
for (; (o = c.exec(e)) !== null; ) {
|
|
70
|
-
n +=
|
|
78
|
+
n += r(e.slice(a, o.index));
|
|
71
79
|
const i = t.get(o[1]);
|
|
72
80
|
if (i) {
|
|
73
81
|
const d = i.meta;
|
|
@@ -78,16 +86,16 @@ const b = (e, t = "Manifest") => e ? m[e] ?? e : t, h = (e) => {
|
|
|
78
86
|
d.source
|
|
79
87
|
);
|
|
80
88
|
} else
|
|
81
|
-
n +=
|
|
89
|
+
n += r(o[0]);
|
|
82
90
|
a = c.lastIndex;
|
|
83
91
|
}
|
|
84
|
-
return n +=
|
|
92
|
+
return n += r(e.slice(a)), n.replace(/\n/g, "<br>");
|
|
85
93
|
}, A = (e, t = []) => {
|
|
86
94
|
if (!e)
|
|
87
95
|
return "";
|
|
88
96
|
const n = T(t);
|
|
89
|
-
return e.split(/\n{2,}/).map((a) => `<p>${
|
|
90
|
-
},
|
|
97
|
+
return e.split(/\n{2,}/).map((a) => `<p>${_(a, n)}</p>`).join("");
|
|
98
|
+
}, v = (e, t, n) => t === "variable" ? `{{variable:${e}}}` : (t ?? (n.has(e) ? "tool" : "subagent")) === "tool" ? `{{tool:${e}}}` : `{{subagent:${e}}}`, u = (e, t) => {
|
|
91
99
|
switch (e.type) {
|
|
92
100
|
case "text":
|
|
93
101
|
return e.text ?? "";
|
|
@@ -97,7 +105,7 @@ const b = (e, t = "Manifest") => e ? m[e] ?? e : t, h = (e) => {
|
|
|
97
105
|
if (n == null)
|
|
98
106
|
return "";
|
|
99
107
|
const a = e.attrs?.kind;
|
|
100
|
-
return
|
|
108
|
+
return v(
|
|
101
109
|
String(n),
|
|
102
110
|
a == null ? null : String(a),
|
|
103
111
|
t
|
|
@@ -126,7 +134,7 @@ const b = (e, t = "Manifest") => e ? m[e] ?? e : t, h = (e) => {
|
|
|
126
134
|
` : n;
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
|
-
},
|
|
137
|
+
}, N = (e, t) => {
|
|
130
138
|
if (!e)
|
|
131
139
|
return "";
|
|
132
140
|
const n = new Set(t.map((a) => a.tool_id));
|
|
@@ -139,12 +147,12 @@ export {
|
|
|
139
147
|
m as TOOL_SOURCE_LABELS,
|
|
140
148
|
h as appTypeLabel,
|
|
141
149
|
E as buildAgentMentionItems,
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
y as buildCustomToolMentionItems,
|
|
151
|
+
M as buildMentionHtml,
|
|
144
152
|
I as buildVariableMentionItems,
|
|
145
153
|
S as configToolMentionItem,
|
|
146
154
|
k as configToolName,
|
|
147
|
-
|
|
155
|
+
N as editorDocToInstructions,
|
|
148
156
|
A as instructionsToEditorHtml,
|
|
149
157
|
f as restApiMentionItem,
|
|
150
158
|
$ as restApiToolName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mentionSerialization.js","sources":["../../../../../src/components/agent-builder/utils/mentionSerialization.ts"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport { MentionItem } from '@src/editor';\nimport type {\n\tSubHeader,\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport {\n\tAgentTool,\n\tConfigToolConfig,\n\tRestApiToolConfig,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport { TOOL_SOURCE_LABELS, ToolSource } from '../constants/tools';\n\n/**\n * Serialization helpers between the BikEditor document and the firebase\n * `instructions` string.\n *\n * Firebase stores `instructions` as PLAIN TEXT with inline reference tokens:\n * - `{{subagent:<agentId>}}` — hand-off to another agent\n * - `{{tool:<tool_id>}}` — an action the agent can call\n * - `{{variable:<name>}}` — a template variable picked from the catalog\n *\n * In the editor those references are inserted via the `@` mention menu (which we\n * populate with BOTH tools and sub-agents). Mention nodes keep their `id` in the\n * ProseMirror doc JSON (the rendered HTML drops it), so we serialize from the doc\n * JSON — not from HTML.\n */\n\nexport interface MentionKindMeta {\n\t/** Distinguishes a tool / sub-agent / variable reference. */\n\tkind: 'tool' | 'subagent' | 'variable';\n\t/** Plain item name (no prefix) shown in the picker dropdown rows. */\n\tplainLabel?: string;\n\t/** For tools: the source bucket (manifest / shopify / …) the picker groups by. */\n\tsource?: string;\n\t/** For tools: touches customer-private data → shows a shield in the picker. */\n\tauthRequired?: boolean;\n}\n\n// Source labels moved to constants/tools.ts; re-exported for existing importers.\nexport { TOOL_SOURCE_LABELS };\n\n/** Human label for a tool source; falls back to the host-app label, then the raw key. */\nexport const toolSourceLabel = (\n\tsource: string | undefined,\n\tfallback = 'Manifest',\n): string => {\n\tif (!source) {\n\t\treturn fallback;\n\t}\n\treturn TOOL_SOURCE_LABELS[source as ToolSource] ?? source;\n};\n\n/** Human label for the host application, used as the tool-chip prefix. */\nexport const appTypeLabel = (applicationType?: ApplicationType): string => {\n\tconst key = applicationType ? String(applicationType) : '';\n\tif (key === 'BIK') {\n\t\treturn 'BIK';\n\t}\n\tif (key === 'BSP') {\n\t\treturn 'BSP';\n\t}\n\treturn 'Manifest';\n};\n\n/**\n * Build the combined `@` mention list from the available tools + sub-agents.\n *\n * The `label` is the CHIP text shown once inserted — tools read\n * `\"<App> : <tool name>\"` (e.g. \"Manifest : Look up order\"), sub-agents read\n * `\"sub-agent: <name>\"`. `meta.plainLabel` is the un-prefixed name for the\n * picker rows, and `meta.kind` drives the `{{tool}}` / `{{subagent}}` colour.\n */\nexport const buildAgentMentionItems = (\n\ttools: AgentTool[],\n\tsubAgents: SubAgentRef[],\n\tappLabel = 'Manifest',\n): MentionItem[] => [\n\t...tools.map(\n\t\t(t): MentionItem => ({\n\t\t\tid: t.tool_id,\n\t\t\tlabel: `${toolSourceLabel(t.source, appLabel)} : ${t.display_name}`,\n\t\t\tmeta: {\n\t\t\t\tkind: 'tool',\n\t\t\t\tplainLabel: t.display_name,\n\t\t\t\tsource: t.source,\n\t\t\t\tauthRequired: t.auth_required,\n\t\t\t},\n\t\t}),\n\t),\n\t...subAgents.map(\n\t\t(s): MentionItem => ({\n\t\t\tid: s.id,\n\t\t\tlabel: `sub-agent: ${s.name}`,\n\t\t\tmeta: { kind: 'subagent', plainLabel: s.name },\n\t\t}),\n\t),\n];\n\n/** Strip the `{{ }}` wrapper from a variable token (`{{a.b}}` → `a.b`). */\nexport const variableTokenName = (actualValue: string): string =>\n\tactualValue.replace(/^\\{\\{|\\}\\}$/g, '');\n\n/**\n * Flatten the (nested) variable catalog into mention items, so stored\n * `{{<name>}}` tokens rehydrate as `Variable: <display name>` chips. The item\n * id is the BARE token name (no braces) — `resolveMentionToken` re-wraps it on\n * save. Merge alongside {@link buildAgentMentionItems} for serialization.\n */\nexport const buildVariableMentionItems = (\n\tvariablesData: VariableListInterfaceV3[] = [],\n): MentionItem[] => {\n\tconst items: MentionItem[] = [];\n\tconst walk = (entry: VariableListInterfaceV3 | SubHeader | VariableV3) => {\n\t\tconst actual = (entry as VariableV3).actualValue;\n\t\tif (actual) {\n\t\t\tconst name = variableTokenName(actual);\n\t\t\titems.push({\n\t\t\t\tid: name,\n\t\t\t\t// Chip text is the raw token — designers want variables to read as\n\t\t\t\t// {{a.b.c}} (styled purple by the editor), not a labelled chip.\n\t\t\t\tlabel: `{{${name}}}`,\n\t\t\t\tmeta: { kind: 'variable', plainLabel: entry.displayName },\n\t\t\t});\n\t\t}\n\t\tObject.values(entry.variables ?? {}).forEach(walk);\n\t};\n\tvariablesData.forEach(walk);\n\treturn items;\n};\n\n/** Display name for a shared config tool: first recipient / channel, else generic. */\nexport const configToolName = (t: ConfigToolConfig): string => {\n\tif (t.tool_key === 'send_slack_message') {\n\t\treturn (\n\t\t\tString(t.params['channelId']?.value ?? '').trim() || 'Send Slack message'\n\t\t);\n\t}\n\treturn (\n\t\tString(t.params['sendTo']?.value ?? '')\n\t\t\t.split(',')\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean)[0] || 'Send email'\n\t);\n};\n\n/** Display name for a Rest API tool row / chip. */\nexport const restApiToolName = (t: RestApiToolConfig): string =>\n\tt.name || 'Rest API';\n\n/** The `@`-mention chip item for a Rest API tool (kind 'tool', restapi source). */\nexport const restApiMentionItem = (t: RestApiToolConfig): MentionItem => {\n\tconst name = restApiToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[ToolSource.RestApi]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source: ToolSource.RestApi },\n\t};\n};\n\n/** The `@`-mention chip item for a shared config tool (email / Slack). */\nexport const configToolMentionItem = (t: ConfigToolConfig): MentionItem => {\n\tconst source =\n\t\tt.tool_key === 'send_slack_message'\n\t\t\t? ToolSource.Slack\n\t\t\t: ToolSource.EmailHandover;\n\tconst name = configToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[source]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source },\n\t};\n};\n\n/**\n * Mention items for the inline-configured custom tools (Rest API + email / Slack)\n * so their `{{tool:<id>}}` tokens rehydrate as chips — they live on the agent\n * value, not in the catalog `availableTools`. Merge alongside\n * {@link buildAgentMentionItems} in the editor's mention list.\n */\nexport const buildCustomToolMentionItems = (\n\tconfigTools: ConfigToolConfig[] = [],\n\trestApiTools: RestApiToolConfig[] = [],\n): MentionItem[] => [\n\t...restApiTools.map(restApiMentionItem),\n\t...configTools.map(configToolMentionItem),\n];\n\nconst escapeHtml = (raw: string): string =>\n\traw.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nconst escapeAttr = (raw: string): string =>\n\tescapeHtml(raw).replace(/\"/g, '"');\n\n/**\n * The HTML for a single mention chip. Must round-trip through the TipTap mention\n * extension's `parseHTML` (`span[data-type=\"mentionAgent\"]`, reading\n * `data-id`/`data-label`/`data-kind`) — see MentionExtension.ts. `normalizeHtml`\n * is taught to keep `data-type=\"mention…\"` spans so this survives to the parser.\n */\nconst mentionSpanHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: string,\n\tsource?: string,\n): string =>\n\t`<span data-type=\"mentionAgent\" class=\"bik-mention bik-mention--agent\"` +\n\t` data-id=\"${escapeAttr(id)}\" data-label=\"${escapeAttr(label)}\"` +\n\t` data-kind=\"${escapeAttr(kind)}\"` +\n\t(source ? ` data-source=\"${escapeAttr(source)}\"` : '') +\n\t`>${escapeHtml(label)}</span>`;\n\n/**\n * Public: HTML for one mention chip, for inserting at the cursor (e.g. when a\n * tool / sub-agent is added from the Step-3 side panel). Round-trips through the\n * same parser path as the rehydrated chips. `source` (tool source bucket) drives\n * the chip's leading icon.\n */\nexport const buildMentionHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: 'tool' | 'subagent' | 'variable',\n\tsource?: string,\n): string => mentionSpanHtml(id, label, kind, source);\n\n/**\n * `{{tool:<id>}}` / `{{subagent:<id>}}` / `{{<variableName>}}` → the mention\n * item that produced them. The map key is the token's INNER text.\n */\nconst buildTokenLookup = (\n\tmentionItems: MentionItem[],\n): Map<string, MentionItem> => {\n\tconst byToken = new Map<string, MentionItem>();\n\tfor (const item of mentionItems) {\n\t\tconst meta = item.meta as unknown as MentionKindMeta | undefined;\n\t\t// Everything is keyed by its kind-prefixed id (a tool's id is its tool_id).\n\t\tif (meta?.kind === 'tool') {\n\t\t\tbyToken.set(`tool:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'subagent') {\n\t\t\tbyToken.set(`subagent:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'variable') {\n\t\t\tbyToken.set(`variable:${String(item.id)}`, item);\n\t\t}\n\t}\n\treturn byToken;\n};\n\n// Matches the kind-prefixed reference tokens we render as chips. Other\n// `{{var}}` tokens fall through untouched (left as literal text for the\n// variable decoration).\nconst REFERENCE_TOKEN = /\\{\\{((?:tool|subagent|variable):[^{}]+)\\}\\}/g;\n\n/** Escape plain text, swapping recognised reference tokens for mention spans. */\nconst inlineToHtml = (\n\tsegment: string,\n\tbyToken: Map<string, MentionItem>,\n): string => {\n\tlet out = '';\n\tlet lastIndex = 0;\n\tREFERENCE_TOKEN.lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\twhile ((match = REFERENCE_TOKEN.exec(segment)) !== null) {\n\t\tout += escapeHtml(segment.slice(lastIndex, match.index));\n\t\tconst item = byToken.get(match[1]);\n\t\tif (item) {\n\t\t\tconst meta = item.meta as unknown as MentionKindMeta;\n\t\t\tout += mentionSpanHtml(\n\t\t\t\tString(item.id),\n\t\t\t\titem.label,\n\t\t\t\tmeta.kind,\n\t\t\t\tmeta.source,\n\t\t\t);\n\t\t} else {\n\t\t\t// Not in any available list (removed tool / unknown variable) → keep the\n\t\t\t// raw token as literal text.\n\t\t\tout += escapeHtml(match[0]);\n\t\t}\n\t\tlastIndex = REFERENCE_TOKEN.lastIndex;\n\t}\n\tout += escapeHtml(segment.slice(lastIndex));\n\treturn out.replace(/\\n/g, '<br>');\n};\n\n/**\n * Convert the stored instructions string into HTML for `BikEditor.initialContent`.\n * `{{tool:KEY}}` / `{{subagent:ID}}` tokens are rehydrated into mention chips\n * (resolved via `mentionItems`); any other `{{…}}` token is left as literal text\n * for the editor's variable decoration. Newlines become paragraph / line breaks.\n */\nexport const instructionsToEditorHtml = (\n\ttext: string,\n\tmentionItems: MentionItem[] = [],\n): string => {\n\tif (!text) {\n\t\treturn '';\n\t}\n\tconst byToken = buildTokenLookup(mentionItems);\n\treturn text\n\t\t.split(/\\n{2,}/)\n\t\t.map((para) => `<p>${inlineToHtml(para, byToken)}</p>`)\n\t\t.join('');\n};\n\ninterface ProseMirrorNode {\n\ttype: string;\n\ttext?: string;\n\tattrs?: Record<string, unknown>;\n\tcontent?: ProseMirrorNode[];\n}\n\n/**\n * The token for a mention node. All kinds store their id in the node, so the\n * token value is just that id — the kind only picks the prefix. The node's\n * `kind` attr is authoritative; `toolIds` is a fallback for older content\n * saved before the kind attr existed.\n */\nconst resolveMentionToken = (\n\tid: string,\n\tkind: string | null,\n\ttoolIds: Set<string>,\n): string => {\n\tif (kind === 'variable') {\n\t\treturn `{{variable:${id}}}`;\n\t}\n\tconst resolved = kind ?? (toolIds.has(id) ? 'tool' : 'subagent');\n\treturn resolved === 'tool' ? `{{tool:${id}}}` : `{{subagent:${id}}}`;\n};\n\nconst nodeToText = (node: ProseMirrorNode, toolIds: Set<string>): string => {\n\tswitch (node.type) {\n\t\tcase 'text':\n\t\t\treturn node.text ?? '';\n\t\tcase 'mentionAgent':\n\t\tcase 'mentionTeam': {\n\t\t\tconst id = node.attrs?.['id'];\n\t\t\tif (id == null) {\n\t\t\t\treturn '';\n\t\t\t}\n\t\t\tconst kind = node.attrs?.['kind'];\n\t\t\treturn resolveMentionToken(\n\t\t\t\tString(id),\n\t\t\t\tkind == null ? null : String(kind),\n\t\t\t\ttoolIds,\n\t\t\t);\n\t\t}\n\t\tcase 'variable':\n\t\t\treturn `{{${String(node.attrs?.['variableName'] ?? '')}}}`;\n\t\tcase 'hardBreak':\n\t\t\treturn '\\n';\n\t\tcase 'orderedList':\n\t\tcase 'bulletList': {\n\t\t\t// Flattening to plain text otherwise drops the list markers, so a\n\t\t\t// numbered / bulleted list looks \"removed\" after publish. Emit an\n\t\t\t// ordinal (\"1. \") / bullet (\"- \") prefix per item to preserve it.\n\t\t\tconst ordered = node.type === 'orderedList';\n\t\t\treturn (\n\t\t\t\t(node.content ?? [])\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(item, i) =>\n\t\t\t\t\t\t\t`${ordered ? `${i + 1}.` : '-'} ${nodeToText(\n\t\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\t\ttoolIds,\n\t\t\t\t\t\t\t).replace(/\\n+$/, '')}`,\n\t\t\t\t\t)\n\t\t\t\t\t.join('\\n') + '\\n'\n\t\t\t);\n\t\t}\n\t\tdefault: {\n\t\t\tconst inner = (node.content ?? [])\n\t\t\t\t.map((child) => nodeToText(child, toolIds))\n\t\t\t\t.join('');\n\t\t\t// Block nodes terminate with a newline so paragraphs stay separated.\n\t\t\tconst BLOCK_NODES = ['paragraph', 'heading', 'listItem', 'blockquote'];\n\t\t\treturn BLOCK_NODES.includes(node.type) ? `${inner}\\n` : inner;\n\t\t}\n\t}\n};\n\n/**\n * Convert a BikEditor document (from `ref.getJSON()`) into the firebase\n * instructions string, replacing mention nodes with `{{subagent:<id>}}` /\n * `{{tool:<tool_id>}}` tokens.\n */\nexport const editorDocToInstructions = (\n\tdoc: Record<string, unknown> | null,\n\ttools: AgentTool[],\n): string => {\n\tif (!doc) {\n\t\treturn '';\n\t}\n\tconst toolIds = new Set(tools.map((t) => t.tool_id));\n\treturn nodeToText(doc as unknown as ProseMirrorNode, toolIds).replace(\n\t\t/\\n+$/,\n\t\t'',\n\t);\n};\n"],"names":["toolSourceLabel","source","fallback","TOOL_SOURCE_LABELS","appTypeLabel","applicationType","key","buildAgentMentionItems","tools","subAgents","appLabel","t","s","variableTokenName","actualValue","buildVariableMentionItems","variablesData","items","walk","entry","actual","name","configToolName","restApiToolName","restApiMentionItem","ToolSource","configToolMentionItem","buildCustomToolMentionItems","configTools","restApiTools","escapeHtml","raw","escapeAttr","mentionSpanHtml","id","label","kind","buildMentionHtml","buildTokenLookup","mentionItems","byToken","item","meta","REFERENCE_TOKEN","inlineToHtml","segment","out","lastIndex","match","instructionsToEditorHtml","text","para","resolveMentionToken","toolIds","nodeToText","node","ordered","i","inner","child","editorDocToInstructions","doc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mentionSerialization.js","sources":["../../../../../src/components/agent-builder/utils/mentionSerialization.ts"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport { MentionItem } from '@src/editor';\nimport type {\n\tSubHeader,\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport {\n\tAgentTool,\n\tConfigToolConfig,\n\tRestApiToolConfig,\n\tSubAgentRef,\n} from '../AgentBuilder.model';\nimport { TOOL_SOURCE_LABELS, ToolSource } from '../constants/tools';\n\n/**\n * Serialization helpers between the BikEditor document and the firebase\n * `instructions` string.\n *\n * Firebase stores `instructions` as PLAIN TEXT with inline reference tokens:\n * - `{{subagent:<agentId>}}` — hand-off to another agent\n * - `{{tool:<tool_id>}}` — an action the agent can call\n * - `{{variable:<name>}}` — a template variable picked from the catalog\n *\n * In the editor those references are inserted via the `@` mention menu (which we\n * populate with BOTH tools and sub-agents). Mention nodes keep their `id` in the\n * ProseMirror doc JSON (the rendered HTML drops it), so we serialize from the doc\n * JSON — not from HTML.\n */\n\nexport interface MentionKindMeta {\n\t/** Distinguishes a tool / sub-agent / variable reference. */\n\tkind: 'tool' | 'subagent' | 'variable';\n\t/** Plain item name (no prefix) shown in the picker dropdown rows. */\n\tplainLabel?: string;\n\t/** For tools: the source bucket (manifest / shopify / …) the picker groups by. */\n\tsource?: string;\n\t/** For tools: touches customer-private data → shows a shield in the picker. */\n\tauthRequired?: boolean;\n}\n\n// Source labels moved to constants/tools.ts; re-exported for existing importers.\nexport { TOOL_SOURCE_LABELS };\n\n/** Human label for a tool source; falls back to the host-app label, then the raw key. */\nexport const toolSourceLabel = (\n\tsource: string | undefined,\n\tfallback = 'Manifest',\n): string => {\n\tif (!source) {\n\t\treturn fallback;\n\t}\n\treturn TOOL_SOURCE_LABELS[source as ToolSource] ?? source;\n};\n\n/** Human label for the host application, used as the tool-chip prefix. */\nexport const appTypeLabel = (applicationType?: ApplicationType): string => {\n\tconst key = applicationType ? String(applicationType) : '';\n\tif (key === 'BIK') {\n\t\treturn 'BIK';\n\t}\n\tif (key === 'BSP') {\n\t\treturn 'BSP';\n\t}\n\treturn 'Manifest';\n};\n\n/**\n * Build the combined `@` mention list from the available tools + sub-agents.\n *\n * The `label` is the CHIP text shown once inserted — tools read\n * `\"<App> : <tool name>\"` (e.g. \"Manifest : Look up order\"), sub-agents read\n * `\"sub-agent: <name>\"`. `meta.plainLabel` is the un-prefixed name for the\n * picker rows, and `meta.kind` drives the `{{tool}}` / `{{subagent}}` colour.\n */\nexport const buildAgentMentionItems = (\n\ttools: AgentTool[],\n\tsubAgents: SubAgentRef[],\n\tappLabel = 'Manifest',\n): MentionItem[] => [\n\t...tools.map(\n\t\t(t): MentionItem => ({\n\t\t\tid: t.tool_id,\n\t\t\tlabel: `${toolSourceLabel(t.source, appLabel)} : ${t.display_name}`,\n\t\t\tmeta: {\n\t\t\t\tkind: 'tool',\n\t\t\t\tplainLabel: t.display_name,\n\t\t\t\tsource: t.source,\n\t\t\t\tauthRequired: t.auth_required,\n\t\t\t},\n\t\t}),\n\t),\n\t...subAgents.map(\n\t\t(s): MentionItem => ({\n\t\t\tid: s.id,\n\t\t\tlabel: `sub-agent: ${s.name}`,\n\t\t\tmeta: { kind: 'subagent', plainLabel: s.name },\n\t\t}),\n\t),\n];\n\n/** Strip the `{{ }}` wrapper from a variable token (`{{a.b}}` → `a.b`). */\nexport const variableTokenName = (actualValue: string): string =>\n\tactualValue.replace(/^\\{\\{|\\}\\}$/g, '');\n\n/**\n * Flatten the (nested) variable catalog into mention items, so stored\n * `{{<name>}}` tokens rehydrate as `Variable: <display name>` chips. The item\n * id is the BARE token name (no braces) — `resolveMentionToken` re-wraps it on\n * save. Merge alongside {@link buildAgentMentionItems} for serialization.\n */\nexport const buildVariableMentionItems = (\n\tvariablesData: VariableListInterfaceV3[] = [],\n): MentionItem[] => {\n\tconst items: MentionItem[] = [];\n\tconst walk = (entry: VariableListInterfaceV3 | SubHeader | VariableV3) => {\n\t\tconst actual = (entry as VariableV3).actualValue;\n\t\tif (actual) {\n\t\t\tconst name = variableTokenName(actual);\n\t\t\titems.push({\n\t\t\t\tid: name,\n\t\t\t\t// Chip text is the raw token — designers want variables to read as\n\t\t\t\t// {{a.b.c}} (styled purple by the editor), not a labelled chip.\n\t\t\t\tlabel: `{{${name}}}`,\n\t\t\t\tmeta: { kind: 'variable', plainLabel: entry.displayName },\n\t\t\t});\n\t\t}\n\t\tObject.values(entry.variables ?? {}).forEach(walk);\n\t};\n\tvariablesData.forEach(walk);\n\treturn items;\n};\n\n/** Display name for a shared config tool: the merchant's action name when set\n * (MAP-7245), else first recipient / channel (pre-action-name tools), else\n * generic. */\nexport const configToolName = (t: ConfigToolConfig): string => {\n\tif (t.tool_key === 'send_slack_message') {\n\t\treturn (\n\t\t\tString(t.params['channelId']?.value ?? '').trim() || 'Send Slack message'\n\t\t);\n\t}\n\tif (t.tool_key === 'send_email') {\n\t\tconst actionName = String(t.params['name']?.value ?? '').trim();\n\t\tif (actionName) {\n\t\t\treturn actionName;\n\t\t}\n\t\treturn (\n\t\t\tString(t.params['sendTo']?.value ?? '')\n\t\t\t\t.split(',')\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter(Boolean)[0] || 'Send email'\n\t\t);\n\t}\n\t// Future config-tool keys: no bespoke naming yet — fall back to the key.\n\treturn t.tool_key;\n};\n\n/** Display name for a Rest API tool row / chip. */\nexport const restApiToolName = (t: RestApiToolConfig): string =>\n\tt.name || 'Rest API';\n\n/** The `@`-mention chip item for a Rest API tool (kind 'tool', restapi source). */\nexport const restApiMentionItem = (t: RestApiToolConfig): MentionItem => {\n\tconst name = restApiToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[ToolSource.RestApi]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source: ToolSource.RestApi },\n\t};\n};\n\n/** The `@`-mention chip item for a shared config tool (email / Slack). */\nexport const configToolMentionItem = (t: ConfigToolConfig): MentionItem => {\n\tconst source =\n\t\tt.tool_key === 'send_slack_message'\n\t\t\t? ToolSource.Slack\n\t\t\t: ToolSource.EmailHandover;\n\tconst name = configToolName(t);\n\treturn {\n\t\tid: t.id,\n\t\tlabel: `${TOOL_SOURCE_LABELS[source]} : ${name}`,\n\t\tmeta: { kind: 'tool', plainLabel: name, source },\n\t};\n};\n\n/**\n * Mention items for the inline-configured custom tools (Rest API + email / Slack)\n * so their `{{tool:<id>}}` tokens rehydrate as chips — they live on the agent\n * value, not in the catalog `availableTools`. Merge alongside\n * {@link buildAgentMentionItems} in the editor's mention list.\n */\nexport const buildCustomToolMentionItems = (\n\tconfigTools: ConfigToolConfig[] = [],\n\trestApiTools: RestApiToolConfig[] = [],\n): MentionItem[] => [\n\t...restApiTools.map(restApiMentionItem),\n\t...configTools.map(configToolMentionItem),\n];\n\nconst escapeHtml = (raw: string): string =>\n\traw.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nconst escapeAttr = (raw: string): string =>\n\tescapeHtml(raw).replace(/\"/g, '"');\n\n/**\n * The HTML for a single mention chip. Must round-trip through the TipTap mention\n * extension's `parseHTML` (`span[data-type=\"mentionAgent\"]`, reading\n * `data-id`/`data-label`/`data-kind`) — see MentionExtension.ts. `normalizeHtml`\n * is taught to keep `data-type=\"mention…\"` spans so this survives to the parser.\n */\nconst mentionSpanHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: string,\n\tsource?: string,\n): string =>\n\t`<span data-type=\"mentionAgent\" class=\"bik-mention bik-mention--agent\"` +\n\t` data-id=\"${escapeAttr(id)}\" data-label=\"${escapeAttr(label)}\"` +\n\t` data-kind=\"${escapeAttr(kind)}\"` +\n\t(source ? ` data-source=\"${escapeAttr(source)}\"` : '') +\n\t`>${escapeHtml(label)}</span>`;\n\n/**\n * Public: HTML for one mention chip, for inserting at the cursor (e.g. when a\n * tool / sub-agent is added from the Step-3 side panel). Round-trips through the\n * same parser path as the rehydrated chips. `source` (tool source bucket) drives\n * the chip's leading icon.\n */\nexport const buildMentionHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: 'tool' | 'subagent' | 'variable',\n\tsource?: string,\n): string => mentionSpanHtml(id, label, kind, source);\n\n/**\n * `{{tool:<id>}}` / `{{subagent:<id>}}` / `{{<variableName>}}` → the mention\n * item that produced them. The map key is the token's INNER text.\n */\nconst buildTokenLookup = (\n\tmentionItems: MentionItem[],\n): Map<string, MentionItem> => {\n\tconst byToken = new Map<string, MentionItem>();\n\tfor (const item of mentionItems) {\n\t\tconst meta = item.meta as unknown as MentionKindMeta | undefined;\n\t\t// Everything is keyed by its kind-prefixed id (a tool's id is its tool_id).\n\t\tif (meta?.kind === 'tool') {\n\t\t\tbyToken.set(`tool:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'subagent') {\n\t\t\tbyToken.set(`subagent:${String(item.id)}`, item);\n\t\t} else if (meta?.kind === 'variable') {\n\t\t\tbyToken.set(`variable:${String(item.id)}`, item);\n\t\t}\n\t}\n\treturn byToken;\n};\n\n// Matches the kind-prefixed reference tokens we render as chips. Other\n// `{{var}}` tokens fall through untouched (left as literal text for the\n// variable decoration).\nconst REFERENCE_TOKEN = /\\{\\{((?:tool|subagent|variable):[^{}]+)\\}\\}/g;\n\n/** Escape plain text, swapping recognised reference tokens for mention spans. */\nconst inlineToHtml = (\n\tsegment: string,\n\tbyToken: Map<string, MentionItem>,\n): string => {\n\tlet out = '';\n\tlet lastIndex = 0;\n\tREFERENCE_TOKEN.lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\twhile ((match = REFERENCE_TOKEN.exec(segment)) !== null) {\n\t\tout += escapeHtml(segment.slice(lastIndex, match.index));\n\t\tconst item = byToken.get(match[1]);\n\t\tif (item) {\n\t\t\tconst meta = item.meta as unknown as MentionKindMeta;\n\t\t\tout += mentionSpanHtml(\n\t\t\t\tString(item.id),\n\t\t\t\titem.label,\n\t\t\t\tmeta.kind,\n\t\t\t\tmeta.source,\n\t\t\t);\n\t\t} else {\n\t\t\t// Not in any available list (removed tool / unknown variable) → keep the\n\t\t\t// raw token as literal text.\n\t\t\tout += escapeHtml(match[0]);\n\t\t}\n\t\tlastIndex = REFERENCE_TOKEN.lastIndex;\n\t}\n\tout += escapeHtml(segment.slice(lastIndex));\n\treturn out.replace(/\\n/g, '<br>');\n};\n\n/**\n * Convert the stored instructions string into HTML for `BikEditor.initialContent`.\n * `{{tool:KEY}}` / `{{subagent:ID}}` tokens are rehydrated into mention chips\n * (resolved via `mentionItems`); any other `{{…}}` token is left as literal text\n * for the editor's variable decoration. Newlines become paragraph / line breaks.\n */\nexport const instructionsToEditorHtml = (\n\ttext: string,\n\tmentionItems: MentionItem[] = [],\n): string => {\n\tif (!text) {\n\t\treturn '';\n\t}\n\tconst byToken = buildTokenLookup(mentionItems);\n\treturn text\n\t\t.split(/\\n{2,}/)\n\t\t.map((para) => `<p>${inlineToHtml(para, byToken)}</p>`)\n\t\t.join('');\n};\n\ninterface ProseMirrorNode {\n\ttype: string;\n\ttext?: string;\n\tattrs?: Record<string, unknown>;\n\tcontent?: ProseMirrorNode[];\n}\n\n/**\n * The token for a mention node. All kinds store their id in the node, so the\n * token value is just that id — the kind only picks the prefix. The node's\n * `kind` attr is authoritative; `toolIds` is a fallback for older content\n * saved before the kind attr existed.\n */\nconst resolveMentionToken = (\n\tid: string,\n\tkind: string | null,\n\ttoolIds: Set<string>,\n): string => {\n\tif (kind === 'variable') {\n\t\treturn `{{variable:${id}}}`;\n\t}\n\tconst resolved = kind ?? (toolIds.has(id) ? 'tool' : 'subagent');\n\treturn resolved === 'tool' ? `{{tool:${id}}}` : `{{subagent:${id}}}`;\n};\n\nconst nodeToText = (node: ProseMirrorNode, toolIds: Set<string>): string => {\n\tswitch (node.type) {\n\t\tcase 'text':\n\t\t\treturn node.text ?? '';\n\t\tcase 'mentionAgent':\n\t\tcase 'mentionTeam': {\n\t\t\tconst id = node.attrs?.['id'];\n\t\t\tif (id == null) {\n\t\t\t\treturn '';\n\t\t\t}\n\t\t\tconst kind = node.attrs?.['kind'];\n\t\t\treturn resolveMentionToken(\n\t\t\t\tString(id),\n\t\t\t\tkind == null ? null : String(kind),\n\t\t\t\ttoolIds,\n\t\t\t);\n\t\t}\n\t\tcase 'variable':\n\t\t\treturn `{{${String(node.attrs?.['variableName'] ?? '')}}}`;\n\t\tcase 'hardBreak':\n\t\t\treturn '\\n';\n\t\tcase 'orderedList':\n\t\tcase 'bulletList': {\n\t\t\t// Flattening to plain text otherwise drops the list markers, so a\n\t\t\t// numbered / bulleted list looks \"removed\" after publish. Emit an\n\t\t\t// ordinal (\"1. \") / bullet (\"- \") prefix per item to preserve it.\n\t\t\tconst ordered = node.type === 'orderedList';\n\t\t\treturn (\n\t\t\t\t(node.content ?? [])\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(item, i) =>\n\t\t\t\t\t\t\t`${ordered ? `${i + 1}.` : '-'} ${nodeToText(\n\t\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\t\ttoolIds,\n\t\t\t\t\t\t\t).replace(/\\n+$/, '')}`,\n\t\t\t\t\t)\n\t\t\t\t\t.join('\\n') + '\\n'\n\t\t\t);\n\t\t}\n\t\tdefault: {\n\t\t\tconst inner = (node.content ?? [])\n\t\t\t\t.map((child) => nodeToText(child, toolIds))\n\t\t\t\t.join('');\n\t\t\t// Block nodes terminate with a newline so paragraphs stay separated.\n\t\t\tconst BLOCK_NODES = ['paragraph', 'heading', 'listItem', 'blockquote'];\n\t\t\treturn BLOCK_NODES.includes(node.type) ? `${inner}\\n` : inner;\n\t\t}\n\t}\n};\n\n/**\n * Convert a BikEditor document (from `ref.getJSON()`) into the firebase\n * instructions string, replacing mention nodes with `{{subagent:<id>}}` /\n * `{{tool:<tool_id>}}` tokens.\n */\nexport const editorDocToInstructions = (\n\tdoc: Record<string, unknown> | null,\n\ttools: AgentTool[],\n): string => {\n\tif (!doc) {\n\t\treturn '';\n\t}\n\tconst toolIds = new Set(tools.map((t) => t.tool_id));\n\treturn nodeToText(doc as unknown as ProseMirrorNode, toolIds).replace(\n\t\t/\\n+$/,\n\t\t'',\n\t);\n};\n"],"names":["toolSourceLabel","source","fallback","TOOL_SOURCE_LABELS","appTypeLabel","applicationType","key","buildAgentMentionItems","tools","subAgents","appLabel","t","s","variableTokenName","actualValue","buildVariableMentionItems","variablesData","items","walk","entry","actual","name","configToolName","actionName","restApiToolName","restApiMentionItem","ToolSource","configToolMentionItem","buildCustomToolMentionItems","configTools","restApiTools","escapeHtml","raw","escapeAttr","mentionSpanHtml","id","label","kind","buildMentionHtml","buildTokenLookup","mentionItems","byToken","item","meta","REFERENCE_TOKEN","inlineToHtml","segment","out","lastIndex","match","instructionsToEditorHtml","text","para","resolveMentionToken","toolIds","nodeToText","node","ordered","i","inner","child","editorDocToInstructions","doc"],"mappings":"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"}
|