fix: normalize agnet runtime callbacks
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
1.4.17
|
1.4.18
|
||||||
|
|||||||
@@ -164,13 +164,14 @@ func agnetCallbackDeploymentContext(deploymentID string, swarmID string) (agnetD
|
|||||||
return record, true
|
return record, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if swarmID == "" {
|
runtimeID := firstNonEmpty(swarmID, deploymentID)
|
||||||
|
if runtimeID == "" {
|
||||||
return agnetDeploymentRecord{}, false
|
return agnetDeploymentRecord{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
agnetMu.RLock()
|
agnetMu.RLock()
|
||||||
for _, record := range agnetDeployments {
|
for _, record := range agnetDeployments {
|
||||||
if strings.TrimSpace(record.RuntimeSwarmID) == swarmID {
|
if strings.TrimSpace(record.RuntimeSwarmID) == runtimeID || strings.TrimSpace(record.RuntimeDeploymentID) == runtimeID {
|
||||||
agnetMu.RUnlock()
|
agnetMu.RUnlock()
|
||||||
return record, true
|
return record, true
|
||||||
}
|
}
|
||||||
@@ -181,7 +182,7 @@ func agnetCallbackDeploymentContext(deploymentID string, swarmID string) (agnetD
|
|||||||
return agnetDeploymentRecord{}, false
|
return agnetDeploymentRecord{}, false
|
||||||
}
|
}
|
||||||
var row model.AgnetDeployment
|
var row model.AgnetDeployment
|
||||||
if err := model.DB.Where("runtime_swarm_id = ?", swarmID).First(&row).Error; err != nil {
|
if err := model.DB.Where("runtime_swarm_id = ? OR runtime_deployment_id = ?", runtimeID, runtimeID).First(&row).Error; err != nil {
|
||||||
return agnetDeploymentRecord{}, false
|
return agnetDeploymentRecord{}, false
|
||||||
}
|
}
|
||||||
record, err := agnetDeploymentModelToRecord(row)
|
record, err := agnetDeploymentModelToRecord(row)
|
||||||
@@ -553,9 +554,14 @@ func AgnetReceiveSwarmEventCallback(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
record, _ := agnetCallbackDeploymentContext(strings.TrimSpace(payload.DeploymentID), strings.TrimSpace(payload.SwarmID))
|
incomingDeploymentID := strings.TrimSpace(payload.DeploymentID)
|
||||||
if strings.TrimSpace(payload.DeploymentID) == "" && strings.TrimSpace(record.DeploymentID) != "" {
|
incomingSwarmID := strings.TrimSpace(payload.SwarmID)
|
||||||
|
record, _ := agnetCallbackDeploymentContext(incomingDeploymentID, incomingSwarmID)
|
||||||
|
if strings.TrimSpace(record.DeploymentID) != "" {
|
||||||
payload.DeploymentID = record.DeploymentID
|
payload.DeploymentID = record.DeploymentID
|
||||||
|
if strings.TrimSpace(payload.SwarmID) == "" {
|
||||||
|
payload.SwarmID = firstNonEmpty(record.RuntimeSwarmID, record.RuntimeDeploymentID, incomingDeploymentID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if payload.CorrelationID == "" {
|
if payload.CorrelationID == "" {
|
||||||
payload.CorrelationID = record.Plan.Metadata.CorrelationID
|
payload.CorrelationID = record.Plan.Metadata.CorrelationID
|
||||||
|
|||||||
@@ -48,10 +48,13 @@ type agnetUserContext struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type agnetBillingContext struct {
|
type agnetBillingContext struct {
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
NewAPIUserRef string `json:"newapi_user_ref"`
|
NewAPIUserRef string `json:"newapi_user_ref"`
|
||||||
NewAPIGroup string `json:"newapi_group"`
|
NewAPIGroup string `json:"newapi_group"`
|
||||||
QuotaRef string `json:"quota_ref"`
|
QuotaRef string `json:"quota_ref"`
|
||||||
|
DefaultModelID string `json:"default_model_id"`
|
||||||
|
AllowedModelIDs []string `json:"allowed_model_ids"`
|
||||||
|
SecretRef string `json:"secret_ref"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type agnetAgileContext struct {
|
type agnetAgileContext struct {
|
||||||
|
|||||||
@@ -1154,6 +1154,70 @@ func TestAgnetCallbackUsesSwarmIDFallbackAndCreatesApproval(t *testing.T) {
|
|||||||
require.Equal(t, "azkv://heicode-kv.vault.azure.net/secrets/repo-main", approval.SecretRef)
|
require.Equal(t, "azkv://heicode-kv.vault.azure.net/secrets/repo-main", approval.SecretRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAgnetCallbackUsesRuntimeDeploymentIDFallback(t *testing.T) {
|
||||||
|
db := setupAgnetControlPlaneTestDB(t)
|
||||||
|
resetAgnetControlPlaneState(t)
|
||||||
|
t.Setenv("AGNET_CALLBACK_TOKEN", "callback-token")
|
||||||
|
|
||||||
|
plan := baseAgnetResourceGrantPlan()
|
||||||
|
plan.UserContext.UserID = "7"
|
||||||
|
plan.BillingContext.DefaultModelID = "model-runtime-smoke"
|
||||||
|
plan.BillingContext.AllowedModelIDs = []string{"model-runtime-smoke", "model-runtime-fallback"}
|
||||||
|
plan.BillingContext.SecretRef = "azkv://heicode-kv.vault.azure.net/secrets/model-gateway-key"
|
||||||
|
for idx := range plan.Agents[0].ResourceGrants {
|
||||||
|
plan.Agents[0].ResourceGrants[idx].UserID = "7"
|
||||||
|
}
|
||||||
|
createRecorder, createEnvelope := postAgnetCreateUserDeployment(t, 7, plan)
|
||||||
|
require.True(t, createEnvelope.Success)
|
||||||
|
var createBody map[string]any
|
||||||
|
require.NoError(t, common.Unmarshal(createRecorder.Body.Bytes(), &createBody))
|
||||||
|
deploymentID := createBody["data"].(map[string]any)["deployment_id"].(string)
|
||||||
|
runtimeID := "swm-runtime-deployment-only-1"
|
||||||
|
require.NoError(t, db.Model(&model.AgnetDeployment{}).
|
||||||
|
Where("deployment_id = ?", deploymentID).
|
||||||
|
Updates(map[string]any{
|
||||||
|
"runtime_deployment_id": runtimeID,
|
||||||
|
"runtime_swarm_id": runtimeID,
|
||||||
|
}).Error)
|
||||||
|
resetAgnetControlPlaneState(t)
|
||||||
|
|
||||||
|
body := `{
|
||||||
|
"event_id":"evt-runtime-deployment-fallback",
|
||||||
|
"event_type":"timeline.updated",
|
||||||
|
"deployment_id":"swm-runtime-deployment-only-1",
|
||||||
|
"agent_instance_id":"agi-backend-runtime",
|
||||||
|
"occurred_at":"2026-05-28T12:30:00Z",
|
||||||
|
"payload":{
|
||||||
|
"title":"Runtime accepted",
|
||||||
|
"summary":"Agent Manager returned a runtime deployment id only",
|
||||||
|
"stage":"testing",
|
||||||
|
"checkpoint":"runtime_accepted"
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
ctx, _ := gin.CreateTestContext(recorder)
|
||||||
|
ctx.Request = httptest.NewRequest(http.MethodPost, "/api/agnet/callbacks/swarm-events", strings.NewReader(body))
|
||||||
|
ctx.Request.Header.Set("Content-Type", "application/json")
|
||||||
|
ctx.Request.Header.Set("X-Agnet-Service-Token", "callback-token")
|
||||||
|
AgnetReceiveSwarmEventCallback(ctx)
|
||||||
|
require.Equal(t, http.StatusOK, recorder.Code)
|
||||||
|
require.Contains(t, recorder.Body.String(), `"success":true`)
|
||||||
|
require.Contains(t, recorder.Body.String(), `"deployment_id":"`+deploymentID+`"`)
|
||||||
|
|
||||||
|
var callback model.AgnetCallbackEvent
|
||||||
|
require.NoError(t, db.Where("event_id = ?", "evt-runtime-deployment-fallback").First(&callback).Error)
|
||||||
|
require.Equal(t, deploymentID, callback.DeploymentID)
|
||||||
|
require.Equal(t, runtimeID, callback.SwarmID)
|
||||||
|
require.Equal(t, "7", callback.UserID)
|
||||||
|
|
||||||
|
var stored model.AgnetDeployment
|
||||||
|
require.NoError(t, db.Where("deployment_id = ?", deploymentID).First(&stored).Error)
|
||||||
|
require.Contains(t, stored.PlanJSON, `"default_model_id":"model-runtime-smoke"`)
|
||||||
|
require.Contains(t, stored.PlanJSON, `"allowed_model_ids":["model-runtime-smoke","model-runtime-fallback"]`)
|
||||||
|
require.Contains(t, stored.PlanJSON, `"secret_ref":"azkv://heicode-kv.vault.azure.net/secrets/model-gateway-key"`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAgnetCallbackRejectsPlaintextSecretsAndMissingToken(t *testing.T) {
|
func TestAgnetCallbackRejectsPlaintextSecretsAndMissingToken(t *testing.T) {
|
||||||
setupAgnetControlPlaneTestDB(t)
|
setupAgnetControlPlaneTestDB(t)
|
||||||
resetAgnetControlPlaneState(t)
|
resetAgnetControlPlaneState(t)
|
||||||
|
|||||||
Reference in New Issue
Block a user