feat(sandbox): update sandbox status messages and improve loading feedback
- Modified Docker run commands in CI workflows to include the `-direct` flag for enhanced server operation. - Removed outdated loading status message during sandbox preparation and added new messages for improved user feedback. - Introduced a loading message for waiting on AI responses, enhancing the user experience during sandbox execution. - Refactored identity handling in stream processing to streamline message management. Made-with: Cursor
This commit is contained in:
parent
a5c8109db8
commit
89e5840490
7 changed files with 50 additions and 34 deletions
2
.github/workflows/pr-test.yml
vendored
2
.github/workflows/pr-test.yml
vendored
|
|
@ -1142,7 +1142,7 @@ jobs:
|
|||
-v /tmp/kubeconfig-tai-k8s.yml:/etc/tai/kubeconfig.yml:ro \
|
||||
-e TAI_K8S_UPSTREAM="tcp://${K3D_IP}:6443" \
|
||||
-e TAI_KUBECONFIG=/etc/tai/kubeconfig.yml \
|
||||
yaoapp/tai:latest server \
|
||||
yaoapp/tai:latest server -direct \
|
||||
-grpc 0.0.0.0:19100 -http 0.0.0.0:8099 -vnc 0.0.0.0:16080 -k8s 0.0.0.0:16443
|
||||
|
||||
for i in $(seq 1 30); do
|
||||
|
|
|
|||
2
.github/workflows/unit-test.yml
vendored
2
.github/workflows/unit-test.yml
vendored
|
|
@ -853,7 +853,7 @@ jobs:
|
|||
-v /tmp/kubeconfig-tai-k8s.yml:/etc/tai/kubeconfig.yml:ro \
|
||||
-e TAI_K8S_UPSTREAM="tcp://${K3D_IP}:6443" \
|
||||
-e TAI_KUBECONFIG=/etc/tai/kubeconfig.yml \
|
||||
yaoapp/tai:latest server \
|
||||
yaoapp/tai:latest server -direct \
|
||||
-grpc 0.0.0.0:19100 -http 0.0.0.0:8099 -vnc 0.0.0.0:16080 -k8s 0.0.0.0:16443
|
||||
|
||||
for i in $(seq 1 30); do
|
||||
|
|
|
|||
|
|
@ -227,32 +227,30 @@ func (s *streamState) handleToolCall(data []byte) int {
|
|||
tc := toolCallArray[0]
|
||||
props = map[string]interface{}{}
|
||||
|
||||
hasStaticFields := false
|
||||
hasIdentity := false
|
||||
if id, ok := tc["id"].(string); ok {
|
||||
props["id"] = id
|
||||
hasStaticFields = true
|
||||
hasIdentity = true
|
||||
}
|
||||
if typ, ok := tc["type"].(string); ok {
|
||||
props["type"] = typ
|
||||
hasStaticFields = true
|
||||
hasIdentity = true
|
||||
}
|
||||
if index, ok := tc["index"].(float64); ok {
|
||||
props["index"] = int(index)
|
||||
hasStaticFields = true
|
||||
}
|
||||
if fn, ok := tc["function"].(map[string]interface{}); ok {
|
||||
if name, ok := fn["name"].(string); ok {
|
||||
props["name"] = name
|
||||
hasStaticFields = true
|
||||
hasIdentity = true
|
||||
}
|
||||
if args, ok := fn["arguments"].(string); ok {
|
||||
props["arguments"] = args
|
||||
}
|
||||
}
|
||||
|
||||
if hasStaticFields {
|
||||
if hasIdentity {
|
||||
// First chunk with id/name/type: merge so all fields are applied.
|
||||
// arguments="" is included but that's fine — subsequent appends build on it.
|
||||
deltaAction = "merge"
|
||||
} else if _, ok := props["arguments"]; ok {
|
||||
// Subsequent chunk with only arguments fragment: append to arguments.
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ func (ast *Assistant) initSandboxV2(ctx *context.Context, opts *context.Options)
|
|||
}
|
||||
|
||||
// 7. Runner.Prepare (standard context).
|
||||
updateLoadingV2(ctx, loadingMsgID, "sandbox.configuring")
|
||||
err = runner.Prepare(stdCtx, &sandboxTypes.PrepareRequest{
|
||||
Computer: computer,
|
||||
Config: cfg,
|
||||
|
|
|
|||
|
|
@ -100,14 +100,14 @@ func init() {
|
|||
"kb.chat.description": "Auto-created knowledge base collection for chat sessions",
|
||||
|
||||
// Sandbox: assistant/sandbox.go - Sandbox status messages
|
||||
"sandbox.preparing": "Preparing sandbox environment",
|
||||
"sandbox.ready": "Sandbox ready",
|
||||
"sandbox.working": "Working on your request",
|
||||
"sandbox.completed": "Completed",
|
||||
"sandbox.failed": "Execution failed",
|
||||
"sandbox.starting": "Starting sandbox environment",
|
||||
"sandbox.configuring": "Configuring runtime environment",
|
||||
"sandbox.pulling_image": "Pulling container image",
|
||||
"sandbox.preparing": "Getting things ready...",
|
||||
"sandbox.ready": "Sandbox ready",
|
||||
"sandbox.working": "Working on your request",
|
||||
"sandbox.completed": "Completed",
|
||||
"sandbox.failed": "Execution failed",
|
||||
"sandbox.starting": "Setting up workspace...",
|
||||
"sandbox.pulling_image": "Preparing environment (first time may take a moment)",
|
||||
"sandbox.waiting_response": "Waiting for AI response...",
|
||||
|
||||
// Sandbox: claude/executor.go - Tool execution messages
|
||||
"sandbox.tool.read": "Reading file",
|
||||
|
|
@ -227,14 +227,14 @@ func init() {
|
|||
"kb.chat.description": "自动为聊天会话创建的知识库集合",
|
||||
|
||||
// Sandbox: assistant/sandbox.go - Sandbox status messages
|
||||
"sandbox.preparing": "正在准备沙箱环境",
|
||||
"sandbox.ready": "沙箱环境就绪",
|
||||
"sandbox.working": "正在处理您的请求",
|
||||
"sandbox.completed": "处理完成",
|
||||
"sandbox.failed": "执行失败",
|
||||
"sandbox.starting": "正在启动沙箱环境",
|
||||
"sandbox.configuring": "正在配置运行环境",
|
||||
"sandbox.pulling_image": "正在拉取容器镜像",
|
||||
"sandbox.preparing": "正在准备...",
|
||||
"sandbox.ready": "就绪",
|
||||
"sandbox.working": "正在处理您的请求",
|
||||
"sandbox.completed": "处理完成",
|
||||
"sandbox.failed": "执行失败",
|
||||
"sandbox.starting": "正在启动工作区...",
|
||||
"sandbox.pulling_image": "正在准备运行环境(首次可能需要一点时间)",
|
||||
"sandbox.waiting_response": "等待 AI 响应...",
|
||||
|
||||
// Sandbox: claude/executor.go - Tool execution messages
|
||||
"sandbox.tool.read": "正在读取文件",
|
||||
|
|
@ -382,14 +382,14 @@ func init() {
|
|||
"kb.chat.description": "自动为聊天会话创建的知识库集合",
|
||||
|
||||
// Sandbox: assistant/sandbox.go - Sandbox status messages
|
||||
"sandbox.preparing": "正在准备沙箱环境",
|
||||
"sandbox.ready": "沙箱环境就绪",
|
||||
"sandbox.working": "正在处理您的请求",
|
||||
"sandbox.completed": "处理完成",
|
||||
"sandbox.failed": "执行失败",
|
||||
"sandbox.starting": "正在启动沙箱环境",
|
||||
"sandbox.configuring": "正在配置运行环境",
|
||||
"sandbox.pulling_image": "正在拉取容器镜像",
|
||||
"sandbox.preparing": "正在准备...",
|
||||
"sandbox.ready": "就绪",
|
||||
"sandbox.working": "正在处理您的请求",
|
||||
"sandbox.completed": "处理完成",
|
||||
"sandbox.failed": "执行失败",
|
||||
"sandbox.starting": "正在启动工作区...",
|
||||
"sandbox.pulling_image": "正在准备运行环境(首次可能需要一点时间)",
|
||||
"sandbox.waiting_response": "等待 AI 响应...",
|
||||
|
||||
// Sandbox: claude/executor.go - Tool execution messages
|
||||
"sandbox.tool.read": "正在读取文件",
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@ func parseStreamJSON(_ context.Context, stdout io.ReadCloser, handler message.St
|
|||
toolIndex++
|
||||
|
||||
if handler != nil {
|
||||
if messageStarted {
|
||||
handler(message.ChunkMessageEnd, nil)
|
||||
messageStarted = false
|
||||
}
|
||||
if !toolBlockActive {
|
||||
startData := message.EventMessageStartData{
|
||||
MessageID: fmt.Sprintf("sandbox-tool-%d", time.Now().UnixNano()),
|
||||
|
|
@ -119,6 +123,7 @@ func parseStreamJSON(_ context.Context, stdout io.ReadCloser, handler message.St
|
|||
if toolBlockActive {
|
||||
handler(message.ChunkMessageEnd, nil)
|
||||
toolBlockActive = false
|
||||
messageStarted = false
|
||||
}
|
||||
if !messageStarted {
|
||||
startData := message.EventMessageStartData{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
agentContext "github.com/yaoapp/yao/agent/context"
|
||||
"github.com/yaoapp/yao/agent/i18n"
|
||||
"github.com/yaoapp/yao/agent/output/message"
|
||||
"github.com/yaoapp/yao/agent/sandbox/v2/types"
|
||||
infra "github.com/yaoapp/yao/sandbox/v2"
|
||||
|
|
@ -106,6 +107,19 @@ func ExecuteSandboxStream(
|
|||
}
|
||||
}()
|
||||
|
||||
if req.LoadingMsgID != "" {
|
||||
waitMsg := &message.Message{
|
||||
MessageID: req.LoadingMsgID,
|
||||
Delta: true,
|
||||
DeltaAction: message.DeltaReplace,
|
||||
Type: message.TypeLoading,
|
||||
Props: map[string]any{
|
||||
"message": i18n.T(ctx.Locale, "sandbox.waiting_response"),
|
||||
},
|
||||
}
|
||||
ctx.Send(waitMsg)
|
||||
}
|
||||
|
||||
var textContent []byte
|
||||
loadingClosed := false
|
||||
wrappedHandler := func(chunkType message.StreamChunkType, data []byte) int {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue