ReadonlyAgentObservable stream of agent context updates from resource components. The shell subscribes to this to update the ComponentCacheManager and push changes to the chat overlay's AppContextSnapshot.DashboardContext.
ReadonlyAppLatest AppContextSnapshot published by the Explorer app shell.
Why: any embedded <mj-conversation-chat-area> instance outside the
floating chat overlay (Form Builder cockpit, future domain dashboards
that pop their own AI pane) needs to feed the SAME context the overlay
does so the agent sees what app + view + dashboard state the user is
looking at. Without this, the agent only sees the embedder's narrow
AdditionalContext slice and treats the user as if they have no app
context at all — which is the bug we just fixed.
MJExplorerAppComponent is the canonical publisher (it owns the
snapshot construction); consumers SUBSCRIBE and bind the value to
their chat-area's [appContext]. Non-Explorer apps (custom MJ apps
that don't include explorer-app at all) build their own snapshot via
BuildAppContextSnapshot() in @memberjunction/ai-core-plus.
Initial value is null; the publisher emits the first real snapshot
after the active app + nav state resolve on bootstrap.
Observable that emits when query params change on a tab (back/forward navigation).
ReadonlyResourceEmits each cached resource component as the shell reattaches it to a tab. A cached component keeps its instance and runs no init on reattach, so one that publishes agent context listens here to publish it again.
Emits the ID of the tab an OpenDashboard call with openInEditMode opened. The component
bound to the tab takes the request with TakeDashboardEditModeRequest.
Use ClearHomeAppCache.
Clears the cached Home app info. Call this if apps are reloaded or user logs out.
Drop a destroyed component's captured tools and detached mark (e.g. on LRU eviction), so nothing here retains references to dead component instances.
True between NotifyResourceDetached and NotifyResourceReattached for this component: its tab is not on screen, so it must not replace the agent context of the one that is.
True while the tab shows owner: the same app, resource type, driver class, entity and record as the
resource data the tab container gave the owner. The app, resource type, driver class and entity are
compared only when the owner has them; the record is always compared.
A callback method that performs custom clean-up, invoked immediately before a directive, pipe, or service instance is destroyed.
Notify subscribers that query params changed on a specific tab. Called by the shell when back/forward navigation changes query params on the active tab. The notification includes the tab ID so only the component in that tab reacts.
Clears the agent's client tools when the tab of the surface that registered them is detached (the user
navigated away), and keeps them for that tab's reattach, so the previous surface's tools are not offered
on the next surface. The detach of any other tab leaves the attached surface its tools. Every detach
carries Lifecycle: 'Detached', so the shell can also clear the context the detached surface reported.
The match is by tab, so a wrapper component being the one cached and detached while an inner child
registered the tools (e.g. Data Explorer) still clears and later replays them.
The component counts as detached (IsResourceDetached) until it is reattached.
Re-publish a cached resource component's tools when its tab is re-focused. Cached components keep
their Angular instance but do NOT re-run ngAfterViewInit, so they never re-register on reattach
— the shell calls this so the just-reactivated surface's tools become the agent's active set
again. Replays the set captured for this component at its last detach; replays nothing (lets a
fresh component register itself) when none was captured (e.g. a component's very first attach).
The reattach of a detached component sends an update with Lifecycle: 'Reattached' (with the
replayed tools, when there are any), so the shell can restore the context the surface reported
before its detach. Either way the component stops counting as detached and
ResourceReattached$ emits it.
Reactively observe the query params for a specific tab.
Backed by the workspace BehaviorSubject, so a subscriber receives the current params immediately on subscribe AND every subsequent change — including the deep-link params that the ResourceResolver merges into the tab configuration on a cold/direct URL load.
This is the race-free counterpart to NotifyQueryParamsChanged (a plain Subject that drops events fired before a component has subscribed). A resource component that mounts from workspace restoration can subscribe here and still pick up its initial deep-link state regardless of whether the params landed in the tab config before or after it mounted.
With owner, the params arrive only while the tab shows that resource (see
IsTabShowingResource). A tab can be reused for another resource while the
owner stays alive in the component cache, still bound to the tab's ID.
Optionalowner: ResourceDataOpen an artifact Artifacts are versioned content containers (reports, dashboards, UI components, etc.) Uses Home app if available, otherwise falls back to active app or system app
OptionalartifactName: stringOptionaloptions: NavigationOptionsOpen a dashboard in a tab of an application: options.applicationId when that application is
loaded, otherwise the default application (Home app if available, otherwise the active app or
system app). The workspace matches open tabs per application, so a tab that shows the same
dashboard in another application is not reused. A tab already open for the dashboard is
focused. Otherwise a plain open replaces the preview tab, so Back returns to the page it
showed, and a Shift-click or options.forceNewTab opens a separate tab.
options.openInEditMode asks the tab to enter edit mode (see
TakeDashboardEditModeRequest). The tab holds the request in its configuration, and
DashboardEditModeRequested$ tells the component bound to the tab.
Optionaloptions: DashboardNavigationOptionsOpen a dynamic view Dynamic views are entity-based views with custom filters, not saved views Uses Home app if available, otherwise falls back to active app or system app
OptionalextraFilter: stringOptionaloptions: NavigationOptionsOpen an entity record view. Behavior forks on the deployment's record-open style (see record-open-style.ts):
Optionaloptions: NavigationOptionsGo to the Home app's landing dashboard. Used where there is nowhere more specific to return to — e.g. a record loaded straight from a URL is deleted. Returns false when the deployment has no Home app (or the user cannot see it), so the caller can choose its own fallback.
Open a navigation item within an app
Optionaloptions: NavigationOptionsNavigate to a nav item by name within the current or specified application. Allows passing additional configuration parameters to merge with the nav item's config. This is useful for cross-resource navigation where a component needs to navigate to another nav item with specific parameters (e.g., navigate to Conversations with a specific conversationId).
The label/name of the nav item to navigate to
Optionalconfiguration: Record<string, unknown>Additional configuration to merge (e.g., conversationId, artifactId)
OptionalappId: stringOptional app ID (defaults to current active app)
Optionaloptions: NavigationOptionsNavigation options
The tab ID if successful, null if nav item not found
Open a new entity record creation form Uses Home app if available, otherwise falls back to active app or system app
The name of the entity to create a new record for
Optionaloptions: NavigationOptionsNavigation options including optional newRecordValues for pre-populating fields
Open a query Uses Home app if available, otherwise falls back to active app or system app
Optionaloptions: NavigationOptionsOpen a universal search results tab for the given query. This is the primary way to open search results from anywhere in the application.
The search query text
OptionalsearchOptions: { minRelevance?: number; scopeIDs?: string[] }Optional search-specific options (e.g., minRelevance, scopeIDs)
Optionaloptions: NavigationOptionsNavigation options
Open a view Uses Home app if available, otherwise falls back to active app or system app
Optionaloptions: NavigationOptionsPush a fresh AppContextSnapshot. Called by MJExplorerAppComponent
after each (a) app/tab change, (b) handleAgentContextUpdate
merging in AdditionalContext from a dashboard. Idempotent — no
de-duplication; embedders should treat the stream as "the latest
value is canonical."
Moves each saved tab of a moved nav item (ResolveMovedNavItem) to the new app's nav item, when the tab's app no longer has the nav item and the user has the new app. The tab keeps its id, driver class and query params. When the new app already has a tab for that nav item, the saved tab is closed instead, and the existing tab becomes active if the saved tab was. Waits for the user's app list. Runs never overlap: a call made during a run gets the one run after it, which every call made meanwhile shares.
The number of saved tabs it moved or closed. A failure is logged and changes nothing.
Take the user back to where they were when a record was opened (the origin crumb's click path). Fidelity ladder:
Register the client tools available from a resource component. Call this on component init and whenever the available tools change. Tools are automatically unregistered when the component becomes inactive (tab switch) and re-registered when it becomes active again.
Pass this from the calling component.
Array of tool definitions with Name, Description, ParameterSchema (JSON Schema), and Handler function.
Report the current agent-visible state from a resource component. Call this whenever the dashboard's internal state changes (tab switch, filter change, pipeline status change, drill-down, etc.).
Pass this from the calling component. Used to match
against the ComponentCacheManager to identify which cached component
this update belongs to.
Key-value pairs representing dashboard state the agent should know about. Each dashboard defines its own shape.
Switch to an application by ID. This sets the app as active and either opens a specific nav item or creates a default tab. If the requested nav item already has an open tab, switches to that tab instead of creating a new one. A nav item the app no longer has, which moved to another app (ResolveMovedNavItem), opens in that app with the same query params when the user has that app.
The application ID to switch to
OptionalnavItemName: stringOptional name of a nav item to open within the app. If provided, opens that nav item.
OptionalqueryParams: Record<string, string | null>Optional query params to apply to the target tab. Applied SYNCHRONOUSLY once the target tab is active — critical when navigating (e.g. from a Home pin) to an app whose resource component is cached: the params must be in the tab config BEFORE the tab-container reattaches the cached component, otherwise the cache restores its own (stale) saved params and the navigation intent is lost.
Switch to an app's LANDING page — its default nav item in its BASE state (drifted section params cleared, reset force-delivered so the dashboard actually returns to its landing even if its state diverged). The origin crumb's APP segment uses this: classic breadcrumb semantics, each level goes to that level's home.
Returns true when the tab shows the dashboard in the application and has an openInEditMode
request (see OpenDashboard), and removes that request from the tab, so only the first
call returns true. The dashboard tab calls this when its dashboard has loaded, when
DashboardEditModeRequested$ names its tab, and when the tab container reattaches it to a
new tab. A restored or reloaded tab then opens for viewing. OpenTab can replace a preview tab in
place, so a cached component can still be bound to a tab that now shows another dashboard, or
the same dashboard in another application. That tab keeps its request for its own component.
The dashboard the caller shows.
The application of the caller's tab.
Update the query params for the currently active tab. This updates the tab's configuration and triggers a URL sync via the shell's workspace configuration subscription.
🚨 NEVER CALL THIS FROM A RESOURCE COMPONENT OR DASHBOARD. "The active tab" is whatever the user is looking at right now, which is not necessarily the tab the caller lives in. A component whose async work completes while it sits in a BACKGROUND tab will rewrite — and destroy — the deep link of the tab the user is actually viewing. Components use BaseResourceComponent.UpdateQueryParams, which routes to UpdateTabQueryParams with their own tab id and refuses to write when they have none.
This remains only for shell-level navigation code that is, by construction, acting on behalf of the user's current tab (nothing in this repo does today).
Object containing query param key-value pairs. Use null values to remove a query param.
Prefer UpdateTabQueryParams with an explicit tab id.
Use this instead of directly calling router.navigate() to ensure proper URL management that respects app-scoped routes.
Update query params for a specific tab, optionally only if the tab still hosts the expected resource identity. This matters in single-resource mode where a tab ID can be reused for a different resource while the previous component is detached but still alive in the cache.
Optionalguard: TabQueryParamUpdateGuardRuns RetargetMovedNavItemTabs now, and again each time the user's app list changes while no app load is in progress, for example when an app is installed during the session. Resolves after the first run.
The subscription for the later runs. Unsubscribe it to stop them.
Centralized navigation service that handles all navigation operations with automatic shift-key detection for power user workflows