apteva 0.4.51 → 0.4.52

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.
@@ -1,3 +1,3 @@
1
- import{c as a}from"./App.vza4fxg0.js";import"./App.9sryp183.js";import"./App.vkg121c6.js";import"./App.p7jjw1zf.js";import"./App.94x6mh7f.js";export{a as SettingsPage};
1
+ import{c as a}from"./App.pse0pzar.js";import"./App.9sryp183.js";import"./App.vkg121c6.js";import"./App.p7jjw1zf.js";import"./App.94x6mh7f.js";export{a as SettingsPage};
2
2
 
3
3
  //# debugId=96AC58639A6F59EB64756E2164756E21
package/dist/index.html CHANGED
@@ -11,6 +11,6 @@
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
14
- <script type="module" src="/App.k4nmqgek.js"></script>
14
+ <script type="module" src="/App.r43t58w6.js"></script>
15
15
  </body>
16
16
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apteva",
3
- "version": "0.4.51",
3
+ "version": "0.4.52",
4
4
  "description": "Run AI agents locally. Multi-provider support for Claude, GPT, Gemini, Llama, and more.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -451,13 +451,6 @@ export async function startAgentProcess(
451
451
  // Mark as starting
452
452
  agentsStarting.add(agent.id);
453
453
 
454
- // Get the API key for the agent's provider
455
- const providerKey = ProviderKeys.getDecrypted(agent.provider);
456
- if (!providerKey) {
457
- agentsStarting.delete(agent.id);
458
- return { success: false, error: `No API key for provider: ${agent.provider}` };
459
- }
460
-
461
454
  // Get provider config for env var name
462
455
  const providerConfig = PROVIDERS[agent.provider as ProviderId];
463
456
  if (!providerConfig) {
@@ -465,6 +458,14 @@ export async function startAgentProcess(
465
458
  return { success: false, error: `Unknown provider: ${agent.provider}` };
466
459
  }
467
460
 
461
+ // Get the API key for the agent's provider (local providers like Ollama use URL instead)
462
+ const isLocalProvider = "isLocal" in providerConfig && providerConfig.isLocal;
463
+ const providerKey = ProviderKeys.getDecrypted(agent.provider);
464
+ if (!providerKey && !isLocalProvider) {
465
+ agentsStarting.delete(agent.id);
466
+ return { success: false, error: `No API key for provider: ${agent.provider}` };
467
+ }
468
+
468
469
  // Use agent's permanently assigned port
469
470
  const port = agent.port;
470
471
  if (!port) {
@@ -553,7 +554,7 @@ export async function startAgentProcess(
553
554
  DATA_DIR: agentDataDir,
554
555
  CONFIG_PATH: agentConfigPath,
555
556
  AGENT_API_KEY: agentApiKey,
556
- [providerConfig.envVar]: providerKey,
557
+ [providerConfig.envVar]: providerKey || ("defaultBaseUrl" in providerConfig ? (providerConfig as any).defaultBaseUrl : ""),
557
558
  };
558
559
 
559
560
  // If memory is enabled and agent doesn't use OpenAI, also pass OpenAI key for embeddings
@@ -1457,6 +1457,8 @@ function SettingsTab({ agent, providers, onUpdateAgent, onDeleteAgent }: {
1457
1457
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
1458
1458
  const [availableMcpServers, setAvailableMcpServers] = useState<McpServer[]>([]);
1459
1459
  const [availableSkills, setAvailableSkills] = useState<AvailableSkill[]>([]);
1460
+ const [ollamaModels, setOllamaModels] = useState<Array<{ value: string; label: string }>>([]);
1461
+ const [loadingOllamaModels, setLoadingOllamaModels] = useState(false);
1460
1462
  const [apiKey, setApiKey] = useState<string | null>(null);
1461
1463
  const [apiKeyFull, setApiKeyFull] = useState<string | null>(null);
1462
1464
  const [showApiKey, setShowApiKey] = useState(false);
@@ -1531,6 +1533,27 @@ function SettingsTab({ agent, providers, onUpdateAgent, onDeleteAgent }: {
1531
1533
  fetchSkills();
1532
1534
  }, [authFetch]);
1533
1535
 
1536
+ // Fetch Ollama models when Ollama is selected
1537
+ useEffect(() => {
1538
+ if (form.provider === "ollama") {
1539
+ setLoadingOllamaModels(true);
1540
+ authFetch("/api/providers/ollama/models")
1541
+ .then(res => res.json())
1542
+ .then(data => {
1543
+ if (data.models && data.models.length > 0) {
1544
+ setOllamaModels(data.models.map((m: { value: string; label?: string }) => ({
1545
+ value: m.value,
1546
+ label: m.label || m.value,
1547
+ })));
1548
+ }
1549
+ })
1550
+ .catch(() => setOllamaModels([]))
1551
+ .finally(() => setLoadingOllamaModels(false));
1552
+ } else {
1553
+ setOllamaModels([]);
1554
+ }
1555
+ }, [form.provider, authFetch]);
1556
+
1534
1557
  // Reset form when agent changes
1535
1558
  useEffect(() => {
1536
1559
  setForm({
@@ -1554,11 +1577,13 @@ function SettingsTab({ agent, providers, onUpdateAgent, onDeleteAgent }: {
1554
1577
  .filter(p => p.hasKey && p.type === "llm")
1555
1578
  .map(p => ({ value: p.id, label: p.name }));
1556
1579
 
1557
- const modelOptions = selectedProvider?.models.map(m => ({
1558
- value: m.value,
1559
- label: m.label,
1560
- recommended: m.recommended,
1561
- })) || [];
1580
+ const modelOptions = form.provider === "ollama" && ollamaModels.length > 0
1581
+ ? ollamaModels
1582
+ : selectedProvider?.models.map(m => ({
1583
+ value: m.value,
1584
+ label: m.label,
1585
+ recommended: m.recommended,
1586
+ })) || [];
1562
1587
 
1563
1588
  const handleProviderChange = (providerId: string) => {
1564
1589
  const provider = providers.find(p => p.id === providerId);
@@ -1704,11 +1729,19 @@ function SettingsTab({ agent, providers, onUpdateAgent, onDeleteAgent }: {
1704
1729
  </FormField>
1705
1730
 
1706
1731
  <FormField label="Model">
1707
- <Select
1708
- value={form.model}
1709
- options={modelOptions}
1710
- onChange={(value) => setForm(prev => ({ ...prev, model: value }))}
1711
- />
1732
+ {loadingOllamaModels ? (
1733
+ <div className="text-sm text-[var(--color-text-muted)] py-2">Loading Ollama models...</div>
1734
+ ) : form.provider === "ollama" && modelOptions.length === 0 ? (
1735
+ <div className="text-sm text-yellow-400/80 py-2">
1736
+ No models found. Run <code className="bg-[var(--color-surface-raised)] px-1 rounded">ollama pull llama3.3</code> to download a model.
1737
+ </div>
1738
+ ) : (
1739
+ <Select
1740
+ value={form.model}
1741
+ options={modelOptions}
1742
+ onChange={(value) => setForm(prev => ({ ...prev, model: value }))}
1743
+ />
1744
+ )}
1712
1745
  </FormField>
1713
1746
 
1714
1747
  <FormField label="System Prompt">
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { Modal } from "../common/Modal";
3
3
  import { Select } from "../common/Select";
4
4
  import { MemoryIcon, TasksIcon, FilesIcon, VisionIcon, OperatorIcon, McpIcon, RealtimeIcon, MultiAgentIcon } from "../common/Icons";
5
- import { useProjects } from "../../context";
5
+ import { useProjects, useAuth } from "../../context";
6
6
  import type { Provider, NewAgentForm, AgentFeatures, MultiAgentConfig } from "../../types";
7
7
  import { getMultiAgentConfig } from "../../types";
8
8
 
@@ -39,6 +39,7 @@ export function CreateAgentModal({
39
39
  onGoToSettings,
40
40
  }: CreateAgentModalProps) {
41
41
  const { projects, currentProjectId } = useProjects();
42
+ const { authFetch } = useAuth();
42
43
  const selectedProvider = providers.find(p => p.id === form.provider);
43
44
  const [ollamaModels, setOllamaModels] = React.useState<Array<{ value: string; label: string }>>([]);
44
45
  const [loadingOllamaModels, setLoadingOllamaModels] = React.useState(false);
@@ -47,7 +48,7 @@ export function CreateAgentModal({
47
48
  React.useEffect(() => {
48
49
  if (form.provider === "ollama") {
49
50
  setLoadingOllamaModels(true);
50
- fetch("/api/providers/ollama/models")
51
+ authFetch("/api/providers/ollama/models")
51
52
  .then(res => res.json())
52
53
  .then(data => {
53
54
  if (data.models && data.models.length > 0) {
@@ -1027,6 +1027,7 @@ function ProviderKeyCard({
1027
1027
  extraField,
1028
1028
  onExtraFieldChange,
1029
1029
  }: ProviderKeyCardProps) {
1030
+ const { authFetch: providerAuthFetch } = useAuth();
1030
1031
  const isOllama = provider.id === "ollama";
1031
1032
  const isCDP = provider.id === "cdp";
1032
1033
  const isUrlBased = isOllama || isCDP;
@@ -1038,11 +1039,11 @@ function ProviderKeyCard({
1038
1039
 
1039
1040
  // Check Ollama status when configured or after install
1040
1041
  const checkOllamaStatus = React.useCallback(() => {
1041
- fetch("/api/providers/ollama/status")
1042
+ providerAuthFetch("/api/providers/ollama/status")
1042
1043
  .then(res => res.json())
1043
1044
  .then(data => setOllamaStatus({ connected: data.connected, modelCount: data.modelCount, isDocker: data.isDocker }))
1044
1045
  .catch(() => setOllamaStatus({ connected: false }));
1045
- }, []);
1046
+ }, [providerAuthFetch]);
1046
1047
 
1047
1048
  React.useEffect(() => {
1048
1049
  if (isOllama) {
@@ -1054,7 +1055,7 @@ function ProviderKeyCard({
1054
1055
  setInstalling(true);
1055
1056
  setInstallResult(null);
1056
1057
  try {
1057
- const res = await fetch("/api/providers/ollama/install", { method: "POST" });
1058
+ const res = await providerAuthFetch("/api/providers/ollama/install", { method: "POST" });
1058
1059
  const data = await res.json();
1059
1060
  if (data.success) {
1060
1061
  setInstallResult({ success: true, message: data.message });