fix(agent-office): CommandTab approval state + blog→insta agent
- Approval card gated on 'waiting_approval' (was 'waiting'), matching the state useAgentManager emits — previously the approval UI was silently suppressed and pendingTask buttons unreachable - QUICK_ACTIONS/PARAM_ACTIONS: drop blog (agent removed), add insta (extract / collect_trends / render) - Regression test covers the three approval-card branches Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 MiB |
@@ -5,7 +5,7 @@ import { sendAgentCommand, approveAgentTask } from '../../../api';
|
||||
const QUICK_ACTIONS = {
|
||||
stock: [{ action: 'fetch_news', label: 'Fetch News' }, { action: 'test_telegram', label: 'Test Telegram' }],
|
||||
music: [{ action: 'credits', label: 'Check Credits' }],
|
||||
blog: [{ action: 'list_trend_keywords', label: 'List Keywords' }],
|
||||
insta: [{ action: 'extract', label: 'Extract News' }, { action: 'collect_trends', label: 'Collect Trends' }],
|
||||
realestate: [{ action: 'dashboard', label: 'Dashboard' }],
|
||||
lotto: [{ action: 'status', label: 'Status' }, { action: 'curate_now', label: 'Curate Now' }]
|
||||
};
|
||||
@@ -13,7 +13,7 @@ const QUICK_ACTIONS = {
|
||||
const PARAM_ACTIONS = {
|
||||
stock: { action: 'add_alert', label: 'Add Alert', placeholder: '{"symbol":"005930","target_price":70000,"direction":"above"}' },
|
||||
music: { action: 'compose', label: 'Compose', placeholder: 'jazzy lo-fi piano beat' },
|
||||
blog: { action: 'research', label: 'Research', placeholder: 'keyword to research' },
|
||||
insta: { action: 'render', label: 'Render Slate', placeholder: 'keyword_id (예: 42)' },
|
||||
realestate: { action: 'fetch_matches', label: 'Fetch Matches', placeholder: '' },
|
||||
lotto: null
|
||||
};
|
||||
@@ -46,6 +46,8 @@ export default function CommandTab({ agentId, agentState, pendingTask, onCommand
|
||||
params = { prompt: paramInput };
|
||||
} else if (paramAction.action === 'research') {
|
||||
params = { keyword: paramInput };
|
||||
} else if (paramAction.action === 'render') {
|
||||
params = { keyword_id: parseInt(paramInput, 10) };
|
||||
} else {
|
||||
try { params = JSON.parse(paramInput); } catch { params = { value: paramInput }; }
|
||||
}
|
||||
@@ -87,7 +89,7 @@ export default function CommandTab({ agentId, agentState, pendingTask, onCommand
|
||||
return (
|
||||
<div className="ao-command-tab">
|
||||
{/* 승인 대기 UI */}
|
||||
{agentState === 'waiting' && pendingTask && (
|
||||
{agentState === 'waiting_approval' && pendingTask && (
|
||||
<div className="ao-approval-card">
|
||||
<div className="ao-approval-title">Awaiting Approval</div>
|
||||
<div className="ao-approval-desc">{pendingTask.task_type}: {pendingTask.detail || JSON.stringify(pendingTask.input_data)}</div>
|
||||
|
||||
51
src/pages/agent-office/components/CommandTab.test.jsx
Normal file
51
src/pages/agent-office/components/CommandTab.test.jsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import CommandTab from './CommandTab.jsx';
|
||||
|
||||
vi.mock('../../../api', () => ({
|
||||
sendAgentCommand: vi.fn(),
|
||||
approveAgentTask: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('CommandTab approval card', () => {
|
||||
const samplePendingTask = {
|
||||
id: 'task-123',
|
||||
task_type: 'lotto_briefing',
|
||||
input_data: { draw_no: 1234 },
|
||||
};
|
||||
|
||||
it('agentState가 waiting_approval이고 pendingTask가 있으면 승인 카드를 표시', () => {
|
||||
render(
|
||||
<CommandTab
|
||||
agentId="lotto"
|
||||
agentState="waiting_approval"
|
||||
pendingTask={samplePendingTask}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('Awaiting Approval')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Approve' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Reject' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('agentState가 working이면 승인 카드를 표시하지 않음', () => {
|
||||
render(
|
||||
<CommandTab
|
||||
agentId="lotto"
|
||||
agentState="working"
|
||||
pendingTask={samplePendingTask}
|
||||
/>
|
||||
);
|
||||
expect(screen.queryByText('Awaiting Approval')).toBeNull();
|
||||
});
|
||||
|
||||
it('pendingTask가 null이면 waiting_approval이어도 승인 카드를 표시하지 않음', () => {
|
||||
render(
|
||||
<CommandTab
|
||||
agentId="lotto"
|
||||
agentState="waiting_approval"
|
||||
pendingTask={null}
|
||||
/>
|
||||
);
|
||||
expect(screen.queryByText('Awaiting Approval')).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user