mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-17 06:04:56 +00:00
test: update snapshots and test gating
This commit is contained in:
parent
08c7723c26
commit
308d7f279c
14 changed files with 181 additions and 5 deletions
|
|
@ -678,6 +678,28 @@
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.empty-state-menu-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state-menu {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
margin-top: 4px;
|
||||||
|
min-width: 160px;
|
||||||
|
background: var(--surface);
|
||||||
|
border: 1px solid var(--border-2);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
|
||||||
|
padding: 6px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
z-index: 60;
|
||||||
|
}
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
|
||||||
|
|
@ -836,6 +836,9 @@ export default function App() {
|
||||||
onSendMessage={sendMessage}
|
onSendMessage={sendMessage}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
onCreateSession={createNewSession}
|
onCreateSession={createNewSession}
|
||||||
|
availableAgents={availableAgents}
|
||||||
|
agentsLoading={agentsLoading}
|
||||||
|
agentsError={agentsError}
|
||||||
messagesEndRef={messagesEndRef}
|
messagesEndRef={messagesEndRef}
|
||||||
agentLabel={agentLabel}
|
agentLabel={agentLabel}
|
||||||
agentMode={agentMode}
|
agentMode={agentMode}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { MessageSquare, PauseCircle, PlayCircle, Plus, Terminal } from "lucide-react";
|
import { MessageSquare, PauseCircle, PlayCircle, Plus, Terminal } from "lucide-react";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
import type { AgentModeInfo, PermissionEventData, QuestionEventData } from "sandbox-agent";
|
import type { AgentModeInfo, PermissionEventData, QuestionEventData } from "sandbox-agent";
|
||||||
import ApprovalsTab from "../debug/ApprovalsTab";
|
import ApprovalsTab from "../debug/ApprovalsTab";
|
||||||
import ChatInput from "./ChatInput";
|
import ChatInput from "./ChatInput";
|
||||||
|
|
@ -17,6 +18,9 @@ const ChatPanel = ({
|
||||||
onSendMessage,
|
onSendMessage,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
onCreateSession,
|
onCreateSession,
|
||||||
|
availableAgents,
|
||||||
|
agentsLoading,
|
||||||
|
agentsError,
|
||||||
messagesEndRef,
|
messagesEndRef,
|
||||||
agentLabel,
|
agentLabel,
|
||||||
agentMode,
|
agentMode,
|
||||||
|
|
@ -53,7 +57,10 @@ const ChatPanel = ({
|
||||||
onMessageChange: (value: string) => void;
|
onMessageChange: (value: string) => void;
|
||||||
onSendMessage: () => void;
|
onSendMessage: () => void;
|
||||||
onKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
|
onKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
|
||||||
onCreateSession: () => void;
|
onCreateSession: (agentId: string) => void;
|
||||||
|
availableAgents: string[];
|
||||||
|
agentsLoading: boolean;
|
||||||
|
agentsError: string | null;
|
||||||
messagesEndRef: React.RefObject<HTMLDivElement>;
|
messagesEndRef: React.RefObject<HTMLDivElement>;
|
||||||
agentLabel: string;
|
agentLabel: string;
|
||||||
agentMode: string;
|
agentMode: string;
|
||||||
|
|
@ -81,6 +88,29 @@ const ChatPanel = ({
|
||||||
onRejectQuestion: (requestId: string) => void;
|
onRejectQuestion: (requestId: string) => void;
|
||||||
onReplyPermission: (requestId: string, reply: "once" | "always" | "reject") => void;
|
onReplyPermission: (requestId: string, reply: "once" | "always" | "reject") => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const [showAgentMenu, setShowAgentMenu] = useState(false);
|
||||||
|
const menuRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!showAgentMenu) return;
|
||||||
|
const handler = (event: MouseEvent) => {
|
||||||
|
if (!menuRef.current) return;
|
||||||
|
if (!menuRef.current.contains(event.target as Node)) {
|
||||||
|
setShowAgentMenu(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener("mousedown", handler);
|
||||||
|
return () => document.removeEventListener("mousedown", handler);
|
||||||
|
}, [showAgentMenu]);
|
||||||
|
|
||||||
|
const agentLabels: Record<string, string> = {
|
||||||
|
claude: "Claude Code",
|
||||||
|
codex: "Codex",
|
||||||
|
opencode: "OpenCode",
|
||||||
|
amp: "Amp",
|
||||||
|
mock: "Mock"
|
||||||
|
};
|
||||||
|
|
||||||
const hasApprovals = questionRequests.length > 0 || permissionRequests.length > 0;
|
const hasApprovals = questionRequests.length > 0 || permissionRequests.length > 0;
|
||||||
const isTurnMode = streamMode === "turn";
|
const isTurnMode = streamMode === "turn";
|
||||||
const isStreaming = isTurnMode ? turnStreaming : polling;
|
const isStreaming = isTurnMode ? turnStreaming : polling;
|
||||||
|
|
@ -141,10 +171,37 @@ const ChatPanel = ({
|
||||||
<MessageSquare className="empty-state-icon" />
|
<MessageSquare className="empty-state-icon" />
|
||||||
<div className="empty-state-title">No Session Selected</div>
|
<div className="empty-state-title">No Session Selected</div>
|
||||||
<p className="empty-state-text">Create a new session to start chatting with an agent.</p>
|
<p className="empty-state-text">Create a new session to start chatting with an agent.</p>
|
||||||
<button className="button primary" onClick={onCreateSession}>
|
<div className="empty-state-menu-wrapper" ref={menuRef}>
|
||||||
<Plus className="button-icon" />
|
<button
|
||||||
Create Session
|
className="button primary"
|
||||||
</button>
|
onClick={() => setShowAgentMenu((value) => !value)}
|
||||||
|
>
|
||||||
|
<Plus className="button-icon" />
|
||||||
|
Create Session
|
||||||
|
</button>
|
||||||
|
{showAgentMenu && (
|
||||||
|
<div className="empty-state-menu">
|
||||||
|
{agentsLoading && <div className="sidebar-add-status">Loading agents...</div>}
|
||||||
|
{agentsError && <div className="sidebar-add-status error">{agentsError}</div>}
|
||||||
|
{!agentsLoading && !agentsError && availableAgents.length === 0 && (
|
||||||
|
<div className="sidebar-add-status">No agents available.</div>
|
||||||
|
)}
|
||||||
|
{!agentsLoading && !agentsError &&
|
||||||
|
availableAgents.map((id) => (
|
||||||
|
<button
|
||||||
|
key={id}
|
||||||
|
className="sidebar-add-option"
|
||||||
|
onClick={() => {
|
||||||
|
onCreateSession(id);
|
||||||
|
setShowAgentMenu(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{agentLabels[id] ?? id}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : transcriptEntries.length === 0 && !sessionError ? (
|
) : transcriptEntries.length === 0 && !sessionError ? (
|
||||||
<div className="empty-state">
|
<div className="empty-state">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: snapshot_status(status)
|
||||||
|
---
|
||||||
|
status: 204
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: normalize_agent_modes(&modes)
|
||||||
|
---
|
||||||
|
modes:
|
||||||
|
- description: true
|
||||||
|
id: build
|
||||||
|
name: Build
|
||||||
|
- description: true
|
||||||
|
id: plan
|
||||||
|
name: Plan
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: normalize_agent_list(&agents)
|
||||||
|
---
|
||||||
|
agents:
|
||||||
|
- id: amp
|
||||||
|
- id: claude
|
||||||
|
- id: codex
|
||||||
|
- id: mock
|
||||||
|
- id: opencode
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: normalize_health(&health)
|
||||||
|
---
|
||||||
|
status: ok
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: "json!({ \"status\": status.as_u16(), \"payload\": normalize_health(&payload), })"
|
||||||
|
---
|
||||||
|
payload:
|
||||||
|
status: ok
|
||||||
|
status: 200
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: "json!({ \"status\": status.as_u16(), \"payload\": payload, })"
|
||||||
|
---
|
||||||
|
payload:
|
||||||
|
detail: token invalid
|
||||||
|
details:
|
||||||
|
message: missing or invalid token
|
||||||
|
status: 401
|
||||||
|
title: Token Invalid
|
||||||
|
type: "urn:sandbox-agent:error:token_invalid"
|
||||||
|
status: 401
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: "json!({ \"status\": status.as_u16(), \"payload\": payload, })"
|
||||||
|
---
|
||||||
|
payload:
|
||||||
|
detail: token invalid
|
||||||
|
details:
|
||||||
|
message: missing or invalid token
|
||||||
|
status: 401
|
||||||
|
title: Token Invalid
|
||||||
|
type: "urn:sandbox-agent:error:token_invalid"
|
||||||
|
status: 401
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: "json!({\n \"status\": status.as_u16(), \"payload\": normalize_agent_list(&payload),\n})"
|
||||||
|
---
|
||||||
|
payload:
|
||||||
|
agents:
|
||||||
|
- id: amp
|
||||||
|
- id: claude
|
||||||
|
- id: codex
|
||||||
|
- id: mock
|
||||||
|
- id: opencode
|
||||||
|
status: 200
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: "json!({\n \"cors\": snapshot_cors(status, &headers), \"payload\":\n normalize_health(&payload),\n})"
|
||||||
|
---
|
||||||
|
cors:
|
||||||
|
access-control-allow-origin: "http://example.com"
|
||||||
|
status: 200
|
||||||
|
vary: "origin, access-control-request-method, access-control-request-headers"
|
||||||
|
payload:
|
||||||
|
status: ok
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
source: server/packages/sandbox-agent/tests/http/agent_endpoints.rs
|
||||||
|
expression: "snapshot_cors(status, &headers)"
|
||||||
|
---
|
||||||
|
access-control-allow-headers: "content-type,authorization"
|
||||||
|
access-control-allow-methods: "GET,POST"
|
||||||
|
access-control-allow-origin: "http://example.com"
|
||||||
|
status: 200
|
||||||
|
vary: "origin, access-control-request-method, access-control-request-headers"
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
#[cfg(feature = "test-utils")]
|
||||||
mod agent_server_manager;
|
mod agent_server_manager;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue