npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@e-llm-studio/instant-learning

v1.3.0-alpha.120

Published

The library exposes two independently consumable components:

Readme

Instant Learning Library

Usage & Integration

The library exposes two independently consumable components:

  • LearningManagement — renders the full Learning Management screen (scope tree, learnings, access, change history).
  • TeachMePlugin — renders the Teach Me popup, an AI-assisted rule/learning creation interface. Can be mounted on its own, anywhere.

Install:

npm install @e-llm-studio/instant-learning

1. LearningManagement

Renders the Learning Management screen. It uses @tanstack/react-query internally, so it must be wrapped in a QueryClientProvider by the consumer.

Import & sample usage

import LearningManagement from '@e-llm-studio/instant-learning';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <LearningManagement
        userDetails={userDetails}                 // logged-in user + access token
        llmStudioUrl="https://devllmstudio.creativeworkspace.ai"
        audacyBackendUrl="https://dev-audacy-traffic-manager.techo.camp"
        config={config}                           // runtime config (BASE_URL, ASSISTANT_NAME, …)
        rbacConfig={rbacConfig}                   // RBAC / AppSec identifiers
        auditLogConfig={{ configId: '6a1825e9fb722c37637b9490' }}
        ilLabels={{
          setupLabel: 'Learning Setup',
          ruleTitle: 'Learning Title',
          ruleDescriptionTitle: 'Learning Description',
        }}
        app_integration_id="019eb639-8eca-715a-95c1-efe0ee237ecc"
        backwardCompatibility={false}
        cognitiveCompareCompatibility={false}
        modeDetails={{
          activeModeName: 'Instant Learning Mode',
          modeNameFromURL: 'Instant Learning Mode',
          submodeNameFromURL: '',
        }}
      />
    </QueryClientProvider>
  );
}

Props

| Prop | Type | Required | Description | |---|---|:---:|---| | userDetails | User | ✅ | Logged-in user object. Must include accessToken (used for all API calls and as the GraphQL userDetails param). | | llmStudioUrl | string | ✅ | Base URL of LLM Studio; used for tiers, IL instance, and rule APIs. | | audacyBackendUrl | string | ✅ | Base URL of the client/product backend. | | config | object (any) | ✅ | Runtime config consumed by the rule-creation flow (BASE_URL, BASE_WEBSOCKET_URL, ASSISTANT_NAME, ORGANIZATION_NAME, CHAT_TITLE, SOCKET_TIMEOUT, etc.). | | rbacConfig | RbacConfig | ✅ | RBAC/AppSec identifiers: applicationName, applicationId, moduleId, applicationModuleId, applicationResourceId, appsecRbacUrl, appsecBaseUrl. Drives permission resolution. | | auditLogConfig | AuditLogConfig | ✅ | Audit log config — { configId: string }. | | ilLabels | { setupLabel; ruleTitle; ruleDescriptionTitle } | ✅ | Label overrides for the rule setup form (all three strings required). | | app_integration_id | string | ⚠️ Optional* | Integration context used to load the per-integration remote JSON config (dt()/dtt() values) and scoped API calls. *Effectively required in non-backward-compat mode — without it the remote config won't load. | | backwardCompatibility | boolean | ❌ Optional | Enables legacy mode (legacy create modal, legacy inherit API). Default false. | | cognitiveCompareCompatibility | boolean | ❌ Optional | Enables cognitive-compare behavior. Default false. | | modeId | string | ❌ Optional | Mode identifier passed through to the layout / rule content. | | modeDetails | { activeModeName; modeNameFromURL; submodeNameFromURL } | ❌ Optional | Active mode metadata used for base-mode naming. |

Note: When backwardCompatibility={false}, the screen reads its labels/dialogs from the remote config resolved via app_integration_id using the dt() helper. Missing keys fall back to built-in defaults.


2. TeachMePlugin

Renders the AI-assisted Teach Me rule-creation popup. Unlike LearningManagement, it provides its own QueryClientProvider internally — no extra wrapper needed.

Import & sample usage

import TeachMePlugin from '@e-llm-studio/instant-learning';

// Required config fields for TeachMePlugin
const configuration = {
  BASE_URL: 'https://devllmstudio.creativeworkspace.ai',
  BASE_WEBSOCKET_URL: 'wss://devllmstudio.creativeworkspace.ai/graphql',
  ORGANIZATION_NAME: 'techolution',
  ASSISTANT_NAME: 'preview',
};

function CreateLearningButton({ open, setOpen, token }) {
  return (
    <TeachMePlugin
      app_integration_id="019ecbcf-98c9-71bb-a663-ea962085c118"
      isOpen={open}
      onClose={() => setOpen(false)}
      token={token}                 // bearer token for API calls
      mode="ADD"                    // "ADD" | "EDIT"
      config={configuration}        // required runtime config (see table below)
      pluginPayload={{
        initialScope: 'global',     // {scope} value for titles
        ruleSet: selectedRuleSet,   // optional ruleset context
        // renderer-specific context (Radio Traffic, etc.):
        editingRule: null,
        editingTier: null,
        editingVariants: null,
        // optionally inline the config instead of remote-loading:
        // teachMe: { teachMe, template, learningManagement, agents },
        // tiers: [...],
      }}
    />
  );
}

Props

| Prop | Type | Required | Description | |---|---|:---:|---| | isOpen | boolean | ✅ | Controls popup visibility. | | onClose | () => void | ✅ | Called when the dialog requests to close. | | token | string | ✅ | Bearer token for API calls. | | mode | "ADD" \| "EDIT" | ✅ | Whether the popup is creating a new learning or editing an existing one. | | config | object | ✅ | Runtime config for the chat/socket. See required config fields below. | | app_integration_id | string | ⚠️ Optional* | Resolves the correct renderer template and remote config. *Optional only in backward-compat mode; otherwise required to load the template/config. | | pluginPayload | Record<string, any> | ❌ Optional | Free-form data passed straight through to the active renderer. Recognized keys: initialScope ({scope} value), ruleSet, tiers (sets tiers directly), and teachMe ({ teachMe, template, learningManagement, agents } to inline config instead of remote-loading). Any other keys are forwarded to the renderer (e.g. editingRule, editingTier, editingVariants, focusedVariantIndex, triggerAddVariant, triggerFixGaps, copiedRule, initialDraftMessage, modeId). |

Required config fields

| Field | Type | Required | Description | |---|---|:---:|---| | BASE_URL | string | ✅ | LLM Studio base URL; used for the chat/REST calls. | | BASE_WEBSOCKET_URL | string | ✅ | WebSocket (GraphQL) endpoint used by the live chat. | | ORGANIZATION_NAME | string | ✅ | Organization identifier for the assistant. | | ASSISTANT_NAME | string | ✅ | Name of the assistant that powers the Teach Me flow. |

const configuration = {
  BASE_URL: 'https://devllmstudio.creativeworkspace.ai',
  BASE_WEBSOCKET_URL: 'wss://devllmstudio.creativeworkspace.ai/graphql',
  ORGANIZATION_NAME: 'techolution',
  ASSISTANT_NAME: 'preview',
};

Template resolution: The renderer is chosen from the template key (in pluginPayload.teachMe.template or the remote config) via TemplateRegistry. Unknown values fall back to "Default". See the v17 changelog entry below for the registry and full config JSON.


Configuration Reference

Both LearningManagement and TeachMePlugin are fully label-driven. The UI text — titles, buttons, dialog copy, placeholders — comes from a JSON config loaded per appIntegrationId (or passed inline via pluginPayload.teachMe). Values are resolved at runtime with the dt() (LMS) and dtt() (TeachMe) helpers; any missing key falls back to a built-in default, so you only need to override what you want to change.

Top-level structure

{
  "template": "Default",
  "agents": { "LearningTerm": "Instruction" },
  "teachMe": { "...": "TeachMe popup labels" },
  "learningManagement": { "...": "Learning Management screen labels" }
}

| Key | Type | Required | Description | |---|---|:---:|---| | template | string | ✅ | Renderer key. Must be present for any customisation to apply; must match a TemplateRegistry key ("Default", "Radio Traffic Learning", "Guidelines", …). Unknown values fall back to "Default". | | agents.LearningTerm | string | ❌ | Word used for a "learning" across the UI (e.g. "Instruction", "Guideline"). | | teachMe | object | ❌ | Labels for the Teach Me popup. See teachMe fields. | | learningManagement | object | ❌ | Labels for the Learning Management screen (maps to LMSConfig). See learningManagement fields. |

Placeholders supported in values: {scope} / {scope_name} / {parent} (names), {count} / {N} (counts), {variant_name} (approve/reject dialogs), {rule_title} (enable/disable dialogs). They are interpolated at runtime.

{
  "template": "Default",
  "agents": {
    "LearningTerm": "Instruction"
  },
  "teachMe": {
    "welcomeMessage": "Hi! 👋 I'm your Instant Learning Concierge.",
    "welcomeMessageSubtitle": "I can help you create and manage instructions.\nSelect an option below or type your requirement.",
    "actions": [
      { "label": "Add new instruction",  "value": "I would want to add a new Instruction" },
      { "label": "Update an instruction", "value": "I would want to edit an existing instruction" }
    ],
    "chatTitle": "Teach Me ILOTJ - {scope} - Add Instruction",
    "chatTitleEdit": "Teach Me ILOTJ - {scope} - Edit Instruction",
    "chatTextareaPlaceholder": "Tell me about the instruction you want to create",
    "formTitle": "Add Instruction",
    "setupLabel": "Configure your IL",
    "ruleTitle": "Main Instruction Name",
    "scopeLabel": "Define Scope",
    "tierLabel": "Select Tiers",
    "ruleDescriptionTitle": "Explanation of the instruction",
    "whenToApplyTitle": "Trigger Events (When to Apply)",
    "addWhenToApplyBtnLabel": "Add WTA",
    "whenNotToApplyTitle": "Exclusion Events (When NOT to Apply)",
    "addWhenNotToApplyBtnLabel": "Add WNTA",
    "configTitle": "Advanced Settings",
    "saveBtnLabel": "Save Instruction",
    "saveBtnLoadingLabel": "Saving Instruction...",
    "showScope": false,
    "showConfiguration": false
  },
  "learningManagement": {
    "pageTitle": "Instruction Management",
    "middleDrawer": {
      "scope": "Scope",
      "addScope": "Add Scope",
      "addSubScope": "Add Subscope",
      "subScope": "Subscope",
      "treeMenu": {
        "search": "Search for scopes",
        "submenu": {
          "learnings": "Instructions",
          "access": "Access",
          "changeHistory": "Change History"
        },
        "contextMenu": {
          "addScope": "Add Scope",
          "rename": "Rename",
          "delete": "Delete {scope}",
          "addSubScope": "Add SubScope"
        }
      },
      "addScopeDialog": {
        "title": "Add Scope",
        "globalTitle": "Add Global Scope",
        "subtitle": "This scope will be created under {parent} and will inherit its Learnings by default.",
        "globalSubtitle": "This global scope defines base learnings that apply across all scopes.",
        "scopeName": "Scope Name",
        "submitButton": "Create Scope",
        "cancel": "Cancel",
        "learningApprovalSettings": {
          "title": "Instruction Approval Settings",
          "approvalRequired": {
            "title": "Approval Required before Publishing",
            "subtitle": "Learnings require approval before publishing"
          },
          "publishWithoutApproval": {
            "title": "Publish Without Approval",
            "subtitle": "Instructions can be published directly"
          }
        }
      },
      "scopeDisplayLimit": {
        "enabled": "true",
        "count": "3",
        "compactView": "true",
        "applyToLevels": "",
        "viewMoreText": "show {count} more...",
        "title": "Stations",
        "description": "Manage the stations assigned to the {scope} scope.",
        "searchPlaceholder": "Search station...",
        "onboardBtn": "Onboard a station",
        "viewText": "View"
      }
    },
    "learnings": {
      "header": {
        "title": "{scope} Instructions",
        "exportButton": "Export",
        "addNewLearningButton": "Add New Instruction"
      },
      "tier": {
        "showTierHeader": true,
        "tierHeader": "Tier",
        "subtitle": "These are the system-wide instructions applied across all documents.",
        "tierHeaderNoOfLearnings": "Instructions",
        "deleteDialog": {
          "title": "Delete Tier {N}?",
          "description": "This will permanently delete all rules and variants under this tier, including any inherited rules. This action cannot be undone.",
          "cancel": "Cancel",
          "submit": "Yes, Delete"
        },
        "learning": {
          "inheritance": "Inheritance",
          "actions": {
            "disable": "Disable",
            "enable": "Enable",
            "approve": "Approve All",
            "reject": "Reject All",
            "delete": "Delete"
          },
          "approveDialog": {
            "title": "Approve Guideline",
            "desc": "{variant_name} will be published and become active within the selected scope after approval.",
            "footer": "Take a moment to check the configuration before moving forward.",
            "cancel": "Cancel",
            "approveLearning": "Approve Guideline"
          },
          "rejectDialog": {
            "title": "Reject Guideline",
            "desc": "{variant_name} will not be published or applied within the selected scope. You can provide feedback before rejecting.",
            "feedbackTitle": "Feedback",
            "feedbackPlaceholder": "Add feedback or reason for rejection",
            "deleteCheckboxLabel": "Also delete this guideline",
            "cancel": "Cancel",
            "rejectLearning": "Reject Guideline"
          },
          "deleteDialog": {
            "title": "Delete",
            "desc": "Are you sure you want to delete this rule? This action cannot be undone.",
            "warningText": "This will permanently delete the rule configuration.",
            "cancelText": "Cancel",
            "deleteText": "Delete"
          }
        }
      }
    },
    "emptyStateLearning": {
      "title": "No instructions have been added !",
      "desc": "Start by adding instructions that should apply across all documents.",
      "createNewLearning": "Create New Instruction",
      "createGlobalScope": "Create Global Scope",
      "noAccessTitle": "Access Restricted",
      "noAccessDesc": "You do not have access for this application.",
      "requestAccessButton": "Request Access",
      "requestSentButton": "Request Sent"
    }
  }
}

teachMe fields

Drives the LHS of the Teach Me popup (greeting, quick actions, form labels). Resolved via dtt().

"teachMe": {
  "welcomeMessage": "Hi! 👋 I'm your Instant Learning Concierge.",
  "welcomeMessageSubtitle": "I can help you create and manage instructions.\nSelect an option below or type your requirement.",
  "actions": [
    { "label": "Add new instruction",   "value": "I would want to add a new Instruction" },
    { "label": "Update an instruction",  "value": "I would want to edit an existing instruction" }
  ],
  "chatTitle": "Teach Me ILOTJ - {scope} - Add Instruction",
  "chatTitleEdit": "Teach Me ILOTJ - {scope} - Edit Instruction",
  "chatTextareaPlaceholder": "Tell me about the instruction you want to create",
  "formTitle": "Add Instruction",
  "setupLabel": "Configure your IL",
  "ruleTitle": "Main Instruction Name",
  "scopeLabel": "Define Scope",
  "tierLabel": "Select Tiers",
  "ruleDescriptionTitle": "Explanation of the instruction",
  "whenToApplyTitle": "Trigger Events (When to Apply)",
  "addWhenToApplyBtnLabel": "Add WTA",
  "whenNotToApplyTitle": "Exclusion Events (When NOT to Apply)",
  "addWhenNotToApplyBtnLabel": "Add WNTA",
  "configTitle": "Advanced Settings",
  "saveBtnLabel": "Save Instruction",
  "saveBtnLoadingLabel": "Saving Instruction...",
  "showScope": false,
  "showConfiguration": false
}

| Field | Type | Description | Default | |---|---|---|---| | welcomeMessage | string | Primary greeting shown at the top of the chat. | "Hi! 👋 I'm your Instant Learning Concierge." | | welcomeMessageSubtitle | string | Subtitle under the greeting. Supports Markdown and \n line breaks. | "How would you like to get started?…" | | actions | Array<{ label, value }> | Quick-action buttons. label is the button text; value is the message sent to the agent when clicked. | 6 default actions | | chatTitle | string | Popup title in Add mode. Supports {scope}. | "Teach Me OTJ - {scope} - Add Learning" | | chatTitleEdit | string | Popup title in Edit mode. Supports {scope}. | "Teach Me OTJ - {scope} - Edit Learning" | | chatTextareaPlaceholder | string | Placeholder for the freeform chat textarea. | "Tell me more about this learning.." | | formTitle | string | Title of the inline rule form section. | "Rule setup" | | setupLabel | string | Label for the setup/configuration area. | "Configure your IL" | | ruleTitle | string | Label for the rule/learning name field. | "Main Rule Name" | | scopeLabel | string | Label for the scope selector. | "Define Scope" | | tierLabel | string | Label for the tier selector. | "Select Tiers" | | ruleDescriptionTitle | string | Label for the description field. | "Learning Explanation" | | whenToApplyTitle | string | Section title for trigger events. | "Trigger Events (When to Apply)" | | addWhenToApplyBtnLabel | string | Button to add a "when to apply" entry. | "Add WTA" | | whenNotToApplyTitle | string | Section title for exclusion events. | "Exclusion Events (When NOT to Apply)" | | addWhenNotToApplyBtnLabel | string | Button to add a "when NOT to apply" entry. | "Add WNTA" | | configTitle | string | Title for the advanced settings area. | "Advanced Settings" | | saveBtnLabel | string | Save button label. | "Save Rule" | | saveBtnLoadingLabel | string | Save button label while saving. | "Saving Rule..." | | showScope | boolean | Whether to show the scope selection section. | false | | showConfiguration | boolean | Whether to show the advanced configuration section. | false |


learningManagement fields

Maps to LMSConfig and drives the Learning Management screen. Resolved via dt(). Grouped below by area.

Page & middle drawer

"learningManagement": {
  "pageTitle": "Instruction Management",
  "middleDrawer": {
    "scope": "Scope",
    "addScope": "Add Scope",
    "addSubScope": "Add Subscope",
    "subScope": "Subscope",
    "treeMenu": {
      "search": "Search for scopes",
      "submenu": { "learnings": "Instructions", "access": "Access", "changeHistory": "Change History" },
      "contextMenu": { "addScope": "Add Scope", "rename": "Rename", "delete": "Delete {scope}", "addSubScope": "Add SubScope" }
    },
    "addScopeDialog": {
      "title": "Add Scope",
      "subtitle": "This scope will be created under {parent} and will inherit its Learnings by default.",
      "scopeName": "Scope Name",
      "submitButton": "Create Scope",
      "cancel": "Cancel",
      "learningApprovalSettings": {
        "title": "Instruction Approval Settings",
        "approvalRequired": { "title": "Approval Required before Publishing", "subtitle": "Learnings require approval before publishing" },
        "publishWithoutApproval": { "title": "Publish Without Approval", "subtitle": "Instructions can be published directly" }
      }
    },
    "scopeDisplayLimit": {
      "enabled": "true",
      "count": "3",
      "compactView": "true",
      "applyToLevels": "",
      "viewMoreText": "show {count} more...",
      "title": "Stations",
      "description": "Manage the stations assigned to the {scope} scope.",
      "searchPlaceholder": "Search station...",
      "onboardBtn": "Onboard a station",
      "viewText": "View"
    }
  }
}

| Field (path under middleDrawer) | Type | Description | |---|---|---| | pageTitle (sibling of middleDrawer) | string | Title shown in the LMS header. | | scope | string | Heading word for the current scope. | | addScope / addSubScope / subScope | string | Labels for add-scope, add-subscope buttons and the subscope node. | | treeMenu.search | string | Placeholder for the scope-tree search input. | | treeMenu.submenu.{learnings, access, changeHistory} | string | Tree submenu labels. | | treeMenu.contextMenu.{addScope, rename, delete, addSubScope} | string | Right-click context-menu actions. delete supports {scope}. | | addScopeDialog.title / globalTitle | string | Dialog title for creating a scope / global scope. | | addScopeDialog.subtitle / globalSubtitle | string | Dialog subtitle. Supports {parent}. | | addScopeDialog.scopeName | string | Label for the scope-name field. | | addScopeDialog.submitButton / cancel | string | Dialog action buttons. | | addScopeDialog.learningApprovalSettings.title | string | Approval-settings section title. | | …approvalRequired.{title, subtitle} | string | Copy for the "approval required" option. | | …publishWithoutApproval.{title, subtitle} | string | Copy for the "publish without approval" option. | | scopeDisplayLimit.enabled | string ("true"/"false") | Toggles the per-level display limit. | | scopeDisplayLimit.count | string (number) | How many items to show before collapsing. | | scopeDisplayLimit.compactView | string ("true"/"false") | Enables compact rendering. | | scopeDisplayLimit.applyToLevels | string | JSON array of 1-indexed levels to limit, e.g. "[1,2]". Empty = all levels. | | scopeDisplayLimit.viewMoreText | string | "See more" toggle text. Supports {count}. | | scopeDisplayLimit.title | string | Word substituted for "Stations" in headers. Supports {scope}. | | scopeDisplayLimit.description | string | Description under the Stations header. Supports {scope}. | | scopeDisplayLimit.searchPlaceholder | string | Station search placeholder. | | scopeDisplayLimit.onboardBtn | string | "Onboard a station" button label. | | scopeDisplayLimit.viewText | string | Per-station "View" button label. |

Learnings, tiers & dialogs

"learnings": {
  "header": { "title": "{scope} Instructions", "exportButton": "Export", "addNewLearningButton": "Add New Instruction" },
  "tier": {
    "showTierHeader": true,
    "tierHeader": "Tier",
    "subtitle": "These are the system-wide instructions applied across all documents.",
    "tierHeaderNoOfLearnings": "Instructions",
    "deleteDialog": { "title": "Delete Tier {N}?", "description": "This will permanently delete all rules…", "cancel": "Cancel", "submit": "Yes, Delete" },
    "learning": {
      "inheritance": "Inheritance",
      "actions": { "disable": "Disable", "enable": "Enable", "approve": "Approve All", "reject": "Reject All", "delete": "Delete" },
      "approveDialog": { "title": "Approve Guideline", "desc": "{variant_name} will be published…", "footer": "Take a moment to check…", "cancel": "Cancel", "approveLearning": "Approve Guideline" },
      "rejectDialog": { "title": "Reject Guideline", "desc": "{variant_name} will not be published…", "feedbackTitle": "Feedback", "feedbackPlaceholder": "Add feedback…", "deleteCheckboxLabel": "Also delete this guideline", "cancel": "Cancel", "rejectLearning": "Reject Guideline" },
      "deleteDialog": { "title": "Delete", "desc": "Are you sure…", "warningText": "This will permanently delete…", "cancelText": "Cancel", "deleteText": "Delete" }
    }
  }
}

| Field (path under learnings) | Type | Description | |---|---|---| | header.title | string | Learnings page title. Supports {scope}. | | header.exportButton | string | Export button label. | | header.addNewLearningButton | string | "Add new learning" button label. | | tier.showTierHeader | boolean | Whether the tier header region is shown. | | tier.tierHeader | string | Tier header title. | | tier.subtitle | string | Tier subtitle / description. | | tier.tierHeaderNoOfLearnings | string | Word for the learnings count label. | | tier.deleteDialog.{title, description, cancel, submit} | string | Bulk tier-delete dialog copy. title supports {N}. | | tier.learning.inheritance | string | Label for the inheritance indicator. | | tier.learning.actions.{disable, enable, approve, reject, delete} | string | Per-learning action labels. | | tier.learning.approveDialog.{title, desc, footer, cancel, approveLearning} | string | Approve dialog copy. desc supports {variant_name}. | | tier.learning.rejectDialog.{title, desc, feedbackTitle, feedbackPlaceholder, deleteCheckboxLabel, cancel, rejectLearning} | string | Reject dialog copy. desc supports {variant_name}. | | tier.learning.deleteDialog.{title, desc, warningText, cancelText, deleteText} | string | Single-learning delete dialog copy. |

Empty state

"emptyStateLearning": {
  "title": "No instructions have been added !",
  "desc": "Start by adding instructions that should apply across all documents.",
  "createNewLearning": "Create New Instruction",
  "createGlobalScope": "Create Global Scope",
  "noAccessTitle": "Access Restricted",
  "noAccessDesc": "You do not have access for this application.",
  "requestAccessButton": "Request Access",
  "requestSentButton": "Request Sent"
}

| Field | Type | Required | Description | |---|---|:---:|---| | title | string | ✅ | Empty-state heading. | | desc | string | ✅ | Empty-state description. | | createNewLearning | string | ✅ | CTA to create a learning. | | createGlobalScope | string | ✅ | CTA to create a global scope. | | noAccessTitle | string | ❌ | Heading when the user has no access. | | noAccessDesc | string | ❌ | Description when the user has no access. | | requestAccessButton | string | ❌ | "Request access" button label. | | requestSentButton | string | ❌ | "Request sent" state label. |


Changelog

1.3.0-alpha.31 - 2026, June 10th

-Hide "Copy to Tier" option -Hide Tier Accordian in Learning Management screen -Configuring Max hirearchy from ILKB config and its UI changes

1.3.0-alpha.31 - 2026, June 10th

Backward Compatibility support for Save from AI changes

1.3.0-alpha.21 - 2026, June 8th

Permissions — Union-based access resolution

  • Union model: When a user holds multiple roles on the same resource (e.g. inherited group role + direct assignment), permissions from all roles are merged. If any role grants a permission, the user has it.
  • Removed: ROLE_HIERARCHY, getRolePrecedence(), resolveHighestRolePerResource(), and the resolvedData store field are all gone.
  • hasPermission() and hasApplicationAccess() now run against the raw accessData via a new internal getUnionPermissionsForResource() helper that builds a Set of all permissions across matching records.
  • fetchPermissions() no longer calls the resolver — stores raw API response only.

1.3.0-alpha.20 - 2026, June 8th

TeachMe Popup — LHS Customisation via dtt()

  • Chat Title: Configurable for both Add and Edit modes via teachMe.chatTitle and teachMe.chatTitleEdit. Both support {scope} placeholder which is replaced at runtime with the selected scope name.
  • Welcome Message: Configurable greeting via teachMe.welcomeMessage. Subtitle via teachMe.welcomeMessageSubtitle with full Markdown support rendered via ReactMarkdown.
  • Action Buttons: Configurable via teachMe.actions array — each entry has a label (button text) and value (message sent to agent on click).
  • Textarea Placeholder: Configurable via teachMe.textareaPlaceholder.
  • Backward Compatibility: TeachMe popup customisation is supported with backwardCompatibility flag.

Keys added in this version:

| JSON Key | Default | |---|---| | teachMe.chatTitle | "Teach Me OTJ - {scope} - Add Learning" | | teachMe.chatTitleEdit | "Teach Me OTJ - {scope} - Edit Learning" | | teachMe.welcomeMessageSubtitle | "How would you like to get started?..." | | teachMe.actions | Array of { label, value } — see sample JSON in v17 | | teachMe.textareaPlaceholder | "Tell me more about this learning.." |

1.3.0-alpha.19 - 2026, June 6th

  • Cognitive Compare UI: Updated comparison UI with visual changes
  • GraphQL Params: userDetails object is now passed through as a GraphQL parameter

1.3.0-alpha.18 - 2026, June 6th

Patch Fix: Removal of underscore for all labels

1.3.0-alpha.17 - 2026, June 6th

Without BackwardCompatibiltity Support

  • TeachMe Renderer: Added valuetype json support to render teachMe popup and create rule from the same.

    Configurable UI via dtt() — all LHS labels in the TeachMe popup are driven by value_type_config.teachMe JSON loaded per appIntegrationId and resolved at runtime through the dtt() helper.

    Supported keys:

    | JSON Key | Default | |---|---| | teachMe.welcomeMessage | "Hi! 👋 I'm your Instant Learning Concierge." | | teachMe.formTitle | "Rule setup" | | teachMe.setupLabel | "Configure your IL" | | teachMe.ruleTitle | "Main Rule Name" | | teachMe.scopeLabel | "Define Scope" | | teachMe.tierLabel | "Select Tiers" | | teachMe.ruleDescriptionTitle | "Learning Explanation" | | teachMe.whenToApplyTitle | "Trigger Events (When to Apply)" | | teachMe.addWhenToApplyBtnLabel | "Add WTA" | | teachMe.whenNotToApplyTitle | "Exclusion Events (When NOT to Apply)" | | teachMe.addWhenNotToApplyBtnLabel | "Add WNTA" | | teachMe.configTitle | "Advanced Settings" | | teachMe.saveBtnLabel | "Save Rule" | | teachMe.saveBtnLoadingLabel | "Saving Rule..." | | teachMe.showConfiguration | false | | teachMe.showScope | false |

    Full sample value_type_config JSON:

  {
    "template": "Default",
    "teachMe": {
      "welcomeMessage": "Hi! 👋 I'm your Instant Learning Concierge.",
      "welcomeMessageSubtitle": "How would you like to get started?\nYou can select an option below or **describe the rule** you'd like to create.",
      "actions": [
        { "label": "Separation rule",          "value": "I would want to add a separation rule" },
        { "label": "Max priority rule",        "value": "I would want to set a max priority rule" },
        { "label": "Break code matching",      "value": "I would want to add a break code matching rule" },
        { "label": "Inventory code matching",  "value": "I would want to add a inventory window matching rule" },
        { "label": "Enter a rule description", "value": "I want to add a rule description" },
        { "label": "Tester Genie",             "value": "Loading prompt..." }
      ],
      "chatTitle": "Teach Me OTJ - {scope} - Add Learning",
      "chatTitleEdit": "Teach Me OTJ - {scope} - Edit Learning",
      "formTitle": "Rule Setup",
      "setupLabel": "Configure your IL",
      "ruleTitle": "Main Rule Name",
      "scopeLabel": "Define Scope",
      "tierLabel": "Select Tiers",
      "ruleDescriptionTitle": "Learning Explanation",
      "whenToApplyTitle": "Trigger Events (When to Apply)",
      "addWhenToApplyBtnLabel": "Add WTA",
      "whenNotToApplyTitle": "Exclusion Events (When NOT to Apply)",
      "addWhenNotToApplyBtnLabel": "Add WNTA",
      "configTitle": "Advanced Settings",
      "saveBtnLabel": "Save Rule",
      "saveBtnLoadingLabel": "Saving Rule...",
      "textareaPlaceholder": "Tell me more about this learning..",
      "showConfiguration": false,
      "showScope": false
    },
    "learningManagement": {}
  }

⚠️ Important: The template key at the root of value_type_config must be provided for any JSON customisation to take effect. Without it, the system falls back to resolving the renderer via value_type_name from the API, and config values may not be applied.

{
  "template": "Default"
}

The value must exactly match a key registered in TemplateRegistry:

| template value | Renderer | |---|---| | "Default" | DefaultTeachMeRenderer | | "Radio Traffic Learning" | RadioTrafficLearningRenderer | | "Guidelines" | GuidelinesTeachMeRenderer |

For custom plugins, use the exact key you registered in TemplateRegistry in TeachMePlugin.tsx:

export const TemplateRegistry: Record<string, React.FC<TeachMeWrapperProps>> = {
  "Default": DefaultTeachMeRenderer,
  "Radio Traffic Learning": RadioTrafficLearningRenderer,
  "Guidelines": GuidelinesTeachMeRenderer,
  "Your Template Name": YourCustomRenderer, // ← use this exact string in "template"
};

If the provided template value is not found in TemplateRegistry, the system automatically falls back to "Default".

  • Learning Management Renderer: Added valuetype json support to render Learning Management Screen and create rule from the same.

    Configurable UI via dt()

    The LMS UI is driven by a remote JSON config loaded per appIntegrationId. Every label, button text, and dialog copy is resolved at runtime through the dt() helper instead of being hardcoded.

    dt() — read a config value anywhere

  function dt(
    path: string,                             // dot-notation key into LMSConfig
    fallback?: string,                        // returned when key is missing
    params?: Record<string, string | number>  // fills {placeholder} tokens in the value
  ): string
  • Reads directly from the Zustand store (no hook — works outside React components).
  • Returns fallback ?? path when the key is not found or config is not loaded.

Examples:

  dt('pageTitle')
  // → value of lmsConfig.pageTitle

  dt('middleDrawer.addScope', 'Add Scope')
  // → config value or fallback 'Add Scope'

  dt('learnings.tier.deleteDialog.title', 'Delete {N} learnings', { N: 3 })
  // → "Delete 3 learnings"  (placeholder replaced)

  dt('learnings.tier.learning.approveDialog.desc', undefined, { variant_name: 'Rule A' })
  // → config string with {variant_name} replaced by "Rule A"

1.3.0-alpha.16 - 2026, June 5th

  • Scope Management: Added appIntegrationId support to scope creation and deletion flows in AddScopeModal and related API endpoints
  • Override History: Included appIntegrationId when fetching override history to ensure correct integration context
  • Rule Retrieval: Added appIntegrationId support when fetching rules by ruleId
  • Scope Deletion: Fixed deletion logic for station scopes so that associated stations are correctly removed when type = station

1.3.0-alpha.15 - 2026, June 5th

  • Teach Me Renderer: Modified default Teach Me renderer — switched from generic renderer to Radio Traffic value type renderer to support rule creation flow

1.3.0-alpha.14 - 2026, June 5th

  • IL Mode - Scope Creation: parentScopeId now correctly receives the parent scope's ID (global ID) when creating a new scope from a child node, instead of always being null
  • Auth Fallback: Added optional chaining (?.) on userDetails.accessToken to prevent crashes on reload
  • Access Section: Fixed logic that was hiding the Access section — it is now always visible regardless of backwardCompatibility flag

Alpha Release Commands

Create the first alpha version (e.g. 0.1.0-alpha.0)

npm version prerelease --preid=alpha

Increment the alpha version (e.g. 0.1.0-alpha.1)

npm version prerelease --preid=alpha

Publish the package under the alpha tag

npm publish --tag alpha

Install a specific alpha version

npm install @e-llm-studio/[email protected]