@ai-matrx/chat 0.5.18 → 0.6.1
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.
- package/CHANGELOG.md +32 -0
- package/dist/agents/components/identity-refs/AiIdentityRef.d.ts +33 -0
- package/dist/agents/components/identity-refs/AiIdentityRef.js +138 -0
- package/dist/agents/components/inputs/resources/RenderedArtifactChip.d.ts +8 -0
- package/dist/agents/components/inputs/resources/RenderedArtifactChip.js +109 -0
- package/dist/agents/components/inputs/resources/SmartAgentResourceChips.js +20 -0
- package/dist/agents/components/inputs/resources/useAttachRenderedArtifact.js +31 -6
- package/dist/agents/components/inputs/smart-input/QuicksetPanel.js +5 -9
- package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
- package/dist/agents/components/inputs/smart-input/RunToolPicker.js +6 -11
- package/dist/agents/components/inputs/smart-input/ShapeChipsRow.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerEffortPill.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerOutput.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/useRunControlCounts.d.ts +3 -0
- package/dist/agents/components/inputs/smart-input/composer/useRunControlCounts.js +54 -0
- package/dist/agents/components/model-tiers/ModelTierIdentityList.js +1 -1
- package/dist/agents/components/run-controls/RunConfigOverrides.js +1 -1
- package/dist/agents/components/run-controls/RunInputCapabilities.js +1 -1
- package/dist/agents/components/run-controls/panels/shared.d.ts +0 -2
- package/dist/agents/hooks/useDiffEnrichment.js +3 -6
- package/dist/agents/identity/agent-catalog-lists.js +2 -1
- package/dist/agents/identity/agent-identity.js +2 -1
- package/dist/agents/identity/model-catalog.d.ts +9 -0
- package/dist/agents/identity/model-catalog.js +25 -0
- package/dist/agents/identity/preferred-chat-model.d.ts +9 -0
- package/dist/agents/identity/preferred-chat-model.js +33 -0
- package/dist/agents/identity/settings-store.d.ts +10 -0
- package/dist/agents/identity/settings-store.js +49 -0
- package/dist/agents/identity/skill-catalog.d.ts +27 -0
- package/dist/agents/identity/skill-catalog.js +100 -0
- package/dist/agents/identity/tool-catalog.d.ts +15 -0
- package/dist/agents/identity/tool-catalog.js +67 -0
- package/dist/agents/redux/agent-definition/cache-bust-middleware.d.ts +0 -1
- package/dist/agents/redux/agent-definition/cache-bust-middleware.js +1 -13
- package/dist/agents/redux/agent-definition/selectors.d.ts +12 -546
- package/dist/agents/redux/agent-settings/internal-utils.d.ts +2 -123
- package/dist/agents/redux/agent-settings/internal-utils.js +1 -315
- package/dist/agents/redux/agent-settings/settings-catalogue.d.ts +2 -78
- package/dist/agents/redux/agent-settings/settings-catalogue.js +1 -176
- package/dist/agents/redux/agent-settings/types.d.ts +2 -148
- package/dist/agents/redux/agent-settings/types.js +1 -0
- package/dist/agents/redux/agent-settings/ui-gates.d.ts +2 -54
- package/dist/agents/redux/agent-settings/ui-gates.js +1 -38
- package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +0 -100
- package/dist/agents/redux/agent-shortcuts/selectors.d.ts +0 -294
- package/dist/agents/redux/conversation-history/selectors.d.ts +0 -32
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +0 -4
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +0 -108
- package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +0 -28
- package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +0 -10
- package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +0 -6
- package/dist/agents/redux/execution-system/instance-model-overrides/launch-model-overrides.js +1 -1
- package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +0 -16
- package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +0 -10
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +0 -14
- package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +0 -2
- package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +0 -14
- package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +0 -2
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +0 -28
- package/dist/agents/redux/execution-system/thunks/process-stream.js +2 -5
- package/dist/agents/redux/execution-system/utils/loaded-skill-sources.d.ts +1 -1
- package/dist/agents/redux/execution-system/utils/loaded-skill-sources.js +3 -3
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +0 -2
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +0 -4
- package/dist/agents/utils/renderedArtifactContext.d.ts +55 -17
- package/dist/agents/utils/renderedArtifactContext.js +83 -2
- package/dist/conversation/utils/frame-print.d.ts +10 -5
- package/dist/conversation/utils/frame-print.js +65 -27
- package/dist/host/frame-print.d.ts +10 -0
- package/dist/host/frame-print.js +9 -0
- package/dist/host/ui-slots.d.ts +0 -46
- package/dist/host/ui-slots.js +0 -33
- package/dist/store/create-chat-store.d.ts +0 -4
- package/dist/store/middlewares.d.ts +0 -10
- package/dist/store/slices.d.ts +0 -2
- package/dist/store/slices.js +0 -4
- package/dist/surfaces/redux/selectors.d.ts +0 -4
- package/dist/tool-call-visualization/redux/selectors.d.ts +0 -2
- package/dist/ui/chat-default-model-knob.d.ts +1 -1
- package/dist/ui/chat-default-model-knob.js +1 -1
- package/package.json +5 -5
- package/dist/agents/components/model/AgentModelPanel.d.ts +0 -4
- package/dist/agents/components/model/AgentModelPanel.js +0 -9
- package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +0 -1015
- package/dist/agents/redux/agent-settings/agentSettingsSlice.js +0 -659
- package/dist/agents/redux/agent-settings/selectors.d.ts +0 -10057
- package/dist/agents/redux/agent-settings/selectors.js +0 -234
- package/dist/agents/redux/agent-settings/useNormalizedControls.d.ts +0 -8
- package/dist/agents/redux/agent-settings/useNormalizedControls.js +0 -24
- package/dist/agents/redux/tools/tools.selectors.d.ts +0 -529
- package/dist/agents/redux/tools/tools.selectors.js +0 -24
- package/dist/agents/redux/tools/tools.slice.d.ts +0 -12
- package/dist/agents/redux/tools/tools.slice.js +0 -37
- package/dist/agents/redux/tools/tools.thunks.d.ts +0 -125
- package/dist/agents/redux/tools/tools.thunks.js +0 -45
- package/dist/host/defaults/setting-control-input.d.ts +0 -11
- package/dist/host/defaults/setting-control-input.js +0 -91
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
buildSettingsRows
|
|
31
31
|
} from "../../redux/agent-settings/settings-catalogue.js";
|
|
32
|
-
import { SettingControlInput } from "
|
|
32
|
+
import { SettingControlInput } from "@ai-matrx/agents/settings/react";
|
|
33
33
|
import { Label, ErrorBox } from "@ai-matrx/design-system";
|
|
34
34
|
import { cn } from "@ai-matrx/design-system";
|
|
35
35
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../../ui/tabs.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useAppDispatch, useAppSelector } from "../../../store/hooks.js";
|
|
4
|
-
import { InputCapabilitiesEditor } from "
|
|
4
|
+
import { InputCapabilitiesEditor } from "@ai-matrx/agents/settings/react";
|
|
5
5
|
import { selectInputCapabilitiesState } from "../../redux/execution-system/instance-input-capabilities/instance-input-capabilities.selectors.js";
|
|
6
6
|
import {
|
|
7
7
|
resetInputCapabilityOverride,
|
|
@@ -30,7 +30,6 @@ export declare function makeSelectConversationRequests(conversationId: string):
|
|
|
30
30
|
agentShortcut: import("../../../redux/agent-shortcuts/types.js").AgentShortcutSliceState;
|
|
31
31
|
agentShortcutCategory: import("../../../redux/agent-shortcut-categories/types.js").AgentShortcutCategorySliceState;
|
|
32
32
|
surfaceUserState: import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice;
|
|
33
|
-
tools: import("../../../redux/tools/tools.slice.js").ToolsSliceState;
|
|
34
33
|
conversations: import("../../../redux/execution-system/conversations/conversations.slice.js").ConversationsState;
|
|
35
34
|
chatIncognito: import("../../../redux/chat/chat-incognito.slice.js").ChatIncognitoState;
|
|
36
35
|
chatRoute: import("../../../redux/chat/chat-route.slice.js").ChatRouteState;
|
|
@@ -62,7 +61,6 @@ export declare function makeSelectConversationRequests(conversationId: string):
|
|
|
62
61
|
agentAssistantMarkdownDraft: import("../../../redux/agent-assistant-markdown-draft.slice.js").AgentAssistantMarkdownDraftState;
|
|
63
62
|
mcp: import("../../../redux/mcp/mcp.slice.js").McpSliceState;
|
|
64
63
|
proposedDirectives: import("../../../redux/proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
65
|
-
agentSettings: import("../../../redux/agent-settings/types.js").AgentSettingsState;
|
|
66
64
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
67
65
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
68
66
|
hostConversations: import("../../../redux/execution-system/host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { useAppSelector } from "../../store/hooks.js";
|
|
4
|
-
import {
|
|
5
|
-
selectAllTools,
|
|
6
|
-
selectToolIdentityMap
|
|
7
|
-
} from "../redux/tools/tools.selectors.js";
|
|
8
4
|
import { selectMcpCatalog } from "../redux/mcp/mcp.slice.js";
|
|
9
5
|
import { useModelRecords } from "../identity/model-catalog.js";
|
|
6
|
+
import { selectAllTools, selectToolIdentityMap, useToolCatalog } from "../identity/tool-catalog.js";
|
|
10
7
|
function useDiffEnrichment() {
|
|
11
|
-
const allTools =
|
|
12
|
-
const toolIdentities =
|
|
8
|
+
const allTools = useToolCatalog(selectAllTools);
|
|
9
|
+
const toolIdentities = useToolCatalog(selectToolIdentityMap);
|
|
13
10
|
const mcpCatalog = useAppSelector(selectMcpCatalog);
|
|
14
11
|
const modelEntities = useModelRecords((s) => s.entities);
|
|
15
12
|
const modelIdentities = useModelRecords((s) => s.identityById);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect, useMemo, useSyncExternalStore } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { getChatHost } from "../../host/configure.js";
|
|
4
|
+
const getAgentCatalog = () => getChatHost().catalog();
|
|
4
5
|
import { ensureAgentCatalog } from "./agent-identity.js";
|
|
5
6
|
const EMPTY_ROWS = [];
|
|
6
7
|
const EMPTY_BY_ID = {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { getChatHost } from "../../host/configure.js";
|
|
3
|
+
const getAgentCatalog = () => getChatHost().catalog();
|
|
3
4
|
import { useAppSelector } from "../../store/hooks.js";
|
|
4
5
|
import { useEffect, useMemo, useSyncExternalStore } from "react";
|
|
5
6
|
import { hasField } from "@ai-matrx/agents/field-flags";
|
|
@@ -35,3 +35,12 @@ export type ModelClassControls = undefined | {
|
|
|
35
35
|
config: ModelClassConfig;
|
|
36
36
|
};
|
|
37
37
|
export declare function useModelClassControls(modelId: string | null | undefined, offeringId: string | null | undefined): ModelClassControls;
|
|
38
|
+
/** The active model options; loads them once (idempotent, shared with every picker). */
|
|
39
|
+
export declare function useModelOptions(): {
|
|
40
|
+
options: import("@ai-matrx/agents/models").ModelOption[];
|
|
41
|
+
isLoading: boolean;
|
|
42
|
+
error: string | null;
|
|
43
|
+
isReady: boolean;
|
|
44
|
+
};
|
|
45
|
+
/** One model's FULL record (controls included), or undefined until it has loaded. */
|
|
46
|
+
export declare function useModelFull(modelId: string | null | undefined): ModelRecord | undefined;
|
|
@@ -4,8 +4,11 @@ import {
|
|
|
4
4
|
classConfigKey,
|
|
5
5
|
createModelCatalog,
|
|
6
6
|
EMPTY_MODEL_RECORDS,
|
|
7
|
+
selectActiveModelsReady,
|
|
7
8
|
selectModelById,
|
|
9
|
+
selectModelFullyLoaded,
|
|
8
10
|
selectModelLabelById,
|
|
11
|
+
selectModelOptions,
|
|
9
12
|
selectModelLabelWithClass
|
|
10
13
|
} from "@ai-matrx/agents/models";
|
|
11
14
|
import { useModelRecordsSelector } from "@ai-matrx/agents/models/react";
|
|
@@ -92,14 +95,36 @@ function useModelClassControls(modelId, offeringId) {
|
|
|
92
95
|
if (status === "failed") return { failed: true };
|
|
93
96
|
return { pending: true };
|
|
94
97
|
}
|
|
98
|
+
function useModelOptions() {
|
|
99
|
+
const options = useModelRecords(selectModelOptions);
|
|
100
|
+
const isLoading = useModelRecords((s) => s.isLoading);
|
|
101
|
+
const error = useModelRecords((s) => s.error);
|
|
102
|
+
const isReady = useModelRecords(selectActiveModelsReady);
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (chatHostHasDatabase()) void getModelRecords().loadOptions();
|
|
105
|
+
}, []);
|
|
106
|
+
return { options, isLoading, error, isReady };
|
|
107
|
+
}
|
|
108
|
+
function useModelFull(modelId) {
|
|
109
|
+
const record = useModelRecords((s) => selectModelById(s, modelId));
|
|
110
|
+
const isFull = useModelRecords((s) => selectModelFullyLoaded(s, modelId));
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (!chatHostHasDatabase()) return;
|
|
113
|
+
void getModelRecords().loadOptions();
|
|
114
|
+
if (modelId && !isFull) void getModelRecords().loadModel(modelId);
|
|
115
|
+
}, [modelId, isFull]);
|
|
116
|
+
return isFull ? record : void 0;
|
|
117
|
+
}
|
|
95
118
|
export {
|
|
96
119
|
getModelCatalog,
|
|
97
120
|
getModelRecords,
|
|
98
121
|
readModelRecords,
|
|
99
122
|
useModelClassControls,
|
|
100
123
|
useModelClassLabels,
|
|
124
|
+
useModelFull,
|
|
101
125
|
useModelLabel,
|
|
102
126
|
useModelLabelWithClass,
|
|
127
|
+
useModelOptions,
|
|
103
128
|
useModelRecord,
|
|
104
129
|
useModelRecords
|
|
105
130
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The person's preferred chat model (agent core B6 — chat resolves it itself; the
|
|
3
|
+
* `resolvePreferredChatModel` host slot is retired). `agents.model_prefs.chat_default_model` and
|
|
4
|
+
* its class companion, through the settings ladder (organization → user → device) of the host's
|
|
5
|
+
* knobs port. Null when nobody set one — the Holder's own model answers. A read failure is
|
|
6
|
+
* announced and answers null: a run never blocks on a preference.
|
|
7
|
+
*/
|
|
8
|
+
import { type PreferredModelChoice } from "@ai-matrx/agents/models";
|
|
9
|
+
export declare function resolvePreferredChatModel(): Promise<PreferredModelChoice | null>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CHAT_DEFAULT_MODEL_KNOB,
|
|
3
|
+
modelClassKnobFor,
|
|
4
|
+
modelClassPinOf,
|
|
5
|
+
resolvePreferredModelChoice
|
|
6
|
+
} from "@ai-matrx/agents/models";
|
|
7
|
+
import { supabase } from "../../host/db.js";
|
|
8
|
+
import { ensureEffectiveKnob } from "../../host/prefs.js";
|
|
9
|
+
import { getActiveOrgId } from "../../host/org.js";
|
|
10
|
+
import { getUserId } from "../../host/identity.js";
|
|
11
|
+
async function resolvePreferredChatModel() {
|
|
12
|
+
try {
|
|
13
|
+
return await resolvePreferredModelChoice(
|
|
14
|
+
{
|
|
15
|
+
client: () => supabase,
|
|
16
|
+
resolveKnob: (fullKey) => ensureEffectiveKnob(getActiveOrgId(), getUserId(), fullKey),
|
|
17
|
+
classKnobFor: modelClassKnobFor,
|
|
18
|
+
classPinOf: (value) => modelClassPinOf(value) ?? null
|
|
19
|
+
},
|
|
20
|
+
CHAT_DEFAULT_MODEL_KNOB,
|
|
21
|
+
"preferredChatModel"
|
|
22
|
+
);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(
|
|
25
|
+
`[preferredChatModel] ${CHAT_DEFAULT_MODEL_KNOB} could not be resolved \u2014 the Holder's own model answers this run:`,
|
|
26
|
+
error
|
|
27
|
+
);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
resolvePreferredChatModel
|
|
33
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type NormalizedControls, type SettingsStore } from "@ai-matrx/agents/settings";
|
|
2
|
+
export declare function getSettingsStore(): SettingsStore;
|
|
3
|
+
/** One agent's settings entry from the page's store. */
|
|
4
|
+
export declare function useAgentSettingsEntry(agentId: string | null | undefined): import("@ai-matrx/agents/settings").AgentSettingsEntry | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Parsed controls for a settings entry's effective model: the pinned CLASS's controls when a pin
|
|
7
|
+
* is set and loaded (a model's classes run through different APIs), else the model's own. Null
|
|
8
|
+
* until the record (full, with controls) is loaded or when the agent has no entry.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useNormalizedControls(agentId: string): NormalizedControls | null;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { selectModelById, selectModelClassConfig } from "@ai-matrx/agents/models";
|
|
4
|
+
import {
|
|
5
|
+
createSettingsStore,
|
|
6
|
+
effectiveOfferingPinOf,
|
|
7
|
+
parseModelControls,
|
|
8
|
+
readEffectiveModelId
|
|
9
|
+
} from "@ai-matrx/agents/settings";
|
|
10
|
+
import { useSettingsEntry } from "@ai-matrx/agents/settings/react";
|
|
11
|
+
import { readModelRecords, useModelRecords } from "./model-catalog.js";
|
|
12
|
+
const KEY = /* @__PURE__ */ Symbol.for("ai-matrx.chat.settings-store");
|
|
13
|
+
function getSettingsStore() {
|
|
14
|
+
const g = globalThis;
|
|
15
|
+
if (g[KEY]) return g[KEY];
|
|
16
|
+
const store = createSettingsStore({
|
|
17
|
+
lookupModel: (modelId) => {
|
|
18
|
+
const model = selectModelById(readModelRecords(), modelId);
|
|
19
|
+
if (!model) return void 0;
|
|
20
|
+
return {
|
|
21
|
+
id: model.id,
|
|
22
|
+
name: model.common_name || model.name || model.id,
|
|
23
|
+
controls: model.controls ?? null
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
g[KEY] = store;
|
|
28
|
+
return store;
|
|
29
|
+
}
|
|
30
|
+
function useAgentSettingsEntry(agentId) {
|
|
31
|
+
return useSettingsEntry(getSettingsStore(), agentId);
|
|
32
|
+
}
|
|
33
|
+
function useNormalizedControls(agentId) {
|
|
34
|
+
const entry = useAgentSettingsEntry(agentId);
|
|
35
|
+
const modelId = readEffectiveModelId(entry);
|
|
36
|
+
const pin = effectiveOfferingPinOf(entry) ?? null;
|
|
37
|
+
const model = useModelRecords((s) => selectModelById(s, modelId));
|
|
38
|
+
const classConfig = useModelRecords((s) => selectModelClassConfig(s, modelId, pin));
|
|
39
|
+
return useMemo(() => {
|
|
40
|
+
if (!model) return null;
|
|
41
|
+
const controls = classConfig ? classConfig.controls : model.controls;
|
|
42
|
+
return parseModelControls(controls);
|
|
43
|
+
}, [model, classConfig]);
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
getSettingsStore,
|
|
47
|
+
useAgentSettingsEntry,
|
|
48
|
+
useNormalizedControls
|
|
49
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type SkillCatalog, type SkillRow } from "@ai-matrx/agents/skills";
|
|
2
|
+
import { type UseSkillsArgs } from "@ai-matrx/agents/skills/react";
|
|
3
|
+
export declare function getSkillCatalog(): SkillCatalog;
|
|
4
|
+
export interface ChatSkillsResult {
|
|
5
|
+
skills: SkillRow[];
|
|
6
|
+
grouped: Record<string, SkillRow[]>;
|
|
7
|
+
count: number;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
error: string | null;
|
|
10
|
+
reload: () => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/** The skills list, grouped by type; reloads and announces when a skill stream event lands. */
|
|
13
|
+
export declare function useSkills(args?: UseSkillsArgs): ChatSkillsResult;
|
|
14
|
+
/** The skills already loaded, without a read: `ready` + rows, or the status while not ready. */
|
|
15
|
+
export declare function readLoadedSkills(): {
|
|
16
|
+
status: string;
|
|
17
|
+
skills: SkillRow[];
|
|
18
|
+
};
|
|
19
|
+
/** True when a `resource_changed` kind is skill-related. */
|
|
20
|
+
export declare function isSkillStreamEvent(kind: string | undefined): boolean;
|
|
21
|
+
/** Hand a skill `resource_changed` event to the catalog (it bumps `lastIngestAt`; lists reload). */
|
|
22
|
+
export declare function applySkillStreamEvent(payload: {
|
|
23
|
+
kind?: string;
|
|
24
|
+
action?: string;
|
|
25
|
+
resource_id?: string;
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
}): void;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
3
|
+
import { createSkillCatalog } from "@ai-matrx/agents/skills";
|
|
4
|
+
import { useSkillCatalogSelector, useSkills as useCoreSkills } from "@ai-matrx/agents/skills/react";
|
|
5
|
+
import { supabase } from "../../host/db.js";
|
|
6
|
+
import { captureError } from "../../host/diagnostics.js";
|
|
7
|
+
import { toast } from "../../host/notify.js";
|
|
8
|
+
import { associationsService, isScopesRpcErr } from "../../context/sources/scopes.js";
|
|
9
|
+
import { chatHostHasDatabase } from "../../host/configure.js";
|
|
10
|
+
const KEY = /* @__PURE__ */ Symbol.for("ai-matrx.chat.skill-catalog");
|
|
11
|
+
function getSkillCatalog() {
|
|
12
|
+
const g = globalThis;
|
|
13
|
+
if (g[KEY]) return g[KEY];
|
|
14
|
+
const catalog = createSkillCatalog({
|
|
15
|
+
client: supabase,
|
|
16
|
+
associations: {
|
|
17
|
+
async skillIdsForProject(projectId) {
|
|
18
|
+
const res = await associationsService.listForTargets("project", [projectId]);
|
|
19
|
+
if (isScopesRpcErr(res)) return { ok: false, message: res.error.message };
|
|
20
|
+
return {
|
|
21
|
+
ok: true,
|
|
22
|
+
ids: res.data.edges.filter((e) => e.sourceType === "skill" && e.role === "member").map((e) => e.sourceId)
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
async projectIdsBySkill(skillIds) {
|
|
26
|
+
const out = {};
|
|
27
|
+
if (skillIds.length === 0) return out;
|
|
28
|
+
const res = await associationsService.listForSources("skill", [...skillIds], "project");
|
|
29
|
+
if (isScopesRpcErr(res)) return out;
|
|
30
|
+
for (const edge of res.data.edges) {
|
|
31
|
+
if (edge.role !== "member") continue;
|
|
32
|
+
(out[edge.sourceId] ??= []).push(edge.targetId);
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
errorSink: (event) => {
|
|
38
|
+
captureError({ source: "supabase-postgrest", schema: "skill", message: event.message, code: event.code });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
g[KEY] = catalog;
|
|
42
|
+
return catalog;
|
|
43
|
+
}
|
|
44
|
+
function useSkills(args = {}) {
|
|
45
|
+
const catalog = getSkillCatalog();
|
|
46
|
+
const result = useCoreSkills(catalog, { ...args, skipAutoFetch: Boolean(args.skipAutoFetch) || !chatHostHasDatabase() });
|
|
47
|
+
const lastIngestAt = useSkillCatalogSelector(catalog, (s) => s.lastIngestAt);
|
|
48
|
+
const lastReport = useSkillCatalogSelector(catalog, (s) => s.lastStreamReport);
|
|
49
|
+
const seen = useRef(lastIngestAt);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!lastIngestAt || lastIngestAt === seen.current) return;
|
|
52
|
+
seen.current = lastIngestAt;
|
|
53
|
+
const created = lastReport?.created ?? 0;
|
|
54
|
+
const updated = lastReport?.updated ?? 0;
|
|
55
|
+
const total = created + updated;
|
|
56
|
+
if (total > 0) {
|
|
57
|
+
const parts = [];
|
|
58
|
+
if (created) parts.push(`${created} new`);
|
|
59
|
+
if (updated) parts.push(`${updated} updated`);
|
|
60
|
+
toast.success(`Discovered ${parts.join(", ")} skill${total === 1 ? "" : "s"}`);
|
|
61
|
+
}
|
|
62
|
+
}, [lastIngestAt, lastReport]);
|
|
63
|
+
const all = useSkillCatalogSelector(catalog, (s) => s.skills);
|
|
64
|
+
const grouped = useMemo(() => {
|
|
65
|
+
const groups = {};
|
|
66
|
+
for (const id of all.allIds) {
|
|
67
|
+
const row = all.byId[id];
|
|
68
|
+
if (!row) continue;
|
|
69
|
+
(groups[row.skillType || "reference"] ??= []).push(row);
|
|
70
|
+
}
|
|
71
|
+
return groups;
|
|
72
|
+
}, [all]);
|
|
73
|
+
return { ...result, grouped };
|
|
74
|
+
}
|
|
75
|
+
function readLoadedSkills() {
|
|
76
|
+
const { skills } = getSkillCatalog().getState();
|
|
77
|
+
return {
|
|
78
|
+
status: skills.status,
|
|
79
|
+
skills: skills.allIds.map((id) => skills.byId[id]).filter((r) => Boolean(r))
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function isSkillStreamEvent(kind) {
|
|
83
|
+
return Boolean(kind && kind.startsWith("skill"));
|
|
84
|
+
}
|
|
85
|
+
function applySkillStreamEvent(payload) {
|
|
86
|
+
if (!isSkillStreamEvent(payload.kind)) return;
|
|
87
|
+
getSkillCatalog().applyStreamEvent({
|
|
88
|
+
kind: payload.kind,
|
|
89
|
+
action: payload.action ?? "modified",
|
|
90
|
+
resourceId: payload.resource_id ?? "",
|
|
91
|
+
metadata: payload.metadata ?? {}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
applySkillStreamEvent,
|
|
96
|
+
getSkillCatalog,
|
|
97
|
+
isSkillStreamEvent,
|
|
98
|
+
readLoadedSkills,
|
|
99
|
+
useSkills
|
|
100
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ToolCatalog, type ToolCatalogState } from "@ai-matrx/agents/tools";
|
|
2
|
+
import type { DatabaseTool } from "../../ui/database-tool.js";
|
|
3
|
+
export { selectAllTools, selectToolsStatus, selectToolsError, selectToolsReady, selectToolIdentityMap, selectToolById, selectToolLookupStatus, } from "@ai-matrx/agents/tools";
|
|
4
|
+
export type ChatToolCatalogState = ToolCatalogState<DatabaseTool>;
|
|
5
|
+
export declare function getToolCatalog(): ToolCatalog<DatabaseTool>;
|
|
6
|
+
/** Subscribe to a slice of the tool catalogue. `select` must return a stable value for unchanged state. */
|
|
7
|
+
export declare function useToolCatalog<T>(select: (state: ChatToolCatalogState) => T): T;
|
|
8
|
+
/** Read the active catalogue (once per session). A failure lands in the state's `error`. */
|
|
9
|
+
export declare function loadAvailableTools(options?: {
|
|
10
|
+
force?: boolean;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
/** Resolve one tool reference (inactive included). */
|
|
13
|
+
export declare function loadToolById(toolId: string): Promise<DatabaseTool | undefined>;
|
|
14
|
+
/** One tool by id (active list, else a resolved historical reference); resolves it when unknown. */
|
|
15
|
+
export declare function useToolById(toolId: string | null | undefined): DatabaseTool | undefined;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useSyncExternalStore } from "react";
|
|
3
|
+
import {
|
|
4
|
+
createToolCatalog,
|
|
5
|
+
selectToolById
|
|
6
|
+
} from "@ai-matrx/agents/tools";
|
|
7
|
+
import { supabase } from "../../host/db.js";
|
|
8
|
+
import { captureError } from "../../host/diagnostics.js";
|
|
9
|
+
import { chatHostHasDatabase } from "../../host/configure.js";
|
|
10
|
+
import {
|
|
11
|
+
selectAllTools,
|
|
12
|
+
selectToolsStatus,
|
|
13
|
+
selectToolsError,
|
|
14
|
+
selectToolsReady,
|
|
15
|
+
selectToolIdentityMap,
|
|
16
|
+
selectToolById as selectToolById2,
|
|
17
|
+
selectToolLookupStatus
|
|
18
|
+
} from "@ai-matrx/agents/tools";
|
|
19
|
+
const KEY = /* @__PURE__ */ Symbol.for("ai-matrx.chat.tool-catalog");
|
|
20
|
+
function getToolCatalog() {
|
|
21
|
+
const g = globalThis;
|
|
22
|
+
if (g[KEY]) return g[KEY];
|
|
23
|
+
const catalog = createToolCatalog({
|
|
24
|
+
client: () => supabase,
|
|
25
|
+
isAvailable: () => chatHostHasDatabase(),
|
|
26
|
+
errorSink: (event) => {
|
|
27
|
+
captureError({ source: "supabase-postgrest", schema: "tool", code: event.code, message: event.message });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
g[KEY] = catalog;
|
|
31
|
+
return catalog;
|
|
32
|
+
}
|
|
33
|
+
function useToolCatalog(select) {
|
|
34
|
+
const catalog = getToolCatalog();
|
|
35
|
+
return useSyncExternalStore(
|
|
36
|
+
catalog.subscribe,
|
|
37
|
+
() => select(catalog.getState()),
|
|
38
|
+
() => select(catalog.getState())
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function loadAvailableTools(options) {
|
|
42
|
+
return getToolCatalog().load(options).then(() => void 0, () => void 0);
|
|
43
|
+
}
|
|
44
|
+
function loadToolById(toolId) {
|
|
45
|
+
return getToolCatalog().loadById(toolId);
|
|
46
|
+
}
|
|
47
|
+
function useToolById(toolId) {
|
|
48
|
+
const tool = useToolCatalog((s) => selectToolById(s, toolId));
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (toolId && !tool) void loadToolById(toolId);
|
|
51
|
+
}, [toolId, tool]);
|
|
52
|
+
return tool;
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
getToolCatalog,
|
|
56
|
+
loadAvailableTools,
|
|
57
|
+
loadToolById,
|
|
58
|
+
selectAllTools,
|
|
59
|
+
selectToolById2 as selectToolById,
|
|
60
|
+
selectToolIdentityMap,
|
|
61
|
+
selectToolLookupStatus,
|
|
62
|
+
selectToolsError,
|
|
63
|
+
selectToolsReady,
|
|
64
|
+
selectToolsStatus,
|
|
65
|
+
useToolById,
|
|
66
|
+
useToolCatalog
|
|
67
|
+
};
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
* - `agentDefinition/promoteVersion/fulfilled` (past version → live)
|
|
17
17
|
* - `agentDefinition/updateFromSource/fulfilled` (derived reset)
|
|
18
18
|
* - `agentDefinition/purgeVersions/fulfilled` (version history trim)
|
|
19
|
-
* - `agentSettings/saveAgentSettings/fulfilled` (settings/variables writer)
|
|
20
19
|
*
|
|
21
20
|
* NOT the only layer, and deliberately not the load-bearing one. This call can
|
|
22
21
|
* only evict the ONE python process that answers it, and we run several
|
|
@@ -8,19 +8,7 @@ const WATCHED_ACTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
8
8
|
"agentDefinition/saveField/fulfilled",
|
|
9
9
|
"agentDefinition/promoteVersion/fulfilled",
|
|
10
10
|
"agentDefinition/updateFromSource/fulfilled",
|
|
11
|
-
"agentDefinition/purgeVersions/fulfilled"
|
|
12
|
-
// Second agent-save path, living in a DIFFERENT slice: `saveAgentSettings`
|
|
13
|
-
// (`packages/chat/src/agents/redux/agent-settings/agentSettingsSlice.ts`) writes `settings`
|
|
14
|
-
// + `variable_definitions` straight to `agent.definition` and never dispatches
|
|
15
|
-
// an `agentDefinition/*` action. `settings` is where model choice, reasoning
|
|
16
|
-
// effort and GROUNDING live — so this was the client write that made D159's
|
|
17
|
-
// "grounding stayed on in production" reproducible while the Builder's own
|
|
18
|
-
// saves busted correctly. `meta.arg` is `{ agentId }`, already handled below.
|
|
19
|
-
//
|
|
20
|
-
// ⚠️ This entry makes the miss harmless; it does not make the path right. Two
|
|
21
|
-
// parallel writers of one row is the real defect — see FOUND_DEFECTS D159/D160
|
|
22
|
-
// for the recommendation to fold this onto `agentDefinition/saveField`.
|
|
23
|
-
"agentSettings/saveAgentSettings/fulfilled"
|
|
11
|
+
"agentDefinition/purgeVersions/fulfilled"
|
|
24
12
|
]);
|
|
25
13
|
function extractAgentId(action) {
|
|
26
14
|
if (!action || typeof action !== "object") return null;
|