@eclipse-docks/extension-ai-system 0.8.1 → 0.8.3
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/api.d.ts +1 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +87 -2
- package/dist/api.js.map +1 -0
- package/dist/{cognitive-extension-7_ZMUCGD.js → cognitive-extension-CvP05Bw_.js} +241 -36
- package/dist/cognitive-extension-CvP05Bw_.js.map +1 -0
- package/dist/cognitive-extension.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime/cognitive-runtime.d.ts +5 -0
- package/dist/runtime/cognitive-runtime.d.ts.map +1 -1
- package/dist/runtime/context/usage.d.ts +3 -0
- package/dist/runtime/context/usage.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/models/types.d.ts +6 -1
- package/dist/runtime/models/types.d.ts.map +1 -1
- package/dist/runtime/skills-commands.d.ts +3 -0
- package/dist/runtime/skills-commands.d.ts.map +1 -0
- package/dist/runtime/skills-parse.d.ts +14 -0
- package/dist/runtime/skills-parse.d.ts.map +1 -0
- package/dist/runtime/skills-resolve.d.ts +9 -0
- package/dist/runtime/skills-resolve.d.ts.map +1 -0
- package/dist/runtime/skills-select.d.ts +9 -0
- package/dist/runtime/skills-select.d.ts.map +1 -0
- package/dist/runtime/skills-types.d.ts +47 -0
- package/dist/runtime/skills-types.d.ts.map +1 -0
- package/dist/runtime/skills.d.ts +13 -0
- package/dist/runtime/skills.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/fetch-adapter.d.ts +4 -0
- package/dist/runtime/tools/fetch-adapter.d.ts.map +1 -0
- package/dist/runtime/tools/index.d.ts +1 -0
- package/dist/runtime/tools/index.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +7 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/{runtime-By5PP2BC.js → runtime-DVzLyx8h.js} +345 -16
- package/dist/runtime-DVzLyx8h.js.map +1 -0
- package/dist/view/cognitive-view.d.ts +5 -0
- package/dist/view/cognitive-view.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/cognitive-extension-7_ZMUCGD.js.map +0 -1
- package/dist/runtime-By5PP2BC.js.map +0 -1
package/dist/api.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { cognitiveRuntime, CognitiveRuntime, TOPIC, AI_VIEW_NAME, AI_SETTINGS_KEY, AI_SETTINGS_EDITOR_ID, OPEN_AI_SETTINGS_COMMAND, defaultProvidersSettings, fetchOpenAICompatibleModels, listConfiguredModelIds, loadModelsCatalog, parseModelIds, OpenAICompatibleProvider, type ChatMessage, type MessagePart, type PromptAttachment, type SessionAttachment, type CognitiveSession, type Checkpoint, type ModelPolicy, type EffortLevel, type OptimizeFor, type SpecialistRole, type PermissionAction, type ToolApprovalMode, type EmotionalState, type ProviderConfig, type ProvidersSettings, type RemoteModelInfo, type ModelProvider, type StreamParams, type StreamChunk, type ProviderChatMessage, type SystemPromptEnhancer, } from './runtime';
|
|
1
|
+
export { cognitiveRuntime, CognitiveRuntime, TOPIC, AI_VIEW_NAME, AI_SETTINGS_KEY, AI_SETTINGS_EDITOR_ID, OPEN_AI_SETTINGS_COMMAND, defaultProvidersSettings, fetchOpenAICompatibleModels, listConfiguredModelIds, loadModelsCatalog, parseModelIds, OpenAICompatibleProvider, type ChatMessage, type MessagePart, type PromptAttachment, type SessionAttachment, type CognitiveSession, type Checkpoint, type ModelPolicy, type EffortLevel, type OptimizeFor, type SpecialistRole, type PermissionAction, type ToolApprovalMode, type TokenUsage, type EmotionalState, type ProviderConfig, type ProvidersSettings, type RemoteModelInfo, type ModelProvider, type StreamParams, type StreamChunk, type ProviderChatMessage, type SystemPromptEnhancer, type AgentSkill, type ResolvedSkill, type SkillContribution, type SkillLoadResult, type SkillRelevanceContext, SYSTEM_SKILLS, parseSkillMarkdown, formatSkillForPrompt, formatSkillsPromptSection, registerSkillMarkdown, registerSkillCommands, listSkillContributions, resolveSkill, resolveSkillBody, selectRelevantSkills, isSkillContribution, } from './runtime';
|
|
2
2
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,sBAAsB,EACtB,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,sBAAsB,EACtB,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,WAAW,CAAC"}
|
package/dist/api.js
CHANGED
|
@@ -1,2 +1,87 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { D as AI_VIEW_NAME, E as AI_SETTINGS_KEY, O as OPEN_AI_SETTINGS_COMMAND, S as parseModelIds, T as AI_SETTINGS_EDITOR_ID, a as listSkillContributions, b as defaultProvidersSettings, c as resolveSkillBody, d as parseSkillMarkdown, i as SYSTEM_SKILLS, k as TOPIC, l as isSkillContribution, n as CognitiveRuntime, o as registerSkillMarkdown, r as cognitiveRuntime, s as resolveSkill, t as registerSkillCommands, u as formatSkillForPrompt, v as OpenAICompatibleProvider, w as loadModelsCatalog, x as listConfiguredModelIds, y as fetchOpenAICompatibleModels } from "./runtime-DVzLyx8h.js";
|
|
2
|
+
//#region src/runtime/skills-select.ts
|
|
3
|
+
/**
|
|
4
|
+
* Catalog-only prompt section. The model loads full skill bodies via skills.load.
|
|
5
|
+
*/
|
|
6
|
+
function formatSkillsPromptSection(skills) {
|
|
7
|
+
if (!skills.length) return "";
|
|
8
|
+
return ["Available skills (call skills.load with the skill name to load full instructions before relying on them):", skills.map((skill) => `- ${skill.name}: ${(skill.description ?? "").trim() || skill.label}`).join("\n")].join("\n");
|
|
9
|
+
}
|
|
10
|
+
/** @deprecated Prefer skills.load; kept for tests/helpers that still filter by goal. */
|
|
11
|
+
function selectRelevantSkills(skills, ctx) {
|
|
12
|
+
return skills.filter((skill) => {
|
|
13
|
+
if (skill.relevant) return skill.relevant(ctx);
|
|
14
|
+
return skillMatchesGoal(skill, ctx.goal);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
18
|
+
"that",
|
|
19
|
+
"this",
|
|
20
|
+
"with",
|
|
21
|
+
"from",
|
|
22
|
+
"your",
|
|
23
|
+
"have",
|
|
24
|
+
"when",
|
|
25
|
+
"into",
|
|
26
|
+
"call",
|
|
27
|
+
"file",
|
|
28
|
+
"files",
|
|
29
|
+
"default",
|
|
30
|
+
"export",
|
|
31
|
+
"write",
|
|
32
|
+
"using",
|
|
33
|
+
"such",
|
|
34
|
+
"does",
|
|
35
|
+
"send",
|
|
36
|
+
"open",
|
|
37
|
+
"name",
|
|
38
|
+
"they",
|
|
39
|
+
"them",
|
|
40
|
+
"then",
|
|
41
|
+
"than",
|
|
42
|
+
"also",
|
|
43
|
+
"only",
|
|
44
|
+
"over",
|
|
45
|
+
"under",
|
|
46
|
+
"about",
|
|
47
|
+
"after",
|
|
48
|
+
"before",
|
|
49
|
+
"other",
|
|
50
|
+
"which",
|
|
51
|
+
"where",
|
|
52
|
+
"whose",
|
|
53
|
+
"their",
|
|
54
|
+
"there",
|
|
55
|
+
"these",
|
|
56
|
+
"those",
|
|
57
|
+
"and",
|
|
58
|
+
"for",
|
|
59
|
+
"the",
|
|
60
|
+
"a",
|
|
61
|
+
"an",
|
|
62
|
+
"to",
|
|
63
|
+
"of",
|
|
64
|
+
"in",
|
|
65
|
+
"on",
|
|
66
|
+
"or",
|
|
67
|
+
"by",
|
|
68
|
+
"is",
|
|
69
|
+
"are",
|
|
70
|
+
"be",
|
|
71
|
+
"as",
|
|
72
|
+
"at",
|
|
73
|
+
"it",
|
|
74
|
+
"do",
|
|
75
|
+
"not"
|
|
76
|
+
]);
|
|
77
|
+
function skillMatchesGoal(skill, goal) {
|
|
78
|
+
const hay = goal.toLowerCase();
|
|
79
|
+
if (!hay.trim()) return false;
|
|
80
|
+
const tokens = `${skill.name} ${skill.label ?? ""} ${skill.description ?? ""}`.toLowerCase().split(/[^a-z0-9._-]+/).filter((token) => token.length >= 4 && !STOP_WORDS.has(token));
|
|
81
|
+
if (!tokens.length) return false;
|
|
82
|
+
return tokens.some((token) => hay.includes(token));
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { AI_SETTINGS_EDITOR_ID, AI_SETTINGS_KEY, AI_VIEW_NAME, CognitiveRuntime, OPEN_AI_SETTINGS_COMMAND, OpenAICompatibleProvider, SYSTEM_SKILLS, TOPIC, cognitiveRuntime, defaultProvidersSettings, fetchOpenAICompatibleModels, formatSkillForPrompt, formatSkillsPromptSection, isSkillContribution, listConfiguredModelIds, listSkillContributions, loadModelsCatalog, parseModelIds, parseSkillMarkdown, registerSkillCommands, registerSkillMarkdown, resolveSkill, resolveSkillBody, selectRelevantSkills };
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","names":[],"sources":["../src/runtime/skills-select.ts"],"sourcesContent":["import type { SkillContribution, SkillRelevanceContext } from './skills-types';\n\nexport type { SkillContribution, SkillRelevanceContext } from './skills-types';\n\n/**\n * Catalog-only prompt section. The model loads full skill bodies via skills.load.\n */\nexport function formatSkillsPromptSection(skills: SkillContribution[]): string {\n if (!skills.length) return '';\n const catalog = skills\n .map((skill) => `- ${skill.name}: ${(skill.description ?? '').trim() || skill.label}`)\n .join('\\n');\n return [\n 'Available skills (call skills.load with the skill name to load full instructions before relying on them):',\n catalog,\n ].join('\\n');\n}\n\n/** @deprecated Prefer skills.load; kept for tests/helpers that still filter by goal. */\nexport function selectRelevantSkills(\n skills: SkillContribution[],\n ctx: SkillRelevanceContext,\n): SkillContribution[] {\n return skills.filter((skill) => {\n if (skill.relevant) return skill.relevant(ctx);\n return skillMatchesGoal(skill, ctx.goal);\n });\n}\n\nconst STOP_WORDS = new Set([\n 'that',\n 'this',\n 'with',\n 'from',\n 'your',\n 'have',\n 'when',\n 'into',\n 'call',\n 'file',\n 'files',\n 'default',\n 'export',\n 'write',\n 'using',\n 'such',\n 'does',\n 'send',\n 'open',\n 'name',\n 'they',\n 'them',\n 'then',\n 'than',\n 'also',\n 'only',\n 'over',\n 'under',\n 'about',\n 'after',\n 'before',\n 'other',\n 'which',\n 'where',\n 'whose',\n 'their',\n 'there',\n 'these',\n 'those',\n 'and',\n 'for',\n 'the',\n 'a',\n 'an',\n 'to',\n 'of',\n 'in',\n 'on',\n 'or',\n 'by',\n 'is',\n 'are',\n 'be',\n 'as',\n 'at',\n 'it',\n 'do',\n 'not',\n]);\n\nfunction skillMatchesGoal(skill: SkillContribution, goal: string): boolean {\n const hay = goal.toLowerCase();\n if (!hay.trim()) return false;\n const tokens = `${skill.name} ${skill.label ?? ''} ${skill.description ?? ''}`\n .toLowerCase()\n .split(/[^a-z0-9._-]+/)\n .filter((token) => token.length >= 4 && !STOP_WORDS.has(token));\n if (!tokens.length) return false;\n return tokens.some((token) => hay.includes(token));\n}\n"],"mappings":";;;;;AAOA,SAAgB,0BAA0B,QAAqC;CAC7E,IAAI,CAAC,OAAO,QAAQ,OAAO;CAI3B,OAAO,CACL,6GAJc,OACb,KAAK,UAAU,KAAK,MAAM,KAAK,KAAK,MAAM,eAAe,GAAA,CAAI,KAAK,KAAK,MAAM,OAAO,CAAC,CACrF,KAAK,IAGN,CACF,CAAC,CAAC,KAAK,IAAI;AACb;;AAGA,SAAgB,qBACd,QACA,KACqB;CACrB,OAAO,OAAO,QAAQ,UAAU;EAC9B,IAAI,MAAM,UAAU,OAAO,MAAM,SAAS,GAAG;EAC7C,OAAO,iBAAiB,OAAO,IAAI,IAAI;CACzC,CAAC;AACH;AAEA,IAAM,6BAAa,IAAI,IAAI;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,iBAAiB,OAA0B,MAAuB;CACzE,MAAM,MAAM,KAAK,YAAY;CAC7B,IAAI,CAAC,IAAI,KAAK,GAAG,OAAO;CACxB,MAAM,SAAS,GAAG,MAAM,KAAK,GAAG,MAAM,SAAS,GAAG,GAAG,MAAM,eAAe,KACvE,YAAY,CAAC,CACb,MAAM,eAAe,CAAC,CACtB,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC;CAChE,IAAI,CAAC,OAAO,QAAQ,OAAO;CAC3B,OAAO,OAAO,MAAM,UAAU,IAAI,SAAS,KAAK,CAAC;AACnD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DocksPart, SIDEBAR_AUXILIARY, confirmDialog, contributionRegistry, editorRegistry, registerAll, rootContext, toastError, toastInfo } from "@eclipse-docks/core";
|
|
3
|
-
import { css, customElement, html, nothing, property, query, state } from "@eclipse-docks/core/externals/lit";
|
|
1
|
+
import { C as detectEffortCapability, D as AI_VIEW_NAME, E as AI_SETTINGS_KEY, O as OPEN_AI_SETTINGS_COMMAND, S as parseModelIds, T as AI_SETTINGS_EDITOR_ID, _ as readPromptAttachmentFromFile, b as defaultProvidersSettings, f as estimateSessionContextUsage, g as ATTACHMENT_FILE_ACCEPT, h as formatTokenCount, k as TOPIC, m as formatContextPercent, p as formatBucketDetail, r as cognitiveRuntime, t as registerSkillCommands, y as fetchOpenAICompatibleModels } from "./runtime-DVzLyx8h.js";
|
|
2
|
+
import { DocksPart, File as File$1, FileContentType, SIDEBAR_AUXILIARY, confirmDialog, contributionRegistry, editorRegistry, filebrowserDialog, parseMarkdownHtml, registerAll, rootContext, toastError, toastInfo, workspaceService } from "@eclipse-docks/core";
|
|
3
|
+
import { css, customElement, html, nothing, property, query, state, unsafeHTML } from "@eclipse-docks/core/externals/lit";
|
|
4
4
|
import "@eclipse-docks/core/externals/webawesome";
|
|
5
5
|
import _decorate from "@oxc-project/runtime/helpers/decorate";
|
|
6
6
|
//#region src/view/busy-status.ts
|
|
@@ -64,6 +64,7 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
64
64
|
this.toolDetail = null;
|
|
65
65
|
this.busy = false;
|
|
66
66
|
this.busyStatus = INITIAL_BUSY_STATUS;
|
|
67
|
+
this.queuedPrompt = null;
|
|
67
68
|
this.pendingPermission = null;
|
|
68
69
|
this.policyMode = "auto";
|
|
69
70
|
this.optimizeFor = "balance";
|
|
@@ -180,11 +181,21 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
180
181
|
display: flex;
|
|
181
182
|
flex-direction: column;
|
|
182
183
|
gap: var(--wa-space-2xs);
|
|
183
|
-
|
|
184
|
+
width: 90%;
|
|
185
|
+
min-width: 90%;
|
|
186
|
+
max-width: 90%;
|
|
187
|
+
align-self: flex-start;
|
|
188
|
+
align-items: stretch;
|
|
184
189
|
}
|
|
185
190
|
|
|
186
191
|
.msg.user {
|
|
187
|
-
align-
|
|
192
|
+
align-self: flex-end;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.msg .bubble,
|
|
196
|
+
.msg wa-details.msg-details {
|
|
197
|
+
width: 100%;
|
|
198
|
+
box-sizing: border-box;
|
|
188
199
|
}
|
|
189
200
|
|
|
190
201
|
.msg-meta {
|
|
@@ -222,6 +233,39 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
222
233
|
white-space: pre-wrap;
|
|
223
234
|
line-height: var(--wa-line-height-normal);
|
|
224
235
|
max-width: 100%;
|
|
236
|
+
overflow-wrap: anywhere;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.bubble.markdown {
|
|
240
|
+
white-space: normal;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.bubble.markdown > :first-child {
|
|
244
|
+
margin-block-start: 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.bubble.markdown > :last-child {
|
|
248
|
+
margin-block-end: 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.bubble.markdown pre {
|
|
252
|
+
overflow-x: auto;
|
|
253
|
+
padding: var(--wa-space-s);
|
|
254
|
+
border-radius: var(--wa-border-radius-m);
|
|
255
|
+
background: color-mix(in srgb, var(--wa-color-neutral-fill-quiet) 55%, transparent);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.bubble.markdown code {
|
|
259
|
+
font-family: var(--wa-font-family-code, ui-monospace, monospace);
|
|
260
|
+
font-size: 0.92em;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.bubble.markdown pre code {
|
|
264
|
+
font-size: inherit;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.bubble.markdown a {
|
|
268
|
+
color: var(--wa-color-brand-on-normal);
|
|
225
269
|
}
|
|
226
270
|
|
|
227
271
|
.msg.user .bubble {
|
|
@@ -318,6 +362,34 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
318
362
|
background: var(--bucket-color, var(--wa-color-brand-fill-normal));
|
|
319
363
|
}
|
|
320
364
|
|
|
365
|
+
.context-io {
|
|
366
|
+
display: grid;
|
|
367
|
+
grid-template-columns: 1fr 1fr;
|
|
368
|
+
gap: var(--wa-space-2xs);
|
|
369
|
+
padding-top: var(--wa-space-s);
|
|
370
|
+
border-top: var(--wa-border-width-s) solid var(--wa-color-border-normal);
|
|
371
|
+
font-size: var(--wa-font-size-xs);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.context-io-heading {
|
|
375
|
+
grid-column: 1 / -1;
|
|
376
|
+
font-weight: var(--wa-font-weight-semibold, 600);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.context-io-item {
|
|
380
|
+
display: flex;
|
|
381
|
+
flex-direction: column;
|
|
382
|
+
gap: 0.1rem;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.context-io-item span {
|
|
386
|
+
color: var(--wa-color-text-quiet);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.context-io-item strong {
|
|
390
|
+
font-variant-numeric: tabular-nums;
|
|
391
|
+
}
|
|
392
|
+
|
|
321
393
|
.context-footer {
|
|
322
394
|
display: flex;
|
|
323
395
|
flex-direction: column;
|
|
@@ -337,6 +409,27 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
337
409
|
min-width: 0;
|
|
338
410
|
}
|
|
339
411
|
|
|
412
|
+
.queued-prompt {
|
|
413
|
+
display: flex;
|
|
414
|
+
align-items: center;
|
|
415
|
+
gap: var(--wa-space-2xs);
|
|
416
|
+
padding: var(--wa-space-2xs) var(--wa-space-s);
|
|
417
|
+
border-radius: var(--wa-border-radius-m);
|
|
418
|
+
border: var(--wa-border-width-s) solid var(--wa-color-border-normal);
|
|
419
|
+
background: color-mix(in srgb, var(--wa-color-brand-fill-quiet) 40%, transparent);
|
|
420
|
+
color: var(--wa-color-text-quiet);
|
|
421
|
+
font-size: var(--wa-font-size-s);
|
|
422
|
+
min-width: 0;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.queued-prompt-text {
|
|
426
|
+
flex: 1;
|
|
427
|
+
min-width: 0;
|
|
428
|
+
overflow: hidden;
|
|
429
|
+
text-overflow: ellipsis;
|
|
430
|
+
white-space: nowrap;
|
|
431
|
+
}
|
|
432
|
+
|
|
340
433
|
.composer-row {
|
|
341
434
|
display: flex;
|
|
342
435
|
gap: var(--wa-space-s);
|
|
@@ -626,12 +719,10 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
626
719
|
startBusyStatus() {
|
|
627
720
|
this.stopBusyStatus();
|
|
628
721
|
this.busyStatus = INITIAL_BUSY_STATUS;
|
|
629
|
-
this.setComposerText(this.busyStatus);
|
|
630
722
|
window.addEventListener("keydown", this.cancelKeyHandler);
|
|
631
723
|
const schedule = () => {
|
|
632
724
|
this.busyStatusTimer = setTimeout(() => {
|
|
633
725
|
this.busyStatus = nextBusyStatus(this.busyStatus);
|
|
634
|
-
this.setComposerText(this.busyStatus);
|
|
635
726
|
schedule();
|
|
636
727
|
}, busyStatusRotateMs());
|
|
637
728
|
};
|
|
@@ -823,6 +914,40 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
823
914
|
if (this.previewAttachmentId === attachmentId) this.previewAttachmentId = null;
|
|
824
915
|
this.syncSessions();
|
|
825
916
|
}
|
|
917
|
+
async saveAttachmentToWorkspace(attachmentId) {
|
|
918
|
+
const attachment = this.sessionAttachments().find((a) => a.id === attachmentId);
|
|
919
|
+
if (!attachment) return;
|
|
920
|
+
const preferredName = attachmentSaveFileName(attachment);
|
|
921
|
+
const parent = await filebrowserDialog("directory");
|
|
922
|
+
if (!parent) return;
|
|
923
|
+
try {
|
|
924
|
+
const workspace = await workspaceService.getWorkspace();
|
|
925
|
+
if (!workspace) {
|
|
926
|
+
toastError("No workspace connected");
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
const parentPath = parent.replace(/\/$/, "");
|
|
930
|
+
const fileName = await uniqueWorkspaceFileName(workspace, parentPath, preferredName);
|
|
931
|
+
const path = `${parentPath}/${fileName}`;
|
|
932
|
+
const resource = await workspace.getResource(path, { create: true });
|
|
933
|
+
if (!(resource instanceof File$1)) {
|
|
934
|
+
toastError("Could not create file in the selected folder");
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
937
|
+
if (attachment.dataUrl) {
|
|
938
|
+
const blob = await (await fetch(attachment.dataUrl)).blob();
|
|
939
|
+
const named = new globalThis.File([blob], fileName, { type: blob.type || attachment.mime || "" });
|
|
940
|
+
await resource.saveContents(named, { contentType: FileContentType.BINARY });
|
|
941
|
+
} else if (attachment.text != null) await resource.saveContents(attachment.text);
|
|
942
|
+
else {
|
|
943
|
+
toastError("Attachment has no payload to save");
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
toastInfo(`Saved ${fileName}`);
|
|
947
|
+
} catch (err) {
|
|
948
|
+
toastError(err instanceof Error ? err.message : String(err));
|
|
949
|
+
}
|
|
950
|
+
}
|
|
826
951
|
async addFiles(fileList) {
|
|
827
952
|
const files = [...fileList];
|
|
828
953
|
if (!files.length) return;
|
|
@@ -870,10 +995,6 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
870
995
|
}
|
|
871
996
|
/** Attach clipboard files/images (e.g. Ctrl+V screenshot) when focused in the prompt. */
|
|
872
997
|
async onComposerPaste(e) {
|
|
873
|
-
if (this.busy) {
|
|
874
|
-
e.preventDefault();
|
|
875
|
-
return;
|
|
876
|
-
}
|
|
877
998
|
const files = filesFromClipboard(e.clipboardData);
|
|
878
999
|
if (!files.length) return;
|
|
879
1000
|
e.preventDefault();
|
|
@@ -884,13 +1005,30 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
884
1005
|
this.promptController?.abort();
|
|
885
1006
|
if (this.pendingPermission) this.resolvePermission("deny");
|
|
886
1007
|
}
|
|
1008
|
+
clearQueuedPrompt() {
|
|
1009
|
+
this.queuedPrompt = null;
|
|
1010
|
+
}
|
|
1011
|
+
async queueFollowUp(text, attachmentIds) {
|
|
1012
|
+
this.queuedPrompt = {
|
|
1013
|
+
text,
|
|
1014
|
+
attachmentIds
|
|
1015
|
+
};
|
|
1016
|
+
this.pendingAttachmentIds = [];
|
|
1017
|
+
if (this.fileInput) this.fileInput.value = "";
|
|
1018
|
+
await this.setComposerText("");
|
|
1019
|
+
}
|
|
887
1020
|
async send() {
|
|
888
1021
|
const text = this.draft.trim();
|
|
889
1022
|
const attachmentIds = [...this.pendingAttachmentIds];
|
|
890
|
-
if (!text && !attachmentIds.length
|
|
1023
|
+
if (!text && !attachmentIds.length) return;
|
|
1024
|
+
if (this.busy) {
|
|
1025
|
+
await this.queueFollowUp(text, attachmentIds);
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
891
1028
|
this.applyPolicy();
|
|
892
1029
|
this.pendingAttachmentIds = [];
|
|
893
1030
|
if (this.fileInput) this.fileInput.value = "";
|
|
1031
|
+
await this.setComposerText("");
|
|
894
1032
|
const controller = new AbortController();
|
|
895
1033
|
this.promptController = controller;
|
|
896
1034
|
this.busy = true;
|
|
@@ -908,9 +1046,18 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
908
1046
|
this.stopBusyStatus();
|
|
909
1047
|
this.busy = false;
|
|
910
1048
|
this.streamingParts = [];
|
|
911
|
-
await this.clearComposer();
|
|
912
1049
|
this.syncSessions();
|
|
913
1050
|
this.scheduleScrollToBottom();
|
|
1051
|
+
const next = this.queuedPrompt;
|
|
1052
|
+
this.queuedPrompt = null;
|
|
1053
|
+
if (next && (next.text.trim() || next.attachmentIds.length)) {
|
|
1054
|
+
this.draft = next.text;
|
|
1055
|
+
this.pendingAttachmentIds = next.attachmentIds;
|
|
1056
|
+
await this.updateComplete;
|
|
1057
|
+
if (this.textarea) this.textarea.value = next.text;
|
|
1058
|
+
await this.send();
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
914
1061
|
this.textarea?.focus();
|
|
915
1062
|
}
|
|
916
1063
|
}
|
|
@@ -924,7 +1071,6 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
924
1071
|
size="s"
|
|
925
1072
|
appearance="plain"
|
|
926
1073
|
title=${count ? `${count} attachment${count === 1 ? "" : "s"}` : "Attachments"}
|
|
927
|
-
?disabled=${this.busy}
|
|
928
1074
|
>
|
|
929
1075
|
<wa-icon name="paperclip" label="Attachments"></wa-icon>
|
|
930
1076
|
${count > 0 ? html`<wa-badge pill>${count}</wa-badge>` : nothing}
|
|
@@ -955,11 +1101,18 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
955
1101
|
`}
|
|
956
1102
|
<span class="attach-name">${file.name}</span>
|
|
957
1103
|
</button>
|
|
1104
|
+
<wa-button
|
|
1105
|
+
size="s"
|
|
1106
|
+
appearance="plain"
|
|
1107
|
+
title=${`Save ${file.name} to workspace folder`}
|
|
1108
|
+
@click=${() => void this.saveAttachmentToWorkspace(file.id)}
|
|
1109
|
+
>
|
|
1110
|
+
<wa-icon name="floppy-disk" label=${`Save ${file.name}`}></wa-icon>
|
|
1111
|
+
</wa-button>
|
|
958
1112
|
<wa-button
|
|
959
1113
|
size="s"
|
|
960
1114
|
appearance="plain"
|
|
961
1115
|
title="Remove from session"
|
|
962
|
-
?disabled=${this.busy}
|
|
963
1116
|
@click=${() => this.removeSessionAttachment(file.id)}
|
|
964
1117
|
>
|
|
965
1118
|
<wa-icon name="xmark" label="Remove"></wa-icon>
|
|
@@ -971,7 +1124,7 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
971
1124
|
<wa-button
|
|
972
1125
|
size="s"
|
|
973
1126
|
appearance="outlined"
|
|
974
|
-
?disabled=${
|
|
1127
|
+
?disabled=${count >= 8}
|
|
975
1128
|
@click=${() => this.openFilePicker()}
|
|
976
1129
|
>
|
|
977
1130
|
<wa-icon slot="start" name="plus"></wa-icon>
|
|
@@ -1079,7 +1232,7 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
1079
1232
|
const usage = this.contextUsage();
|
|
1080
1233
|
const canCompact = (this.focusedSession()?.history.length ?? 0) > 12;
|
|
1081
1234
|
const percentLabel = formatContextPercent(usage.percent);
|
|
1082
|
-
const title = `Context ${percentLabel} ·
|
|
1235
|
+
const title = `Context window ${percentLabel} · ~${formatTokenCount(usage.used)} / ${formatTokenCount(usage.limit)}`;
|
|
1083
1236
|
const ringValue = Math.min(100, Math.max(usage.percent, usage.used > 0 ? 1 : 0));
|
|
1084
1237
|
return html`
|
|
1085
1238
|
<wa-dropdown
|
|
@@ -1108,7 +1261,7 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
1108
1261
|
@keydown=${(e) => e.stopPropagation()}
|
|
1109
1262
|
>
|
|
1110
1263
|
<div class="context-header">
|
|
1111
|
-
<strong>Context
|
|
1264
|
+
<strong>Context window</strong>
|
|
1112
1265
|
<span>${percentLabel}</span>
|
|
1113
1266
|
</div>
|
|
1114
1267
|
<div class="context-bars">
|
|
@@ -1129,10 +1282,26 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
1129
1282
|
</div>
|
|
1130
1283
|
<div class="context-footer">
|
|
1131
1284
|
<span class="context-remaining">
|
|
1132
|
-
~${formatTokenCount(usage.used)}
|
|
1285
|
+
~${formatTokenCount(usage.used)} in window · ${formatTokenCount(usage.remaining)} free of
|
|
1133
1286
|
${formatTokenCount(usage.limit)}
|
|
1134
1287
|
· ${shortModelLabel(usage.modelRef)}
|
|
1135
1288
|
</span>
|
|
1289
|
+
</div>
|
|
1290
|
+
<div
|
|
1291
|
+
class="context-io"
|
|
1292
|
+
title="Sum of provider-reported tokens across every model request in this chat. Each tool-loop call re-sends the prompt, so API input grows much faster than the context window fill."
|
|
1293
|
+
>
|
|
1294
|
+
<div class="context-io-heading">API usage (this chat)</div>
|
|
1295
|
+
<div class="context-io-item">
|
|
1296
|
+
<span>Input</span>
|
|
1297
|
+
<strong>${usage.inputTokens ? formatTokenCount(usage.inputTokens) : "—"}</strong>
|
|
1298
|
+
</div>
|
|
1299
|
+
<div class="context-io-item">
|
|
1300
|
+
<span>Output</span>
|
|
1301
|
+
<strong>${usage.outputTokens ? formatTokenCount(usage.outputTokens) : "—"}</strong>
|
|
1302
|
+
</div>
|
|
1303
|
+
</div>
|
|
1304
|
+
<div class="context-footer">
|
|
1136
1305
|
<wa-button
|
|
1137
1306
|
size="s"
|
|
1138
1307
|
variant=${usage.level === "critical" ? "danger" : "neutral"}
|
|
@@ -1174,27 +1343,36 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
1174
1343
|
@change=${(e) => void this.onFileInputChange(e)}
|
|
1175
1344
|
/>
|
|
1176
1345
|
<div class="composer">
|
|
1346
|
+
${this.queuedPrompt ? html`
|
|
1347
|
+
<div class="queued-prompt" title="Sends automatically when the current turn finishes">
|
|
1348
|
+
<wa-icon name="clock"></wa-icon>
|
|
1349
|
+
<span class="queued-prompt-text">
|
|
1350
|
+
Queued: ${this.queuedPrompt.text.trim() || `(${this.queuedPrompt.attachmentIds.length} attachment${this.queuedPrompt.attachmentIds.length === 1 ? "" : "s"})`}
|
|
1351
|
+
</span>
|
|
1352
|
+
<wa-button
|
|
1353
|
+
size="s"
|
|
1354
|
+
appearance="plain"
|
|
1355
|
+
title="Remove queued follow-up"
|
|
1356
|
+
@click=${() => this.clearQueuedPrompt()}
|
|
1357
|
+
>
|
|
1358
|
+
<wa-icon name="xmark" label="Remove queue"></wa-icon>
|
|
1359
|
+
</wa-button>
|
|
1360
|
+
</div>
|
|
1361
|
+
` : nothing}
|
|
1177
1362
|
<div class="composer-row">
|
|
1178
1363
|
<wa-textarea
|
|
1179
|
-
placeholder=${this.busy ?
|
|
1364
|
+
placeholder=${this.busy ? "Add a follow-up…" : "Enter your message here…"}
|
|
1180
1365
|
size="s"
|
|
1181
1366
|
resize="auto"
|
|
1182
1367
|
rows="1"
|
|
1183
|
-
.value=${this.
|
|
1184
|
-
?disabled=${this.busy}
|
|
1185
|
-
?readonly=${this.busy}
|
|
1368
|
+
.value=${this.draft}
|
|
1186
1369
|
@input=${(e) => {
|
|
1187
|
-
if (this.busy) return;
|
|
1188
1370
|
this.draft = e.target.value;
|
|
1189
1371
|
}}
|
|
1190
1372
|
@keydown=${(e) => {
|
|
1191
|
-
if (this.busy) {
|
|
1192
|
-
if (e.key === "Escape") {
|
|
1193
|
-
e.preventDefault();
|
|
1194
|
-
this.cancelTurn();
|
|
1195
|
-
return;
|
|
1196
|
-
}
|
|
1373
|
+
if (e.key === "Escape" && this.busy) {
|
|
1197
1374
|
e.preventDefault();
|
|
1375
|
+
this.cancelTurn();
|
|
1198
1376
|
return;
|
|
1199
1377
|
}
|
|
1200
1378
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
@@ -1227,7 +1405,7 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
1227
1405
|
`;
|
|
1228
1406
|
}
|
|
1229
1407
|
renderTranscript(session) {
|
|
1230
|
-
const showStreaming = this.streamingParts.length > 0;
|
|
1408
|
+
const showStreaming = this.busy || this.streamingParts.length > 0;
|
|
1231
1409
|
const showPermission = this.pendingPermission && this.pendingPermission.sessionId === session.id;
|
|
1232
1410
|
return html`
|
|
1233
1411
|
${session.history.map((m) => this.renderMessage(m))}
|
|
@@ -1495,7 +1673,7 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
1495
1673
|
renderAssistantMessage(message, opts = {}) {
|
|
1496
1674
|
const { summaryText, techParts } = splitAssistantPresentation(message.parts);
|
|
1497
1675
|
const open = opts.streaming === true || techParts.some((p) => (p.type === "reasoning" || p.type === "tool") && p.status === "streaming");
|
|
1498
|
-
const summaryBubble = summaryText.length ? summaryText.map((p) => this.renderTextPart(p)) : html`<div class="bubble">${technicalSummary(techParts)}</div>`;
|
|
1676
|
+
const summaryBubble = summaryText.length ? summaryText.map((p) => this.renderTextPart(p, { markdown: true })) : opts.streaming ? nothing : html`<div class="bubble">${technicalSummary(techParts)}</div>`;
|
|
1499
1677
|
const summary = html`
|
|
1500
1678
|
<div slot="summary" class="msg-summary">
|
|
1501
1679
|
${opts.streaming ? html`
|
|
@@ -1541,9 +1719,10 @@ var DocksCognitiveView = class DocksCognitiveView extends DocksPart {
|
|
|
1541
1719
|
</div>
|
|
1542
1720
|
`;
|
|
1543
1721
|
}
|
|
1544
|
-
renderTextPart(part) {
|
|
1545
|
-
if (part.type
|
|
1546
|
-
return
|
|
1722
|
+
renderTextPart(part, opts = {}) {
|
|
1723
|
+
if (part.type !== "text") return nothing;
|
|
1724
|
+
if (opts.markdown) return html`<div class="bubble markdown">${unsafeHTML(parseMarkdownHtml(part.text))}</div>`;
|
|
1725
|
+
return html`<div class="bubble">${part.text}</div>`;
|
|
1547
1726
|
}
|
|
1548
1727
|
renderTechnicalPart(part) {
|
|
1549
1728
|
if (part.type === "reasoning") return html`
|
|
@@ -1586,6 +1765,7 @@ _decorate([state()], DocksCognitiveView.prototype, "previewAttachmentId", void 0
|
|
|
1586
1765
|
_decorate([state()], DocksCognitiveView.prototype, "toolDetail", void 0);
|
|
1587
1766
|
_decorate([state()], DocksCognitiveView.prototype, "busy", void 0);
|
|
1588
1767
|
_decorate([state()], DocksCognitiveView.prototype, "busyStatus", void 0);
|
|
1768
|
+
_decorate([state()], DocksCognitiveView.prototype, "queuedPrompt", void 0);
|
|
1589
1769
|
_decorate([state()], DocksCognitiveView.prototype, "pendingPermission", void 0);
|
|
1590
1770
|
_decorate([state()], DocksCognitiveView.prototype, "policyMode", void 0);
|
|
1591
1771
|
_decorate([state()], DocksCognitiveView.prototype, "optimizeFor", void 0);
|
|
@@ -1614,6 +1794,30 @@ var APPROVAL_OPTIONS$1 = [
|
|
|
1614
1794
|
function capitalize(value) {
|
|
1615
1795
|
return value ? value[0].toUpperCase() + value.slice(1) : value;
|
|
1616
1796
|
}
|
|
1797
|
+
/** Basename used when saving an attachment into a workspace folder. */
|
|
1798
|
+
function attachmentSaveFileName(attachment) {
|
|
1799
|
+
const fromName = attachment.name.trim().split(/[/\\]/).pop()?.trim();
|
|
1800
|
+
if (fromName) return fromName;
|
|
1801
|
+
const fromPath = attachment.path?.split(/[/\\]/).pop()?.trim();
|
|
1802
|
+
if (fromPath) return fromPath;
|
|
1803
|
+
if (attachment.kind === "image") return attachment.mime === "image/jpeg" ? "attachment.jpg" : "attachment.png";
|
|
1804
|
+
return "attachment.txt";
|
|
1805
|
+
}
|
|
1806
|
+
/** `photo.png` → `photo (1).png`, `photo (2).png`, … when the path is taken. */
|
|
1807
|
+
function withNumericSuffix(fileName, n) {
|
|
1808
|
+
const dot = fileName.lastIndexOf(".");
|
|
1809
|
+
if (dot > 0) return `${fileName.slice(0, dot)} (${n})${fileName.slice(dot)}`;
|
|
1810
|
+
return `${fileName} (${n})`;
|
|
1811
|
+
}
|
|
1812
|
+
async function uniqueWorkspaceFileName(workspace, parentPath, fileName) {
|
|
1813
|
+
const candidatePath = (name) => `${parentPath}/${name}`;
|
|
1814
|
+
if (!await workspace.getResource(candidatePath(fileName))) return fileName;
|
|
1815
|
+
for (let n = 1; n < 1e4; n++) {
|
|
1816
|
+
const next = withNumericSuffix(fileName, n);
|
|
1817
|
+
if (!await workspace.getResource(candidatePath(next))) return next;
|
|
1818
|
+
}
|
|
1819
|
+
return withNumericSuffix(fileName, Date.now());
|
|
1820
|
+
}
|
|
1617
1821
|
/**
|
|
1618
1822
|
* Prefer text after the last tool/reasoning as the visible reply.
|
|
1619
1823
|
* Interim narration stays out of the bubble — tool details cover the execution trail.
|
|
@@ -2354,6 +2558,7 @@ function uniqueProviderId(existing) {
|
|
|
2354
2558
|
//#endregion
|
|
2355
2559
|
//#region src/cognitive-extension.ts
|
|
2356
2560
|
cognitiveRuntime.start();
|
|
2561
|
+
registerSkillCommands();
|
|
2357
2562
|
rootContext.put("cognitiveRuntime", cognitiveRuntime);
|
|
2358
2563
|
contributionRegistry.registerContribution(SIDEBAR_AUXILIARY, {
|
|
2359
2564
|
name: AI_VIEW_NAME,
|
|
@@ -2392,4 +2597,4 @@ registerAll({
|
|
|
2392
2597
|
});
|
|
2393
2598
|
//#endregion
|
|
2394
2599
|
|
|
2395
|
-
//# sourceMappingURL=cognitive-extension-
|
|
2600
|
+
//# sourceMappingURL=cognitive-extension-CvP05Bw_.js.map
|