Skip to content

Commit bcb63e2

Browse files
author
Sisyphus Agent
committed
feat: oho add 命令完整实现 + Model 类型修复
功能实现: - oho add "message" 等价于 session create + message add - 自动使用当前工作目录作为 session directory - 支持 --title, --directory, --agent, --model, --no-reply, --file 等标志 - 支持 JSON 格式输出 (--json) API 修复: - 修复 MessageRequest.Model 类型为 interface{} (支持 string 或 Model 对象) - 根据 OpenCode SDK, model 应为 {providerID, modelID} 格式 - 添加 convertModel() 函数处理向后兼容 - 修复 session list 输出,正确处理 Model 类型 代码清理: - 移除 message.go 调试输出 - 修复 session.go 模型显示逻辑 测试验证: - oho add "消息" 在 /mnt/d/fe/babylon3DWorld 成功创建会话 - directory: /mnt/d/fe/babylon3DWorld ✓ - projectID: 正确关联 ✓ - 消息发送成功 ✓
1 parent 1a8e56e commit bcb63e2

6 files changed

Lines changed: 339 additions & 289 deletions

File tree

oho/cmd/add/add.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,27 @@ func createSession(c *client.Client, ctx context.Context, title, parentID, direc
160160
return session.ID, nil
161161
}
162162

163+
// convertModel converts a model string to the appropriate format (string or object)
164+
func convertModel(model string) interface{} {
165+
if model == "" {
166+
return nil
167+
}
168+
169+
// Check if the model string contains a colon, which indicates provider:model format
170+
if strings.Contains(model, ":") {
171+
parts := strings.SplitN(model, ":", 2)
172+
if len(parts) == 2 {
173+
return types.Model{
174+
ProviderID: parts[0],
175+
ModelID: parts[1],
176+
}
177+
}
178+
}
179+
180+
// If no colon, treat as simple string model (backward compatibility)
181+
return model
182+
}
183+
163184
// sendMessage sends a message to the session and returns the message ID
164185
func sendMessage(c *client.Client, ctx context.Context, sessionID, message, agent, model string, noReply bool, system string, tools, files []string) (string, error) {
165186
// Build message parts
@@ -201,7 +222,7 @@ func sendMessage(c *client.Client, ctx context.Context, sessionID, message, agen
201222

202223
// Build message request
203224
msgReq := types.MessageRequest{
204-
Model: model,
225+
Model: convertModel(model),
205226
Agent: agent,
206227
NoReply: noReply,
207228
System: system,

oho/cmd/message/message.go

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,27 @@ func init() {
7878
shellCmd.Flags().StringVar(&shellCommand, "command", "", "Shell 命令")
7979
}
8080

81+
// convertModel converts a model string to the appropriate format (string or object)
82+
func convertModel(model string) interface{} {
83+
if model == "" {
84+
return nil
85+
}
86+
87+
// Check if the model string contains a colon, which indicates provider:model format
88+
if strings.Contains(model, ":") {
89+
parts := strings.SplitN(model, ":", 2)
90+
if len(parts) == 2 {
91+
return types.Model{
92+
ProviderID: parts[0],
93+
ModelID: parts[1],
94+
}
95+
}
96+
}
97+
98+
// If no colon, treat as simple string model (backward compatibility)
99+
return model
100+
}
101+
81102
// listCmd 列出消息
82103
var listCmd = &cobra.Command{
83104
Use: "list",
@@ -187,18 +208,14 @@ var addCmd = &cobra.Command{
187208

188209
req := types.MessageRequest{
189210
MessageID: messageID,
190-
Model: model,
211+
Model: convertModel(model),
191212
Agent: agent,
192213
NoReply: noReply,
193214
System: systemPrompt,
194215
Tools: tools,
195216
Parts: parts,
196217
}
197218

198-
// 调试输出:打印请求内容
199-
reqJSON, _ := json.MarshalIndent(req, "", " ")
200-
fmt.Fprintf(os.Stderr, "DEBUG: 发送请求:\n%s\n", string(reqJSON))
201-
202219
resp, err := c.Post(ctx, fmt.Sprintf("/session/%s/message", sessionID), req)
203220
if err != nil {
204221
return err
@@ -301,7 +318,7 @@ var promptAsyncCmd = &cobra.Command{
301318

302319
req := types.MessageRequest{
303320
MessageID: messageID,
304-
Model: model,
321+
Model: convertModel(model),
305322
Agent: agent,
306323
NoReply: false,
307324
System: systemPrompt,
@@ -340,7 +357,7 @@ var commandCmd = &cobra.Command{
340357
req := types.CommandRequest{
341358
MessageID: messageID,
342359
Agent: agent,
343-
Model: model,
360+
Model: convertModel(model),
344361
Command: args[0],
345362
Arguments: argMap,
346363
}
@@ -401,7 +418,7 @@ var shellCmd = &cobra.Command{
401418

402419
req := types.ShellRequest{
403420
Agent: agent,
404-
Model: model,
421+
Model: convertModel(model),
405422
Command: cmdStr,
406423
}
407424

@@ -438,7 +455,7 @@ var shellCmd = &cobra.Command{
438455
// detectMimeType 根据文件扩展名检测 MIME 类型
439456
func detectMimeType(filePath string) string {
440457
ext := strings.ToLower(filePath[strings.LastIndex(filePath, "."):])
441-
458+
442459
mimeTypes := map[string]string{
443460
// 图片
444461
".jpg": "image/jpeg",
@@ -448,7 +465,7 @@ func detectMimeType(filePath string) string {
448465
".webp": "image/webp",
449466
".bmp": "image/bmp",
450467
".svg": "image/svg+xml",
451-
468+
452469
// 文档
453470
".pdf": "application/pdf",
454471
".doc": "application/msword",
@@ -457,7 +474,7 @@ func detectMimeType(filePath string) string {
457474
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
458475
".ppt": "application/vnd.ms-powerpoint",
459476
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
460-
477+
461478
// 文本
462479
".txt": "text/plain",
463480
".md": "text/markdown",
@@ -468,7 +485,7 @@ func detectMimeType(filePath string) string {
468485
".xml": "application/xml",
469486
".yaml": "application/x-yaml",
470487
".yml": "application/x-yaml",
471-
488+
472489
// 代码
473490
".py": "text/x-python",
474491
".go": "text/x-go",
@@ -479,20 +496,20 @@ func detectMimeType(filePath string) string {
479496
".rs": "text/x-rust",
480497
".ts": "text/x-typescript",
481498
".tsx": "text/x-typescript",
482-
499+
483500
// 其他
484-
".zip": "application/zip",
485-
".tar": "application/x-tar",
486-
".gz": "application/gzip",
487-
".mp3": "audio/mpeg",
488-
".mp4": "video/mp4",
489-
".wav": "audio/wav",
501+
".zip": "application/zip",
502+
".tar": "application/x-tar",
503+
".gz": "application/gzip",
504+
".mp3": "audio/mpeg",
505+
".mp4": "video/mp4",
506+
".wav": "audio/wav",
490507
}
491-
508+
492509
if mimeType, ok := mimeTypes[ext]; ok {
493510
return mimeType
494511
}
495-
512+
496513
// 默认返回 octet-stream
497514
return "application/octet-stream"
498515
}

oho/cmd/message/message_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func TestMessageAddCmd(t *testing.T) {
115115
}
116116

117117
req := types.MessageRequest{
118-
Model: tt.model,
118+
Model: convertModel(tt.model),
119119
Agent: tt.agent,
120120
NoReply: tt.noReply,
121121
Parts: parts,

0 commit comments

Comments
 (0)