mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: graduate aibridge API out of experimental (#20523)
<!-- If you have used AI to produce some or all of this PR, please ensure you have read our [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING) before submitting. -->
This commit is contained in:
Generated
+1
-1
@@ -85,7 +85,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/experimental/aibridge/interceptions": {
|
||||
"/aibridge/interceptions": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
|
||||
Generated
+1
-1
@@ -65,7 +65,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/experimental/aibridge/interceptions": {
|
||||
"/aibridge/interceptions": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
|
||||
@@ -113,8 +113,8 @@ func (f AIBridgeListInterceptionsFilter) asRequestOption() RequestOption {
|
||||
|
||||
// AIBridgeListInterceptions returns AIBridge interceptions with the given
|
||||
// filter.
|
||||
func (c *ExperimentalClient) AIBridgeListInterceptions(ctx context.Context, filter AIBridgeListInterceptionsFilter) (AIBridgeListInterceptionsResponse, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/experimental/aibridge/interceptions", nil, filter.asRequestOption(), filter.Pagination.asRequestOption(), filter.Pagination.asRequestOption())
|
||||
func (c *Client) AIBridgeListInterceptions(ctx context.Context, filter AIBridgeListInterceptionsFilter) (AIBridgeListInterceptionsResponse, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/aibridge/interceptions", nil, filter.asRequestOption(), filter.Pagination.asRequestOption(), filter.Pagination.asRequestOption())
|
||||
if err != nil {
|
||||
return AIBridgeListInterceptionsResponse{}, err
|
||||
}
|
||||
|
||||
Generated
+2
-2
@@ -6,12 +6,12 @@
|
||||
|
||||
```shell
|
||||
# Example request using curl
|
||||
curl -X GET http://coder-server:8080/api/v2/api/experimental/aibridge/interceptions \
|
||||
curl -X GET http://coder-server:8080/api/v2/aibridge/interceptions \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Coder-Session-Token: API_KEY'
|
||||
```
|
||||
|
||||
`GET /api/experimental/aibridge/interceptions`
|
||||
`GET /aibridge/interceptions`
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ var _ io.Closer = &Server{}
|
||||
|
||||
// Server provides the AI Bridge functionality.
|
||||
// It is responsible for:
|
||||
// - receiving requests on /api/experimental/aibridged/* // TODO: update endpoint once out of experimental
|
||||
// - receiving requests on /api/v2/aibridged/*
|
||||
// - manipulating the requests
|
||||
// - relaying requests to upstream AI services and relaying responses to caller
|
||||
//
|
||||
|
||||
@@ -36,7 +36,7 @@ const (
|
||||
// @Param after_id query string false "Cursor pagination after ID (cannot be used with offset)"
|
||||
// @Param offset query int false "Offset pagination (cannot be used with after_id)"
|
||||
// @Success 200 {object} codersdk.AIBridgeListInterceptionsResponse
|
||||
// @Router /api/experimental/aibridge/interceptions [get]
|
||||
// @Router /aibridge/interceptions [get]
|
||||
func (api *API) aiBridgeListInterceptions(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
apiKey := httpmw.APIKey(r)
|
||||
|
||||
@@ -36,10 +36,10 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
Features: license.Features{},
|
||||
},
|
||||
})
|
||||
experimentalClient := codersdk.NewExperimentalClient(client)
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
_, err := experimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
//nolint:gocritic // Owner role is irrelevant here.
|
||||
_, err := client.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
var sdkErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &sdkErr)
|
||||
require.Equal(t, http.StatusForbidden, sdkErr.StatusCode())
|
||||
@@ -59,9 +59,9 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
experimentalClient := codersdk.NewExperimentalClient(client)
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
res, err := experimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
//nolint:gocritic // Owner role is irrelevant here.
|
||||
res, err := client.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, res.Results)
|
||||
})
|
||||
@@ -79,7 +79,6 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
experimentalClient := codersdk.NewExperimentalClient(client)
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
user1, err := client.User(ctx, codersdk.Me)
|
||||
@@ -140,7 +139,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
i1SDK := db2sdk.AIBridgeInterception(i1, user1Visible, []database.AIBridgeTokenUsage{i1tok2, i1tok1}, []database.AIBridgeUserPrompt{i1up2, i1up1}, []database.AIBridgeToolUsage{i1tool2, i1tool1})
|
||||
i2SDK := db2sdk.AIBridgeInterception(i2, user2Visible, nil, nil, nil)
|
||||
|
||||
res, err := experimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
res, err := client.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res.Results, 2)
|
||||
require.Equal(t, i2SDK.ID, res.Results[0].ID)
|
||||
@@ -190,7 +189,6 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
experimentalClient := codersdk.NewExperimentalClient(client)
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
allInterceptionIDs := make([]uuid.UUID, 0, 20)
|
||||
@@ -221,7 +219,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
}
|
||||
|
||||
// Try to fetch with an invalid limit.
|
||||
res, err := experimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
res, err := client.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
Pagination: codersdk.Pagination{
|
||||
Limit: 1001,
|
||||
},
|
||||
@@ -232,7 +230,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
require.Empty(t, res.Results)
|
||||
|
||||
// Try to fetch with both after_id and offset pagination.
|
||||
res, err = experimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
res, err = client.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
Pagination: codersdk.Pagination{
|
||||
AfterID: allInterceptionIDs[0],
|
||||
Offset: 1,
|
||||
@@ -265,7 +263,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
} else {
|
||||
pagination.Offset = len(interceptionIDs)
|
||||
}
|
||||
res, err := experimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
res, err := client.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
Pagination: pagination,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -305,11 +303,9 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
adminExperimentalClient := codersdk.NewExperimentalClient(adminClient)
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
secondUserClient, secondUser := coderdtest.CreateAnotherUser(t, adminClient, firstUser.OrganizationID)
|
||||
secondUserExperimentalClient := codersdk.NewExperimentalClient(secondUserClient)
|
||||
|
||||
now := dbtime.Now()
|
||||
i1 := dbgen.AIBridgeInterception(t, db, database.InsertAIBridgeInterceptionParams{
|
||||
@@ -322,7 +318,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
}, &now)
|
||||
|
||||
// Admin can see all interceptions.
|
||||
res, err := adminExperimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
res, err := adminClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 2, res.Count)
|
||||
require.Len(t, res.Results, 2)
|
||||
@@ -330,7 +326,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
require.Equal(t, i2.ID, res.Results[1].ID)
|
||||
|
||||
// Second user can only see their own interceptions.
|
||||
res, err = secondUserExperimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
res, err = secondUserClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{})
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 1, res.Count)
|
||||
require.Len(t, res.Results, 1)
|
||||
@@ -350,7 +346,6 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
experimentalClient := codersdk.NewExperimentalClient(client)
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
user1, err := client.User(ctx, codersdk.Me)
|
||||
@@ -500,7 +495,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
res, err := experimentalClient.AIBridgeListInterceptions(ctx, tc.filter)
|
||||
res, err := client.AIBridgeListInterceptions(ctx, tc.filter)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, len(tc.want), res.Count)
|
||||
// We just compare UUID strings for the sake of this test.
|
||||
@@ -530,7 +525,6 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
experimentalClient := codersdk.NewExperimentalClient(client)
|
||||
|
||||
// No need to insert any test data, we're just testing the filter
|
||||
// errors.
|
||||
@@ -587,7 +581,7 @@ func TestAIBridgeListInterceptions(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
res, err := experimentalClient.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
res, err := client.AIBridgeListInterceptions(ctx, codersdk.AIBridgeListInterceptionsFilter{
|
||||
FilterQuery: tc.q,
|
||||
})
|
||||
var sdkErr *codersdk.Error
|
||||
|
||||
@@ -226,7 +226,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
||||
return api.refreshEntitlements(ctx)
|
||||
}
|
||||
|
||||
api.AGPL.ExperimentalHandler.Group(func(r chi.Router) {
|
||||
api.AGPL.APIHandler.Group(func(r chi.Router) {
|
||||
r.Route("/aibridge", func(r chi.Router) {
|
||||
r.Use(api.RequireFeatureMW(codersdk.FeatureAIBridge))
|
||||
r.Group(func(r chi.Router) {
|
||||
@@ -243,7 +243,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
||||
})
|
||||
return
|
||||
}
|
||||
http.StripPrefix("/api/experimental/aibridge", api.aibridgedHandler).ServeHTTP(rw, r)
|
||||
http.StripPrefix("/api/v2/aibridge", api.aibridgedHandler).ServeHTTP(rw, r)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user