暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

create_session.go 2.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package api
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "log"
  8. "net/http"
  9. "git.x2erp.com/qdy/go-base/ctx"
  10. "git.x2erp.com/qdy/go-base/model/response"
  11. opencode "git.x2erp.com/qdy/go-base/sdk/opencode"
  12. "git.x2erp.com/qdy/go-svc-code/internal/opencode/container"
  13. )
  14. // CreateSessionHandler 创建OpenCode会话
  15. // 路由: POST /api/opencode/projects/:id/sessions
  16. func CreateSessionHandler(manager *container.InstanceManager) func(string, map[string]interface{}, *ctx.RequestContext) (*response.QueryResult[interface{}], error) {
  17. return func(id string, req map[string]interface{}, reqCtx *ctx.RequestContext) (*response.QueryResult[interface{}], error) {
  18. log.Printf("创建OpenCode会话请求: 项目ID=%s, 请求参数=%v", id, req)
  19. // 获取实例
  20. instance := manager.GetInstance(id)
  21. if instance == nil {
  22. return ErrorResponse(fmt.Errorf("项目 %s 的OpenCode实例未启动", id))
  23. }
  24. if instance.Status != container.StatusRunning {
  25. return ErrorResponse(fmt.Errorf("项目 %s 的OpenCode实例不在运行状态", id))
  26. }
  27. // 创建OpenCode客户端
  28. serverURL := fmt.Sprintf("http://localhost:%d", instance.Port)
  29. client, err := opencode.NewClient(serverURL)
  30. if err != nil {
  31. return ErrorResponse(fmt.Errorf("创建OpenCode客户端失败: %v", err))
  32. }
  33. // 准备请求体
  34. var parentID *string
  35. if pid, ok := req["parent_id"].(string); ok && pid != "" {
  36. parentID = &pid
  37. }
  38. var title *string
  39. if t, ok := req["title"].(string); ok && t != "" {
  40. title = &t
  41. }
  42. // 创建认证请求编辑器
  43. var requestEditors []opencode.RequestEditorFn
  44. if instance.Token != "" {
  45. requestEditors = append(requestEditors, func(ctx context.Context, req *http.Request) error {
  46. req.Header.Set("Authorization", "Bearer "+instance.Token)
  47. return nil
  48. })
  49. }
  50. // 调用OpenCode API创建会话
  51. resp, err := client.SessionCreate(
  52. context.Background(),
  53. &opencode.SessionCreateParams{},
  54. opencode.SessionCreateJSONRequestBody{
  55. ParentID: parentID,
  56. Title: title,
  57. },
  58. requestEditors...,
  59. )
  60. if err != nil {
  61. return ErrorResponse(fmt.Errorf("请求OpenCode API失败: %v", err))
  62. }
  63. defer resp.Body.Close()
  64. // 读取响应
  65. body, err := io.ReadAll(resp.Body)
  66. if err != nil {
  67. return ErrorResponse(fmt.Errorf("读取响应失败: %v", err))
  68. }
  69. // 检查HTTP状态码
  70. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
  71. return ErrorResponse(fmt.Errorf("OpenCode API返回错误: 状态码=%d, 响应=%s", resp.StatusCode, string(body)))
  72. }
  73. // 解析响应
  74. var opencodeResponse map[string]interface{}
  75. if err := json.Unmarshal(body, &opencodeResponse); err != nil {
  76. return ErrorResponse(fmt.Errorf("解析OpenCode响应失败: %v", err))
  77. }
  78. log.Printf("OpenCode会话创建成功: 项目=%s, 响应=%v", id, opencodeResponse)
  79. return SuccessResponseWithMessage(opencodeResponse, "会话创建成功")
  80. }
  81. }