Loading orbit.go +65 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package gitlab import ( "bytes" "encoding/json" "io" "net/http" Loading Loading @@ -61,6 +62,23 @@ type ( // https://docs.gitlab.com/api/orbit/#get-tools GetTools(options ...RequestOptionFunc) (*OrbitTools, *Response, error) // GetDsl returns the Orbit query DSL as a raw string body // from `GET /api/v4/orbit/schema/dsl`. // // The body is intended for agent consumption: format=raw // returns a JSON Schema document, format=llm returns a // JSON-encoded TOON grammar string. Both shapes are forwarded // verbatim — the Orbit team treats the DSL surface as // in-flux during beta and intentionally does not pin a typed // schema here. // // Note: This API is experimental and may change or be // removed in future versions. // // GitLab API docs: // https://docs.gitlab.com/api/orbit/#get-dsl GetDsl(opt *GetOrbitDslOptions, options ...RequestOptionFunc) (string, *Response, error) // Query executes an Orbit (Knowledge Graph) query. // // Note: This API is experimental and may change or be Loading Loading @@ -266,6 +284,16 @@ type OrbitTool struct { Parameters json.RawMessage `json:"parameters,omitempty"` } // GetOrbitDslOptions represents the available GetDsl() options. // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-dsl type GetOrbitDslOptions struct { // ResponseFormat selects the response shape: "raw" (JSON Schema // document, default) or "llm" (a JSON-encoded TOON grammar // string). GetDsl returns the body verbatim either way. ResponseFormat *OrbitResponseFormatValue `url:"response_format,omitempty"` } // OrbitQueryRequest represents the JSON body sent to // `POST /api/v4/orbit/query`. // Loading Loading @@ -309,7 +337,8 @@ type OrbitQueryResult struct { // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-status func (s *OrbitService) GetStatus(opt *GetOrbitStatusOptions, options ...RequestOptionFunc) (*OrbitStatus, *Response, error) { return do[*OrbitStatus](s.client, return do[*OrbitStatus]( s.client, withMethod(http.MethodGet), withPath("orbit/status"), withAPIOpts(opt), Loading @@ -325,7 +354,8 @@ func (s *OrbitService) GetStatus(opt *GetOrbitStatusOptions, options ...RequestO // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-schema func (s *OrbitService) GetSchema(opt *GetOrbitSchemaOptions, options ...RequestOptionFunc) (*OrbitSchema, *Response, error) { return do[*OrbitSchema](s.client, return do[*OrbitSchema]( s.client, withMethod(http.MethodGet), withPath("orbit/schema"), withAPIOpts(opt), Loading @@ -341,13 +371,41 @@ func (s *OrbitService) GetSchema(opt *GetOrbitSchemaOptions, options ...RequestO // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-tools func (s *OrbitService) GetTools(options ...RequestOptionFunc) (*OrbitTools, *Response, error) { return do[*OrbitTools](s.client, return do[*OrbitTools]( s.client, withMethod(http.MethodGet), withPath("orbit/tools"), withRequestOpts(options...), ) } // GetDsl returns the Orbit query DSL body verbatim from // `GET /api/v4/orbit/schema/dsl`. // // The DSL surface is in flux during the Orbit beta and is intended // for agent consumption, so the body is returned as a raw string // rather than a typed schema. format=raw yields a JSON Schema // document; format=llm yields a JSON-encoded TOON grammar string. // // Note: This API is experimental and may change or be removed in // future versions. // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-dsl func (s *OrbitService) GetDsl(opt *GetOrbitDslOptions, options ...RequestOptionFunc) (string, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "orbit/schema/dsl", opt, options) if err != nil { return "", nil, err } var buf bytes.Buffer resp, err := s.client.Do(req, &buf) if err != nil { return "", resp, err } return buf.String(), resp, nil } // Query executes an Orbit (Knowledge Graph) query against // `POST /api/v4/orbit/query`. // Loading @@ -369,7 +427,8 @@ func (s *OrbitService) GetTools(options ...RequestOptionFunc) (*OrbitTools, *Res // // GitLab API docs: https://docs.gitlab.com/api/orbit/#post-query func (s *OrbitService) Query(opt *OrbitQueryRequest, options ...RequestOptionFunc) (*OrbitQueryResult, *Response, error) { return do[*OrbitQueryResult](s.client, return do[*OrbitQueryResult]( s.client, withMethod(http.MethodPost), withPath("orbit/query"), withAPIOpts(opt), Loading Loading @@ -508,7 +567,8 @@ type OrbitGraphStatusIndexing struct { // GitLab API docs: // https://docs.gitlab.com/api/orbit/#get-graph-status func (s *OrbitService) GetGraphStatus(opt *GetGraphStatusOptions, options ...RequestOptionFunc) (*OrbitGraphStatus, *Response, error) { return do[*OrbitGraphStatus](s.client, return do[*OrbitGraphStatus]( s.client, withMethod(http.MethodGet), withPath("orbit/graph_status"), withAPIOpts(opt), Loading orbit_test.go +44 −2 Original line number Diff line number Diff line Loading @@ -231,13 +231,54 @@ func TestOrbitService_GetTools(t *testing.T) { require.NotNil(t, resp) require.Len(t, tools.Tools, 2) assert.Equal(t, "query_graph", tools.Tools[0].Name) assert.JSONEq(t, assert.JSONEq( t, `{"type": "object", "properties": {"query": {}}}`, string(tools.Tools[0].Parameters), ) assert.Equal(t, "get_graph_schema", tools.Tools[1].Name) } func TestOrbitService_GetDsl_RawFormat(t *testing.T) { t.Parallel() // GIVEN a DSL endpoint returning a JSON Schema body mux, client := setup(t) body := `{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"QueryDSL","type":"object"}` mux.HandleFunc("/api/v4/orbit/schema/dsl", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) fmt.Fprint(w, body) }) // WHEN GetDsl is called dsl, resp, err := client.Orbit.GetDsl(nil) // THEN the body is returned verbatim as a string require.NoError(t, err) require.NotNil(t, resp) assert.Equal(t, body, dsl) } func TestOrbitService_GetDsl_LLMFormat(t *testing.T) { t.Parallel() // GIVEN a DSL endpoint returning a JSON-encoded TOON string for llm mux, client := setup(t) body := `"QueryDSL v2.1.0:\nquery_type: traversal | search"` mux.HandleFunc("/api/v4/orbit/schema/dsl", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) assert.Equal(t, "llm", r.URL.Query().Get("response_format")) fmt.Fprint(w, body) }) // WHEN GetDsl is called with format=llm dsl, _, err := client.Orbit.GetDsl(&GetOrbitDslOptions{ResponseFormat: Ptr(OrbitResponseFormatLLM)}) // THEN the body is returned verbatim require.NoError(t, err) assert.Equal(t, body, dsl) } func TestOrbitService_Query(t *testing.T) { t.Parallel() // GIVEN an Orbit query endpoint that echoes back a structured result Loading Loading @@ -289,7 +330,8 @@ func TestOrbitService_Query(t *testing.T) { assert.Equal(t, "traversal", result.QueryType) assert.Equal(t, []string{"SELECT ..."}, result.RawQueryStrings) assert.Equal(t, int64(2), result.RowCount) assert.JSONEq(t, assert.JSONEq( t, `[{"_id": "1", "_type": "Project", "name": "alpha"}, {"_id": "2", "_type": "Project", "name": "beta"}]`, string(result.Result), ) Loading testing/orbit_mock.go +45 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,51 @@ func (m *MockOrbitServiceInterface) EXPECT() *MockOrbitServiceInterfaceMockRecor return m.recorder } // GetDsl mocks base method. func (m *MockOrbitServiceInterface) GetDsl(opt *gitlab.GetOrbitDslOptions, options ...gitlab.RequestOptionFunc) (string, *gitlab.Response, error) { m.ctrl.T.Helper() varargs := []any{opt} for _, a := range options { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "GetDsl", varargs...) ret0, _ := ret[0].(string) ret1, _ := ret[1].(*gitlab.Response) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } // GetDsl indicates an expected call of GetDsl. func (mr *MockOrbitServiceInterfaceMockRecorder) GetDsl(opt any, options ...any) *MockOrbitServiceInterfaceGetDslCall { mr.mock.ctrl.T.Helper() varargs := append([]any{opt}, options...) call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDsl", reflect.TypeOf((*MockOrbitServiceInterface)(nil).GetDsl), varargs...) return &MockOrbitServiceInterfaceGetDslCall{Call: call} } // MockOrbitServiceInterfaceGetDslCall wrap *gomock.Call type MockOrbitServiceInterfaceGetDslCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return func (c *MockOrbitServiceInterfaceGetDslCall) Return(arg0 string, arg1 *gitlab.Response, arg2 error) *MockOrbitServiceInterfaceGetDslCall { c.Call = c.Call.Return(arg0, arg1, arg2) return c } // Do rewrite *gomock.Call.Do func (c *MockOrbitServiceInterfaceGetDslCall) Do(f func(*gitlab.GetOrbitDslOptions, ...gitlab.RequestOptionFunc) (string, *gitlab.Response, error)) *MockOrbitServiceInterfaceGetDslCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn func (c *MockOrbitServiceInterfaceGetDslCall) DoAndReturn(f func(*gitlab.GetOrbitDslOptions, ...gitlab.RequestOptionFunc) (string, *gitlab.Response, error)) *MockOrbitServiceInterfaceGetDslCall { c.Call = c.Call.DoAndReturn(f) return c } // GetGraphStatus mocks base method. func (m *MockOrbitServiceInterface) GetGraphStatus(opt *gitlab.GetGraphStatusOptions, options ...gitlab.RequestOptionFunc) (*gitlab.OrbitGraphStatus, *gitlab.Response, error) { m.ctrl.T.Helper() Loading Loading
orbit.go +65 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package gitlab import ( "bytes" "encoding/json" "io" "net/http" Loading Loading @@ -61,6 +62,23 @@ type ( // https://docs.gitlab.com/api/orbit/#get-tools GetTools(options ...RequestOptionFunc) (*OrbitTools, *Response, error) // GetDsl returns the Orbit query DSL as a raw string body // from `GET /api/v4/orbit/schema/dsl`. // // The body is intended for agent consumption: format=raw // returns a JSON Schema document, format=llm returns a // JSON-encoded TOON grammar string. Both shapes are forwarded // verbatim — the Orbit team treats the DSL surface as // in-flux during beta and intentionally does not pin a typed // schema here. // // Note: This API is experimental and may change or be // removed in future versions. // // GitLab API docs: // https://docs.gitlab.com/api/orbit/#get-dsl GetDsl(opt *GetOrbitDslOptions, options ...RequestOptionFunc) (string, *Response, error) // Query executes an Orbit (Knowledge Graph) query. // // Note: This API is experimental and may change or be Loading Loading @@ -266,6 +284,16 @@ type OrbitTool struct { Parameters json.RawMessage `json:"parameters,omitempty"` } // GetOrbitDslOptions represents the available GetDsl() options. // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-dsl type GetOrbitDslOptions struct { // ResponseFormat selects the response shape: "raw" (JSON Schema // document, default) or "llm" (a JSON-encoded TOON grammar // string). GetDsl returns the body verbatim either way. ResponseFormat *OrbitResponseFormatValue `url:"response_format,omitempty"` } // OrbitQueryRequest represents the JSON body sent to // `POST /api/v4/orbit/query`. // Loading Loading @@ -309,7 +337,8 @@ type OrbitQueryResult struct { // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-status func (s *OrbitService) GetStatus(opt *GetOrbitStatusOptions, options ...RequestOptionFunc) (*OrbitStatus, *Response, error) { return do[*OrbitStatus](s.client, return do[*OrbitStatus]( s.client, withMethod(http.MethodGet), withPath("orbit/status"), withAPIOpts(opt), Loading @@ -325,7 +354,8 @@ func (s *OrbitService) GetStatus(opt *GetOrbitStatusOptions, options ...RequestO // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-schema func (s *OrbitService) GetSchema(opt *GetOrbitSchemaOptions, options ...RequestOptionFunc) (*OrbitSchema, *Response, error) { return do[*OrbitSchema](s.client, return do[*OrbitSchema]( s.client, withMethod(http.MethodGet), withPath("orbit/schema"), withAPIOpts(opt), Loading @@ -341,13 +371,41 @@ func (s *OrbitService) GetSchema(opt *GetOrbitSchemaOptions, options ...RequestO // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-tools func (s *OrbitService) GetTools(options ...RequestOptionFunc) (*OrbitTools, *Response, error) { return do[*OrbitTools](s.client, return do[*OrbitTools]( s.client, withMethod(http.MethodGet), withPath("orbit/tools"), withRequestOpts(options...), ) } // GetDsl returns the Orbit query DSL body verbatim from // `GET /api/v4/orbit/schema/dsl`. // // The DSL surface is in flux during the Orbit beta and is intended // for agent consumption, so the body is returned as a raw string // rather than a typed schema. format=raw yields a JSON Schema // document; format=llm yields a JSON-encoded TOON grammar string. // // Note: This API is experimental and may change or be removed in // future versions. // // GitLab API docs: https://docs.gitlab.com/api/orbit/#get-dsl func (s *OrbitService) GetDsl(opt *GetOrbitDslOptions, options ...RequestOptionFunc) (string, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "orbit/schema/dsl", opt, options) if err != nil { return "", nil, err } var buf bytes.Buffer resp, err := s.client.Do(req, &buf) if err != nil { return "", resp, err } return buf.String(), resp, nil } // Query executes an Orbit (Knowledge Graph) query against // `POST /api/v4/orbit/query`. // Loading @@ -369,7 +427,8 @@ func (s *OrbitService) GetTools(options ...RequestOptionFunc) (*OrbitTools, *Res // // GitLab API docs: https://docs.gitlab.com/api/orbit/#post-query func (s *OrbitService) Query(opt *OrbitQueryRequest, options ...RequestOptionFunc) (*OrbitQueryResult, *Response, error) { return do[*OrbitQueryResult](s.client, return do[*OrbitQueryResult]( s.client, withMethod(http.MethodPost), withPath("orbit/query"), withAPIOpts(opt), Loading Loading @@ -508,7 +567,8 @@ type OrbitGraphStatusIndexing struct { // GitLab API docs: // https://docs.gitlab.com/api/orbit/#get-graph-status func (s *OrbitService) GetGraphStatus(opt *GetGraphStatusOptions, options ...RequestOptionFunc) (*OrbitGraphStatus, *Response, error) { return do[*OrbitGraphStatus](s.client, return do[*OrbitGraphStatus]( s.client, withMethod(http.MethodGet), withPath("orbit/graph_status"), withAPIOpts(opt), Loading
orbit_test.go +44 −2 Original line number Diff line number Diff line Loading @@ -231,13 +231,54 @@ func TestOrbitService_GetTools(t *testing.T) { require.NotNil(t, resp) require.Len(t, tools.Tools, 2) assert.Equal(t, "query_graph", tools.Tools[0].Name) assert.JSONEq(t, assert.JSONEq( t, `{"type": "object", "properties": {"query": {}}}`, string(tools.Tools[0].Parameters), ) assert.Equal(t, "get_graph_schema", tools.Tools[1].Name) } func TestOrbitService_GetDsl_RawFormat(t *testing.T) { t.Parallel() // GIVEN a DSL endpoint returning a JSON Schema body mux, client := setup(t) body := `{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"QueryDSL","type":"object"}` mux.HandleFunc("/api/v4/orbit/schema/dsl", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) fmt.Fprint(w, body) }) // WHEN GetDsl is called dsl, resp, err := client.Orbit.GetDsl(nil) // THEN the body is returned verbatim as a string require.NoError(t, err) require.NotNil(t, resp) assert.Equal(t, body, dsl) } func TestOrbitService_GetDsl_LLMFormat(t *testing.T) { t.Parallel() // GIVEN a DSL endpoint returning a JSON-encoded TOON string for llm mux, client := setup(t) body := `"QueryDSL v2.1.0:\nquery_type: traversal | search"` mux.HandleFunc("/api/v4/orbit/schema/dsl", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) assert.Equal(t, "llm", r.URL.Query().Get("response_format")) fmt.Fprint(w, body) }) // WHEN GetDsl is called with format=llm dsl, _, err := client.Orbit.GetDsl(&GetOrbitDslOptions{ResponseFormat: Ptr(OrbitResponseFormatLLM)}) // THEN the body is returned verbatim require.NoError(t, err) assert.Equal(t, body, dsl) } func TestOrbitService_Query(t *testing.T) { t.Parallel() // GIVEN an Orbit query endpoint that echoes back a structured result Loading Loading @@ -289,7 +330,8 @@ func TestOrbitService_Query(t *testing.T) { assert.Equal(t, "traversal", result.QueryType) assert.Equal(t, []string{"SELECT ..."}, result.RawQueryStrings) assert.Equal(t, int64(2), result.RowCount) assert.JSONEq(t, assert.JSONEq( t, `[{"_id": "1", "_type": "Project", "name": "alpha"}, {"_id": "2", "_type": "Project", "name": "beta"}]`, string(result.Result), ) Loading
testing/orbit_mock.go +45 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,51 @@ func (m *MockOrbitServiceInterface) EXPECT() *MockOrbitServiceInterfaceMockRecor return m.recorder } // GetDsl mocks base method. func (m *MockOrbitServiceInterface) GetDsl(opt *gitlab.GetOrbitDslOptions, options ...gitlab.RequestOptionFunc) (string, *gitlab.Response, error) { m.ctrl.T.Helper() varargs := []any{opt} for _, a := range options { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "GetDsl", varargs...) ret0, _ := ret[0].(string) ret1, _ := ret[1].(*gitlab.Response) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } // GetDsl indicates an expected call of GetDsl. func (mr *MockOrbitServiceInterfaceMockRecorder) GetDsl(opt any, options ...any) *MockOrbitServiceInterfaceGetDslCall { mr.mock.ctrl.T.Helper() varargs := append([]any{opt}, options...) call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDsl", reflect.TypeOf((*MockOrbitServiceInterface)(nil).GetDsl), varargs...) return &MockOrbitServiceInterfaceGetDslCall{Call: call} } // MockOrbitServiceInterfaceGetDslCall wrap *gomock.Call type MockOrbitServiceInterfaceGetDslCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return func (c *MockOrbitServiceInterfaceGetDslCall) Return(arg0 string, arg1 *gitlab.Response, arg2 error) *MockOrbitServiceInterfaceGetDslCall { c.Call = c.Call.Return(arg0, arg1, arg2) return c } // Do rewrite *gomock.Call.Do func (c *MockOrbitServiceInterfaceGetDslCall) Do(f func(*gitlab.GetOrbitDslOptions, ...gitlab.RequestOptionFunc) (string, *gitlab.Response, error)) *MockOrbitServiceInterfaceGetDslCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn func (c *MockOrbitServiceInterfaceGetDslCall) DoAndReturn(f func(*gitlab.GetOrbitDslOptions, ...gitlab.RequestOptionFunc) (string, *gitlab.Response, error)) *MockOrbitServiceInterfaceGetDslCall { c.Call = c.Call.DoAndReturn(f) return c } // GetGraphStatus mocks base method. func (m *MockOrbitServiceInterface) GetGraphStatus(opt *gitlab.GetGraphStatusOptions, options ...gitlab.RequestOptionFunc) (*gitlab.OrbitGraphStatus, *gitlab.Response, error) { m.ctrl.T.Helper() Loading