automagik-cli
Version:
Automagik CLI - A powerful command-line interface for interacting with Automagik Hive multi-agent AI systems
202 lines (201 loc) • 7.7 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { appConfig } from '../../config/settings.js';
import { localAPIClient } from '../../config/localClient.js';
import { resolve } from 'path';
import { writeFile, readFile, mkdir } from 'fs/promises';
import { existsSync } from 'fs';
const SessionContext = createContext(undefined);
export const useSession = () => {
const context = useContext(SessionContext);
if (!context) {
throw new Error('useSession must be used within a SessionProvider');
}
return context;
};
export const SessionProvider = ({ children }) => {
const [history, setHistory] = useState([]);
const [currentSessionId, setCurrentSessionId] = useState('');
const [currentTarget, setCurrentTarget] = useState(null);
const [nextMessageId, setNextMessageId] = useState(1);
// Initialize session
useEffect(() => {
const initSession = async () => {
const sessionId = generateSessionId();
setCurrentSessionId(sessionId);
// Ensure session directory exists
try {
const sessionDir = getSessionDir();
if (!existsSync(sessionDir)) {
await mkdir(sessionDir, { recursive: true });
}
}
catch (error) {
console.error('Failed to create session directory:', error);
}
};
initSession();
}, []);
const generateSessionId = useCallback(() => {
return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}, []);
const getSessionDir = useCallback(() => {
const sessionDir = appConfig.sessionDir.replace('~', process.env.HOME || '');
return resolve(sessionDir);
}, []);
const getSessionFilePath = useCallback((sessionId) => {
return resolve(getSessionDir(), `${sessionId}.json`);
}, [getSessionDir]);
const addMessage = useCallback((message) => {
const newMessage = {
...message,
id: nextMessageId,
};
setHistory(prev => [...prev, newMessage]);
setNextMessageId(prev => prev + 1);
// Auto-save if enabled
if (appConfig.sessionAutoSave) {
saveSessionData(); // No delay
}
}, [nextMessageId]);
const clearHistory = useCallback(() => {
setHistory([]);
setNextMessageId(1);
}, []);
const saveSessionData = useCallback(async () => {
if (!currentSessionId || history.length === 0) {
return;
}
const sessionData = {
id: currentSessionId,
messages: history,
createdAt: history[0]?.timestamp || Date.now(),
updatedAt: Date.now(),
metadata: {
totalMessages: history.length,
lastTarget: history[history.length - 1]?.metadata?.target,
},
};
try {
const filePath = getSessionFilePath(currentSessionId);
await writeFile(filePath, JSON.stringify(sessionData, null, 2), 'utf8');
if (appConfig.cliDebug) {
console.log(`Session saved: ${filePath}`);
}
}
catch (error) {
console.error('Failed to save session:', error);
}
}, [currentSessionId, history, getSessionFilePath]);
const loadSessionData = useCallback(async (sessionId) => {
try {
const filePath = getSessionFilePath(sessionId);
const data = await readFile(filePath, 'utf8');
const sessionData = JSON.parse(data);
setHistory(sessionData.messages);
setCurrentSessionId(sessionId);
setNextMessageId(Math.max(...sessionData.messages.map(m => m.id), 0) + 1);
if (appConfig.cliDebug) {
console.log(`Session loaded: ${filePath}`);
}
}
catch (error) {
console.error('Failed to load session:', error);
throw error;
}
}, [getSessionFilePath]);
const createNewSession = useCallback((target) => {
const newSessionId = generateSessionId();
setCurrentSessionId(newSessionId);
setHistory([]);
setNextMessageId(1);
if (target) {
setCurrentTarget(target);
}
}, [generateSessionId]);
const listSessions = useCallback(async (target) => {
try {
const { readdir } = await import('fs/promises');
const sessionDir = getSessionDir();
if (!existsSync(sessionDir)) {
return [];
}
const files = await readdir(sessionDir);
const sessionFiles = files.filter(file => file.endsWith('.json'));
const sessions = [];
for (const file of sessionFiles) {
try {
const sessionId = file.replace('.json', '');
const filePath = getSessionFilePath(sessionId);
const data = await readFile(filePath, 'utf8');
const sessionData = JSON.parse(data);
sessions.push(sessionData);
}
catch (error) {
console.error(`Failed to load session ${file}:`, error);
}
}
return sessions.sort((a, b) => b.updatedAt - a.updatedAt); // Most recent first
}
catch (error) {
console.error('Failed to list sessions:', error);
return [];
}
}, [getSessionDir, getSessionFilePath]);
const listBackendSessions = useCallback(async (target) => {
try {
const endpoint = `/playground/${target.type}s/${target.id}/sessions`;
const response = await localAPIClient.apiCall(endpoint, { method: 'GET' });
if (response.error) {
throw new Error(`Failed to fetch sessions: ${response.error}`);
}
return Array.isArray(response.data) ? response.data : [];
}
catch (error) {
console.error('Failed to list backend sessions:', error);
return [];
}
}, []);
const getSessionMetadata = useCallback(async (sessionId) => {
try {
const filePath = getSessionFilePath(sessionId);
const data = await readFile(filePath, 'utf8');
const sessionData = JSON.parse(data);
return sessionData;
}
catch (error) {
console.error(`Failed to get session metadata for ${sessionId}:`, error);
return null;
}
}, [getSessionFilePath]);
const deleteSession = useCallback(async (sessionId) => {
try {
const filePath = getSessionFilePath(sessionId);
const { unlink } = await import('fs/promises');
await unlink(filePath);
if (appConfig.cliDebug) {
console.log(`Session deleted: ${filePath}`);
}
}
catch (error) {
console.error('Failed to delete session:', error);
throw error;
}
}, [getSessionFilePath]);
const contextValue = {
history,
currentSessionId,
currentTarget,
addMessage,
clearHistory,
saveSession: saveSessionData,
loadSession: loadSessionData,
createNewSession,
listSessions,
listBackendSessions,
deleteSession,
getSessionMetadata,
setCurrentTarget,
};
return (_jsx(SessionContext.Provider, { value: contextValue, children: children }));
};