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