@eclipse-docks/extension-ai-system 0.8.0 → 0.8.1
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 +2 -2
- package/dist/api.js +1 -1
- package/dist/{cognitive-extension-CG_d39K5.js → cognitive-extension-7_ZMUCGD.js} +358 -92
- package/dist/cognitive-extension-7_ZMUCGD.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.d.ts.map +1 -0
- package/dist/runtime/attachment-paths.d.ts +17 -0
- package/dist/runtime/attachment-paths.d.ts.map +1 -0
- package/dist/runtime/attachments.d.ts +5 -5
- package/dist/runtime/attachments.d.ts.map +1 -1
- package/dist/runtime/cognitive-runtime.d.ts +7 -3
- package/dist/runtime/cognitive-runtime.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/models/openai-compatible.d.ts.map +1 -1
- package/dist/runtime/session-workspace.d.ts +20 -0
- package/dist/runtime/session-workspace.d.ts.map +1 -0
- package/dist/runtime/specialists/index.d.ts.map +1 -1
- package/dist/runtime/specialists/loop.d.ts.map +1 -1
- package/dist/runtime/tools/command-adapter.d.ts.map +1 -1
- package/dist/runtime/tools/index.d.ts +0 -1
- package/dist/runtime/tools/index.d.ts.map +1 -1
- package/dist/runtime/tools/workspace-adapter.d.ts +1 -1
- package/dist/runtime/tools/workspace-adapter.d.ts.map +1 -1
- package/dist/runtime/tools/workspace-path-qualify.d.ts +22 -0
- package/dist/runtime/tools/workspace-path-qualify.d.ts.map +1 -0
- package/dist/runtime/tools/workspace-path.d.ts +17 -0
- package/dist/runtime/tools/workspace-path.d.ts.map +1 -0
- package/dist/{runtime-DfNGzEjU.js → runtime-By5PP2BC.js} +696 -384
- package/dist/runtime-By5PP2BC.js.map +1 -0
- package/dist/view/busy-status.d.ts +12 -0
- package/dist/view/busy-status.d.ts.map +1 -0
- package/dist/view/cognitive-settings-editor.d.ts +0 -1
- package/dist/view/cognitive-settings-editor.d.ts.map +1 -1
- package/dist/view/cognitive-view.d.ts +21 -0
- package/dist/view/cognitive-view.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/cognitive-extension-CG_d39K5.js.map +0 -1
- package/dist/runtime/tools/attachment-adapter.d.ts +0 -6
- package/dist/runtime/tools/attachment-adapter.d.ts.map +0 -1
- package/dist/runtime-DfNGzEjU.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cognitive-view.d.ts","sourceRoot":"","sources":["../../src/view/cognitive-view.ts"],"names":[],"mappings":"AAAA,OAAO,0CAA0C,CAAC;AAClD,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAc,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"cognitive-view.d.ts","sourceRoot":"","sources":["../../src/view/cognitive-view.ts"],"names":[],"mappings":"AAAA,OAAO,0CAA0C,CAAC;AAClD,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAc,MAAM,qBAAqB,CAAC;AAuC5D,qBACa,kBAAmB,SAAQ,SAAS;IAC/C,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAU;IAE9D,MAAM,CAAC,MAAM,0BAweX;IAEoB,OAAO,CAAC,QAAQ,CAAC,CAAiE;IAC3E,OAAO,CAAC,SAAS,CAAC,CAAmB;IAClE,OAAO,CAAC,kBAAkB,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,KAAK,CAAM;IAC5B,iEAAiE;IACxD,OAAO,CAAC,oBAAoB,CAAgB;IAC5C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,UAAU,CAAuD;IACzE,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,WAAW,CAAkD;IACrE,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAM;IACnC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,mBAAmB,CAAC,CAAgC;IAC5D,OAAO,CAAC,eAAe,CAAC,CAAgC;IACxD,OAAO,CAAC,gBAAgB,CAAgC;IACxD,OAAO,CAAC,kBAAkB,CAAgE;IAC1F,OAAO,CAAC,gBAAgB,CAItB;IAEF,SAAS,CAAC,OAAO,IAAI,IAAI;IAIzB,OAAO,CAAC,iBAAiB;IAQzB,SAAS,CAAC,UAAU,IAAI,IAAI;IAqC5B,SAAS,CAAC,OAAO,IAAI,IAAI;IAYzB,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,sBAAsB;YAQhB,cAAc;IAW5B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,UAAU;IAOlB,wEAAwE;IACxE,OAAO,CAAC,yBAAyB;IAkBjC,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,YAAY;YAIN,cAAc;IAM5B,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,WAAW;YAYL,eAAe;YAMf,aAAa;IAM3B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,uBAAuB;YAQjB,QAAQ;IAsCtB,OAAO,CAAC,cAAc;YAIR,iBAAiB;IAM/B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,mBAAmB;YAIb,cAAc;IAM5B,yFAAyF;YAC3E,eAAe;IAW7B,OAAO,CAAC,UAAU;YAMJ,IAAI;IA+BlB,OAAO,CAAC,wBAAwB;IA0EhC,OAAO,CAAC,sBAAsB;IAoC9B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,iBAAiB;IAMzB,SAAS,CAAC,aAAa,IAAI,cAAc;IA0BzC,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,qBAAqB;IA2E7B,SAAS,CAAC,aAAa;IAiFvB,OAAO,CAAC,gBAAgB;IA6CxB,OAAO,CAAC,qBAAqB;IAuF7B,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,sBAAsB;IAoG9B,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,aAAa;IAyCrB,OAAO,CAAC,sBAAsB;IAoD9B,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,mBAAmB;CAmC5B;AAuLD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,kBAAkB,CAAC;KAC5C;CACF"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cognitive-extension-CG_d39K5.js","names":["APPROVAL_OPTIONS"],"sources":["../src/view/cognitive-view.ts","../src/view/cognitive-settings-editor.ts","../src/cognitive-extension.ts"],"sourcesContent":["import '@eclipse-docks/core/externals/webawesome';\nimport {\n html,\n css,\n nothing,\n customElement,\n query,\n state,\n type TemplateResult,\n} from '@eclipse-docks/core/externals/lit';\nimport { DocksPart, toastError } from '@eclipse-docks/core';\nimport {\n ATTACHMENT_FILE_ACCEPT,\n MAX_ATTACHMENTS,\n OPEN_AI_SETTINGS_COMMAND,\n TOPIC,\n cognitiveRuntime,\n detectEffortCapability,\n estimateSessionContextUsage,\n formatBucketDetail,\n formatContextPercent,\n formatTokenCount,\n readPromptAttachmentFromFile,\n} from '../runtime';\nimport type {\n ChatMessage,\n CognitiveSession,\n ContextUsage,\n EffortLevel,\n MessagePart,\n ModelPolicy,\n PermissionAction,\n PromptAttachment,\n SessionAttachment,\n ToolApprovalMode,\n} from '../runtime';\n\ninterface PermissionRequest {\n requestId: string;\n toolName: string;\n args: Record<string, unknown>;\n sessionId: string;\n}\n\n@customElement('docks-cognitive-view')\nexport class DocksCognitiveView extends DocksPart {\n protected scrollMode: 'scroller' | 'native' | 'none' = 'none';\n\n static styles = css`\n :host {\n height: 100%;\n min-height: 0;\n background: var(--wa-color-surface-default);\n color: var(--wa-color-text-normal);\n font-family: var(--wa-font-family-body);\n }\n\n .part-content,\n .part-content-inner {\n height: 100%;\n min-height: 0;\n }\n\n .cognitive-shell {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n /* Establish a definite containing block for wa-scroller's height: 100%. */\n position: relative;\n }\n\n wa-dropdown.history-menu::part(menu) {\n min-width: 18rem;\n max-width: min(24rem, 92vw);\n max-height: min(28rem, 70vh);\n overflow-y: auto;\n padding-top: 0;\n }\n\n .history-search {\n position: sticky;\n top: 0;\n z-index: 1;\n display: block;\n padding: var(--wa-space-s);\n background: var(--wa-color-surface-raised);\n border-bottom: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n }\n\n .history-search wa-input {\n width: 100%;\n }\n\n .history-item-title {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .history-item-meta {\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-xs);\n flex-shrink: 0;\n }\n\n .history-empty {\n padding: var(--wa-space-m);\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-s);\n text-align: center;\n }\n\n wa-scroller.transcript {\n /* flex-basis 0 so the host gets a definite height; wa-scroller vertical uses height:100%. */\n flex: 1 1 0;\n min-height: 0;\n height: 100%;\n overflow: hidden;\n }\n\n .transcript-inner {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-m);\n padding: var(--wa-space-m);\n min-height: 100%;\n box-sizing: border-box;\n }\n\n /* Pushes short threads to the bottom without breaking overflow scroll. */\n .transcript-spacer {\n flex: 1 0 0;\n min-height: 0;\n }\n\n .msg {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xs);\n max-width: 100%;\n }\n\n .msg.user {\n align-items: flex-end;\n }\n\n .msg-meta {\n position: absolute;\n right: var(--wa-space-2xs);\n bottom: var(--wa-space-2xs);\n z-index: 1;\n display: flex;\n gap: var(--wa-space-2xs);\n align-items: center;\n flex-wrap: wrap;\n justify-content: flex-end;\n max-width: calc(100% - var(--wa-space-s));\n padding: var(--wa-space-3xs) var(--wa-space-2xs);\n border-radius: var(--wa-border-radius-m);\n background: color-mix(in srgb, var(--wa-color-surface-default) 88%, transparent);\n font-size: var(--wa-font-size-xs);\n color: var(--wa-color-text-quiet);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--wa-transition-fast, 120ms) ease;\n }\n\n .msg:hover .msg-meta,\n .msg:focus-within .msg-meta {\n opacity: 1;\n pointer-events: auto;\n }\n\n .bubble {\n padding: var(--wa-space-s) var(--wa-space-m);\n border-radius: var(--wa-border-radius-l);\n background: var(--wa-color-surface-raised);\n border: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n white-space: pre-wrap;\n line-height: var(--wa-line-height-normal);\n max-width: 100%;\n }\n\n .msg.user .bubble {\n background: color-mix(in srgb, var(--wa-color-brand-fill-normal) 22%, transparent);\n border-color: color-mix(in srgb, var(--wa-color-brand-fill-normal) 40%, transparent);\n }\n\n .streaming-meta {\n display: flex;\n gap: var(--wa-space-2xs);\n align-items: center;\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-s);\n }\n\n .composer-shell {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-s);\n padding: var(--wa-space-s) var(--wa-space-m) var(--wa-space-m);\n border-top: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n flex-shrink: 0;\n }\n\n wa-dropdown.settings-menu::part(menu) {\n min-width: 16rem;\n max-width: min(28rem, 92vw);\n }\n\n wa-dropdown.context-menu::part(menu) {\n min-width: 17rem;\n max-width: min(22rem, 92vw);\n padding: var(--wa-space-s);\n }\n\n .context-ring {\n --size: 1.35rem;\n --track-width: 2.5px;\n --indicator-width: 2.5px;\n font-size: 0;\n }\n\n .context-panel {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-s);\n }\n\n .context-header {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n gap: var(--wa-space-s);\n }\n\n .context-header strong {\n font-size: var(--wa-font-size-s);\n }\n\n .context-header span {\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-xs);\n }\n\n .context-bars {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xs);\n }\n\n .context-row {\n display: grid;\n grid-template-columns: 1fr auto;\n gap: var(--wa-space-2xs);\n font-size: var(--wa-font-size-xs);\n }\n\n .context-row-label {\n color: var(--wa-color-text-quiet);\n }\n\n .context-meter {\n grid-column: 1 / -1;\n height: 0.35rem;\n border-radius: var(--wa-border-radius-pill);\n background: var(--wa-color-neutral-fill-quiet);\n overflow: hidden;\n }\n\n .context-meter > span {\n display: block;\n height: 100%;\n border-radius: inherit;\n background: var(--bucket-color, var(--wa-color-brand-fill-normal));\n }\n\n .context-footer {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xs);\n }\n\n .context-remaining {\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-xs);\n }\n\n .composer {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xs);\n flex: 1;\n min-width: 0;\n }\n\n .composer-row {\n display: flex;\n gap: var(--wa-space-s);\n align-items: flex-end;\n }\n\n .composer wa-textarea {\n flex: 1;\n min-width: 0;\n }\n\n .composer-actions {\n display: flex;\n align-items: center;\n gap: var(--wa-space-2xs);\n flex-shrink: 0;\n }\n\n .composer-shell.drag-over {\n outline: 2px dashed var(--wa-color-brand-border-normal);\n outline-offset: -2px;\n background: color-mix(in srgb, var(--wa-color-brand-fill-quiet) 35%, transparent);\n }\n\n wa-dropdown.attach-menu::part(menu) {\n min-width: 18rem;\n max-width: min(24rem, 92vw);\n padding: var(--wa-space-2xs);\n }\n\n .attach-panel {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xs);\n max-height: min(22rem, 50vh);\n }\n\n .attach-list {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xs);\n overflow: auto;\n min-height: 0;\n }\n\n .attach-row {\n display: flex;\n align-items: center;\n gap: var(--wa-space-2xs);\n min-width: 0;\n }\n\n .attach-preview-btn {\n display: flex;\n align-items: center;\n gap: var(--wa-space-s);\n flex: 1;\n min-width: 0;\n margin: 0;\n padding: var(--wa-space-2xs);\n border: none;\n border-radius: var(--wa-border-radius-s);\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: start;\n cursor: pointer;\n }\n\n .attach-preview-btn:hover {\n background: var(--wa-color-neutral-fill-quiet);\n }\n\n .attach-thumb,\n .msg-file-thumb {\n width: 2.5rem;\n height: 2.5rem;\n object-fit: cover;\n border-radius: var(--wa-border-radius-s);\n border: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n flex-shrink: 0;\n }\n\n .attach-file-icon {\n display: grid;\n place-items: center;\n width: 2.5rem;\n height: 2.5rem;\n border-radius: var(--wa-border-radius-s);\n border: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n color: var(--wa-color-text-quiet);\n flex-shrink: 0;\n }\n\n .attach-name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--wa-font-size-s);\n }\n\n .attach-empty {\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-xs);\n padding: var(--wa-space-s);\n }\n\n .msg-file-thumb {\n width: 4.5rem;\n height: 4.5rem;\n }\n\n .attach-dialog-body {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-s);\n max-height: min(70vh, 40rem);\n overflow: auto;\n }\n\n .attach-dialog-image {\n max-width: 100%;\n height: auto;\n border-radius: var(--wa-border-radius-m);\n }\n\n .attach-dialog-text {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: var(--wa-font-family-code, ui-monospace, monospace);\n font-size: var(--wa-font-size-s);\n }\n\n .msg-files {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wa-space-2xs);\n margin-bottom: var(--wa-space-2xs);\n }\n\n .approval-actions {\n display: flex;\n gap: var(--wa-space-s);\n margin-top: var(--wa-space-s);\n flex-wrap: wrap;\n }\n\n pre.args {\n margin: var(--wa-space-s) 0 0;\n font-family: var(--wa-font-family-code, var(--wa-font-mono));\n font-size: var(--wa-font-size-xs);\n white-space: pre-wrap;\n overflow-x: auto;\n }\n\n wa-details {\n font-size: var(--wa-font-size-s);\n }\n\n wa-details.msg-details {\n width: 100%;\n font-size: var(--wa-font-size-s);\n }\n\n wa-details.msg-details::part(base),\n wa-details.msg-details::part(details) {\n border: none;\n background: transparent;\n }\n\n wa-details.msg-details::part(header) {\n align-items: flex-start;\n gap: var(--wa-space-2xs);\n padding: 0;\n }\n\n wa-details.msg-details::part(summary) {\n flex: 1;\n min-width: 0;\n }\n\n wa-details.msg-details::part(content) {\n padding: var(--wa-space-s) 0 0;\n }\n\n .msg-summary {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xs);\n width: 100%;\n }\n\n .msg-tech {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-s);\n margin-inline-start: var(--wa-space-l);\n padding-inline-start: var(--wa-space-m);\n border-inline-start: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n }\n\n .tool-heading {\n font-size: var(--wa-font-size-xs);\n color: var(--wa-color-text-quiet);\n margin-bottom: var(--wa-space-2xs);\n }\n `;\n\n @query('wa-textarea') private textarea?: HTMLTextAreaElement & { value: string };\n @query('#attach-file-input') private fileInput?: HTMLInputElement;\n\n @state() private sessions: CognitiveSession[] = [];\n @state() private focusedId: string | null = null;\n @state() private draft = '';\n /** Session attachment ids to publish with the next user turn. */\n @state() private pendingAttachmentIds: string[] = [];\n @state() private dragOver = false;\n @state() private previewAttachmentId: string | null = null;\n @state() private busy = false;\n @state() private pendingPermission: PermissionRequest | null = null;\n @state() private policyMode: 'auto' | 'manual' = 'auto';\n @state() private optimizeFor: 'cost' | 'balance' | 'intelligence' = 'balance';\n @state() private manualModel = '';\n @state() private manualEffort: EffortLevel | 'auto' = 'auto';\n @state() private approvalMode: ToolApprovalMode = 'auto_safe';\n @state() private modelIds: string[] = [];\n @state() private streamingParts: MessagePart[] = [];\n @state() private historyOpen = false;\n @state() private historyQuery = '';\n private unsubs: Array<() => void> = [];\n private scrollDebounceTimer?: ReturnType<typeof setTimeout>;\n\n protected doBeforeUI(): void {\n cognitiveRuntime.start();\n this.syncSessions();\n this.syncModels();\n this.approvalMode = cognitiveRuntime.getApprovalMode();\n void cognitiveRuntime.whenReady().then(() => {\n this.syncSessions();\n this.syncModels();\n this.approvalMode = cognitiveRuntime.getApprovalMode();\n this.scheduleScrollToBottom();\n });\n this.unsubs.push(\n cognitiveRuntime.events.subscribe(TOPIC.sessionChanged, () => {\n this.syncSessions();\n this.scheduleScrollToBottom();\n }),\n cognitiveRuntime.events.subscribe(TOPIC.providersChanged, () => this.syncModels()),\n cognitiveRuntime.events.subscribe(TOPIC.approvalModeChanged, (mode) => {\n this.approvalMode = mode as ToolApprovalMode;\n }),\n cognitiveRuntime.events.subscribe(TOPIC.permissionAsked, (payload) => {\n this.pendingPermission = payload as PermissionRequest;\n this.scheduleScrollToBottom();\n }),\n cognitiveRuntime.events.subscribe(TOPIC.messagePart, (payload) => {\n const { sessionId, part } = payload as { sessionId: string; part: MessagePart };\n if (sessionId !== this.focusedId) return;\n this.streamingParts = mergePart(this.streamingParts, part);\n this.scheduleScrollToBottom();\n }),\n cognitiveRuntime.events.subscribe(TOPIC.messageDone, () => {\n this.streamingParts = [];\n this.syncSessions();\n this.scheduleScrollToBottom();\n }),\n );\n }\n\n protected doClose(): void {\n if (this.scrollDebounceTimer) clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = undefined;\n for (const u of this.unsubs) u();\n this.unsubs = [];\n }\n\n private syncSessions(): void {\n const byRecency = cognitiveRuntime.sessions.list();\n this.sessions = [...byRecency].sort((a, b) => a.createdAt - b.createdAt);\n const focused = cognitiveRuntime.sessions.focused();\n const activeId = focused?.id ?? byRecency[0]?.id ?? null;\n if (activeId && focused?.id !== activeId) {\n cognitiveRuntime.sessions.focus(activeId);\n }\n this.focusedId = activeId;\n }\n\n private scheduleScrollToBottom(): void {\n if (this.scrollDebounceTimer) clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = setTimeout(() => {\n this.scrollDebounceTimer = undefined;\n void this.scrollToBottom();\n }, 50);\n }\n\n private async scrollToBottom(): Promise<void> {\n await this.updateComplete;\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n const scroller = this.renderRoot.querySelector('wa-scroller.transcript');\n if (!scroller?.shadowRoot) return;\n\n const container = scroller.shadowRoot.querySelector('#content');\n if (!(container instanceof HTMLElement)) return;\n container.scrollTop = container.scrollHeight;\n }\n\n private focusedSession(): CognitiveSession | undefined {\n return this.sessions.find((s) => s.id === this.focusedId) ?? this.sessions[0];\n }\n\n private deleteSession(sessionId: string): void {\n if (this.sessions.length <= 1) {\n cognitiveRuntime.sessions.createSession({ title: 'Chat' });\n cognitiveRuntime.sessions.remove(sessionId);\n } else {\n cognitiveRuntime.sessions.remove(sessionId);\n }\n this.streamingParts = [];\n this.syncSessions();\n cognitiveRuntime.commitSessions();\n }\n\n private openSession(sessionId: string): void {\n if (!cognitiveRuntime.sessions.focus(sessionId)) return;\n this.streamingParts = [];\n this.syncSessions();\n this.historyOpen = false;\n this.historyQuery = '';\n cognitiveRuntime.commitSessions();\n this.scheduleScrollToBottom();\n }\n\n private newSession(): void {\n cognitiveRuntime.sessions.createSession({ title: 'Chat' });\n this.streamingParts = [];\n this.historyOpen = false;\n this.historyQuery = '';\n this.syncSessions();\n cognitiveRuntime.commitSessions();\n }\n\n private historySessions(): CognitiveSession[] {\n const q = this.historyQuery.trim().toLowerCase();\n const sorted = [...this.sessions].sort((a, b) => b.updatedAt - a.updatedAt);\n if (!q) return sorted;\n return sorted.filter((s) => {\n if (s.title.toLowerCase().includes(q)) return true;\n return s.history.some((m) =>\n m.parts.some((p) => {\n if (p.type === 'text') return p.text.toLowerCase().includes(q);\n if (p.type === 'file') {\n return (\n p.name.toLowerCase().includes(q) ||\n p.id.toLowerCase().includes(q) ||\n (p.path?.toLowerCase().includes(q) ?? false)\n );\n }\n return false;\n }),\n );\n });\n }\n\n private syncModels(): void {\n this.modelIds = cognitiveRuntime.listConfiguredModels();\n if (!this.manualModel || !this.modelIds.includes(this.manualModel)) {\n this.manualModel = this.modelIds[0] ?? cognitiveRuntime.defaultModelId();\n }\n }\n\n private effortChoices(): Array<EffortLevel | 'auto'> {\n const cap = detectEffortCapability(this.manualModel || cognitiveRuntime.defaultModelId());\n if (!cap.supported) return ['auto', 'none'];\n return ['auto', ...cap.levels];\n }\n\n private routerValue(): string {\n return this.policyMode === 'auto' ? `auto:${this.optimizeFor}` : `model:${this.manualModel}`;\n }\n\n private routerLabel(): string {\n if (this.policyMode === 'auto') return `Auto · ${capitalize(this.optimizeFor)}`;\n if (!this.modelIds.length) return 'No models';\n return shortModelLabel(this.manualModel || this.modelIds[0]!);\n }\n\n private activeModelRef(): string {\n const session = this.focusedSession();\n const routed = [...(session?.history ?? [])]\n .reverse()\n .find((m) => m.role === 'assistant' && m.routedModel)?.routedModel;\n if (routed) return routed;\n if (this.policyMode === 'manual') {\n return this.manualModel || this.modelIds[0] || cognitiveRuntime.defaultModelId();\n }\n return this.modelIds[0] || cognitiveRuntime.defaultModelId();\n }\n\n private contextUsage(): ContextUsage {\n return estimateSessionContextUsage(this.focusedSession(), this.activeModelRef());\n }\n\n private async compactFocused(): Promise<void> {\n if (!this.focusedId) return;\n await cognitiveRuntime.compactSession(this.focusedId);\n this.syncSessions();\n }\n\n private onRouterSelect(value: string): void {\n if (value.startsWith('auto:')) {\n const optimize = value.slice(5);\n if (optimize === 'cost' || optimize === 'balance' || optimize === 'intelligence') {\n this.policyMode = 'auto';\n this.optimizeFor = optimize;\n }\n return;\n }\n if (value.startsWith('model:')) {\n const model = value.slice(6);\n if (!model) return;\n this.policyMode = 'manual';\n this.manualModel = model;\n }\n }\n\n private applyPolicy(): void {\n const policy: ModelPolicy =\n this.policyMode === 'manual'\n ? {\n mode: 'manual',\n model: this.manualModel || cognitiveRuntime.defaultModelId(),\n effort: this.manualEffort,\n }\n : { mode: 'auto', optimizeFor: this.optimizeFor };\n cognitiveRuntime.setModelPolicy(policy);\n }\n\n private async clearComposer(): Promise<void> {\n this.draft = '';\n this.pendingAttachmentIds = [];\n await this.updateComplete;\n if (this.textarea) this.textarea.value = '';\n if (this.fileInput) this.fileInput.value = '';\n }\n\n private sessionAttachments(): SessionAttachment[] {\n return this.focusedSession()?.attachments ?? [];\n }\n\n private previewAttachment(): SessionAttachment | undefined {\n if (!this.previewAttachmentId) return undefined;\n return this.sessionAttachments().find((a) => a.id === this.previewAttachmentId);\n }\n\n private openAttachmentPreview(attachmentId: string): void {\n this.previewAttachmentId = attachmentId;\n }\n\n private closeAttachmentPreview(): void {\n this.previewAttachmentId = null;\n }\n\n private removeSessionAttachment(attachmentId: string): void {\n const sessionId = this.focusedId ?? cognitiveRuntime.ensureSessionId();\n cognitiveRuntime.removeAttachment(sessionId, attachmentId);\n this.pendingAttachmentIds = this.pendingAttachmentIds.filter((id) => id !== attachmentId);\n if (this.previewAttachmentId === attachmentId) this.previewAttachmentId = null;\n this.syncSessions();\n }\n\n private async addFiles(fileList: FileList | File[]): Promise<void> {\n const files = [...fileList];\n if (!files.length) return;\n\n const sessionId = cognitiveRuntime.ensureSessionId(this.focusedId ?? undefined);\n this.focusedId = sessionId;\n const existing = this.sessionAttachments();\n const accepted: PromptAttachment[] = [];\n\n for (const file of files) {\n if (existing.length + accepted.length >= MAX_ATTACHMENTS) {\n toastError(`At most ${MAX_ATTACHMENTS} files per session`);\n break;\n }\n if (\n existing.some((a) => a.name === file.name && a.byteLength === file.size) ||\n accepted.some((a) => a.name === file.name && a.byteLength === file.size)\n ) {\n continue;\n }\n const result = await readPromptAttachmentFromFile(file);\n if (!result.ok) {\n toastError(result.error);\n continue;\n }\n accepted.push(result.attachment);\n }\n\n const stored = cognitiveRuntime.addAttachments(sessionId, accepted);\n if (stored.length) {\n this.pendingAttachmentIds = [\n ...this.pendingAttachmentIds,\n ...stored.map((a) => a.id).filter((id) => !this.pendingAttachmentIds.includes(id)),\n ];\n }\n this.syncSessions();\n }\n\n private openFilePicker(): void {\n this.fileInput?.click();\n }\n\n private async onFileInputChange(e: Event): Promise<void> {\n const input = e.target as HTMLInputElement;\n if (input.files?.length) await this.addFiles(input.files);\n input.value = '';\n }\n\n private onComposerDragOver(e: DragEvent): void {\n if (!e.dataTransfer?.types.includes('Files')) return;\n e.preventDefault();\n this.dragOver = true;\n }\n\n private onComposerDragLeave(e: DragEvent): void {\n if (e.currentTarget === e.target) this.dragOver = false;\n }\n\n private async onComposerDrop(e: DragEvent): Promise<void> {\n e.preventDefault();\n this.dragOver = false;\n if (e.dataTransfer?.files?.length) await this.addFiles(e.dataTransfer.files);\n }\n\n private async send(): Promise<void> {\n const text = this.draft.trim();\n const attachmentIds = [...this.pendingAttachmentIds];\n if ((!text && !attachmentIds.length) || this.busy) return;\n this.applyPolicy();\n await this.clearComposer();\n this.busy = true;\n this.streamingParts = [];\n try {\n await cognitiveRuntime.prompt({\n sessionId: this.focusedId ?? undefined,\n text,\n attachmentIds,\n });\n } finally {\n this.busy = false;\n this.syncSessions();\n this.scheduleScrollToBottom();\n this.textarea?.focus();\n }\n }\n\n private renderAttachmentDropdown() {\n const attachments = this.sessionAttachments();\n const count = attachments.length;\n return html`\n <wa-dropdown class=\"attach-menu\" size=\"s\" placement=\"top-end\" distance=\"4\">\n <wa-button\n slot=\"trigger\"\n size=\"s\"\n appearance=\"plain\"\n title=${count ? `${count} attachment${count === 1 ? '' : 's'}` : 'Attachments'}\n ?disabled=${this.busy}\n >\n <wa-icon name=\"paperclip\" label=\"Attachments\"></wa-icon>\n ${count > 0 ? html`<wa-badge pill>${count}</wa-badge>` : nothing}\n </wa-button>\n <div\n class=\"attach-panel\"\n @click=${(e: Event) => e.stopPropagation()}\n @keydown=${(e: Event) => e.stopPropagation()}\n >\n ${count\n ? html`\n <div class=\"attach-list\">\n ${attachments.map(\n (file) => html`\n <div class=\"attach-row\">\n <button\n type=\"button\"\n class=\"attach-preview-btn\"\n title=\"Open ${file.name}\"\n @click=${() => this.openAttachmentPreview(file.id)}\n >\n ${file.kind === 'image' && file.dataUrl\n ? html`<img\n class=\"attach-thumb\"\n src=${file.dataUrl}\n alt=${file.name}\n />`\n : html`\n <span class=\"attach-file-icon\">\n <wa-icon name=\"file\" label=\"\"></wa-icon>\n </span>\n `}\n <span class=\"attach-name\">${file.name}</span>\n </button>\n <wa-button\n size=\"s\"\n appearance=\"plain\"\n title=\"Remove from session\"\n ?disabled=${this.busy}\n @click=${() => this.removeSessionAttachment(file.id)}\n >\n <wa-icon name=\"xmark\" label=\"Remove\"></wa-icon>\n </wa-button>\n </div>\n `,\n )}\n </div>\n `\n : html`<div class=\"attach-empty\">No attachments in this session</div>`}\n <wa-button\n size=\"s\"\n appearance=\"outlined\"\n ?disabled=${this.busy || count >= MAX_ATTACHMENTS}\n @click=${() => this.openFilePicker()}\n >\n <wa-icon slot=\"start\" name=\"plus\"></wa-icon>\n Add files…\n </wa-button>\n </div>\n </wa-dropdown>\n `;\n }\n\n private renderAttachmentDialog() {\n const preview = this.previewAttachment();\n if (!preview) return nothing;\n return html`\n <wa-dialog\n label=${preview.name}\n open\n light-dismiss\n with-footer\n style=\"--width: min(40rem, 94vw)\"\n @wa-after-hide=${() => this.closeAttachmentPreview()}\n >\n <div class=\"attach-dialog-body\">\n ${preview.kind === 'image' && preview.dataUrl\n ? html`<img class=\"attach-dialog-image\" src=${preview.dataUrl} alt=${preview.name} />`\n : nothing}\n ${preview.text\n ? html`<pre class=\"attach-dialog-text\">${preview.text}</pre>`\n : preview.kind === 'image' && preview.dataUrl\n ? nothing\n : html`<pre class=\"attach-dialog-text\"></pre>`}\n </div>\n <div slot=\"footer\">\n <wa-button\n variant=\"danger\"\n appearance=\"outlined\"\n @click=${() => this.removeSessionAttachment(preview.id)}\n >\n Remove\n </wa-button>\n <wa-button variant=\"brand\" @click=${() => this.closeAttachmentPreview()}>Close</wa-button>\n </div>\n </wa-dialog>\n `;\n }\n\n private resolvePermission(action: PermissionAction): void {\n if (!this.pendingPermission) return;\n cognitiveRuntime.resolvePermission(this.pendingPermission.requestId, action);\n this.pendingPermission = null;\n }\n\n protected renderToolbar(): TemplateResult {\n const session = this.focusedSession();\n const title = session?.title || 'Chat';\n return html`\n <span class=\"toolbar-title\" title=${title}>${title}</span>\n <wa-button size=\"s\" appearance=\"plain\" title=\"New chat\" @click=${() => this.newSession()}>\n <wa-icon name=\"plus\" label=\"New chat\"></wa-icon>\n </wa-button>\n ${this.renderHistoryDropdown()}\n <wa-button\n size=\"s\"\n appearance=\"plain\"\n title=\"Checkpoint\"\n @click=${() => {\n if (!this.focusedId) return;\n cognitiveRuntime.sessions.checkpoint(this.focusedId);\n this.syncSessions();\n cognitiveRuntime.commitSessions();\n }}\n >\n <wa-icon name=\"floppy-disk\" label=\"Checkpoint\"></wa-icon>\n </wa-button>\n ${this.renderSettingsDropdown()}\n `;\n }\n\n private contextRingStyle(level: ContextUsage['level']): string {\n const tone = level === 'critical' ? 'danger' : level === 'warn' ? 'warning' : 'success';\n // Match Web Awesome docs: quiet track + loud indicator.\n return [\n `--track-color: var(--wa-color-${tone}-fill-quiet)`,\n `--indicator-color: var(--wa-color-${tone}-fill-loud)`,\n ].join(';');\n }\n\n private renderContextDropdown() {\n const usage = this.contextUsage();\n const canCompact = (this.focusedSession()?.history.length ?? 0) > 12;\n const percentLabel = formatContextPercent(usage.percent);\n const title = `Context ${percentLabel} · ${formatTokenCount(usage.used)} / ${formatTokenCount(usage.limit)} tokens`;\n const ringValue = Math.min(100, Math.max(usage.percent, usage.used > 0 ? 1 : 0));\n\n return html`\n <wa-dropdown\n class=\"context-menu\"\n size=\"s\"\n placement=\"top-end\"\n distance=\"4\"\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"s\"\n title=${title}\n >\n <wa-progress-ring\n class=\"context-ring\"\n style=${this.contextRingStyle(usage.level)}\n value=${ringValue}\n label=${title}\n ></wa-progress-ring>\n </wa-button>\n\n <div\n class=\"context-panel\"\n @click=${(e: Event) => e.stopPropagation()}\n @keydown=${(e: Event) => e.stopPropagation()}\n >\n <div class=\"context-header\">\n <strong>Context tokens</strong>\n <span>${percentLabel}</span>\n </div>\n <div class=\"context-bars\">\n ${usage.buckets.map((bucket) => {\n const share = usage.limit > 0 ? (bucket.tokens / usage.limit) * 100 : 0;\n return html`\n <div class=\"context-row\">\n <span class=\"context-row-label\">${bucket.label}</span>\n <span>${formatBucketDetail(bucket)}</span>\n <div class=\"context-meter\">\n <span\n style=\"width:${Math.max(share, bucket.tokens > 0 ? 0.5 : 0)}%; --bucket-color: var(--wa-color-brand-fill-normal)\"\n ></span>\n </div>\n </div>\n `;\n })}\n </div>\n <div class=\"context-footer\">\n <span class=\"context-remaining\">\n ~${formatTokenCount(usage.used)} used · ${formatTokenCount(usage.remaining)} free of\n ${formatTokenCount(usage.limit)}\n · ${shortModelLabel(usage.modelRef)}\n </span>\n <wa-button\n size=\"s\"\n variant=${usage.level === 'critical' ? 'danger' : 'neutral'}\n appearance=${canCompact ? 'filled' : 'outlined'}\n ?disabled=${!canCompact || this.busy}\n @click=${() => this.compactFocused()}\n >\n <wa-icon slot=\"start\" name=\"arrows-down-to-line\"></wa-icon>\n Compact conversation\n </wa-button>\n </div>\n </div>\n </wa-dropdown>\n `;\n }\n\n protected renderContent() {\n const session = this.focusedSession();\n return html`\n <div class=\"cognitive-shell\">\n <wa-scroller class=\"transcript\" orientation=\"vertical\">\n <div class=\"transcript-inner\">\n <div class=\"transcript-spacer\" aria-hidden=\"true\"></div>\n ${session ? this.renderTranscript(session) : nothing}\n </div>\n </wa-scroller>\n\n <div\n class=\"composer-shell ${this.dragOver ? 'drag-over' : ''}\"\n @dragover=${(e: DragEvent) => this.onComposerDragOver(e)}\n @dragleave=${(e: DragEvent) => this.onComposerDragLeave(e)}\n @drop=${(e: DragEvent) => void this.onComposerDrop(e)}\n >\n <input\n id=\"attach-file-input\"\n type=\"file\"\n multiple\n accept=${ATTACHMENT_FILE_ACCEPT}\n hidden\n @change=${(e: Event) => void this.onFileInputChange(e)}\n />\n <div class=\"composer\">\n <div class=\"composer-row\">\n <wa-textarea\n placeholder=\"Enter your message here...\"\n size=\"s\"\n resize=\"auto\"\n rows=\"1\"\n .value=${this.draft}\n ?disabled=${this.busy}\n @input=${(e: Event) => {\n this.draft = (e.target as HTMLTextAreaElement).value;\n }}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n void this.send();\n }\n }}\n ></wa-textarea>\n <div class=\"composer-actions\">\n ${this.renderAttachmentDropdown()}\n ${this.renderContextDropdown()}\n </div>\n </div>\n </div>\n </div>\n ${this.renderAttachmentDialog()}\n </div>\n `;\n }\n\n private renderTranscript(session: CognitiveSession) {\n const showStreaming = this.streamingParts.length > 0;\n const showPermission =\n this.pendingPermission && this.pendingPermission.sessionId === session.id;\n\n return html`\n ${session.history.map((m) => this.renderMessage(m))}\n ${showStreaming\n ? this.renderAssistantMessage(\n {\n id: 'streaming',\n role: 'assistant',\n parts: this.streamingParts,\n createdAt: Date.now(),\n },\n { streaming: true },\n )\n : nothing}\n ${showPermission\n ? html`\n <wa-callout variant=\"warning\" appearance=\"outlined\">\n <wa-icon slot=\"icon\" name=\"shield-halved\"></wa-icon>\n Allow tool <code>${this.pendingPermission!.toolName}</code>?\n <pre class=\"args\">${JSON.stringify(this.pendingPermission!.args, null, 2)}</pre>\n <div class=\"approval-actions\">\n <wa-button size=\"s\" variant=\"success\" @click=${() => this.resolvePermission('allow')}>\n <wa-icon slot=\"start\" name=\"check\"></wa-icon>\n Allow\n </wa-button>\n <wa-button\n size=\"s\"\n variant=\"neutral\"\n appearance=\"outlined\"\n @click=${() => this.resolvePermission('deny')}\n >\n <wa-icon slot=\"start\" name=\"xmark\"></wa-icon>\n Deny\n </wa-button>\n </div>\n </wa-callout>\n `\n : nothing}\n `;\n }\n\n private renderHistoryDropdown() {\n const items = this.historySessions();\n const groups = groupSessionsByRecency(items);\n\n return html`\n <wa-dropdown\n class=\"history-menu\"\n size=\"s\"\n placement=\"bottom-end\"\n distance=\"4\"\n ?open=${this.historyOpen}\n @wa-after-show=${() => {\n this.historyOpen = true;\n }}\n @wa-after-hide=${() => {\n this.historyOpen = false;\n this.historyQuery = '';\n }}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"s\"\n with-caret\n title=\"Chat history\"\n @click=${(e: Event) => {\n e.stopPropagation();\n this.historyOpen = !this.historyOpen;\n }}\n >\n <wa-icon name=\"clock-rotate-left\" label=\"Chat history\"></wa-icon>\n </wa-button>\n\n <div\n class=\"history-search\"\n @click=${(e: Event) => e.stopPropagation()}\n @keydown=${(e: Event) => e.stopPropagation()}\n >\n <wa-input\n size=\"s\"\n clearable\n placeholder=\"Search chats…\"\n .value=${this.historyQuery}\n @input=${(e: Event) => {\n this.historyQuery = (e.target as HTMLInputElement).value;\n }}\n >\n <wa-icon slot=\"start\" name=\"magnifying-glass\"></wa-icon>\n </wa-input>\n </div>\n\n ${groups.length\n ? groups.map(\n (group) => html`\n <h3>${group.label}</h3>\n ${group.sessions.map(\n (s) => html`\n <wa-dropdown-item @click=${() => this.openSession(s.id)}>\n <wa-icon\n slot=\"icon\"\n name=${s.id === this.focusedId ? 'check' : 'message'}\n ></wa-icon>\n <span class=\"history-item-title\" title=${s.title}>${s.title}</span>\n <div slot=\"details\" style=\"display:flex;align-items:center;gap:0.25rem\">\n <span class=\"history-item-meta\">${relativeTime(s.updatedAt)}</span>\n <wa-button\n appearance=\"plain\"\n size=\"s\"\n title=\"Delete chat\"\n @click=${(e: Event) => {\n e.stopPropagation();\n this.deleteSession(s.id);\n }}\n >\n <wa-icon name=\"trash\" label=\"Delete chat\"></wa-icon>\n </wa-button>\n </div>\n </wa-dropdown-item>\n `,\n )}\n `,\n )\n : html`<div class=\"history-empty\">${this.historyQuery ? 'No matching chats' : 'No chats yet'}</div>`}\n </wa-dropdown>\n `;\n }\n\n private onSettingsSelect(value: string): void {\n if (value === 'settings') {\n void this.executeCommand(OPEN_AI_SETTINGS_COMMAND, {});\n return;\n }\n if (value.startsWith('approval:')) {\n const mode = value.slice('approval:'.length);\n if (mode === 'manual' || mode === 'auto_safe' || mode === 'auto_all') {\n this.approvalMode = mode;\n cognitiveRuntime.setApprovalMode(mode);\n }\n return;\n }\n if (value.startsWith('effort:')) {\n this.manualEffort = (value.slice(7) as EffortLevel | 'auto') || 'auto';\n return;\n }\n this.onRouterSelect(value);\n }\n\n private renderSettingsDropdown() {\n const selected = this.routerValue();\n const autoOptions = [\n { value: 'auto:cost', label: 'Auto · Cost' },\n { value: 'auto:balance', label: 'Auto · Balance' },\n { value: 'auto:intelligence', label: 'Auto · Intelligence' },\n ];\n const effortOptions = this.effortChoices();\n\n return html`\n <wa-dropdown\n class=\"settings-menu\"\n size=\"s\"\n placement=\"bottom-end\"\n distance=\"4\"\n @wa-select=${(e: CustomEvent<{ item?: { value?: string } }>) => {\n const value = e.detail?.item?.value;\n if (value != null) this.onSettingsSelect(value);\n }}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"s\"\n with-caret\n title=${`AI · ${this.routerLabel()}`}\n >\n <wa-icon name=\"gear\" label=\"AI settings\"></wa-icon>\n </wa-button>\n\n <h3>Auto</h3>\n ${autoOptions.map(\n (option) => html`\n <wa-dropdown-item\n value=${option.value}\n type=\"checkbox\"\n ?checked=${option.value === selected}\n >\n ${option.label}\n </wa-dropdown-item>\n `,\n )}\n\n <wa-divider></wa-divider>\n <h3>Models</h3>\n ${this.modelIds.length\n ? this.modelIds.map(\n (id) => html`\n <wa-dropdown-item\n value=${`model:${id}`}\n type=\"checkbox\"\n ?checked=${selected === `model:${id}`}\n >\n ${id}\n </wa-dropdown-item>\n `,\n )\n : html`<wa-dropdown-item disabled>No models configured</wa-dropdown-item>`}\n\n ${this.policyMode === 'manual'\n ? html`\n <wa-divider></wa-divider>\n <h3>Effort</h3>\n ${effortOptions.map(\n (level) => html`\n <wa-dropdown-item\n value=${`effort:${level}`}\n type=\"checkbox\"\n ?checked=${this.manualEffort === level}\n >\n ${level}\n </wa-dropdown-item>\n `,\n )}\n `\n : nothing}\n\n <wa-divider></wa-divider>\n <h3>Tool approvals</h3>\n ${APPROVAL_OPTIONS.map(\n (option) => html`\n <wa-dropdown-item\n value=${`approval:${option.value}`}\n type=\"checkbox\"\n ?checked=${this.approvalMode === option.value}\n >\n ${option.label}\n </wa-dropdown-item>\n `,\n )}\n\n <wa-divider></wa-divider>\n <wa-dropdown-item value=\"settings\">\n <wa-icon slot=\"icon\" name=\"sliders\"></wa-icon>\n Settings…\n </wa-dropdown-item>\n </wa-dropdown>\n `;\n }\n\n private resolveAttachmentDataUrl(fileId: string): string | undefined {\n return this.focusedSession()?.attachments?.find((a) => a.id === fileId)?.dataUrl;\n }\n\n private renderMessage(message: ChatMessage) {\n if (message.role === 'user') {\n const files = message.parts.filter((p): p is Extract<MessagePart, { type: 'file' }> => p.type === 'file');\n const texts = message.parts.filter((p) => p.type === 'text');\n return html`\n <div class=\"msg user\">\n ${files.length\n ? html`\n <div class=\"msg-files\">\n ${files.map((file) => {\n const dataUrl =\n file.kind === 'image' ? this.resolveAttachmentDataUrl(file.id) : undefined;\n return dataUrl\n ? html`<img\n class=\"msg-file-thumb\"\n src=${dataUrl}\n alt=${file.name}\n title=${`${file.name} (${file.id})`}\n />`\n : html`\n <wa-tag\n size=\"s\"\n appearance=\"outlined\"\n title=${`${file.path || file.name} (${file.id})`}\n >\n <wa-icon slot=\"start\" name=${file.kind === 'image' ? 'image' : 'file'}></wa-icon>\n ${file.name}\n </wa-tag>\n `;\n })}\n </div>\n `\n : nothing}\n ${texts.map((p) => this.renderTextPart(p))}\n ${this.renderMessageMeta(message)}\n </div>\n `;\n }\n return this.renderAssistantMessage(message);\n }\n\n private renderAssistantMessage(message: ChatMessage, opts: { streaming?: boolean } = {}) {\n const textParts = message.parts.filter((p) => p.type === 'text');\n const techParts = message.parts.filter((p) => p.type !== 'text');\n const open =\n opts.streaming === true ||\n techParts.some((p) => (p.type === 'reasoning' || p.type === 'tool') && p.status === 'streaming');\n\n const summary = html`\n <div slot=\"summary\" class=\"msg-summary\">\n ${opts.streaming\n ? html`\n <div class=\"streaming-meta\">\n <wa-spinner style=\"font-size: 0.85rem\"></wa-spinner>\n <span>streaming…</span>\n </div>\n `\n : nothing}\n ${textParts.length\n ? textParts.map((p) => this.renderTextPart(p))\n : html`<div class=\"bubble\">${technicalSummary(techParts)}</div>`}\n </div>\n `;\n\n if (!techParts.length) {\n return html`\n <div class=\"msg assistant\">\n ${opts.streaming\n ? html`\n <div class=\"streaming-meta\">\n <wa-spinner style=\"font-size: 0.85rem\"></wa-spinner>\n <span>streaming…</span>\n </div>\n `\n : nothing}\n ${textParts.map((p) => this.renderTextPart(p))}\n ${message.id !== 'streaming' ? this.renderMessageMeta(message) : nothing}\n </div>\n `;\n }\n\n return html`\n <div class=\"msg assistant\">\n <wa-details class=\"msg-details\" appearance=\"plain\" ?open=${open}>\n ${summary}\n <div class=\"msg-tech\">${techParts.map((p) => this.renderTechnicalPart(p))}</div>\n </wa-details>\n ${message.id !== 'streaming' ? this.renderMessageMeta(message) : nothing}\n </div>\n `;\n }\n\n private renderMessageMeta(message: ChatMessage) {\n const timeLabel = formatMessageTime(message.createdAt);\n return html`\n <div class=\"msg-meta\">\n <wa-tag size=\"s\" appearance=\"outlined\" title=${new Date(message.createdAt).toLocaleString()}>\n ${timeLabel}\n </wa-tag>\n ${message.routedModel\n ? html`<wa-tag size=\"s\" appearance=\"outlined\">${message.routedModel}</wa-tag>`\n : nothing}\n ${message.effort\n ? html`<wa-tag size=\"s\" appearance=\"outlined\">${message.effort}</wa-tag>`\n : nothing}\n </div>\n `;\n }\n\n private renderTextPart(part: MessagePart) {\n if (part.type === 'text') return html`<div class=\"bubble\">${part.text}</div>`;\n return nothing;\n }\n\n private renderTechnicalPart(part: MessagePart) {\n if (part.type === 'reasoning') {\n return html`\n <div>\n <div class=\"tool-heading\">Thinking</div>\n <div class=\"bubble\">${part.text}</div>\n </div>\n `;\n }\n if (part.type === 'tool') {\n const heading = `${part.name} · ${part.status}${part.durationMs != null ? ` · ${part.durationMs}ms` : ''}`;\n return html`\n <div>\n <div class=\"tool-heading\">${heading}</div>\n <pre class=\"args\">${JSON.stringify({ args: part.args, result: part.result }, null, 2)}</pre>\n </div>\n `;\n }\n if (part.type === 'step') {\n return html`<div class=\"tool-heading\">Step: ${part.title} · ${part.status}</div>`;\n }\n return nothing;\n }\n}\n\nconst APPROVAL_OPTIONS: Array<{ value: ToolApprovalMode; label: string }> = [\n { value: 'manual', label: 'Manual' },\n { value: 'auto_safe', label: 'Auto-approve non-critical' },\n { value: 'auto_all', label: 'Approve all' },\n];\n\nfunction capitalize(value: string): string {\n return value ? value[0]!.toUpperCase() + value.slice(1) : value;\n}\n\nfunction technicalSummary(parts: MessagePart[]): string {\n const tools = parts.filter((p): p is Extract<MessagePart, { type: 'tool' }> => p.type === 'tool');\n const reasoning = parts.some((p) => p.type === 'reasoning');\n const steps = parts.filter((p): p is Extract<MessagePart, { type: 'step' }> => p.type === 'step');\n\n const bits: string[] = [];\n if (tools.length) {\n bits.push(\n tools\n .map((t) => `${t.name} · ${t.status}${t.durationMs != null ? ` · ${t.durationMs}ms` : ''}`)\n .join(', '),\n );\n }\n if (reasoning) bits.push('Thinking');\n if (steps.length) bits.push(`${steps.length} step${steps.length === 1 ? '' : 's'}`);\n return bits.join(' · ') || 'Details';\n}\n\nfunction startOfDay(ts: number): number {\n const d = new Date(ts);\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n}\n\nfunction groupSessionsByRecency(sessions: CognitiveSession[]): Array<{ label: string; sessions: CognitiveSession[] }> {\n const now = Date.now();\n const today = startOfDay(now);\n const yesterday = today - 86_400_000;\n const week = today - 7 * 86_400_000;\n const buckets: Record<'today' | 'yesterday' | 'week' | 'older', CognitiveSession[]> = {\n today: [],\n yesterday: [],\n week: [],\n older: [],\n };\n\n for (const s of sessions) {\n const day = startOfDay(s.updatedAt);\n if (day >= today) buckets.today.push(s);\n else if (day >= yesterday) buckets.yesterday.push(s);\n else if (day >= week) buckets.week.push(s);\n else buckets.older.push(s);\n }\n\n return (\n [\n { label: 'Today', sessions: buckets.today },\n { label: 'Yesterday', sessions: buckets.yesterday },\n { label: 'Previous 7 Days', sessions: buckets.week },\n { label: 'Older', sessions: buckets.older },\n ] as const\n ).filter((g) => g.sessions.length > 0);\n}\n\nfunction relativeTime(ts: number): string {\n const delta = Math.max(0, Date.now() - ts);\n const mins = Math.floor(delta / 60_000);\n if (mins < 1) return 'now';\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h`;\n const days = Math.floor(hours / 24);\n if (days < 7) return `${days}d`;\n return new Date(ts).toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n}\n\nfunction formatMessageTime(ts: number): string {\n const date = new Date(ts);\n const now = new Date();\n const sameDay =\n date.getFullYear() === now.getFullYear() &&\n date.getMonth() === now.getMonth() &&\n date.getDate() === now.getDate();\n const time = date.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n if (sameDay) return time;\n return `${date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })} ${time}`;\n}\n\nfunction shortModelLabel(modelRef: string): string {\n const slash = modelRef.indexOf('/');\n return slash === -1 ? modelRef : modelRef.slice(slash + 1);\n}\n\nfunction mergePart(parts: MessagePart[], part: MessagePart): MessagePart[] {\n const next = [...parts];\n const last = next[next.length - 1];\n if (part.type === 'text' && last?.type === 'text') {\n next[next.length - 1] = { ...last, text: last.text + part.text };\n return next;\n }\n if (part.type === 'reasoning' && last?.type === 'reasoning') {\n next[next.length - 1] = { ...last, text: last.text + part.text, status: part.status };\n return next;\n }\n if (part.type === 'tool' && last?.type === 'tool' && last.id === part.id) {\n next[next.length - 1] = part;\n return next;\n }\n next.push(part);\n return next;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-cognitive-view': DocksCognitiveView;\n }\n}\n","import '@eclipse-docks/core/externals/webawesome';\nimport {\n DocksPart,\n EditorInput,\n confirmDialog,\n toastError,\n toastInfo,\n} from '@eclipse-docks/core';\nimport { css, customElement, html, property, state } from '@eclipse-docks/core/externals/lit';\nimport {\n cognitiveRuntime,\n TOPIC,\n defaultProvidersSettings,\n fetchOpenAICompatibleModels,\n parseModelIds,\n} from '../runtime';\nimport type { ProviderConfig, ProvidersSettings, RemoteModelInfo, ToolApprovalMode } from '../runtime';\n\nconst APPROVAL_OPTIONS: Array<{ value: ToolApprovalMode; label: string; hint: string }> = [\n { value: 'manual', label: 'Manual', hint: 'Confirm every tool before it runs' },\n {\n value: 'auto_safe',\n label: 'Auto-approve non-critical',\n hint: 'The agent classifies each tool as safe or critical; only critical ones ask for approval',\n },\n { value: 'auto_all', label: 'Approve all', hint: 'Run every tool without asking' },\n];\n\n@customElement('docks-cognitive-settings-editor')\nexport class DocksCognitiveSettingsEditor extends DocksPart {\n @property({ attribute: false }) public input?: EditorInput;\n\n @state() private settings: ProvidersSettings = defaultProvidersSettings();\n @state() private approvalMode: ToolApprovalMode = 'auto_safe';\n @state() private availableModels: Record<number, RemoteModelInfo[]> = {};\n @state() private loadingModels: Record<number, boolean> = {};\n @state() private modelErrors: Record<number, string> = {};\n\n private unsubs: Array<() => void> = [];\n private fetchControllers = new Map<number, AbortController>();\n private fetchTimers = new Map<number, ReturnType<typeof setTimeout>>();\n private autoFetchedKeys = new Set<string>();\n\n protected doInitUI(): void {\n cognitiveRuntime.start();\n this.loadFromRuntime();\n this.unsubs.push(\n cognitiveRuntime.events.subscribe(TOPIC.providersChanged, () => {\n if (!this.isDirty()) this.loadFromRuntime();\n }),\n cognitiveRuntime.events.subscribe(TOPIC.approvalModeChanged, (mode) => {\n this.approvalMode = mode as ToolApprovalMode;\n }),\n );\n }\n\n disconnectedCallback(): void {\n for (const unsub of this.unsubs) unsub();\n this.unsubs = [];\n for (const timer of this.fetchTimers.values()) clearTimeout(timer);\n this.fetchTimers.clear();\n for (const controller of this.fetchControllers.values()) controller.abort();\n this.fetchControllers.clear();\n super.disconnectedCallback();\n }\n\n private loadFromRuntime(): void {\n this.settings = cognitiveRuntime.getProvidersSettings();\n this.approvalMode = cognitiveRuntime.getApprovalMode();\n this.availableModels = {};\n this.loadingModels = {};\n this.modelErrors = {};\n this.autoFetchedKeys.clear();\n this.markDirty(false);\n this.settings.providers.forEach((provider, index) => {\n if (provider.apiKey.trim() && provider.baseUrl.trim()) {\n void this.fetchModels(index, { auto: true });\n }\n });\n }\n\n private setApprovalMode(mode: ToolApprovalMode): void {\n this.approvalMode = mode;\n cognitiveRuntime.setApprovalMode(mode);\n }\n\n private touch(next: ProvidersSettings): void {\n this.settings = next;\n this.markDirty(true);\n }\n\n private updateProvider(index: number, patch: Partial<ProviderConfig>): void {\n const prev = this.settings.providers[index];\n const providers = this.settings.providers.map((p, i) => (i === index ? { ...p, ...patch } : p));\n let defaultProviderId = this.settings.defaultProviderId;\n if (patch.id && prev?.id === defaultProviderId) {\n defaultProviderId = patch.id;\n }\n this.touch({ ...this.settings, defaultProviderId, providers });\n\n if (patch.apiKey !== undefined || patch.baseUrl !== undefined) {\n const next = providers[index];\n if (next?.apiKey.trim() && next.baseUrl.trim()) {\n this.scheduleFetchModels(index);\n } else if (!next?.apiKey.trim()) {\n this.clearModels(index);\n }\n }\n }\n\n private clearModels(index: number): void {\n this.fetchTimers.get(index) && clearTimeout(this.fetchTimers.get(index)!);\n this.fetchTimers.delete(index);\n this.fetchControllers.get(index)?.abort();\n this.fetchControllers.delete(index);\n const { [index]: _a, ...available } = this.availableModels;\n const { [index]: _b, ...loading } = this.loadingModels;\n const { [index]: _c, ...errors } = this.modelErrors;\n this.availableModels = available;\n this.loadingModels = loading;\n this.modelErrors = errors;\n }\n\n private scheduleFetchModels(index: number): void {\n const existing = this.fetchTimers.get(index);\n if (existing) clearTimeout(existing);\n this.fetchTimers.set(\n index,\n setTimeout(() => {\n this.fetchTimers.delete(index);\n void this.fetchModels(index, { auto: true });\n }, 400),\n );\n }\n\n private async fetchModels(index: number, opts: { auto?: boolean } = {}): Promise<void> {\n const provider = this.settings.providers[index];\n if (!provider?.baseUrl.trim()) {\n toastError('Set a base URL before fetching models');\n return;\n }\n if (opts.auto && !provider.apiKey.trim()) return;\n\n const fingerprint = `${provider.baseUrl}|${provider.apiKey}`;\n if (opts.auto && this.autoFetchedKeys.has(fingerprint) && this.availableModels[index]?.length) {\n return;\n }\n\n this.fetchControllers.get(index)?.abort();\n const controller = new AbortController();\n this.fetchControllers.set(index, controller);\n this.loadingModels = { ...this.loadingModels, [index]: true };\n this.modelErrors = { ...this.modelErrors, [index]: '' };\n\n try {\n const models = await fetchOpenAICompatibleModels(\n provider.baseUrl,\n provider.apiKey || undefined,\n controller.signal,\n );\n if (controller.signal.aborted) return;\n this.availableModels = { ...this.availableModels, [index]: models };\n this.autoFetchedKeys.add(fingerprint);\n if (!opts.auto) toastInfo(`Loaded ${models.length} models`);\n } catch (err) {\n if (controller.signal.aborted) return;\n const message = err instanceof Error ? err.message : String(err);\n this.modelErrors = { ...this.modelErrors, [index]: message };\n this.availableModels = { ...this.availableModels, [index]: [] };\n if (!opts.auto) toastError(message);\n } finally {\n if (this.fetchControllers.get(index) === controller) {\n this.fetchControllers.delete(index);\n this.loadingModels = { ...this.loadingModels, [index]: false };\n }\n }\n }\n\n private onModelsSelect(index: number, e: Event): void {\n const target = e.target as HTMLSelectElement & { value: string | string[] };\n const value = target.value;\n const selected = Array.isArray(value) ? value : value ? [value] : [];\n this.updateProvider(index, { models: selected.join(',') });\n }\n\n private addProvider(): void {\n const id = uniqueProviderId(this.settings.providers);\n this.touch({\n ...this.settings,\n providers: [\n ...this.settings.providers,\n { id, baseUrl: '', apiKey: '', models: '', enabled: true },\n ],\n defaultProviderId: this.settings.defaultProviderId || id,\n });\n }\n\n private async deleteProvider(index: number): Promise<void> {\n const provider = this.settings.providers[index];\n if (!provider) return;\n if (!(await confirmDialog(`Delete provider \"${provider.id || '(unnamed)'}\"?`))) return;\n this.clearModels(index);\n const providers = this.settings.providers.filter((_, i) => i !== index);\n const defaultProviderId =\n this.settings.defaultProviderId === provider.id\n ? (providers.find((p) => p.enabled)?.id ?? '')\n : this.settings.defaultProviderId;\n this.touch({ providers, defaultProviderId });\n this.reindexModelState(index);\n }\n\n /** Shift per-row model fetch state after a row is removed. */\n private reindexModelState(removed: number): void {\n const remap = <T,>(src: Record<number, T>): Record<number, T> => {\n const next: Record<number, T> = {};\n for (const [key, value] of Object.entries(src)) {\n const i = Number(key);\n if (Number.isNaN(i) || i === removed) continue;\n next[i > removed ? i - 1 : i] = value;\n }\n return next;\n };\n this.availableModels = remap(this.availableModels);\n this.loadingModels = remap(this.loadingModels);\n this.modelErrors = remap(this.modelErrors);\n }\n\n private setDefault(id: string): void {\n this.touch({ ...this.settings, defaultProviderId: id });\n }\n\n override async save(): Promise<void> {\n if (!this.isDirty()) return;\n try {\n await cognitiveRuntime.setProvidersSettings(this.settings);\n this.loadFromRuntime();\n toastInfo('AI providers saved');\n } catch (err) {\n toastError(err instanceof Error ? err.message : String(err));\n }\n }\n\n protected renderToolbar() {\n return html`\n <wa-button size=\"s\" appearance=\"plain\" title=\"Add provider\" @click=${() => this.addProvider()}>\n <wa-icon name=\"plus\" label=\"Add provider\"></wa-icon>\n </wa-button>\n <wa-button\n size=\"s\"\n variant=\"brand\"\n ?disabled=${!this.isDirty()}\n @click=${() => void this.save()}\n >\n <wa-icon slot=\"start\" name=\"floppy-disk\"></wa-icon>\n Save\n </wa-button>\n `;\n }\n\n protected renderContent() {\n const rows = this.settings.providers;\n return html`\n <div class=\"editor\">\n <section class=\"section\">\n <header class=\"header\">\n <div>\n <h2>Tool approvals</h2>\n <p class=\"hint\">How the agent handles tool confirmation — same options as GitHub Copilot.</p>\n </div>\n </header>\n <wa-radio-group\n name=\"approval-mode\"\n label=\"Approval mode\"\n orientation=\"vertical\"\n .value=${this.approvalMode}\n @change=${(e: Event) => {\n const value = (e.target as HTMLInputElement).value;\n if (value === 'manual' || value === 'auto_safe' || value === 'auto_all') {\n this.setApprovalMode(value);\n }\n }}\n >\n ${APPROVAL_OPTIONS.map(\n (option) => html`\n <wa-radio value=${option.value}>\n <span class=\"approval-option\">\n <span class=\"approval-label\">${option.label}</span>\n <span class=\"approval-hint\">${option.hint}</span>\n </span>\n </wa-radio>\n `,\n )}\n </wa-radio-group>\n </section>\n\n <section class=\"section\">\n <header class=\"header\">\n <div>\n <h2>AI Providers</h2>\n <p class=\"hint\">OpenAI-compatible endpoints. Edit cells in place, then Save.</p>\n </div>\n <wa-button size=\"s\" variant=\"brand\" appearance=\"filled\" @click=${() => this.addProvider()}>\n <wa-icon slot=\"start\" name=\"plus\"></wa-icon>\n Add provider\n </wa-button>\n </header>\n\n ${rows.length === 0\n ? html`<wa-callout variant=\"neutral\" appearance=\"outlined\">No providers configured.</wa-callout>`\n : html`\n <div class=\"table-wrap\">\n <table class=\"providers\">\n <thead>\n <tr>\n <th class=\"col-on\">On</th>\n <th class=\"col-id\">ID</th>\n <th class=\"col-url\">Base URL</th>\n <th class=\"col-key\">API Key</th>\n <th class=\"col-models\">Models</th>\n <th class=\"col-default\">Default</th>\n <th class=\"col-actions\"></th>\n </tr>\n </thead>\n <tbody>\n ${rows.map((provider, index) => this.renderRow(provider, index))}\n </tbody>\n </table>\n </div>\n `}\n\n <wa-callout variant=\"neutral\" appearance=\"plain\" size=\"s\">\n <wa-icon slot=\"icon\" name=\"circle-info\"></wa-icon>\n Enter an API key to load available models. Catalog ids become\n <code>providerId/modelId</code> for Auto routing.\n </wa-callout>\n </section>\n </div>\n `;\n }\n\n private renderRow(provider: ProviderConfig, index: number) {\n const isDefault = this.settings.defaultProviderId === provider.id;\n return html`\n <tr class=${isDefault ? 'is-default' : ''}>\n <td>\n <wa-checkbox\n ?checked=${provider.enabled}\n @change=${(e: Event) =>\n this.updateProvider(index, { enabled: (e.target as HTMLInputElement).checked })}\n ></wa-checkbox>\n </td>\n <td>\n <wa-input\n size=\"s\"\n .value=${provider.id}\n placeholder=\"openai\"\n @input=${(e: Event) => this.updateProvider(index, { id: (e.target as HTMLInputElement).value })}\n ></wa-input>\n </td>\n <td>\n <wa-input\n size=\"s\"\n .value=${provider.baseUrl}\n placeholder=\"https://api.openai.com/v1\"\n @input=${(e: Event) =>\n this.updateProvider(index, { baseUrl: (e.target as HTMLInputElement).value })}\n ></wa-input>\n </td>\n <td>\n <wa-input\n size=\"s\"\n type=\"password\"\n password-toggle\n .value=${provider.apiKey}\n placeholder=\"optional\"\n @input=${(e: Event) =>\n this.updateProvider(index, { apiKey: (e.target as HTMLInputElement).value })}\n ></wa-input>\n </td>\n <td>${this.renderModelsCell(provider, index)}</td>\n <td class=\"col-default\">\n ${isDefault\n ? html`<wa-tag size=\"s\" variant=\"brand\" pill>Default</wa-tag>`\n : html`\n <wa-button\n size=\"s\"\n appearance=\"plain\"\n ?disabled=${!provider.id}\n @click=${() => this.setDefault(provider.id)}\n >\n Set\n </wa-button>\n `}\n </td>\n <td class=\"col-actions\">\n <wa-button\n size=\"s\"\n appearance=\"plain\"\n variant=\"danger\"\n title=\"Delete\"\n @click=${() => void this.deleteProvider(index)}\n >\n <wa-icon name=\"trash\" label=\"Delete\"></wa-icon>\n </wa-button>\n </td>\n </tr>\n `;\n }\n\n private renderModelsCell(provider: ProviderConfig, index: number) {\n const hasKey = Boolean(provider.apiKey.trim());\n const remote = this.availableModels[index] ?? [];\n const loading = Boolean(this.loadingModels[index]);\n const error = this.modelErrors[index];\n const selected = parseModelIds(provider.models);\n const showPicker = hasKey || remote.length > 0;\n\n if (!showPicker) {\n return html`\n <div class=\"models-cell\">\n <wa-input\n size=\"s\"\n .value=${provider.models}\n placeholder=\"gpt-4o-mini,gpt-4o\"\n @input=${(e: Event) =>\n this.updateProvider(index, { models: (e.target as HTMLInputElement).value })}\n ></wa-input>\n <wa-button\n size=\"s\"\n appearance=\"plain\"\n title=\"Fetch models\"\n ?disabled=${!provider.baseUrl.trim() || loading}\n ?loading=${loading}\n @click=${() => void this.fetchModels(index)}\n >\n <wa-icon name=\"arrows-rotate\" label=\"Reload models\"></wa-icon>\n </wa-button>\n </div>\n `;\n }\n\n return html`\n <div class=\"models-cell\">\n <wa-select\n size=\"s\"\n multiple\n with-clear\n placeholder=${loading ? 'Loading models…' : 'Select models'}\n .value=${selected}\n ?disabled=${loading && remote.length === 0}\n @change=${(e: Event) => this.onModelsSelect(index, e)}\n >\n ${remote.map(\n (m) => html`<wa-option value=${m.id}>${m.name === m.id ? m.id : `${m.name} (${m.id})`}</wa-option>`,\n )}\n ${selected\n .filter((id) => !remote.some((m) => m.id === id))\n .map((id) => html`<wa-option value=${id}>${id}</wa-option>`)}\n </wa-select>\n <wa-button\n size=\"s\"\n appearance=\"plain\"\n title=\"Reload models\"\n ?disabled=${!provider.baseUrl.trim() || loading}\n ?loading=${loading}\n @click=${() => void this.fetchModels(index)}\n >\n <wa-icon name=\"arrows-rotate\" label=\"Reload models\"></wa-icon>\n </wa-button>\n </div>\n ${error ? html`<div class=\"models-error\">${error}</div>` : ''}\n `;\n }\n\n static styles = css`\n :host {\n display: block;\n height: 100%;\n }\n\n .editor {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-2xl);\n padding: var(--wa-space-l);\n min-width: 0;\n }\n\n .section {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-l);\n min-width: 0;\n }\n\n .header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: var(--wa-space-m);\n flex-wrap: wrap;\n }\n\n .header h2 {\n margin: 0;\n font-size: var(--wa-font-size-l);\n }\n\n wa-radio-group {\n max-width: 36rem;\n }\n\n .approval-option {\n display: flex;\n flex-direction: column;\n gap: var(--wa-space-3xs);\n padding-block: var(--wa-space-3xs);\n }\n\n .approval-label {\n font-weight: 500;\n }\n\n .approval-hint {\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-s);\n }\n\n .hint {\n margin: var(--wa-space-2xs) 0 0;\n color: var(--wa-color-text-quiet);\n font-size: var(--wa-font-size-s);\n }\n\n .table-wrap {\n overflow: auto;\n border: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n border-radius: var(--wa-border-radius-m);\n }\n\n table.providers {\n width: 100%;\n border-collapse: collapse;\n min-width: 56rem;\n }\n\n th,\n td {\n padding: var(--wa-space-2xs) var(--wa-space-s);\n border-bottom: var(--wa-border-width-s) solid var(--wa-color-border-normal);\n text-align: left;\n vertical-align: middle;\n }\n\n th {\n font-size: var(--wa-font-size-xs);\n font-weight: 600;\n color: var(--wa-color-text-quiet);\n background: var(--wa-color-surface-lowered);\n white-space: nowrap;\n }\n\n tr.is-default td {\n background: color-mix(in srgb, var(--wa-color-brand-fill-normal) 8%, transparent);\n }\n\n tbody tr:last-child td {\n border-bottom: none;\n }\n\n .col-on {\n width: 2.5rem;\n }\n\n .col-id {\n width: 8rem;\n }\n\n .col-key {\n width: 11rem;\n }\n\n .col-models {\n min-width: 16rem;\n }\n\n .col-default {\n width: 5.5rem;\n white-space: nowrap;\n }\n\n .col-actions {\n width: 2.75rem;\n text-align: end;\n }\n\n td wa-input {\n width: 100%;\n }\n\n .models-cell {\n display: flex;\n gap: var(--wa-space-2xs);\n align-items: flex-start;\n min-width: 14rem;\n }\n\n .models-cell wa-input,\n .models-cell wa-select {\n flex: 1;\n min-width: 0;\n }\n\n .models-error {\n margin-top: var(--wa-space-3xs);\n color: var(--wa-color-danger-on-quiet);\n font-size: var(--wa-font-size-xs);\n }\n\n code {\n font-family: var(--wa-font-family-code, var(--wa-font-mono));\n font-size: 0.9em;\n }\n `;\n}\n\nfunction uniqueProviderId(existing: ProviderConfig[]): string {\n const used = new Set(existing.map((p) => p.id));\n if (!used.has('provider')) return 'provider';\n let n = 2;\n while (used.has(`provider-${n}`)) n += 1;\n return `provider-${n}`;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-cognitive-settings-editor': DocksCognitiveSettingsEditor;\n }\n}\n","import {\n contributionRegistry,\n editorRegistry,\n registerAll,\n rootContext,\n SIDEBAR_AUXILIARY,\n type EditorInput,\n} from '@eclipse-docks/core';\nimport { html } from '@eclipse-docks/core/externals/lit';\nimport {\n AI_SETTINGS_EDITOR_ID,\n AI_SETTINGS_KEY,\n AI_VIEW_NAME,\n OPEN_AI_SETTINGS_COMMAND,\n cognitiveRuntime,\n} from './runtime';\nimport './view/cognitive-view';\nimport './view/cognitive-settings-editor';\n\ncognitiveRuntime.start();\nrootContext.put('cognitiveRuntime', cognitiveRuntime);\n\ncontributionRegistry.registerContribution(SIDEBAR_AUXILIARY, {\n name: AI_VIEW_NAME,\n label: 'AI',\n icon: 'robot',\n editorId: AI_VIEW_NAME,\n component: (id: string) => html`<docks-cognitive-view id=\"${id}\"></docks-cognitive-view>`,\n});\n\neditorRegistry.registerEditorInputHandler({\n editorId: AI_SETTINGS_EDITOR_ID,\n label: 'AI Settings',\n ranking: 1000,\n canHandle: (input: EditorInput) => input.key === AI_SETTINGS_KEY,\n handle: async (input: EditorInput) => {\n input.component = (id: string) =>\n html`<docks-cognitive-settings-editor id=\"${id}\" .input=${input}></docks-cognitive-settings-editor>`;\n return input;\n },\n});\n\nregisterAll({\n command: {\n id: OPEN_AI_SETTINGS_COMMAND,\n name: 'Open AI Settings',\n description: 'Configure AI model providers',\n parameters: [],\n },\n handler: {\n execute: () => {\n const editorInput = {\n title: 'AI Settings',\n data: {},\n key: AI_SETTINGS_KEY,\n icon: 'gear',\n state: {},\n } as EditorInput;\n void editorRegistry.loadEditor(editorInput);\n },\n },\n});\n"],"mappings":"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"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { SessionAttachment } from '../types';
|
|
2
|
-
import { ToolBroker } from './broker';
|
|
3
|
-
export type AttachmentLookup = (sessionId: string, attachmentId?: string) => SessionAttachment[];
|
|
4
|
-
/** Registers read-only session attachment tools. */
|
|
5
|
-
export declare function registerAttachmentTools(broker: ToolBroker, lookup: AttachmentLookup): void;
|
|
6
|
-
//# sourceMappingURL=attachment-adapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attachment-adapter.d.ts","sourceRoot":"","sources":["../../../src/runtime/tools/attachment-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAMlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,iBAAiB,EAAE,CAAC;AAEjG,oDAAoD;AACpD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA6D1F"}
|