You've already forked agentic-coding-workflow
修改
This commit is contained in:
+98
-26
@@ -42,6 +42,7 @@ type Handler struct {
|
||||
sessSvc SessionService
|
||||
sup *Supervisor
|
||||
repo Repository
|
||||
permSvc *PermissionService
|
||||
resolver middleware.SessionResolver
|
||||
adminLookup AdminLookup
|
||||
enc *crypto.Encryptor
|
||||
@@ -50,9 +51,10 @@ type Handler struct {
|
||||
|
||||
// NewHandler constructs Handler with full dependencies.
|
||||
func NewHandler(ak AgentKindService, ss SessionService, sup *Supervisor, repo Repository,
|
||||
resolver middleware.SessionResolver, al AdminLookup, enc *crypto.Encryptor, cfg WSConfig) *Handler {
|
||||
permSvc *PermissionService, resolver middleware.SessionResolver, al AdminLookup,
|
||||
enc *crypto.Encryptor, cfg WSConfig) *Handler {
|
||||
return &Handler{
|
||||
akSvc: ak, sessSvc: ss, sup: sup, repo: repo,
|
||||
akSvc: ak, sessSvc: ss, sup: sup, repo: repo, permSvc: permSvc,
|
||||
resolver: resolver, adminLookup: al, enc: enc, cfg: cfg,
|
||||
}
|
||||
}
|
||||
@@ -75,7 +77,74 @@ func (h *Handler) Mount(r chi.Router) {
|
||||
r.Delete("/{id}", h.terminateSession)
|
||||
r.Get("/{id}/events", h.getEvents)
|
||||
r.Get("/{id}/ws", h.sessionWS)
|
||||
r.Get("/{id}/permissions", h.listSessionPermissions)
|
||||
})
|
||||
r.Route("/api/v1/acp/permissions", func(r chi.Router) {
|
||||
r.Use(middleware.Auth(h.resolver, middleware.AuthOptions{}))
|
||||
r.Post("/{reqID}/approve", h.approvePermission)
|
||||
r.Post("/{reqID}/deny", h.denyPermission)
|
||||
})
|
||||
}
|
||||
|
||||
// listSessionPermissions 返回某会话的待审权限请求(owner 或 admin)。
|
||||
func (h *Handler) listSessionPermissions(w http.ResponseWriter, r *http.Request) {
|
||||
c, err := h.caller(r)
|
||||
if err != nil {
|
||||
writeErr(w, r, err)
|
||||
return
|
||||
}
|
||||
id, perr := uuid.Parse(chi.URLParam(r, "id"))
|
||||
if perr != nil {
|
||||
writeErr(w, r, errs.New(errs.CodeInvalidInput, "bad id"))
|
||||
return
|
||||
}
|
||||
reqs, err := h.permSvc.ListPendingBySession(r.Context(), c, id)
|
||||
if err != nil {
|
||||
writeErr(w, r, err)
|
||||
return
|
||||
}
|
||||
out := make([]PermissionRequestDTO, 0, len(reqs))
|
||||
for _, p := range reqs {
|
||||
out = append(out, permissionRequestToDTO(p))
|
||||
}
|
||||
httpx.WriteJSON(w, http.StatusOK, out)
|
||||
}
|
||||
|
||||
type approvePermissionReq struct {
|
||||
OptionID string `json:"option_id"`
|
||||
}
|
||||
|
||||
func (h *Handler) approvePermission(w http.ResponseWriter, r *http.Request) {
|
||||
h.resolvePermission(w, r, true)
|
||||
}
|
||||
|
||||
func (h *Handler) denyPermission(w http.ResponseWriter, r *http.Request) {
|
||||
h.resolvePermission(w, r, false)
|
||||
}
|
||||
|
||||
func (h *Handler) resolvePermission(w http.ResponseWriter, r *http.Request, approve bool) {
|
||||
c, err := h.caller(r)
|
||||
if err != nil {
|
||||
writeErr(w, r, err)
|
||||
return
|
||||
}
|
||||
reqID, perr := uuid.Parse(chi.URLParam(r, "reqID"))
|
||||
if perr != nil {
|
||||
writeErr(w, r, errs.New(errs.CodeInvalidInput, "bad request id"))
|
||||
return
|
||||
}
|
||||
var optionID string
|
||||
if approve {
|
||||
var body approvePermissionReq
|
||||
// 批准时 option_id 可选(缺省自动挑选 allow 类);请求体可空。
|
||||
_ = json.NewDecoder(r.Body).Decode(&body)
|
||||
optionID = body.OptionID
|
||||
}
|
||||
if err := h.permSvc.Resolve(r.Context(), c, reqID, approve, optionID); err != nil {
|
||||
writeErr(w, r, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (h *Handler) caller(r *http.Request) (Caller, error) {
|
||||
@@ -132,13 +201,14 @@ func (h *Handler) createAgentKind(w http.ResponseWriter, r *http.Request) {
|
||||
enabled = *req.Enabled
|
||||
}
|
||||
in := CreateAgentKindInput{
|
||||
Name: strings.TrimSpace(req.Name),
|
||||
DisplayName: req.DisplayName,
|
||||
Description: req.Description,
|
||||
BinaryPath: strings.TrimSpace(req.BinaryPath),
|
||||
Args: req.Args,
|
||||
Env: req.Env,
|
||||
Enabled: enabled,
|
||||
Name: strings.TrimSpace(req.Name),
|
||||
DisplayName: req.DisplayName,
|
||||
Description: req.Description,
|
||||
BinaryPath: strings.TrimSpace(req.BinaryPath),
|
||||
Args: req.Args,
|
||||
Env: req.Env,
|
||||
Enabled: enabled,
|
||||
ToolAllowlist: req.ToolAllowlist,
|
||||
}
|
||||
out, err := h.akSvc.Create(r.Context(), c, in)
|
||||
if err != nil {
|
||||
@@ -188,12 +258,13 @@ func (h *Handler) updateAgentKind(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
in := UpdateAgentKindInput{
|
||||
DisplayName: req.DisplayName,
|
||||
Description: req.Description,
|
||||
BinaryPath: req.BinaryPath,
|
||||
Args: req.Args,
|
||||
Env: req.Env,
|
||||
Enabled: req.Enabled,
|
||||
DisplayName: req.DisplayName,
|
||||
Description: req.Description,
|
||||
BinaryPath: req.BinaryPath,
|
||||
Args: req.Args,
|
||||
Env: req.Env,
|
||||
Enabled: req.Enabled,
|
||||
ToolAllowlist: req.ToolAllowlist,
|
||||
}
|
||||
out, err := h.akSvc.Update(r.Context(), c, id, in)
|
||||
if err != nil {
|
||||
@@ -539,17 +610,18 @@ func (h *Handler) agentKindToAdminDTO(k *AgentKind) AgentKindAdminDTO {
|
||||
}
|
||||
}
|
||||
return AgentKindAdminDTO{
|
||||
ID: k.ID,
|
||||
Name: k.Name,
|
||||
DisplayName: k.DisplayName,
|
||||
Description: k.Description,
|
||||
BinaryPath: k.BinaryPath,
|
||||
Args: append([]string(nil), k.Args...),
|
||||
EnvKeys: envKeys,
|
||||
Enabled: k.Enabled,
|
||||
CreatedBy: k.CreatedBy,
|
||||
CreatedAt: k.CreatedAt.UTC().Format("2006-01-02T15:04:05Z"),
|
||||
UpdatedAt: k.UpdatedAt.UTC().Format("2006-01-02T15:04:05Z"),
|
||||
ID: k.ID,
|
||||
Name: k.Name,
|
||||
DisplayName: k.DisplayName,
|
||||
Description: k.Description,
|
||||
BinaryPath: k.BinaryPath,
|
||||
Args: append([]string(nil), k.Args...),
|
||||
EnvKeys: envKeys,
|
||||
Enabled: k.Enabled,
|
||||
ToolAllowlist: append([]string(nil), k.ToolAllowlist...),
|
||||
CreatedBy: k.CreatedBy,
|
||||
CreatedAt: k.CreatedAt.UTC().Format("2006-01-02T15:04:05Z"),
|
||||
UpdatedAt: k.UpdatedAt.UTC().Format("2006-01-02T15:04:05Z"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user