@data-club/ai-hub 0.0.4 → 0.0.5
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/dist/auth/locales/cs.d.ts.map +1 -1
- package/dist/auth/locales/cs.js +7 -0
- package/dist/auth/locales/cs.js.map +1 -1
- package/dist/auth/locales/sk.d.ts.map +1 -1
- package/dist/auth/locales/sk.js +7 -0
- package/dist/auth/locales/sk.js.map +1 -1
- package/dist/auth/texts.d.ts +8 -0
- package/dist/auth/texts.d.ts.map +1 -1
- package/dist/auth/texts.js +7 -0
- package/dist/auth/texts.js.map +1 -1
- package/dist/client/AIHubClient.d.ts +13 -0
- package/dist/client/AIHubClient.d.ts.map +1 -1
- package/dist/client/AIHubClient.js +10 -0
- package/dist/client/AIHubClient.js.map +1 -1
- package/dist/components/ChatShell/index.d.ts.map +1 -1
- package/dist/components/ChatShell/index.js +35 -2
- package/dist/components/ChatShell/index.js.map +1 -1
- package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts.map +1 -1
- package/dist/components/DataClubAIHubAdmin/SettingsPage.js +56 -1
- package/dist/components/DataClubAIHubAdmin/SettingsPage.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth/locales/cs.ts +9 -0
- package/src/auth/locales/sk.ts +9 -0
- package/src/auth/texts.ts +19 -0
- package/src/client/AIHubClient.ts +23 -0
- package/src/components/ChatShell/index.tsx +34 -2
- package/src/components/DataClubAIHubAdmin/SettingsPage.tsx +145 -1
- package/src/types.ts +11 -0
|
@@ -27,7 +27,10 @@
|
|
|
27
27
|
import { useEffect, useState, type ReactNode } from "react";
|
|
28
28
|
|
|
29
29
|
import type { AIHubAdminTexts, AIHubLanguage } from "../../auth/texts.js";
|
|
30
|
-
import type {
|
|
30
|
+
import type {
|
|
31
|
+
AdminAgentView,
|
|
32
|
+
AdminSettingsView,
|
|
33
|
+
} from "../../client/AIHubClient.js";
|
|
31
34
|
import { useAIHub } from "../../context/useAIHub.js";
|
|
32
35
|
import { useAIHubAuth } from "../../context/useAIHubAuth.js";
|
|
33
36
|
import {
|
|
@@ -188,6 +191,11 @@ export function AdminSettingsPage(props: AdminSettingsPageProps): ReactNode {
|
|
|
188
191
|
texts={props.texts}
|
|
189
192
|
onSaved={handleSectionSaved}
|
|
190
193
|
/>
|
|
194
|
+
<AgentsSection
|
|
195
|
+
settings={settings}
|
|
196
|
+
texts={props.texts}
|
|
197
|
+
onSaved={handleSectionSaved}
|
|
198
|
+
/>
|
|
191
199
|
<FeatureTogglesSection
|
|
192
200
|
settings={settings}
|
|
193
201
|
texts={props.texts}
|
|
@@ -646,6 +654,142 @@ function LanguageSection(props: LanguageSectionProps): ReactNode {
|
|
|
646
654
|
);
|
|
647
655
|
}
|
|
648
656
|
|
|
657
|
+
/* ────────────────────────────────────────────────────────────────────────── */
|
|
658
|
+
/* Section: Agents */
|
|
659
|
+
/* ────────────────────────────────────────────────────────────────────────── */
|
|
660
|
+
|
|
661
|
+
interface AgentsSectionProps extends SectionProps {
|
|
662
|
+
onSaved: (next: AdminSettingsView) => void;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
function AgentsSection(props: AgentsSectionProps): ReactNode {
|
|
666
|
+
const { client } = useAIHub();
|
|
667
|
+
const [defaultAgentId, setDefaultAgentId] = useState<string>(
|
|
668
|
+
props.settings.agents.default_id ?? "",
|
|
669
|
+
);
|
|
670
|
+
const [switcherEnabled, setSwitcherEnabled] = useState(
|
|
671
|
+
props.settings.agents.switcher_enabled,
|
|
672
|
+
);
|
|
673
|
+
// Non-archived agents to populate the default-agent <select>.
|
|
674
|
+
const [agents, setAgents] = useState<AdminAgentView[] | null>(null);
|
|
675
|
+
const [saving, setSaving] = useState(false);
|
|
676
|
+
const [flash, setFlash] = useState<{ tone: "success" | "error"; text: string } | null>(
|
|
677
|
+
null,
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
useEffect(() => {
|
|
681
|
+
let cancelled = false;
|
|
682
|
+
void (async () => {
|
|
683
|
+
try {
|
|
684
|
+
const rows = await client.listAdminAgents();
|
|
685
|
+
if (cancelled) return;
|
|
686
|
+
setAgents(rows.filter((a) => !a.is_archived));
|
|
687
|
+
} catch {
|
|
688
|
+
if (!cancelled) setAgents([]);
|
|
689
|
+
}
|
|
690
|
+
})();
|
|
691
|
+
return () => {
|
|
692
|
+
cancelled = true;
|
|
693
|
+
};
|
|
694
|
+
}, [client]);
|
|
695
|
+
|
|
696
|
+
async function handleSave(event: React.FormEvent): Promise<void> {
|
|
697
|
+
event.preventDefault();
|
|
698
|
+
setSaving(true);
|
|
699
|
+
setFlash(null);
|
|
700
|
+
try {
|
|
701
|
+
const next = await client.patchAdminSettings({
|
|
702
|
+
agents: { defaultId: defaultAgentId, switcherEnabled },
|
|
703
|
+
});
|
|
704
|
+
props.onSaved(next);
|
|
705
|
+
setFlash({ tone: "success", text: props.texts.settingsSaveSuccessFlash });
|
|
706
|
+
} catch (err) {
|
|
707
|
+
setFlash({
|
|
708
|
+
tone: "error",
|
|
709
|
+
text:
|
|
710
|
+
err instanceof Error && err.message.length > 0
|
|
711
|
+
? err.message
|
|
712
|
+
: props.texts.settingsSaveGenericError,
|
|
713
|
+
});
|
|
714
|
+
} finally {
|
|
715
|
+
setSaving(false);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return (
|
|
720
|
+
<section
|
|
721
|
+
className="data-club-ai-hub-admin__settings-section"
|
|
722
|
+
data-testid="admin-settings-agents-section"
|
|
723
|
+
>
|
|
724
|
+
<h2 className="data-club-ai-hub-admin__settings-section-heading">
|
|
725
|
+
{props.texts.settingsAgentsSectionHeading}
|
|
726
|
+
</h2>
|
|
727
|
+
<form onSubmit={(event) => void handleSave(event)} noValidate>
|
|
728
|
+
<label
|
|
729
|
+
className="data-club-ai-hub-admin__form-label"
|
|
730
|
+
htmlFor="admin-settings-default-agent"
|
|
731
|
+
>
|
|
732
|
+
{props.texts.settingsAgentsDefaultLabel}
|
|
733
|
+
</label>
|
|
734
|
+
<select
|
|
735
|
+
id="admin-settings-default-agent"
|
|
736
|
+
className="data-club-ai-hub-admin__form-input"
|
|
737
|
+
data-testid="admin-settings-default-agent"
|
|
738
|
+
value={defaultAgentId}
|
|
739
|
+
onChange={(event) => setDefaultAgentId(event.target.value)}
|
|
740
|
+
disabled={saving || agents === null}
|
|
741
|
+
>
|
|
742
|
+
<option value="">{props.texts.settingsAgentsDefaultNone}</option>
|
|
743
|
+
{(agents ?? []).map((agent) => (
|
|
744
|
+
<option key={agent.id} value={agent.id}>
|
|
745
|
+
{agent.display_name}
|
|
746
|
+
</option>
|
|
747
|
+
))}
|
|
748
|
+
</select>
|
|
749
|
+
<p className="data-club-ai-hub-admin__form-helper">
|
|
750
|
+
{props.texts.settingsAgentsDefaultHelper}
|
|
751
|
+
</p>
|
|
752
|
+
<label className="data-club-ai-hub-admin__checkbox">
|
|
753
|
+
<input
|
|
754
|
+
type="checkbox"
|
|
755
|
+
data-testid="admin-settings-agent-switcher-enabled"
|
|
756
|
+
checked={switcherEnabled}
|
|
757
|
+
onChange={(event) => setSwitcherEnabled(event.target.checked)}
|
|
758
|
+
disabled={saving}
|
|
759
|
+
/>
|
|
760
|
+
<span>{props.texts.settingsAgentsSwitcherEnabledLabel}</span>
|
|
761
|
+
</label>
|
|
762
|
+
<p className="data-club-ai-hub-admin__form-helper">
|
|
763
|
+
{props.texts.settingsAgentsSwitcherEnabledHelper}
|
|
764
|
+
</p>
|
|
765
|
+
{flash !== null ? (
|
|
766
|
+
<div
|
|
767
|
+
className={
|
|
768
|
+
flash.tone === "success"
|
|
769
|
+
? "data-club-ai-hub-admin__flash data-club-ai-hub-admin__flash--success"
|
|
770
|
+
: "data-club-ai-hub-admin__flash data-club-ai-hub-admin__flash--error"
|
|
771
|
+
}
|
|
772
|
+
data-testid="admin-settings-agents-flash"
|
|
773
|
+
role={flash.tone === "error" ? "alert" : "status"}
|
|
774
|
+
>
|
|
775
|
+
{flash.text}
|
|
776
|
+
</div>
|
|
777
|
+
) : null}
|
|
778
|
+
<button
|
|
779
|
+
type="submit"
|
|
780
|
+
className="data-club-ai-hub-admin__button data-club-ai-hub-admin__button--primary"
|
|
781
|
+
data-testid="admin-settings-agents-save"
|
|
782
|
+
disabled={saving}
|
|
783
|
+
>
|
|
784
|
+
{saving
|
|
785
|
+
? props.texts.settingsSaveSavingButton
|
|
786
|
+
: props.texts.settingsSaveAgentsButton}
|
|
787
|
+
</button>
|
|
788
|
+
</form>
|
|
789
|
+
</section>
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
|
|
649
793
|
/* ────────────────────────────────────────────────────────────────────────── */
|
|
650
794
|
/* Section: Feature toggles */
|
|
651
795
|
/* ────────────────────────────────────────────────────────────────────────── */
|
package/src/types.ts
CHANGED
|
@@ -112,6 +112,17 @@ export interface AIHubDeployment {
|
|
|
112
112
|
* per-device choice.
|
|
113
113
|
*/
|
|
114
114
|
user_language_locked: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* ai-hub agent id auto-opened on load (skipping the agents picker). `null` =
|
|
117
|
+
* no default → the picker is shown. Ignored when only one agent exists (that
|
|
118
|
+
* one always opens). A dangling id falls back to the picker.
|
|
119
|
+
*/
|
|
120
|
+
default_agent_id: string | null;
|
|
121
|
+
/**
|
|
122
|
+
* When `false`, users can't switch agents — the "← Agents" back link is
|
|
123
|
+
* hidden. (Also hidden whenever only one agent exists, regardless of this.)
|
|
124
|
+
*/
|
|
125
|
+
agent_switcher_enabled: boolean;
|
|
115
126
|
/**
|
|
116
127
|
* Browser-facing URL of the self-hosted Letta ADE — only present when the
|
|
117
128
|
* caller's role is `power_user` or higher. Absent for `user`-role callers.
|