mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
feat(settings): make action_dir editable via Settings → Agent access (#3313)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
This commit is contained in:
co-authored by
Steven Enamakel
parent
0d9002fcfc
commit
ce3ac82ecf
@@ -84,8 +84,6 @@ const AgentAccessPanel = () => {
|
||||
// RPC is pending or when not running under Tauri — the JSX falls back to
|
||||
// the documented defaults so the section never renders empty.
|
||||
const [agentPaths, setAgentPaths] = useState<AgentPaths | null>(null);
|
||||
// Editable action_dir (issue #3240). `actionDirEditing` toggles the input;
|
||||
// `actionDirInput` holds the in-progress value; error/saved are inline status.
|
||||
const [actionDirEditing, setActionDirEditing] = useState(false);
|
||||
const [actionDirInput, setActionDirInput] = useState('');
|
||||
const [actionDirError, setActionDirError] = useState<string | null>(null);
|
||||
@@ -130,6 +128,7 @@ const AgentAccessPanel = () => {
|
||||
const pathsResp = await openhumanGetAgentPaths();
|
||||
if (cancelled) return;
|
||||
setAgentPaths(pathsResp.result);
|
||||
setActionDirInput(pathsResp.result.action_dir);
|
||||
} catch {
|
||||
// Non-fatal: the Directories section falls back to the documented
|
||||
// defaults below. We don't gate the rest of the panel on this.
|
||||
|
||||
@@ -296,8 +296,6 @@ describe('AgentAccessPanel', () => {
|
||||
);
|
||||
});
|
||||
|
||||
// ── Editable action_dir (issue #3240) ───────────────────────────────────────
|
||||
|
||||
it('shows an Edit affordance for action_dir when the source is not env', async () => {
|
||||
mockGetAgentPaths.mockResolvedValue({
|
||||
result: agentPaths({ action_dir: '/Users/sample/projects', action_dir_source: 'default' }),
|
||||
@@ -348,7 +346,6 @@ describe('AgentAccessPanel', () => {
|
||||
expect(await screen.findByTestId('agent-access-action-dir-error')).toHaveTextContent(
|
||||
'action_dir must be an absolute path'
|
||||
);
|
||||
// Still in edit mode so the user can correct the value.
|
||||
expect(screen.getByTestId('agent-access-action-dir-input')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -3683,6 +3683,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'محظور على الوكيل',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'قواعد بيانات الذاكرة والجلسات والرموز وغيرها من البيانات الأساسية. غير متاحة لأدوات الوكيل.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'مسار صندوق إجراءات الوكيل',
|
||||
'settings.agentAccess.actionDirSave': 'حفظ',
|
||||
'settings.agentAccess.actionDirSaving': 'جارٍ الحفظ…',
|
||||
'settings.agentAccess.actionDirSaved': 'تم تحديث صندوق الإجراءات.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'لا يمكن أن يكون المسار فارغًا.',
|
||||
'settings.agentAccess.actionDirSaveError': 'تعذّر تحديث صندوق الإجراءات.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'تم ضبط OPENHUMAN_ACTION_DIR — قم بإلغاء متغير البيئة لتعديل هذا من الإعدادات.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'تم تجاوزه بواسطة OPENHUMAN_ACTION_DIR — قم بإلغاء متغير البيئة لإدارته من الإعدادات.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3755,6 +3755,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'এজেন্ট-অবরুদ্ধ',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'মেমরি ডেটাবেস, সেশন, টোকেন এবং অন্যান্য মূল ডেটা। এজেন্ট টুলের কাছে অ্যাক্সেসযোগ্য নয়।',
|
||||
'settings.agentAccess.actionDirInputLabel': 'অ্যাকশন স্যান্ডবক্স পাথ',
|
||||
'settings.agentAccess.actionDirSave': 'সংরক্ষণ',
|
||||
'settings.agentAccess.actionDirSaving': 'সংরক্ষণ করা হচ্ছে…',
|
||||
'settings.agentAccess.actionDirSaved': 'অ্যাকশন স্যান্ডবক্স আপডেট করা হয়েছে।',
|
||||
'settings.agentAccess.actionDirEmptyError': 'পাথ ফাঁকা থাকতে পারবে না।',
|
||||
'settings.agentAccess.actionDirSaveError': 'অ্যাকশন স্যান্ডবক্স আপডেট করা যায়নি।',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR সেট করা আছে — সেটিংস থেকে সম্পাদনা করতে এনভ ভ্যারিয়েবলটি আনসেট করুন।',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'OPENHUMAN_ACTION_DIR দ্বারা ওভাররাইড হয়েছে — সেটিংস থেকে পরিচালনা করতে এনভ ভ্যারিয়েবলটি আনসেট করুন।',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3854,6 +3854,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'Agent-gesperrt',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'Speicherdatenbanken, Sitzungen, Token und andere Kerndaten. Für Agent-Tools nicht zugänglich.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'Pfad der Aktions-Sandbox',
|
||||
'settings.agentAccess.actionDirSave': 'Speichern',
|
||||
'settings.agentAccess.actionDirSaving': 'Wird gespeichert…',
|
||||
'settings.agentAccess.actionDirSaved': 'Aktions-Sandbox aktualisiert.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'Pfad darf nicht leer sein.',
|
||||
'settings.agentAccess.actionDirSaveError': 'Aktions-Sandbox konnte nicht aktualisiert werden.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR ist gesetzt — entferne die Umgebungsvariable, um dies in den Einstellungen zu bearbeiten.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'Durch OPENHUMAN_ACTION_DIR überschrieben — entferne die Umgebungsvariable, um dies in den Einstellungen zu verwalten.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -4144,6 +4144,16 @@ const en: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'agent-blocked',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'Memory databases, sessions, tokens, and other core persistence. Not accessible to agent tools.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'Action sandbox path',
|
||||
'settings.agentAccess.actionDirSave': 'Save',
|
||||
'settings.agentAccess.actionDirSaving': 'Saving…',
|
||||
'settings.agentAccess.actionDirSaved': 'Action sandbox updated.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'Path cannot be empty.',
|
||||
'settings.agentAccess.actionDirSaveError': 'Could not update the action sandbox.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR is set — unset the env var to edit this from Settings.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'Overridden by OPENHUMAN_ACTION_DIR — unset the env var to manage from Settings.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3828,6 +3828,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'bloqueado para el agente',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'Bases de datos de memoria, sesiones, tokens y otros datos esenciales. No accesible para herramientas del agente.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'Ruta del sandbox de acciones',
|
||||
'settings.agentAccess.actionDirSave': 'Guardar',
|
||||
'settings.agentAccess.actionDirSaving': 'Guardando…',
|
||||
'settings.agentAccess.actionDirSaved': 'Sandbox de acciones actualizado.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'La ruta no puede estar vacía.',
|
||||
'settings.agentAccess.actionDirSaveError': 'No se pudo actualizar el sandbox de acciones.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR está definido — elimina la variable de entorno para editar esto desde Ajustes.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'Anulado por OPENHUMAN_ACTION_DIR — elimina la variable de entorno para gestionarlo desde Ajustes.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3839,6 +3839,17 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': "bloqué pour l'agent",
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
"Bases de données mémoire, sessions, jetons et autres données essentielles. Non accessible aux outils de l'agent.",
|
||||
'settings.agentAccess.actionDirInputLabel': "Chemin du bac à sable d'actions",
|
||||
'settings.agentAccess.actionDirSave': 'Enregistrer',
|
||||
'settings.agentAccess.actionDirSaving': 'Enregistrement…',
|
||||
'settings.agentAccess.actionDirSaved': "Bac à sable d'actions mis à jour.",
|
||||
'settings.agentAccess.actionDirEmptyError': 'Le chemin ne peut pas être vide.',
|
||||
'settings.agentAccess.actionDirSaveError':
|
||||
"Impossible de mettre à jour le bac à sable d'actions.",
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
"OPENHUMAN_ACTION_DIR est défini — désactivez la variable d'environnement pour modifier cela depuis les Paramètres.",
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
"Remplacé par OPENHUMAN_ACTION_DIR — désactivez la variable d'environnement pour gérer cela depuis les Paramètres.",
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3764,6 +3764,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'एजेंट-अवरुद्ध',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'मेमोरी डेटाबेस, सत्र, टोकन और अन्य मुख्य डेटा। एजेंट टूल के लिए सुलभ नहीं।',
|
||||
'settings.agentAccess.actionDirInputLabel': 'क्रिया सैंडबॉक्स पथ',
|
||||
'settings.agentAccess.actionDirSave': 'सहेजें',
|
||||
'settings.agentAccess.actionDirSaving': 'सहेजा जा रहा है…',
|
||||
'settings.agentAccess.actionDirSaved': 'क्रिया सैंडबॉक्स अपडेट किया गया।',
|
||||
'settings.agentAccess.actionDirEmptyError': 'पथ खाली नहीं हो सकता।',
|
||||
'settings.agentAccess.actionDirSaveError': 'क्रिया सैंडबॉक्स अपडेट नहीं किया जा सका।',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR सेट है — सेटिंग्स से संपादित करने के लिए env चर हटाएँ।',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'OPENHUMAN_ACTION_DIR द्वारा ओवरराइड किया गया — सेटिंग्स से प्रबंधित करने के लिए env चर हटाएँ।',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3771,6 +3771,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'diblokir untuk agen',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'Database memori, sesi, token, dan data inti lainnya. Tidak dapat diakses oleh alat agen.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'Jalur sandbox tindakan',
|
||||
'settings.agentAccess.actionDirSave': 'Simpan',
|
||||
'settings.agentAccess.actionDirSaving': 'Menyimpan…',
|
||||
'settings.agentAccess.actionDirSaved': 'Sandbox tindakan diperbarui.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'Jalur tidak boleh kosong.',
|
||||
'settings.agentAccess.actionDirSaveError': 'Tidak dapat memperbarui sandbox tindakan.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR sudah diatur — hapus variabel env untuk mengedit ini dari Pengaturan.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'Ditimpa oleh OPENHUMAN_ACTION_DIR — hapus variabel env untuk mengelola dari Pengaturan.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3820,6 +3820,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': "bloccato per l'agente",
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
"Database memoria, sessioni, token e altri dati fondamentali. Non accessibile dagli strumenti dell'agente.",
|
||||
'settings.agentAccess.actionDirInputLabel': 'Percorso della sandbox delle azioni',
|
||||
'settings.agentAccess.actionDirSave': 'Salva',
|
||||
'settings.agentAccess.actionDirSaving': 'Salvataggio…',
|
||||
'settings.agentAccess.actionDirSaved': 'Sandbox delle azioni aggiornata.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'Il percorso non può essere vuoto.',
|
||||
'settings.agentAccess.actionDirSaveError': 'Impossibile aggiornare la sandbox delle azioni.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
"OPENHUMAN_ACTION_DIR è impostata — rimuovi la variabile d'ambiente per modificarla dalle Impostazioni.",
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
"Sovrascritta da OPENHUMAN_ACTION_DIR — rimuovi la variabile d'ambiente per gestirla dalle Impostazioni.",
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3717,6 +3717,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': '에이전트 차단됨',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'메모리 데이터베이스, 세션, 토큰 및 기타 핵심 데이터. 에이전트 도구에서 접근할 수 없습니다.',
|
||||
'settings.agentAccess.actionDirInputLabel': '작업 샌드박스 경로',
|
||||
'settings.agentAccess.actionDirSave': '저장',
|
||||
'settings.agentAccess.actionDirSaving': '저장 중…',
|
||||
'settings.agentAccess.actionDirSaved': '작업 샌드박스가 업데이트되었습니다.',
|
||||
'settings.agentAccess.actionDirEmptyError': '경로는 비워둘 수 없습니다.',
|
||||
'settings.agentAccess.actionDirSaveError': '작업 샌드박스를 업데이트할 수 없습니다.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR이 설정되어 있습니다 — 설정에서 편집하려면 환경 변수를 해제하세요.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'OPENHUMAN_ACTION_DIR에 의해 재정의됨 — 설정에서 관리하려면 환경 변수를 해제하세요.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3822,6 +3822,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'zablokowane dla agenta',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'Bazy danych pamięci, sesje, tokeny i inne podstawowe dane. Niedostępne dla narzędzi agenta.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'Ścieżka piaskownicy działań',
|
||||
'settings.agentAccess.actionDirSave': 'Zapisz',
|
||||
'settings.agentAccess.actionDirSaving': 'Zapisywanie…',
|
||||
'settings.agentAccess.actionDirSaved': 'Piaskownica działań zaktualizowana.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'Ścieżka nie może być pusta.',
|
||||
'settings.agentAccess.actionDirSaveError': 'Nie udało się zaktualizować piaskownicy działań.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR jest ustawione — usuń zmienną środowiskową, aby edytować to w Ustawieniach.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'Nadpisane przez OPENHUMAN_ACTION_DIR — usuń zmienną środowiskową, aby zarządzać tym w Ustawieniach.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3821,6 +3821,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'bloqueado para o agente',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'Bancos de dados de memória, sessões, tokens e outros dados essenciais. Não acessível pelas ferramentas do agente.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'Caminho da sandbox de ações',
|
||||
'settings.agentAccess.actionDirSave': 'Salvar',
|
||||
'settings.agentAccess.actionDirSaving': 'Salvando…',
|
||||
'settings.agentAccess.actionDirSaved': 'Sandbox de ações atualizada.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'O caminho não pode estar vazio.',
|
||||
'settings.agentAccess.actionDirSaveError': 'Não foi possível atualizar a sandbox de ações.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR está definido — remova a variável de ambiente para editar isto em Configurações.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'Substituído por OPENHUMAN_ACTION_DIR — remova a variável de ambiente para gerenciar em Configurações.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3790,6 +3790,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': 'заблокировано для агента',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'Базы данных памяти, сеансы, токены и другие основные данные. Недоступно для инструментов агента.',
|
||||
'settings.agentAccess.actionDirInputLabel': 'Путь к песочнице действий',
|
||||
'settings.agentAccess.actionDirSave': 'Сохранить',
|
||||
'settings.agentAccess.actionDirSaving': 'Сохранение…',
|
||||
'settings.agentAccess.actionDirSaved': 'Песочница действий обновлена.',
|
||||
'settings.agentAccess.actionDirEmptyError': 'Путь не может быть пустым.',
|
||||
'settings.agentAccess.actionDirSaveError': 'Не удалось обновить песочницу действий.',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR установлена — снимите переменную окружения, чтобы изменить это в Настройках.',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'Переопределено OPENHUMAN_ACTION_DIR — снимите переменную окружения, чтобы управлять этим в Настройках.',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -3574,6 +3574,16 @@ const messages: TranslationMap = {
|
||||
'settings.agentAccess.agentBlocked': '代理已阻止',
|
||||
'settings.agentAccess.internalStateDesc':
|
||||
'内存数据库、会话、令牌和其他核心数据。代理工具无法访问。',
|
||||
'settings.agentAccess.actionDirInputLabel': '操作沙箱路径',
|
||||
'settings.agentAccess.actionDirSave': '保存',
|
||||
'settings.agentAccess.actionDirSaving': '正在保存…',
|
||||
'settings.agentAccess.actionDirSaved': '操作沙箱已更新。',
|
||||
'settings.agentAccess.actionDirEmptyError': '路径不能为空。',
|
||||
'settings.agentAccess.actionDirSaveError': '无法更新操作沙箱。',
|
||||
'settings.agentAccess.actionDirEnvOverrideError':
|
||||
'OPENHUMAN_ACTION_DIR 已设置 — 请取消该环境变量以在设置中编辑此项。',
|
||||
'settings.agentAccess.actionDirEnvOverrideNote':
|
||||
'已被 OPENHUMAN_ACTION_DIR 覆盖 — 请取消该环境变量以在设置中管理。',
|
||||
'settings.agentAccess.approvalHistory': 'Approval history',
|
||||
'settings.agentAccess.approvalHistoryDesc':
|
||||
'Review past Approve / Deny decisions the agent requested.',
|
||||
|
||||
@@ -452,18 +452,9 @@ export async function openhumanGetAgentPaths(): Promise<CommandResponse<AgentPat
|
||||
|
||||
/** Partial update for the agent's editable filesystem roots (issue #3240). */
|
||||
export interface AgentPathsUpdate {
|
||||
/**
|
||||
* New absolute action sandbox path. An empty string clears the override and
|
||||
* reverts to the default; omit the field to leave it unchanged.
|
||||
*/
|
||||
action_dir?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the agent's `action_dir` sandbox root. The backend validates the path
|
||||
* (must be absolute; auto-creates a missing directory; rejects the internal
|
||||
* workspace dir) and returns the refreshed {@link AgentPaths} payload.
|
||||
*/
|
||||
export async function openhumanUpdateAgentPaths(
|
||||
update: AgentPathsUpdate
|
||||
): Promise<CommandResponse<AgentPaths>> {
|
||||
|
||||
@@ -2167,8 +2167,6 @@ pub struct SandboxSettingsPatch {
|
||||
pub env_passthrough: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/// Returns the current sandbox and Docker runtime settings merged into a
|
||||
/// single JSON object, plus a live status probe for Docker availability.
|
||||
pub async fn get_sandbox_settings() -> Result<RpcOutcome<serde_json::Value>, String> {
|
||||
let config = load_config_with_timeout().await?;
|
||||
let sandbox = &config.sandbox;
|
||||
@@ -2201,7 +2199,6 @@ pub async fn get_sandbox_settings() -> Result<RpcOutcome<serde_json::Value>, Str
|
||||
Ok(RpcOutcome::single_log(value, "sandbox settings read"))
|
||||
}
|
||||
|
||||
/// Updates sandbox and Docker runtime settings, persists to disk.
|
||||
pub async fn apply_sandbox_settings(
|
||||
config: &mut Config,
|
||||
update: SandboxSettingsPatch,
|
||||
@@ -2271,7 +2268,6 @@ pub async fn load_and_apply_sandbox_settings(
|
||||
apply_sandbox_settings(&mut config, update).await
|
||||
}
|
||||
|
||||
/// Probe Docker daemon availability via `docker info` with a 5s timeout.
|
||||
async fn is_docker_available() -> bool {
|
||||
let fut = tokio::process::Command::new("docker")
|
||||
.arg("info")
|
||||
@@ -2284,7 +2280,6 @@ async fn is_docker_available() -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Detect which OS-native sandbox backend is available.
|
||||
fn detect_os_sandbox_backend() -> &'static str {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
|
||||
@@ -1037,7 +1037,7 @@ pub fn schemas(function: &str) -> ControllerSchema {
|
||||
namespace: "config",
|
||||
function: "get_agent_paths",
|
||||
description:
|
||||
"Resolve the agent's filesystem roots (action_dir, workspace_dir, projects_dir) so the UI can render live values instead of hard-coded strings. Read-only.",
|
||||
"Resolve the agent's filesystem roots (action_dir, workspace_dir, projects_dir) so the UI can render live values instead of hard-coded strings. Read-only. Also returns `action_dir_env_override: bool` so the UI knows when OPENHUMAN_ACTION_DIR is forcing the value (Settings → action_dir editing disabled in that case).",
|
||||
inputs: vec![],
|
||||
outputs: vec
|
||||
/// (issue #3240) so a Settings-driven change of the agent's writable root
|
||||
/// takes effect immediately instead of waiting for the next session.
|
||||
///
|
||||
/// Returns the new generation on success, or `Err` if no policy is
|
||||
/// installed yet (typically a CLI-only invocation that never started a
|
||||
/// session runtime).
|
||||
pub fn update_action_dir(new_action_dir: PathBuf) -> Result<u64, String> {
|
||||
let Some(state) = STATE.get() else {
|
||||
return Err(
|
||||
"[security:live_policy] no policy installed yet — cannot update action_dir".into(),
|
||||
);
|
||||
};
|
||||
{
|
||||
let mut guard = state
|
||||
.action_dir
|
||||
.write()
|
||||
.map_err(|e| format!("[security:live_policy] action_dir lock poisoned: {e}"))?;
|
||||
*guard = new_action_dir.clone();
|
||||
}
|
||||
// Rebuild the policy by cloning the current one and swapping the
|
||||
// action_dir field. This preserves the entire autonomy + trusted_roots
|
||||
// + forbidden_paths state — the only thing changing is the sandbox root.
|
||||
let current_policy = state
|
||||
.policy
|
||||
.read()
|
||||
.map(|g| Arc::clone(&g))
|
||||
.map_err(|e| format!("[security:live_policy] policy lock poisoned: {e}"))?;
|
||||
let mut rebuilt: SecurityPolicy = (*current_policy).clone();
|
||||
rebuilt.action_dir = new_action_dir;
|
||||
{
|
||||
let mut guard = state
|
||||
.policy
|
||||
.write()
|
||||
.map_err(|e| format!("[security:live_policy] policy write lock poisoned: {e}"))?;
|
||||
*guard = Arc::new(rebuilt);
|
||||
}
|
||||
let gen = state.generation.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
tracing::info!(
|
||||
generation = gen,
|
||||
"[security:live_policy] SecurityPolicy reloaded after action_dir change"
|
||||
);
|
||||
Ok(gen)
|
||||
}
|
||||
|
||||
/// Rebuild the policy from `autonomy_config` against the stored workspace dir
|
||||
/// and swap it in, bumping the generation counter. No-op if nothing has been
|
||||
/// installed yet (e.g. a CLI invocation that never started a session runtime).
|
||||
|
||||
@@ -1147,7 +1147,7 @@ impl SecurityPolicy {
|
||||
/// through. Gray-area dirs (`/usr`, `/opt`, `/var`, `~/Library`) stay in the
|
||||
/// user-overridable `forbidden_paths` instead, so a grant can still reach
|
||||
/// e.g. `/usr/local/...`.
|
||||
fn is_always_forbidden(path: &Path) -> bool {
|
||||
pub(crate) fn is_always_forbidden(path: &Path) -> bool {
|
||||
// Normalize separators + case BEFORE splitting: a Windows backslash
|
||||
// path is a single component on POSIX (and vice-versa), so we segment
|
||||
// the normalized string rather than rely on `Path::components()`.
|
||||
|
||||
Reference in New Issue
Block a user