openclaw-openagent 1.0.6 → 1.0.8
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/src/app/remote-agent-tool.js +4 -3
- package/dist/src/compat.d.ts +2 -0
- package/dist/src/compat.js +9 -0
- package/dist/src/plugin-ui/assets/openagent-override.js +212 -62
- package/dist/src/plugin-ui/ui-extension-loader/registry-regex.js +106 -48
- package/dist/src/util/url-resolver.d.ts +8 -0
- package/dist/src/util/url-resolver.js +40 -0
- package/package.json +1 -1
- package/src/app/remote-agent-tool.ts +4 -3
- package/src/compat.ts +12 -0
- package/src/plugin-ui/assets/openagent-override.js +212 -62
- package/src/plugin-ui/build.cjs +1 -0
- package/src/plugin-ui/modules/agent-book/panel/inject-ui.js +63 -31
- package/src/plugin-ui/modules/agent-book/panel/styles.js +49 -28
- package/src/plugin-ui/modules/remote-agent/native-style-adapter.js +8 -2
- package/src/plugin-ui/ui-extension-loader/registry-regex.ts +97 -38
- package/src/util/url-resolver.ts +44 -0
|
@@ -111,10 +111,10 @@ function injectStyles() {
|
|
|
111
111
|
.openagent-agent-panel {
|
|
112
112
|
position: fixed;
|
|
113
113
|
max-height: none;
|
|
114
|
-
background: #fff;
|
|
115
|
-
border: 1.2px solid rgba(47, 47, 51, 0.12);
|
|
114
|
+
background: var(--oa-panel-bg, #fff);
|
|
115
|
+
border: 1.2px solid var(--oa-border, rgba(47, 47, 51, 0.12));
|
|
116
116
|
border-radius: 18px;
|
|
117
|
-
box-shadow: 0 -4px 24px rgba(0,0,0,0.08), 0 2px 8px rgba(0,0,0,0.04);
|
|
117
|
+
box-shadow: 0 -4px 24px var(--oa-shadow-color, rgba(0,0,0,0.08)), 0 2px 8px var(--oa-shadow-color, rgba(0,0,0,0.04));
|
|
118
118
|
z-index: 99999;
|
|
119
119
|
overflow: hidden;
|
|
120
120
|
display: none;
|
|
@@ -158,7 +158,7 @@ function injectStyles() {
|
|
|
158
158
|
flex-shrink: 0;
|
|
159
159
|
}
|
|
160
160
|
.openagent-panel-close {
|
|
161
|
-
background: rgba(249, 249, 249, 1);
|
|
161
|
+
background: var(--oa-card-bg, rgba(249, 249, 249, 1));
|
|
162
162
|
border: none;
|
|
163
163
|
color: rgba(47, 47, 51, 0.6);
|
|
164
164
|
cursor: pointer;
|
|
@@ -618,41 +618,61 @@ function injectStyles() {
|
|
|
618
618
|
padding: 32px; text-align: center; color: #aaa; font-size: 13px;
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
-
/* ──
|
|
622
|
-
[data-theme-mode="dark"] .openagent-agent-panel
|
|
621
|
+
/* ── 深色主题(v4: data-theme-mode / v5: data-theme) ── */
|
|
622
|
+
[data-theme-mode="dark"] .openagent-agent-panel,
|
|
623
|
+
[data-theme="dark"] .openagent-agent-panel {
|
|
623
624
|
background: #1c1c1c; border-color: rgba(255,255,255,0.12);
|
|
624
625
|
box-shadow: 0 -4px 24px rgba(0,0,0,0.3);
|
|
625
626
|
}
|
|
626
|
-
[data-theme-mode="dark"] .openagent-panel-head
|
|
627
|
-
[data-theme
|
|
628
|
-
[data-theme-mode="dark"] .openagent-panel-
|
|
629
|
-
[data-theme
|
|
630
|
-
[data-theme-mode="dark"] .openagent-
|
|
631
|
-
[data-theme
|
|
632
|
-
[data-theme-mode="dark"] .openagent-panel-
|
|
633
|
-
|
|
634
|
-
[data-theme-mode="dark"] .
|
|
635
|
-
[data-theme
|
|
636
|
-
[data-theme-mode="dark"] .
|
|
637
|
-
|
|
638
|
-
[data-theme-mode="dark"] .
|
|
639
|
-
[data-theme
|
|
640
|
-
|
|
627
|
+
[data-theme-mode="dark"] .openagent-panel-head,
|
|
628
|
+
[data-theme="dark"] .openagent-panel-head { border-color: #2a2a2a; }
|
|
629
|
+
[data-theme-mode="dark"] .openagent-panel-title,
|
|
630
|
+
[data-theme="dark"] .openagent-panel-title { color: rgba(224, 224, 224, 0.8); }
|
|
631
|
+
[data-theme-mode="dark"] .openagent-panel-close,
|
|
632
|
+
[data-theme="dark"] .openagent-panel-close { background: #2a2a2a; color: #888; }
|
|
633
|
+
[data-theme-mode="dark"] .openagent-panel-close:hover,
|
|
634
|
+
[data-theme="dark"] .openagent-panel-close:hover { background: #333; color: #ccc; }
|
|
635
|
+
[data-theme-mode="dark"] .openagent-section-heading,
|
|
636
|
+
[data-theme="dark"] .openagent-section-heading { color: rgba(224, 224, 224, 0.45); }
|
|
637
|
+
[data-theme-mode="dark"] .openagent-parent-heading,
|
|
638
|
+
[data-theme="dark"] .openagent-parent-heading { color: rgba(224, 224, 224, 0.3); }
|
|
639
|
+
[data-theme-mode="dark"] .openagent-panel-divider,
|
|
640
|
+
[data-theme="dark"] .openagent-panel-divider { border-color: rgba(255,255,255,0.1); }
|
|
641
|
+
|
|
642
|
+
[data-theme-mode="dark"] .agent-card__name,
|
|
643
|
+
[data-theme="dark"] .agent-card__name { color: #e0e0e0; }
|
|
644
|
+
[data-theme-mode="dark"] .agent-card__bio,
|
|
645
|
+
[data-theme="dark"] .agent-card__bio { color: rgba(224, 224, 224, 0.7); }
|
|
646
|
+
[data-theme-mode="dark"] .agent-card__stat,
|
|
647
|
+
[data-theme="dark"] .agent-card__stat { color: #64748b; }
|
|
648
|
+
|
|
649
|
+
[data-theme-mode="dark"] .agent-card--mention,
|
|
650
|
+
[data-theme="dark"] .agent-card--mention { background: transparent; }
|
|
651
|
+
[data-theme-mode="dark"] .agent-card--mention:hover,
|
|
652
|
+
[data-theme="dark"] .agent-card--mention:hover { background: #252525; }
|
|
653
|
+
[data-theme-mode="dark"] .agent-card--mention .agent-card__action,
|
|
654
|
+
[data-theme="dark"] .agent-card--mention .agent-card__action {
|
|
641
655
|
background: #333; border-color: #555; color: #ddd;
|
|
642
656
|
}
|
|
643
|
-
[data-theme-mode="dark"] .agent-card--mention .agent-card__action:hover
|
|
644
|
-
[data-theme
|
|
645
|
-
[data-theme-mode="dark"] .agent-card--search
|
|
657
|
+
[data-theme-mode="dark"] .agent-card--mention .agent-card__action:hover,
|
|
658
|
+
[data-theme="dark"] .agent-card--mention .agent-card__action:hover { background: #444; }
|
|
659
|
+
[data-theme-mode="dark"] .agent-card--search:hover,
|
|
660
|
+
[data-theme="dark"] .agent-card--search:hover { background: #252525; }
|
|
661
|
+
[data-theme-mode="dark"] .agent-card--search.openagent-card-selected,
|
|
662
|
+
[data-theme="dark"] .agent-card--search.openagent-card-selected {
|
|
646
663
|
background: rgba(99, 102, 241, 0.12);
|
|
647
664
|
outline-color: rgba(99, 102, 241, 0.4);
|
|
648
665
|
}
|
|
649
|
-
[data-theme-mode="dark"] .agent-card--search .agent-card__action
|
|
666
|
+
[data-theme-mode="dark"] .agent-card--search .agent-card__action,
|
|
667
|
+
[data-theme="dark"] .agent-card--search .agent-card__action {
|
|
650
668
|
background: #333; border-color: #555; color: #ddd;
|
|
651
669
|
}
|
|
652
|
-
[data-theme-mode="dark"] .agent-card--search .agent-card__action:hover
|
|
670
|
+
[data-theme-mode="dark"] .agent-card--search .agent-card__action:hover,
|
|
671
|
+
[data-theme="dark"] .agent-card--search .agent-card__action:hover { background: #444; }
|
|
653
672
|
|
|
654
673
|
|
|
655
|
-
[data-theme-mode="dark"] .agent-card--inline
|
|
674
|
+
[data-theme-mode="dark"] .agent-card--inline,
|
|
675
|
+
[data-theme="dark"] .agent-card--inline {
|
|
656
676
|
background: linear-gradient(135deg, #1e1b3a 0%, #1a1a2e 100%);
|
|
657
677
|
border-color: #2d2b55;
|
|
658
678
|
}
|
|
@@ -662,7 +682,8 @@ function injectStyles() {
|
|
|
662
682
|
}
|
|
663
683
|
[data-theme-mode="dark"] .agent-card--inline .agent-card__name { color: #e2e8f0; }
|
|
664
684
|
[data-theme-mode="dark"] .agent-card--inline .agent-card__avatar { border-color: #2d2b55; }
|
|
665
|
-
[data-theme-mode="dark"] .agent-card__loading
|
|
685
|
+
[data-theme-mode="dark"] .agent-card__loading,
|
|
686
|
+
[data-theme="dark"] .agent-card__loading {
|
|
666
687
|
background: #1e1b3a; border-color: #2d2b55; color: #64748b;
|
|
667
688
|
}
|
|
668
689
|
`;
|
|
@@ -12,14 +12,20 @@
|
|
|
12
12
|
var SHELL_SELECTORS = [
|
|
13
13
|
'.chat-tool-card:not(:has(.cl-remote-agent-card))',
|
|
14
14
|
'.chat-tool-msg-collapse:not(:has(.cl-remote-agent-card))',
|
|
15
|
-
'.chat-tools-collapse:not(:has(.cl-remote-agent-card))'
|
|
15
|
+
'.chat-tools-collapse:not(:has(.cl-remote-agent-card))',
|
|
16
|
+
// v5.x+ variants
|
|
17
|
+
'.tool-card:not(:has(.cl-remote-agent-card))',
|
|
18
|
+
'.chat-tool-card__wrapper:not(:has(.cl-remote-agent-card))'
|
|
16
19
|
];
|
|
17
20
|
|
|
18
21
|
var SUMMARY_SELECTORS = [
|
|
19
22
|
'.chat-tool-card__header',
|
|
20
23
|
'.chat-tool-card__title',
|
|
21
24
|
'.chat-tool-msg-summary:not(.cl-remote-agent-host-shell *)',
|
|
22
|
-
'.chat-tools-summary:not(.cl-remote-agent-host-shell *)'
|
|
25
|
+
'.chat-tools-summary:not(.cl-remote-agent-host-shell *)',
|
|
26
|
+
// v5.x+ variants
|
|
27
|
+
'.tool-card__header',
|
|
28
|
+
'.tool-card__title'
|
|
23
29
|
];
|
|
24
30
|
|
|
25
31
|
var INDENT_SELECTORS = [
|
|
@@ -258,27 +258,25 @@ const toolcardRender: UIExtension = {
|
|
|
258
258
|
if (hasManualCollapseWrapper) {
|
|
259
259
|
const wrapperFn = findFunctionByAnchor(content, wrapperAnchor);
|
|
260
260
|
if (!wrapperFn) {
|
|
261
|
-
logger.warn('[ui-ext:regex] toolcard-render: manual collapse wrapper function not found');
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
261
|
+
logger.warn('[ui-ext:regex] toolcard-render: manual collapse wrapper function not found, skipping wrapper patch');
|
|
262
|
+
} else if (!wrapperFn.body.includes('chat-tool-msg-body') || !wrapperFn.body.includes('onToggleExpanded')) {
|
|
263
|
+
logger.warn('[ui-ext:regex] toolcard-render: manual collapse wrapper shape mismatch, skipping wrapper patch');
|
|
264
|
+
} else {
|
|
265
|
+
const wrapperReturnTagMatch = wrapperFn.body.match(/return\s+([a-zA-Z_$]\w*)\s*`/);
|
|
266
|
+
if (!wrapperReturnTagMatch) {
|
|
267
|
+
logger.warn('[ui-ext:regex] toolcard-render: manual collapse Lit html tag not found, skipping wrapper patch');
|
|
268
|
+
} else {
|
|
269
|
+
const wrapperHtmlVar = wrapperReturnTagMatch[1];
|
|
270
|
+
const wrapperParams = wrapperFn.params.split(',').map((s: string) => s.trim());
|
|
271
|
+
const wrapperCardParam = wrapperParams[0] || 'e';
|
|
272
|
+
const wrapperOptionsParam = wrapperParams[1] || '';
|
|
273
|
+
const wrapperSidebarArg = wrapperOptionsParam ? `${wrapperOptionsParam}&&${wrapperOptionsParam}.onOpenSidebar` : 'undefined';
|
|
274
|
+
const wrapperHook = `${marker}if(window.__openagentRenderToolCard){let __cl=window.__openagentRenderToolCard(${wrapperCardParam},${wrapperSidebarArg});if(__cl)return ${wrapperHtmlVar}\`\${__cl}\`}`;
|
|
275
|
+
content = content.substring(0, wrapperFn.bodyStart) + wrapperHook + content.substring(wrapperFn.bodyStart);
|
|
276
|
+
patchedWrapper = true;
|
|
277
|
+
logger.info(`[ui-ext:regex] toolcard-render: patched manual wrapper ${wrapperFn.funcName}(${wrapperFn.params.substring(0, 20)}) html=${wrapperHtmlVar}`);
|
|
278
|
+
}
|
|
272
279
|
}
|
|
273
|
-
const wrapperHtmlVar = wrapperReturnTagMatch[1];
|
|
274
|
-
const wrapperParams = wrapperFn.params.split(',').map((s: string) => s.trim());
|
|
275
|
-
const wrapperCardParam = wrapperParams[0] || 'e';
|
|
276
|
-
const wrapperOptionsParam = wrapperParams[1] || '';
|
|
277
|
-
const wrapperSidebarArg = wrapperOptionsParam ? `${wrapperOptionsParam}&&${wrapperOptionsParam}.onOpenSidebar` : 'undefined';
|
|
278
|
-
const wrapperHook = `${marker}if(window.__openagentRenderToolCard){let __cl=window.__openagentRenderToolCard(${wrapperCardParam},${wrapperSidebarArg});if(__cl)return ${wrapperHtmlVar}\`\${__cl}\`}`;
|
|
279
|
-
content = content.substring(0, wrapperFn.bodyStart) + wrapperHook + content.substring(wrapperFn.bodyStart);
|
|
280
|
-
patchedWrapper = true;
|
|
281
|
-
logger.info(`[ui-ext:regex] toolcard-render: patched manual wrapper ${wrapperFn.funcName}(${wrapperFn.params.substring(0, 20)}) html=${wrapperHtmlVar}`);
|
|
282
280
|
}
|
|
283
281
|
|
|
284
282
|
// 4.11+ also renders tool-result messages through the grouped message
|
|
@@ -291,13 +289,13 @@ const toolcardRender: UIExtension = {
|
|
|
291
289
|
let toolMessageOk = true;
|
|
292
290
|
const toolMessageFn = findFunctionByAnchor(content, toolMessageAnchor, 8000);
|
|
293
291
|
if (!toolMessageFn) {
|
|
294
|
-
logger.warn('[ui-ext:regex] toolcard-render: tool message wrapper function not found');
|
|
292
|
+
logger.warn('[ui-ext:regex] toolcard-render: tool message wrapper function not found, skipping');
|
|
295
293
|
toolMessageOk = false;
|
|
296
294
|
}
|
|
297
295
|
|
|
298
296
|
if (toolMessageOk && (!toolMessageFn!.body.includes('chat-tool-msg-collapse--manual')
|
|
299
297
|
|| !toolMessageFn!.body.includes('chat-tool-msg-body'))) {
|
|
300
|
-
logger.warn('[ui-ext:regex] toolcard-render: tool message wrapper shape mismatch');
|
|
298
|
+
logger.warn('[ui-ext:regex] toolcard-render: tool message wrapper shape mismatch, skipping');
|
|
301
299
|
toolMessageOk = false;
|
|
302
300
|
}
|
|
303
301
|
|
|
@@ -313,14 +311,33 @@ const toolcardRender: UIExtension = {
|
|
|
313
311
|
}
|
|
314
312
|
|
|
315
313
|
if (toolMessageOk) {
|
|
314
|
+
// 双模式匹配单卡 guard:
|
|
315
|
+
// Shape A (2026.4.x): ,Z=X.length===1?X[0]:null,Y=Z&&!A&&!B?
|
|
316
|
+
// Shape B (2026.5.x): ,N=u.length===1?u[0]:null,...ae=P?`Tool error`:ne&&!C&&!h?ne:...
|
|
316
317
|
const singleCardMatch = toolMessageFn!.body.match(/(?:let\s+|,)([a-zA-Z_$]\w*)=([a-zA-Z_$]\w*)\.length===1\?\2\[0\]:null,\w+=\1&&!([a-zA-Z_$]\w*)&&!([a-zA-Z_$]\w*)\?/);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
318
|
+
let cardsVar = '';
|
|
319
|
+
let mediaVar = '';
|
|
320
|
+
if (singleCardMatch) {
|
|
321
|
+
// Shape A: old bundle
|
|
322
|
+
cardsVar = singleCardMatch[2];
|
|
323
|
+
mediaVar = singleCardMatch[4];
|
|
324
|
+
} else {
|
|
325
|
+
// Shape B: 2026.5.x bundle
|
|
326
|
+
const shapeB = toolMessageFn!.body.match(/,(?:let\s+)?([a-zA-Z_$]\w*)=([a-zA-Z_$]\w*)\.length===1\?\2\[0\]:null/);
|
|
327
|
+
if (!shapeB) {
|
|
328
|
+
logger.warn('[ui-ext:regex] toolcard-render: tool message single-card guard not found');
|
|
329
|
+
toolMessageOk = false;
|
|
330
|
+
} else {
|
|
331
|
+
cardsVar = shapeB[2];
|
|
332
|
+
// 从 ae=P?`Tool error`:ne&&!C&&!h 中提取排除变量 C, h
|
|
333
|
+
const aeMatch = toolMessageFn!.body.match(/,\w+=\w+\?`Tool error`:(\w+)&&!(\w+)&&!(\w+)\?/);
|
|
334
|
+
if (aeMatch) {
|
|
335
|
+
mediaVar = `(${aeMatch[2]}||${aeMatch[3]})`;
|
|
336
|
+
} else {
|
|
337
|
+
mediaVar = 'false';
|
|
338
|
+
}
|
|
339
|
+
}
|
|
320
340
|
}
|
|
321
|
-
if (toolMessageOk) {
|
|
322
|
-
const cardsVar = singleCardMatch![2];
|
|
323
|
-
const mediaVar = singleCardMatch![4];
|
|
324
341
|
const chatBubbleClassMatch = toolMessageFn!.body.match(/[,;]([a-zA-Z_$]\w*)=\[`chat-bubble`,/);
|
|
325
342
|
if (!chatBubbleClassMatch) {
|
|
326
343
|
logger.warn('[ui-ext:regex] toolcard-render: tool message chat-bubble class var not found');
|
|
@@ -337,7 +354,7 @@ const toolcardRender: UIExtension = {
|
|
|
337
354
|
}
|
|
338
355
|
if (toolMessageOk) {
|
|
339
356
|
const toolMessageHook =
|
|
340
|
-
`${marker}let __openagentToolMsgCard=null;if(!${mediaVar}&&window.__openagentRenderToolCard){for(let __openagentI=${cardsVar}.length-1;__openagentI>=0&&!__openagentToolMsgCard;__openagentI--){let __openagentCandidate=${cardsVar}[__openagentI];if(__openagentCandidate&&(__openagentCandidate.outputText||__openagentCandidate.text))__openagentToolMsgCard=window.__openagentRenderToolCard(__openagentCandidate,${toolMessageSidebarArg})}for(let __openagentI=0;__openagentI<${cardsVar}.length&&!__openagentToolMsgCard;__openagentI++){__openagentToolMsgCard=window.__openagentRenderToolCard(${cardsVar}[__openagentI],${toolMessageSidebarArg})}}if(__openagentToolMsgCard)return ${toolMessageHtmlVar}\`<div class="\${${chatBubbleClassVar}}">\${__openagentToolMsgCard}</div>\`;`;
|
|
357
|
+
`${marker}let __openagentToolMsgCard=null;console.log('[openagent] toolMsg hook: cards='+${cardsVar}.length+' mediaVar='+${mediaVar});if(!${mediaVar}&&window.__openagentRenderToolCard){for(let __openagentI=${cardsVar}.length-1;__openagentI>=0&&!__openagentToolMsgCard;__openagentI--){let __openagentCandidate=${cardsVar}[__openagentI];if(__openagentCandidate&&(__openagentCandidate.outputText||__openagentCandidate.text))__openagentToolMsgCard=window.__openagentRenderToolCard(__openagentCandidate,${toolMessageSidebarArg})}for(let __openagentI=0;__openagentI<${cardsVar}.length&&!__openagentToolMsgCard;__openagentI++){__openagentToolMsgCard=window.__openagentRenderToolCard(${cardsVar}[__openagentI],${toolMessageSidebarArg})}}if(__openagentToolMsgCard)return ${toolMessageHtmlVar}\`<div class="\${${chatBubbleClassVar}}">\${__openagentToolMsgCard}</div>\`;`;
|
|
341
358
|
const toolMessageInsertAt = toolMessageFn!.bodyStart + toolMessageReturnIdx;
|
|
342
359
|
content = content.substring(0, toolMessageInsertAt) + toolMessageHook + content.substring(toolMessageInsertAt);
|
|
343
360
|
patchedToolMessageWrapper = true;
|
|
@@ -346,9 +363,8 @@ const toolcardRender: UIExtension = {
|
|
|
346
363
|
}
|
|
347
364
|
}
|
|
348
365
|
}
|
|
349
|
-
}
|
|
350
366
|
|
|
351
|
-
|
|
367
|
+
writeFileSync(bundlePath, content, 'utf-8');
|
|
352
368
|
logger.info(`[ui-ext:regex] toolcard-render: patched ${funcName}(${params.substring(0, 20)}) html=${litHtmlVar}${patchedWrapper ? ' + wrapper' : ''}${patchedToolMessageWrapper ? ' + tool-message' : ''}`);
|
|
353
369
|
return true;
|
|
354
370
|
},
|
|
@@ -650,11 +666,41 @@ const remoteAgentMessageShortCircuit: UIExtension = {
|
|
|
650
666
|
return true;
|
|
651
667
|
}
|
|
652
668
|
|
|
669
|
+
// Strategy D (v5.17+ fallback): search for any if-condition referencing
|
|
670
|
+
// hasToolCards alongside a role-like variable — v5.17+ may replace the
|
|
671
|
+
// ternary/compound patterns of A/B/C with a different expression shape.
|
|
672
|
+
const strategyDRe = new RegExp(
|
|
673
|
+
`if\\(!` + `([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*&&\\s*` +
|
|
674
|
+
hasToolCardsVar + `\\s*&&\\s*([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\)`
|
|
675
|
+
);
|
|
676
|
+
const strategyDMatch = content.match(strategyDRe);
|
|
677
|
+
if (strategyDMatch) {
|
|
678
|
+
const markdownVarD = strategyDMatch[1]!;
|
|
679
|
+
const isToolResultVarD = strategyDMatch[2]!;
|
|
680
|
+
const dMatchFull = strategyDMatch[0];
|
|
681
|
+
const dIdx = strategyDMatch.index!;
|
|
682
|
+
const patched = `if(` + marker +
|
|
683
|
+
`(!` + markdownVarD + `||window.__openagentOwnsToolCards&&window.__openagentOwnsToolCards(` +
|
|
684
|
+
toolCardsVar + `))&&` + hasToolCardsVar + `&&` + isToolResultVarD + `)`;
|
|
685
|
+
content = content.substring(0, dIdx) + patched + content.substring(dIdx + dMatchFull.length);
|
|
686
|
+
writeFileSync(bundlePath, content, 'utf-8');
|
|
687
|
+
logger.info(`[ui-ext:regex] remote-agent-msg: patched (strategy D, md=${markdownVarD})`);
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
|
|
653
691
|
// 策略B (v4.11~v4.1x fallback): compound = hasToolCards && (showToolCalls ?? !0)
|
|
654
692
|
const compoundRe = new RegExp(`(\\w+)=${hasToolCardsVar}&&\\(\\w+\\.showToolCalls\\?\\?!0\\)`);
|
|
655
693
|
const compoundMatch = content.match(compoundRe);
|
|
656
694
|
if (!compoundMatch) {
|
|
657
|
-
|
|
695
|
+
// All strategies (A/C/D/B) failed — dump context for diagnostics
|
|
696
|
+
const anchorHintIdx = content.indexOf(hasToolCardsVar);
|
|
697
|
+
const ctxStart = anchorHintIdx > 200 ? anchorHintIdx - 200 : 0;
|
|
698
|
+
const ctxEnd = Math.min(anchorHintIdx + 200, content.length);
|
|
699
|
+
logger.warn(
|
|
700
|
+
`[ui-ext:regex] remote-agent-msg: all strategies (A/C/D/B) failed for toolCards=${toolCardsVar}. ` +
|
|
701
|
+
`Context around hasToolCardsVar (at ${anchorHintIdx}): ` +
|
|
702
|
+
content.substring(ctxStart, ctxEnd)
|
|
703
|
+
);
|
|
658
704
|
return false;
|
|
659
705
|
}
|
|
660
706
|
|
|
@@ -709,17 +755,18 @@ const mentionHooks: UIExtension = {
|
|
|
709
755
|
const hookA = `${markerA}if(window.__clMention?.onKeyDown(${eventParam}))return;`;
|
|
710
756
|
content = content.substring(0, keydownInsertIdx) + hookA + content.substring(keydownInsertIdx);
|
|
711
757
|
|
|
712
|
-
// 注入点 B: handleInput —
|
|
758
|
+
// 注入点 B: handleInput — 四种形态兼容
|
|
713
759
|
// Shape A (old): .onDraftChange(target.value)}}
|
|
714
760
|
// Shape B (4.11~4.x): .onDraftChange(target.value) (arrow function 内)
|
|
715
|
-
// Shape C (2026.6.x): be=t=>{let n=t.target;pL(e,n.value)} — 引入 pL helper
|
|
716
|
-
//
|
|
761
|
+
// Shape C (2026.6.x): be=t=>{let n=t.target;pL(e,n.value)} — 引入 pL helper
|
|
762
|
+
// Shape D (generic): .onDraftChange(任意.target.value) 不加结尾限制
|
|
717
763
|
const inputReA = /\.onDraftChange\(([a-zA-Z_$][a-zA-Z0-9_$]*)\.value\)\}\}/;
|
|
718
764
|
const inputReB = /\.onDraftChange\(([a-zA-Z_$][a-zA-Z0-9_$]*)\.value\)/;
|
|
719
765
|
const inputReC = /let ([a-zA-Z_$][a-zA-Z0-9_$]*)=[a-zA-Z_$][a-zA-Z0-9_$]*\.target;[a-zA-Z_$][a-zA-Z0-9_$]*\([a-zA-Z_$][a-zA-Z0-9_$]*,\1\.value\)\}/;
|
|
766
|
+
const inputReD = /\.onDraftChange\(([a-zA-Z_$][a-zA-Z0-9_$]*)\.target\.value\)/;
|
|
720
767
|
|
|
721
768
|
let inputMatch = content.match(inputReA);
|
|
722
|
-
let inputShape: 'A' | 'B' | 'C' = 'A';
|
|
769
|
+
let inputShape: 'A' | 'B' | 'C' | 'D' = 'A';
|
|
723
770
|
|
|
724
771
|
if (!inputMatch) {
|
|
725
772
|
inputMatch = content.match(inputReC);
|
|
@@ -729,14 +776,26 @@ const mentionHooks: UIExtension = {
|
|
|
729
776
|
inputMatch = content.match(inputReB);
|
|
730
777
|
inputShape = 'B';
|
|
731
778
|
}
|
|
779
|
+
if (!inputMatch) {
|
|
780
|
+
inputMatch = content.match(inputReD);
|
|
781
|
+
inputShape = 'D';
|
|
782
|
+
}
|
|
732
783
|
|
|
733
784
|
if (!inputMatch) {
|
|
734
|
-
|
|
785
|
+
// All shapes missed — dump context for diagnostics
|
|
786
|
+
const draftHintIdx = content.indexOf('.onDraftChange');
|
|
787
|
+
const ctxStart = draftHintIdx > 200 ? draftHintIdx - 200 : 0;
|
|
788
|
+
const ctxEnd = Math.min(draftHintIdx + 200, content.length);
|
|
789
|
+
logger.warn(
|
|
790
|
+
`[ui-ext:regex] mention-hooks: input anchor not found (Shape A/B/C/D all missed). ` +
|
|
791
|
+
`Context around onDraftChange (at ${draftHintIdx}): ` +
|
|
792
|
+
content.substring(ctxStart, ctxEnd)
|
|
793
|
+
);
|
|
735
794
|
return false;
|
|
736
795
|
}
|
|
737
796
|
const targetVar = inputMatch[1];
|
|
738
797
|
const inputAnchorIdx = content.indexOf(inputMatch[0]);
|
|
739
|
-
// Shape A: }} 之前;Shape C: 末尾 } 之前;Shape B: ) 之后
|
|
798
|
+
// Shape A: }} 之前;Shape C: 末尾 } 之前;Shape B/D: ) 之后
|
|
740
799
|
const draftCallEnd = inputShape === 'A'
|
|
741
800
|
? inputAnchorIdx + inputMatch[0].length - 2
|
|
742
801
|
: inputShape === 'C'
|
package/src/util/url-resolver.ts
CHANGED
|
@@ -15,3 +15,47 @@ export function resolveOasnAccessUrl(accessApiBase: string | undefined, url: str
|
|
|
15
15
|
return url;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a WebUI continuation URL for user-facing browser clicks.
|
|
21
|
+
*
|
|
22
|
+
* WebUI auth is Owner-cookie based, so the clickable URL must use the same
|
|
23
|
+
* public origin as the claim/login flow. API-key calls can use an internal
|
|
24
|
+
* Access base, but browser links cannot reuse cookies across IP/domain origins.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveOasnWebuiUrl(
|
|
27
|
+
accessApiBase: string | undefined,
|
|
28
|
+
claimUrl: string | undefined,
|
|
29
|
+
url: string,
|
|
30
|
+
): string {
|
|
31
|
+
if (!url) return url;
|
|
32
|
+
|
|
33
|
+
const claimOrigin = originOf(claimUrl);
|
|
34
|
+
if (!claimOrigin || !isWebuiUrl(url, accessApiBase || claimOrigin)) {
|
|
35
|
+
return resolveOasnAccessUrl(accessApiBase, url);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const absolute = new URL(url, accessApiBase || claimOrigin);
|
|
40
|
+
return new URL(`${absolute.pathname}${absolute.search}${absolute.hash}`, claimOrigin).toString();
|
|
41
|
+
} catch {
|
|
42
|
+
return resolveOasnAccessUrl(accessApiBase, url);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function originOf(value: string | undefined): string | undefined {
|
|
47
|
+
if (!value) return undefined;
|
|
48
|
+
try {
|
|
49
|
+
return new URL(value).origin;
|
|
50
|
+
} catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isWebuiUrl(url: string, base: string): boolean {
|
|
56
|
+
try {
|
|
57
|
+
return new URL(url, base).pathname.startsWith('/webui/');
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|