npm.io
1.3.13 • Published 3d ago

@e-llm-studio/instant-learning

Licence
MIT
Version
1.3.13
Deps
0
Vulns
0
Weekly
0

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

The library works without Creative Workspace. Its built-in scope tree and the shared original @e-llm-studio/prompt-editor are used by default. Hosts can override either component when host-specific behavior is required:

import {
  CreativeWorkspaceAdapterProvider,
  LearningManagement,
} from '@e-llm-studio/instant-learning';

<CreativeWorkspaceAdapterProvider value={{ TreeSidebar, AIPromptEditor }}>
  <LearningManagement {...props} />
</CreativeWorkspaceAdapterProvider>

This adapter is optional. In the monorepo, cw-core supplies it from the composition root so Instant Learning and Creative Workspace remain independent.


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.

Full config JSON (copy-paste starter) — click to expand
{
  "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",
        "subScopeTitle": "Add Subscope",
        "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.",
        "subScopeSubtitle": "This subscope 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"
      }
    },
    "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 / subScopeTitle string Dialog title for creating a scope / global scope / subscope. subScopeTitle is used when the dialog is opened with childType="SUBSCOPE"; falls back to middleDrawer.addSubScope if unset.
addScopeDialog.subtitle / globalSubtitle / subScopeSubtitle string Dialog subtitle. Supports {parent}.
addScopeDialog.scopeName / subScopeName string Label for the scope-name field / subscope-name field. subScopeName falls back to middleDrawer.subScope + " Name" if unset.
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/instant-learning@0.1.0-alpha.1

Keywords