@_daniel_jiang/ai-host 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # @_daniel_jiang/ai-host
2
+
3
+ 景行 AI 宿主嵌入 SDK(**新包**)。相对 `@_daniel_jiang/host-sdk` 1.x:
4
+
5
+ - **壳层**:右下 FAB → 圆形展开 → **居中工作室模态**(不再用右侧抽屉)
6
+ - **Hub UI**:`/host/hub?layout=studio` 左会话记录 / 右任务运行
7
+ - **协议**:与 host-sdk 共用 `agent-host` postMessage 通道,API 仍为 `AgentHost.*`
8
+
9
+ 表单提交与附件上传均在 **Agent Widget iframe 内**完成。
10
+
11
+ > 维护者改 SDK / 发版:本仓库 `pnpm run build:ai-host` / `publish:ai-host`。host-sdk 1.x 冻结维护,仅修关键。
12
+
13
+ ## 安装
14
+
15
+ ```bash
16
+ npm install @_daniel_jiang/ai-host
17
+ # 或 yarn add @_daniel_jiang/ai-host
18
+ ```
19
+
20
+ ```json
21
+ {
22
+ "dependencies": {
23
+ "@_daniel_jiang/ai-host": "^0.1.0"
24
+ }
25
+ }
26
+ ```
27
+
28
+ 官方源:https://www.npmjs.com/package/@_daniel_jiang/ai-host
29
+
30
+ ## 用法
31
+
32
+ ```javascript
33
+ import { AgentHost } from '@_daniel_jiang/ai-host'
34
+
35
+ await AgentHost.init({
36
+ host: 'edc',
37
+ bootstrap: () =>
38
+ fetch('/boot-admin/agent/bootstrap?hosts=edc', { credentials: 'include' }).then((r) => r.json()),
39
+ })
40
+
41
+ AgentHost.registerPage(
42
+ 'edc_patient_list',
43
+ [{
44
+ id: 'form_fill',
45
+ workflow: 'edc_form_fill',
46
+ label: 'AI 填表',
47
+ host: 'edc',
48
+ prefilled: () => ({ /* ... */ }),
49
+ enabled: () => true,
50
+ hostContext: { refresh: 'patient_list' },
51
+ }],
52
+ {
53
+ refreshKey: 'patient_list',
54
+ onRefresh: () => refreshPatientList(),
55
+ },
56
+ )
57
+ ```
58
+
59
+ 或脚本标签:
60
+
61
+ ```html
62
+ <script src="https://your-agent-origin/sdk/ai-host.js"></script>
63
+ <script>
64
+ AgentHost.init({ /* ... */ })
65
+ </script>
66
+ ```
67
+
68
+ ## 与 host-sdk 的关系
69
+
70
+ | | host-sdk 1.x | ai-host 0.x |
71
+ |---|---|---|
72
+ | 包名 | `@_daniel_jiang/host-sdk` | `@_daniel_jiang/ai-host` |
73
+ | 壳 | 右侧抽屉(可半屏) | FAB 展开居中模态 |
74
+ | Hub | 窄栏折叠会话 | studio 左右栏 |
75
+ | 全局名 | `AgentHost` | `AgentHost`(兼容) |
76
+ | 产物 | `agent-host.js` | `ai-host.js` |
77
+
78
+ 迁移:改依赖包名与脚本 URL 即可,业务侧 `init` / `registerPage` 一般无需改。
@@ -0,0 +1,262 @@
1
+ var Mt=Object.defineProperty,$t=Object.defineProperties;var Wt=Object.getOwnPropertyDescriptors;var tt=Object.getOwnPropertySymbols;var Bt=Object.prototype.hasOwnProperty,zt=Object.prototype.propertyIsEnumerable;var j=(p,l,d)=>l in p?Mt(p,l,{enumerable:!0,configurable:!0,writable:!0,value:d}):p[l]=d,M=(p,l)=>{for(var d in l||(l={}))Bt.call(l,d)&&j(p,d,l[d]);if(tt)for(var d of tt(l))zt.call(l,d)&&j(p,d,l[d]);return p},et=(p,l)=>$t(p,Wt(l));var c=(p,l,d)=>j(p,typeof l!="symbol"?l+"":l,d);var b=(p,l,d)=>new Promise((k,v)=>{var y=h=>{try{C(d.next(h))}catch(H){v(H)}},L=h=>{try{C(d.throw(h))}catch(H){v(H)}},C=h=>h.done?k(h.value):Promise.resolve(h.value).then(y,L);C((d=d.apply(p,l)).next())});(function(p){"use strict";const l="agent-host";function d(e){return typeof e=="object"&&e!==null&&e.channel===l&&typeof e.type=="string"}function k(e){return e==null?e:JSON.parse(JSON.stringify(e))}function v(e){return typeof e=="function"?e():e}const y={},L={};let C={},h=null,H=!1,x=null,$=null,V=!1;function N(e){$=e}function I(){try{$==null||$()}catch(e){}}function B(e){var o;if(!e)return null;const t=typeof e=="function"?e():e;if(!t)return null;let n=null;if(t instanceof Element?n=t:typeof t=="object"&&t.$el instanceof Element&&(n=t.$el),!n)return null;const i=(o=n.querySelector)==null?void 0:o.call(n,'textarea, input, [contenteditable="true"]');return i instanceof HTMLElement?i:n}function z(e){return!e||typeof e.closest!="function"?!1:!!e.closest("#agent-host-launcher-hint")}function D(e){return!!e.anchor&&e.hintPlacement==="anchor"}function nt(e,t){if(!h){x&&(x=null,I());return}if(z(e)||z(t))return;const n=y[h]||[];let i=null;if(e instanceof Node)for(const o of n){if(!D(o))continue;const s=B(o.anchor);if(s&&s.contains(e)){i=o.id;break}}i!==x&&(x=i,I())}function it(e){nt(e.target)}function ot(e){if(z(e.relatedTarget))return;const t=e.target;if(!(t instanceof Node)||!h)return;const i=(y[h]||[]).find(s=>s.id===x);if(!i)return;const o=B(i.anchor);o&&o.contains(t)&&!o.contains(e.relatedTarget)&&(x=null,I())}function st(){V||typeof document=="undefined"||(document.addEventListener("focusin",it,!0),document.addEventListener("focusout",ot,!0),V=!0)}function rt(e,t){const n=(t||"").trim();if(n)return n;for(const i of e){if(!i.hostContext)continue;const o=v(i.hostContext),s=o&&typeof o=="object"?String(o.refresh||"").trim():"";if(s)return s}}function G(e){return((e==null?void 0:e.kind)||"widget")==="direct"}function at(e,t,n={}){st();const i=e!==h;i&&(H=!1,x=null),y[e]=t,h=e,!i&&t.some(s=>!s.enabled||s.enabled())&&(H=!1);const o=rt(t,n.refreshKey);o&&typeof n.onRefresh=="function"?L[e]={refreshKey:o,onRefresh:n.onRefresh}:delete L[e],I()}function lt(e){delete y[e],delete L[e],h===e&&(h=null,x=null),I()}function ht(e){const t=k(e||{});for(const n of Object.keys(t)){const i=t[n];(i==null||typeof i=="string"&&!i.trim())&&delete t[n]}return t}function ct(e){return C=ht(e||{}),M({},C)}function F(){return M({},C)}function ut(e,t){const n=String(e||"").trim();if(n){for(const i of Object.values(L))if(i.refreshKey===n)try{i.onRefresh(t)}catch(o){}}}function dt(){for(const e of Object.keys(y))delete y[e];for(const e of Object.keys(L))delete L[e];C={},h=null,H=!1,x=null,I()}function ft(e){e!==h&&(H=!1,x=null),h=e,I()}function pt(){H=!0}function K(e){return e.map(t=>({id:t.id,workflow:t.workflow||t.skill||"",label:t.label,host:t.host,hint:t.hint?v(t.hint):void 0,hostContext:t.hostContext?k(v(t.hostContext)):void 0,prefilled:t.prefilled?k(v(t.prefilled)):void 0,enabled:t.enabled?t.enabled():!0,kind:t.kind,skill:t.skill,noTools:t.noTools===!0?!0:void 0}))}function q(e,t){const n=(y[e]||[]).find(o=>o.id===t);if(!n||n.enabled&&!n.enabled())return null;const i=n.prefilled?k(v(n.prefilled)):void 0;return{action:n,prefilled:i,hostContext:n.hostContext?k(v(n.hostContext)):void 0}}function gt(e,t){const n=q(e,t);return!n||G(n.action)?null:{workflow:n.action.workflow||n.action.skill||"",title:n.action.label,host:n.action.host,prefilled:n.prefilled,hostContext:n.hostContext}}function bt(){return h}function wt(){return Object.entries(y).map(([e,t])=>({pageId:e,actions:t}))}function Y(e,t){const n=(y[e]||[]).find(i=>i.id===t);return n?B(n.anchor):null}function yt(e,t){const n=Y(e,t);if(!n)return null;const i=n.getBoundingClientRect();return!i.width&&!i.height?null:i}function xt(){if(H||!h)return null;const e=y[h]||[];for(const t of e){if(t.enabled&&!t.enabled()||D(t)&&x!==t.id)continue;const n=t.hint?v(t.hint):`可使用「${t.label}」`,i=D(t)?"anchor":"launcher";return{pageId:h,actionId:t.id,hint:n,placement:i}}return null}const g="agent-host-launcher",m="agent-host-hub-panel-overlay",mt="agent-host-hub-iframe",J="agent-host-widget-overlay",vt="agent-host-widget-iframe",X="agent-host-ai-host-styles";function Ht(e){return e.replace(/\/$/,"")}function W(e){try{return new URL(e).origin}catch(t){return e.replace(/\/$/,"")}}function kt(e,t){const n=W(e),i=W(t);if(n===i)return!0;try{const o=new URL(n),s=new URL(i),f=new Set(["localhost","127.0.0.1","[::1]"]);return o.protocol===s.protocol&&o.port===s.port&&f.has(o.hostname)&&f.has(s.hostname)}catch(o){return!1}}function Lt(){if(typeof document=="undefined"||document.getElementById(X))return;const e=document.createElement("style");e.id=X,e.textContent=`
2
+ #${g} {
3
+ position: fixed;
4
+ right: 24px;
5
+ bottom: 24px;
6
+ z-index: 2147482999;
7
+ width: 56px;
8
+ height: 56px;
9
+ border: none;
10
+ border-radius: 50%;
11
+ cursor: pointer;
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ color: #fff;
16
+ font-size: 22px;
17
+ line-height: 1;
18
+ background: linear-gradient(145deg, #12a892 0%, #0d8f7b 55%, #0a7a6a 100%);
19
+ box-shadow: 0 4px 18px rgba(13, 143, 123, 0.42);
20
+ transition: transform 0.15s ease, opacity 0.2s ease, visibility 0.2s ease;
21
+ }
22
+ #${g}:hover { transform: scale(1.05); }
23
+ #${g}.is-hidden {
24
+ opacity: 0;
25
+ visibility: hidden;
26
+ pointer-events: none;
27
+ transform: scale(0.85);
28
+ }
29
+ #${g}.is-pulse {
30
+ animation: agent-host-fab-pulse 2s ease-in-out infinite;
31
+ }
32
+ #${g} .agent-host-launcher-icon {
33
+ display: inline-block;
34
+ line-height: 1;
35
+ transform-origin: center center;
36
+ }
37
+ #${g}.is-breathe .agent-host-launcher-icon {
38
+ animation: agent-host-clover-breathe 1.8s ease-in-out infinite;
39
+ }
40
+ #${g} .agent-host-launcher-bell {
41
+ display: none;
42
+ width: 22px;
43
+ height: 22px;
44
+ line-height: 0;
45
+ transform-origin: top center;
46
+ }
47
+ #${g} .agent-host-launcher-bell.is-visible {
48
+ display: inline-block;
49
+ animation: agent-host-bell-shake 0.85s ease-in-out infinite;
50
+ }
51
+ #${g} .agent-host-launcher-bell svg {
52
+ width: 100%;
53
+ height: 100%;
54
+ display: block;
55
+ }
56
+ #${g} .agent-host-launcher-badge {
57
+ position: absolute;
58
+ top: -4px;
59
+ right: -4px;
60
+ box-sizing: border-box;
61
+ min-width: 20px;
62
+ height: 20px;
63
+ padding: 0 5px;
64
+ border-radius: 999px;
65
+ font-size: 11px;
66
+ font-weight: 600;
67
+ line-height: 1;
68
+ display: none;
69
+ align-items: center;
70
+ justify-content: center;
71
+ border: 2px solid #fff;
72
+ background: #f59e0b;
73
+ color: #fff;
74
+ }
75
+ #${g} .agent-host-launcher-badge.is-visible { display: flex; }
76
+ #${g} .agent-host-launcher-badge.is-waiting { background: #ef4444; }
77
+ #agent-host-launcher-hint {
78
+ position: fixed;
79
+ right: 24px;
80
+ bottom: 88px;
81
+ z-index: 2147482998;
82
+ max-width: min(800px, calc(100vw - 48px));
83
+ padding: 10px 14px;
84
+ border-radius: 10px;
85
+ font-size: 13px;
86
+ line-height: 1.45;
87
+ color: #333;
88
+ background: #fff;
89
+ border: 1px solid rgba(13, 143, 123, 0.22);
90
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
91
+ display: none;
92
+ pointer-events: auto;
93
+ }
94
+ #agent-host-launcher-hint.is-visible { display: block; }
95
+ #agent-host-launcher-hint.is-anchored {
96
+ right: auto;
97
+ bottom: auto;
98
+ }
99
+ #agent-host-launcher-hint .agent-host-hint-inner {
100
+ display: flex;
101
+ align-items: center;
102
+ gap: 10px;
103
+ flex-wrap: wrap;
104
+ }
105
+ #agent-host-launcher-hint .agent-host-hint-icon {
106
+ flex-shrink: 0;
107
+ display: inline-flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ width: 20px;
111
+ height: 20px;
112
+ font-size: 16px;
113
+ line-height: 1;
114
+ color: #0d8f7b;
115
+ transform-origin: center center;
116
+ animation: agent-host-hint-clover 4.5s ease-in-out infinite;
117
+ }
118
+ #agent-host-launcher-hint .agent-host-hint-text {
119
+ flex: 1;
120
+ min-width: 140px;
121
+ color: #333;
122
+ }
123
+ #agent-host-launcher-hint .agent-host-hint-actions {
124
+ display: flex;
125
+ align-items: center;
126
+ gap: 4px;
127
+ flex-shrink: 0;
128
+ }
129
+ #agent-host-launcher-hint .agent-host-hint-use {
130
+ border: 1px solid #0d8f7b;
131
+ border-radius: 6px;
132
+ padding: 0 12px;
133
+ height: 28px;
134
+ font-size: 12px;
135
+ font-weight: 500;
136
+ color: #0d8f7b;
137
+ background: transparent;
138
+ cursor: pointer;
139
+ }
140
+ #agent-host-launcher-hint .agent-host-hint-use:hover {
141
+ color: #fff;
142
+ background: #0d8f7b;
143
+ }
144
+ #agent-host-launcher-hint .agent-host-hint-dismiss {
145
+ border: none;
146
+ border-radius: 6px;
147
+ padding: 0 8px;
148
+ height: 28px;
149
+ font-size: 12px;
150
+ color: #999;
151
+ background: transparent;
152
+ cursor: pointer;
153
+ }
154
+ #agent-host-launcher-hint .agent-host-hint-dismiss:hover { color: #666; }
155
+ #${m} {
156
+ position: fixed;
157
+ inset: 0;
158
+ z-index: 2147483000;
159
+ pointer-events: none;
160
+ }
161
+ #${m}.is-open {
162
+ pointer-events: auto;
163
+ }
164
+ #${m} .agent-host-hub-backdrop {
165
+ position: absolute;
166
+ inset: 0;
167
+ background: rgba(15, 23, 42, 0.42);
168
+ opacity: 0;
169
+ transition: opacity 0.35s ease;
170
+ }
171
+ #${m}.is-open .agent-host-hub-backdrop {
172
+ opacity: 1;
173
+ }
174
+ /* FAB 位圆形 → 居中工作室模态 */
175
+ #${m} .agent-host-hub-panel-shell {
176
+ position: absolute;
177
+ right: 24px;
178
+ bottom: 24px;
179
+ width: 56px;
180
+ height: 56px;
181
+ border-radius: 50%;
182
+ background: #fff;
183
+ box-shadow: 0 4px 18px rgba(13, 143, 123, 0.35);
184
+ overflow: hidden;
185
+ opacity: 0;
186
+ transform: scale(0.92);
187
+ transition:
188
+ width 0.42s cubic-bezier(0.22, 1, 0.36, 1),
189
+ height 0.42s cubic-bezier(0.22, 1, 0.36, 1),
190
+ right 0.42s cubic-bezier(0.22, 1, 0.36, 1),
191
+ bottom 0.42s cubic-bezier(0.22, 1, 0.36, 1),
192
+ border-radius 0.42s cubic-bezier(0.22, 1, 0.36, 1),
193
+ box-shadow 0.42s ease,
194
+ opacity 0.2s ease,
195
+ transform 0.42s cubic-bezier(0.22, 1, 0.36, 1);
196
+ }
197
+ #${m}.is-open .agent-host-hub-panel-shell {
198
+ right: max(24px, calc((100vw - min(1120px, calc(100vw - 48px))) / 2));
199
+ bottom: max(24px, calc((100vh - min(780px, calc(100vh - 48px))) / 2));
200
+ width: min(1120px, calc(100vw - 48px));
201
+ height: min(780px, calc(100vh - 48px));
202
+ border-radius: 16px;
203
+ box-shadow: 0 24px 64px rgba(15, 23, 42, 0.22);
204
+ opacity: 1;
205
+ transform: scale(1);
206
+ }
207
+ @media (max-width: 720px) {
208
+ #${m}.is-open .agent-host-hub-panel-shell {
209
+ right: 12px;
210
+ bottom: 12px;
211
+ width: calc(100vw - 24px);
212
+ height: calc(100vh - 24px);
213
+ border-radius: 12px;
214
+ }
215
+ }
216
+ #${m} iframe {
217
+ width: 100%;
218
+ height: 100%;
219
+ border: none;
220
+ background: #fff;
221
+ display: block;
222
+ opacity: 0;
223
+ transition: opacity 0.2s ease 0.18s;
224
+ }
225
+ #${m}.is-open iframe {
226
+ opacity: 1;
227
+ }
228
+ @keyframes agent-host-fab-pulse {
229
+ 0%, 100% { box-shadow: 0 4px 18px rgba(13, 143, 123, 0.42); }
230
+ 50% { box-shadow: 0 4px 26px rgba(13, 143, 123, 0.62); }
231
+ }
232
+ @keyframes agent-host-clover-breathe {
233
+ 0%, 100% { transform: scale(1); }
234
+ 50% { transform: scale(1.28); }
235
+ }
236
+ @keyframes agent-host-hint-clover {
237
+ 0% { transform: scale(0.88) rotate(0deg); }
238
+ 16.67% { transform: scale(1.12) rotate(0deg); }
239
+ 33.33% { transform: scale(0.88) rotate(0deg); }
240
+ 50% { transform: scale(1.12) rotate(0deg); }
241
+ 66.67% { transform: scale(1) rotate(0deg); }
242
+ 100% { transform: scale(1) rotate(360deg); }
243
+ }
244
+ @keyframes agent-host-bell-shake {
245
+ 0%, 100% { transform: rotate(0deg); }
246
+ 12% { transform: rotate(14deg); }
247
+ 24% { transform: rotate(-12deg); }
248
+ 36% { transform: rotate(10deg); }
249
+ 48% { transform: rotate(-8deg); }
250
+ 60% { transform: rotate(5deg); }
251
+ 72% { transform: rotate(-3deg); }
252
+ 84% { transform: rotate(1deg); }
253
+ }
254
+ `,document.head.appendChild(e)}class Ct{constructor(t,n,i){c(this,"agentOrigin","");c(this,"hubLauncher",null);c(this,"hubLauncherBadge",null);c(this,"hubLauncherHint",null);c(this,"hubPanelOverlay",null);c(this,"hubIframe",null);c(this,"widgetIframe",null);c(this,"hubReady",!1);c(this,"widgetReady",!1);c(this,"hubPanelOpen",!1);c(this,"lastRunning",0);c(this,"lastWaiting",0);c(this,"launcherHintAction",null);c(this,"hintRepositionBound",!1);c(this,"hintScrollParents",[]);c(this,"pendingHubMessages",[]);c(this,"pendingWidgetMessages",[]);c(this,"onChildMessage");c(this,"onHintUse");c(this,"onHintDismiss");c(this,"onHintReposition",()=>{const t=this.launcherHintAction,n=this.hubLauncherHint;!t||!n||!n.classList.contains("is-visible")||this.layoutHint(n,t)});c(this,"handleMessage",t=>{var i,o,s;if(!kt(this.agentOrigin,t.origin)||!d(t.data))return;const n=t.data;if(n.type==="ready"){n.surface==="hub"?(this.hubReady=!0,this.flush("hub")):(this.widgetReady=!0,this.flush("widget")),(i=this.onChildMessage)==null||i.call(this,n);return}if(n.type==="hub-panel-close"){this.closeHubPanel();return}if(n.type==="hub-panel-width"){this.setHubPanelExpanded(!!n.expanded);return}if(n.type==="hub-stats"){this.updateLauncherStats(n.running,n.waiting),(o=this.onChildMessage)==null||o.call(this,n);return}(s=this.onChildMessage)==null||s.call(this,n)});this.agentOrigin=Ht(t),this.onChildMessage=n,this.onHintUse=i==null?void 0:i.onHintUse,this.onHintDismiss=i==null?void 0:i.onHintDismiss,window.addEventListener("message",this.handleMessage)}destroy(){window.removeEventListener("message",this.handleMessage),this.unbindHintReposition(),this.removeHub(),this.closeWidget()}mountHub(){this.hubPanelOverlay||typeof document=="undefined"||(Lt(),this.mountLauncher(),this.mountHubPanel())}openHubPanel(){var t,n;this.hubPanelOverlay&&(this.hubPanelOpen=!0,this.hubPanelOverlay.classList.add("is-open"),(t=this.hubLauncher)==null||t.classList.add("is-hidden"),(n=this.hubLauncherHint)==null||n.classList.remove("is-visible"),this.post("hub",{channel:l,type:"open-hub-panel"}),this.applyLauncherVisual())}closeHubPanel(){var t;this.hubPanelOverlay&&(this.hubPanelOpen=!1,this.hubPanelOverlay.classList.remove("is-open"),(t=this.hubLauncher)==null||t.classList.remove("is-hidden"),this.post("hub",{channel:l,type:"close-hub-panel"}),this.updateLauncherHint(this.launcherHintAction),this.applyLauncherVisual())}setHubPanelExpanded(t){}updateLauncherHint(t){this.launcherHintAction=t;const n=this.hubLauncherHint;if(!n)return;if(this.hubPanelOpen){n.classList.remove("is-visible","is-anchored"),this.unbindHintReposition();return}if(!t||!t.hint.trim()){n.innerHTML="",n.classList.remove("is-visible","is-anchored"),this.unbindHintReposition();return}n.innerHTML=`
255
+ <div class="agent-host-hint-inner">
256
+ <span class="agent-host-hint-icon" aria-hidden="true">✦</span>
257
+ <span class="agent-host-hint-text"></span>
258
+ <div class="agent-host-hint-actions">
259
+ <button type="button" class="agent-host-hint-use">立即开始</button>
260
+ <button type="button" class="agent-host-hint-dismiss">稍后</button>
261
+ </div>
262
+ </div>`;const i=n.querySelector(".agent-host-hint-text");i&&(i.textContent=t.hint);const o=n.querySelector(".agent-host-hint-use"),s=n.querySelector(".agent-host-hint-dismiss"),f=u=>u.preventDefault();o==null||o.addEventListener("mousedown",f),s==null||s.addEventListener("mousedown",f),o==null||o.addEventListener("click",u=>{var w;u.stopPropagation(),(w=this.onHintUse)==null||w.call(this,t.pageId,t.actionId)}),s==null||s.addEventListener("click",u=>{var w;u.stopPropagation(),(w=this.onHintDismiss)==null||w.call(this)}),n.classList.add("is-visible"),this.layoutHint(n,t),this.bindHintReposition()}layoutHint(t,n){if(n.placement!=="anchor"){t.classList.remove("is-anchored"),t.style.top="",t.style.left="";return}const i=yt(n.pageId,n.actionId);if(!i){t.classList.remove("is-anchored"),t.style.top="",t.style.left="";return}t.classList.add("is-anchored");const o=8,s=t.offsetWidth||320,f=t.offsetHeight||48;let u=i.top,w=i.right+o;w+s>window.innerWidth-16&&(w=Math.max(16,i.left),u=i.bottom+o),u+f>window.innerHeight-16&&(u=Math.max(16,i.top-f-o)),u<16&&(u=16),w<16&&(w=16),t.style.top=`${Math.round(u)}px`,t.style.left=`${Math.round(w)}px`}collectScrollParents(t){var o;const n=[];let i=(o=t==null?void 0:t.parentElement)!=null?o:null;for(;i;){const s=window.getComputedStyle(i),f=s.overflowY,u=s.overflowX;/(auto|scroll|overlay)/.test(`${u} ${f}`)&&n.push(i),i=i.parentElement}return n}bindHintReposition(){var i,o;if(typeof window=="undefined")return;this.hintRepositionBound||(window.addEventListener("scroll",this.onHintReposition,!0),window.addEventListener("resize",this.onHintReposition),(i=window.visualViewport)==null||i.addEventListener("resize",this.onHintReposition),(o=window.visualViewport)==null||o.addEventListener("scroll",this.onHintReposition),this.hintRepositionBound=!0);const t=this.launcherHintAction;for(const s of this.hintScrollParents)s.removeEventListener("scroll",this.onHintReposition);if(this.hintScrollParents=[],!t||t.placement!=="anchor")return;const n=Y(t.pageId,t.actionId);this.hintScrollParents=this.collectScrollParents(n);for(const s of this.hintScrollParents)s.addEventListener("scroll",this.onHintReposition,{passive:!0})}unbindHintReposition(){var t,n;if(typeof window!="undefined"){this.hintRepositionBound&&(window.removeEventListener("scroll",this.onHintReposition,!0),window.removeEventListener("resize",this.onHintReposition),(t=window.visualViewport)==null||t.removeEventListener("resize",this.onHintReposition),(n=window.visualViewport)==null||n.removeEventListener("scroll",this.onHintReposition),this.hintRepositionBound=!1);for(const i of this.hintScrollParents)i.removeEventListener("scroll",this.onHintReposition);this.hintScrollParents=[]}}mountLauncher(){if(this.hubLauncher||document.getElementById(g))return;const t=document.createElement("button");if(t.id=g,t.type="button",t.title="景行 AI",t.setAttribute("aria-label","景行 AI"),t.innerHTML='<span class="agent-host-launcher-icon" aria-hidden="true">✦</span><span class="agent-host-launcher-bell" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 3a5 5 0 0 0-5 5v1.5c0 1.3-.4 2.6-1.2 3.7L4.5 15.5c-.4.5-.1 1.3.5 1.3h14c.6 0 .9-.8.5-1.3l-1.3-2.3A6.6 6.6 0 0 1 17 9.5V8a5 5 0 0 0-5-5Z" fill="#f59e0b"/><path d="M10 18.5a2 2 0 0 0 4 0" stroke="#f59e0b" stroke-width="1.8" stroke-linecap="round"/></svg></span><span class="agent-host-launcher-badge"></span>',t.addEventListener("click",()=>this.openHubPanel()),document.body.appendChild(t),this.hubLauncher=t,this.hubLauncherBadge=t.querySelector(".agent-host-launcher-badge"),document.getElementById("agent-host-launcher-hint"))this.hubLauncherHint=document.getElementById("agent-host-launcher-hint");else{const n=document.createElement("div");n.id="agent-host-launcher-hint",document.body.appendChild(n),this.hubLauncherHint=n}}mountHubPanel(){const t=document.createElement("div");t.id=m;const n=document.createElement("div");n.className="agent-host-hub-backdrop",n.addEventListener("click",()=>this.closeHubPanel());const i=document.createElement("div");i.className="agent-host-hub-panel-shell";const o=document.createElement("iframe");o.id=mt,o.title="景行 AI",o.src=`${this.agentOrigin}/host/hub?embed=1&panel=1&layout=studio`,o.allow="clipboard-read; clipboard-write",i.appendChild(o),t.appendChild(n),t.appendChild(i),document.body.appendChild(t),this.hubPanelOverlay=t,this.hubIframe=o}updateLauncherStats(t,n){this.lastRunning=t,this.lastWaiting=n,this.applyLauncherVisual()}applyLauncherVisual(){const t=this.hubLauncher,n=this.hubLauncherBadge;if(!t||!n)return;const i=t.querySelector(".agent-host-launcher-icon"),o=t.querySelector(".agent-host-launcher-bell"),s=this.lastRunning,f=this.lastWaiting,u=f>0&&!this.hubPanelOpen;t.classList.toggle("is-pulse",s>0),t.classList.toggle("is-breathe",(s>0||f>0)&&!u),u?(t.title="有待确认事项,点击打开助手",t.setAttribute("aria-label","有待确认事项,点击打开助手")):(t.title="景行 AI",t.setAttribute("aria-label","景行 AI")),i&&(i.style.display=u?"none":""),o&&o.classList.toggle("is-visible",u),s>0?(n.textContent=String(s),n.classList.add("is-visible"),n.classList.remove("is-waiting")):f>0?(n.textContent="!",n.classList.add("is-visible","is-waiting")):(n.textContent="",n.classList.remove("is-visible","is-waiting"))}removeHub(){var t,n,i;(t=document.getElementById(g))==null||t.remove(),(n=document.getElementById("agent-host-launcher-hint"))==null||n.remove(),(i=document.getElementById(m))==null||i.remove(),this.hubLauncher=null,this.hubLauncherBadge=null,this.hubLauncherHint=null,this.hubPanelOverlay=null,this.hubIframe=null,this.hubReady=!1,this.hubPanelOpen=!1,this.pendingHubMessages=[]}openWidget(t,n,i){this.closeWidget();const o=document.createElement("div");o.id=J,o.style.cssText="position:fixed;inset:0;z-index:2147483646;background:rgba(15,23,42,0.45);display:flex;align-items:center;justify-content:center;padding:16px;",o.addEventListener("click",Tt=>{Tt.target===o&&this.closeWidget()});const s=document.createElement("iframe");s.id=vt,s.title=t.title||t.workflow;const f=new URLSearchParams({embed:"1",workflow:t.workflow,host:t.host||"",title:t.title||""});s.src=`${this.agentOrigin}/host/widget?${f.toString()}`,s.style.cssText="width:min(560px,100%);height:80vh;border:none;border-radius:12px;background:#fff;box-shadow:0 20px 60px rgba(0,0,0,0.25);display:block;",o.appendChild(s),document.body.appendChild(o),this.widgetIframe=s,this.widgetReady=!1;const u={channel:l,type:"init",token:n,refreshToken:i},w={workflow:t.workflow,title:t.title,host:t.host,prefilled:t.prefilled?k(t.prefilled):void 0,hostContext:t.hostContext?k(t.hostContext):void 0,sessionId:t.sessionId,preferSandboxFiles:t.preferSandboxFiles},St={channel:l,type:"open-widget",payload:w};this.pendingWidgetMessages=[u,St]}closeWidget(){var t;(t=document.getElementById(J))==null||t.remove(),this.widgetIframe=null,this.widgetReady=!1,this.pendingWidgetMessages=[]}sendToHub(t){this.post("hub",t)}post(t,n){var f;const i=t==="hub"?this.hubReady:this.widgetReady,o=t==="hub"?this.pendingHubMessages:this.pendingWidgetMessages;if(!i){o.push(n);return}const s=t==="hub"?this.hubIframe:this.widgetIframe;(f=s==null?void 0:s.contentWindow)==null||f.postMessage(n,W(this.agentOrigin))}flush(t){const n=t==="hub"?this.pendingHubMessages:this.pendingWidgetMessages,i=t==="hub"?this.hubIframe:this.widgetIframe;if(!(i!=null&&i.contentWindow))return;const o=W(this.agentOrigin);for(;n.length;){const s=n.shift();s&&i.contentWindow.postMessage(s,o)}}}let a={},r=null,E="",A="",P=null;function Et(){const e=(a.agentOrigin||"").replace(/\/$/,"");if(!e)throw new Error("Agent 前端地址未配置:请在 init({ agentOrigin }) 传入,或由宿主 BFF bootstrap 返回 agent_web_origin");return e}function Z(e){var t;e.agent_web_origin&&(a.agentOrigin=e.agent_web_origin.replace(/\/$/,"")),e.agent_token&&(E=e.agent_token),e.refresh_token&&(A=e.refresh_token),(t=a.onBootstrap)==null||t.call(a,e)}function T(){return b(this,null,function*(){if(a.getToken)return E=yield a.getToken(),E;if(E)return E;if(a.bootstrap){const e=yield a.bootstrap();if(Z(e),E)return E}throw new Error("未连接 Agent:请配置 bootstrap 或 getToken")})}function O(){if(a.agentOrigin)try{R().updateLauncherHint(xt())}catch(e){}}function R(){const e=Et();return r||(N(O),r=new Ct(e,Rt,{onHintUse:(t,n)=>{U(t,n)},onHintDismiss:()=>{pt(),O()}}),a.showHub!==!1&&r.mountHub()),r}function Pt(){if(!(!r||!a.agentOrigin)){for(const{pageId:e,actions:t}of wt())r.sendToHub({channel:"agent-host",type:"register-page",pageId:e,actions:K(t)});r.sendToHub({channel:"agent-host",type:"set-page",pageId:bt()}),O()}}function Rt(e){var t;if(e.type==="ready"&&e.surface==="hub"&&T().then(n=>{r==null||r.sendToHub({channel:"agent-host",type:"init",token:n,refreshToken:A||void 0}),Pt()}).catch(()=>{}),e.type==="started"&&(r==null||r.closeWidget(),r==null||r.openHubPanel(),r==null||r.sendToHub({channel:"agent-host",type:"task-started",taskId:e.taskId,sessionId:e.sessionId,workflow:e.workflow,label:e.label||e.workflow,formValues:e.formValues,prefilled:e.prefilled,hostContext:e.hostContext,hubContinue:e.hubContinue})),e.type==="complete"){if(e.status==="success"||e.status==="failed"||e.status==="cancelled"){const n=e.hostContext&&e.hostContext.refresh;ut(n,{taskId:e.taskId,result:e.result,hostContext:e.hostContext,apply:e.apply})}(t=a.onTaskComplete)==null||t.call(a,{taskId:e.taskId,status:e.status,hostContext:e.hostContext,result:e.result,apply:e.apply}),r==null||r.closeWidget()}e.type==="close"&&(r==null||r.closeWidget()),e.type==="open-widget"&&_(e.payload),e.type==="open-action"&&U(e.pageId,e.actionId),e.type==="hub-stats"&&(e.running,r==null||r.updateLauncherStats(e.running,e.waiting),O()),e.type==="request-host-context"&&It()}function It(){return b(this,null,function*(){if(!r||!a.agentOrigin)return;let e={};try{a.getHostContext?e=(yield a.getHostContext())||{}:e=F()}catch(n){e=F()}const t=ct(e);r.sendToHub({channel:"agent-host",type:"set-host-context",context:t})})}function U(e,t){return b(this,null,function*(){const n=q(e,t);if(!n)return;if(G(n.action)){yield Ot(n);return}const i=gt(e,t);i&&(yield _(i))})}function Ot(e){return b(this,null,function*(){yield S(),e.action.workflow&&!e.action.skill&&a.prepareOpenWidget&&(yield a.prepareOpenWidget());const t=yield T(),n=R();n.openHubPanel(),n.sendToHub({channel:"agent-host",type:"init",token:t,refreshToken:A||void 0}),n.sendToHub({channel:"agent-host",type:"run-direct",workflow:e.action.workflow||e.action.skill||"",title:e.action.label,host:e.action.host||a.host,skill:e.action.skill,noTools:e.action.noTools===!0,prefilled:e.prefilled,hostContext:e.hostContext})})}function _(e){return b(this,null,function*(){yield S(),a.prepareOpenWidget&&(yield a.prepareOpenWidget());const t=R(),n=yield T();t.openWidget({workflow:e.workflow,title:e.title||e.label,host:e.host||a.host,prefilled:e.prefilled,hostContext:e.hostContext,sessionId:e.sessionId,preferSandboxFiles:e.preferSandboxFiles},n,A||void 0)})}function S(){return b(this,null,function*(){P&&(yield P)})}function At(e){return b(this,null,function*(){if(a=M({showHub:!0},e),a.bootstrap){const t=yield a.bootstrap();Z(t)}if(a.agentOrigin&&a.showHub!==!1&&typeof document!="undefined")try{R();const t=yield T();r==null||r.sendToHub({channel:"agent-host",type:"init",token:t,refreshToken:A||void 0})}catch(t){}})}const Q={init(e){return b(this,null,function*(){P&&(yield P),P=At(e).finally(()=>{P=null}),yield P})},getToken(){return b(this,null,function*(){return yield S(),T()})},registerPage(i,o){return b(this,arguments,function*(e,t,n={}){yield S(),at(e,t,n),a.agentOrigin&&R().sendToHub({channel:"agent-host",type:"register-page",pageId:e,actions:K(t)}),O()})},getHostContext(){return F()},unregisterPage(e){return b(this,null,function*(){yield S(),lt(e),a.agentOrigin&&(R().sendToHub({channel:"agent-host",type:"unregister-page",pageId:e}),R().sendToHub({channel:"agent-host",type:"set-page",pageId:null})),O()})},setCurrentPage(e){return b(this,null,function*(){yield S(),ft(e),a.agentOrigin&&R().sendToHub({channel:"agent-host",type:"set-page",pageId:e}),O()})},openAction(e,t){return b(this,null,function*(){if(!q(e,t))throw new Error("当前操作不可用");yield U(e,t)})},openWorkflow(n){return b(this,arguments,function*(e,t={}){yield _(et(M({workflow:e},t),{host:t.host||a.host,title:t.title||t.label||e}))})},canOpen(e,t){return!0},destroy(){r==null||r.destroy(),r=null,E="",A="",a={},P=null,N(null),dt()}};typeof window!="undefined"&&(window.AgentHost=Q),p.AGENT_HOST_MSG=l,p.AgentHost=Q,p.isAgentHostMessage=d,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})})(this.AgentHost=this.AgentHost||{});