@kodaris/krubble-app-components 1.0.105 → 1.0.107

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.
@@ -5778,10 +5778,10 @@
5778
5778
  */
5779
5779
  this._globalSkills = [];
5780
5780
  /**
5781
- * Latest results for the `/` composer menu: this instance's own org skills PLUS
5782
- * the global skills installed on it (both are invocable by code). A separate
5783
- * buffer from the two browse-tab lists so merging installed globals into the
5784
- * menu never leaks them into the "Your Org" tab.
5781
+ * Latest results for the `/` composer menu — everything the current user can
5782
+ * actually invoke, merged and role-filtered server-side by
5783
+ * `/conversation/availableSkills`. A separate buffer from the two browse-tab lists
5784
+ * so installed globals in the menu never leak into the "Your Org" tab.
5785
5785
  */
5786
5786
  this._invocableSkills = [];
5787
5787
  /**
@@ -6359,12 +6359,11 @@
6359
6359
  }
6360
6360
  // --- Skills ---
6361
6361
  /**
6362
- * Search the Kodaris AI skills index and store the results in `_orgSkills`.
6363
- * The `/` menu and the browse dialog both call this; results are shared since
6364
- * the two are never open at once. Mirrors the backend's own skill search (BM25
6365
- * over name^3/description^2/instructions, active-only) so the menu ranks skills
6366
- * the way the model does. An empty query uses match_all — multi_match with an
6367
- * empty string matches nothing, so the "show everything" case needs it.
6362
+ * Search the Kodaris AI skills index and store the results in `_orgSkills` — the
6363
+ * browse dialog's "Your Org" tab. Mirrors the backend's own skill search (BM25
6364
+ * over name^3/description^2/instructions, active-only). An empty query uses
6365
+ * match_all — multi_match with an empty string matches nothing, so the "show
6366
+ * everything" case needs it.
6368
6367
  *
6369
6368
  * Follows the kr-combo-box `_fetch` pattern: a request-id guard drops responses
6370
6369
  * that arrive out of order. `/aiskills/search` returns a raw OpenSearch response,
@@ -6444,107 +6443,52 @@
6444
6443
  });
6445
6444
  }
6446
6445
  /**
6447
- * Search skills for the `/` composer menu into `_invocableSkills`: this instance's
6448
- * own org skills PLUS the global skills installed on it, since both are
6449
- * invocable by code. They come from two indexes (the local aiskills search and
6450
- * the registry search filtered client-side to enabled), so we fire both and
6451
- * concat — org skills first, then installed globals. Skill codes are unique
6452
- * across the two, so no dedup is needed. Kept out of `_orgSkills` so
6453
- * installed globals never leak into the browse dialog's "Your Org" tab.
6454
- * (Cross-list relevance ranking is a later concern; for now org skills lead.)
6446
+ * Load the skills for the `/` composer menu into `_invocableSkills` from
6447
+ * `/conversation/availableSkills` — this instance's own skills plus the installed
6448
+ * global ones, already merged, role-filtered and ranked by the server. That's the
6449
+ * same set the model sees via `list_skills`, so the menu can't offer a skill the
6450
+ * chat would then refuse.
6451
+ *
6452
+ * Not the `aiskills` endpoints the browse dialog's Org tab uses: those require a
6453
+ * skill-authoring role, which an ordinary chat user doesn't have.
6454
+ *
6455
+ * Request-id guard drops responses that arrive out of order (kr-combo-box `_fetch`
6456
+ * pattern).
6455
6457
  */
6456
6458
  _searchInvocableSkills(query) {
6457
6459
  this._invocableSkillRequestId++;
6458
6460
  const requestId = this._invocableSkillRequestId;
6459
- // Same wildcard matching as _searchOrgSkills (see there for the rationale).
6460
- let must = { match_all: {} };
6461
- if (query.trim()) {
6462
- must = {
6463
- bool: {
6464
- should: [
6465
- {
6466
- wildcard: {
6467
- 'name.raw': {
6468
- value: `*${query.trim().replace(/([*?\\])/g, '\\$1')}*`,
6469
- case_insensitive: true,
6470
- }
6471
- }
6472
- },
6473
- {
6474
- wildcard: {
6475
- 'code.raw': {
6476
- value: `*${query.trim().replace(/([*?\\])/g, '\\$1')}*`,
6477
- case_insensitive: true,
6478
- }
6479
- }
6480
- },
6481
- {
6482
- wildcard: {
6483
- 'description.raw': {
6484
- value: `*${query.trim().replace(/([*?\\])/g, '\\$1')}*`,
6485
- case_insensitive: true,
6486
- }
6487
- }
6488
- },
6489
- ],
6490
- minimum_should_match: 1,
6491
- },
6492
- };
6493
- }
6494
- // Org skills — this instance's own catalog (globalPublished excluded).
6495
- const orgSearch = krubbleHttp.Http.fetch({
6496
- url: '/api/system/opensearch/aiskills/search',
6497
- method: 'POST',
6498
- body: {
6499
- size: 100,
6500
- query: {
6501
- bool: {
6502
- must: [must],
6503
- filter: [{ term: { active: true } }],
6504
- must_not: [{ term: { globalPublished: true } }],
6505
- },
6506
- },
6507
- },
6508
- })
6509
- .then((r) => r.json())
6510
- .then((res) => (res?.data?.hits?.hits || []).map((hit) => hit._source))
6511
- .catch((error) => {
6512
- console.error('kr-chatbot: invocable skill search failed', error);
6513
- return [];
6514
- });
6515
- // Installed globals — the registry catalog, kept only where enabled=true.
6516
- const globalSearch = krubbleHttp.Http.fetch({
6517
- url: '/api/system/opensearch/aiskills/global/search',
6461
+ krubbleHttp.Http.fetch({
6462
+ url: '/api/system/conversation/availableSkills',
6518
6463
  method: 'POST',
6519
6464
  body: { query: query.trim() },
6520
6465
  })
6521
6466
  .then((r) => r.json())
6522
- .then((res) => (res?.data || []).filter((s) => !!s.enabled))
6523
- .catch((error) => {
6524
- console.error('kr-chatbot: installed global skill search failed', error);
6525
- return [];
6526
- });
6527
- Promise.all([orgSearch, globalSearch]).then(([orgSkills, globalSkills]) => {
6467
+ .then((res) => {
6528
6468
  // Ignore a stale response superseded by a newer search.
6529
6469
  if (requestId !== this._invocableSkillRequestId) {
6530
6470
  return;
6531
6471
  }
6532
- this._invocableSkills = [...orgSkills, ...globalSkills];
6472
+ this._invocableSkills = (res?.data || []);
6473
+ })
6474
+ .catch((error) => {
6475
+ console.error('kr-chatbot: invocable skill search failed', error);
6533
6476
  });
6534
6477
  }
6535
6478
  /**
6536
- * Search the shared Kodaris global-skill registry into `_globalSkills`
6537
- * (the browse dialog's "Kodaris" tab). Unlike `/aiskills/search`,
6538
- * `/aiskills/global/search` returns a digested list
6539
- * (`data: [{ code, name, description, enabled }]`) already in `KRChatbotSkill`
6540
- * shape, so no `_source` lifting is needed. Only the browse dialog calls this
6541
- * (the `/` menu is org-only), so it isn't run per slash keystroke.
6479
+ * Load the browse dialog's "Kodaris" tab into `_globalSkills` — the full Kodaris
6480
+ * catalog, installed or not, each row carrying `enabled` = installed here.
6481
+ *
6482
+ * Uses `/conversation/globalSkillCatalog` rather than the `/aiskills/global/search`
6483
+ * twin, which requires a skill-authoring role an ordinary chat user doesn't have.
6484
+ * Both return the same catalog in `KRChatbotSkill` shape
6485
+ * (`data: [{ code, name, description, enabled }]`), so no `_source` lifting is needed.
6542
6486
  */
6543
6487
  _searchGlobalSkills(query) {
6544
6488
  this._globalSkillRequestId++;
6545
6489
  const requestId = this._globalSkillRequestId;
6546
6490
  krubbleHttp.Http.fetch({
6547
- url: '/api/system/opensearch/aiskills/global/search',
6491
+ url: '/api/system/conversation/globalSkillCatalog',
6548
6492
  method: 'POST',
6549
6493
  body: { query: query.trim() },
6550
6494
  })
@@ -8429,10 +8373,14 @@
8429
8373
  gap: 24px;
8430
8374
  }
8431
8375
 
8376
+ /* anywhere, NOT break-word: both break a long unbreakable run (a pasted URL) for
8377
+ layout, but only anywhere also shrinks the element's intrinsic min-content width.
8378
+ With break-word the URL still reports its full unbroken width as the minimum,
8379
+ which sizes this shrink-to-fit bubble past .messages-inner's 768px cap and
8380
+ overflows the page horizontally. */
8432
8381
  .message-content {
8433
8382
  line-height: 1.7;
8434
- word-wrap: break-word;
8435
- overflow-wrap: break-word;
8383
+ overflow-wrap: anywhere;
8436
8384
  }
8437
8385
 
8438
8386
  .message--user .message-content {