mirror of
https://github.com/hanzoai/agents.git
synced 2026-10-30 18:48:36 +00:00
The admin control surface was the last gRPC/protobuf in the control plane. Replace it end to end with the native ZAP stack — no protobuf, no gRPC, no build-tag dance. Schema + wire: - proto/admin/reasoner_admin.zap: the AdminReasoner interface as a .zap schema (text fields; param-less listReasoners since ZAP rejects an empty struct). - pkg/adminwire: zapgen output — zero-copy New<Msg>/Wrap<Msg>, the bytes are the message, no marshal step. Server: - internal/server/server_admin.go: transport.Serve over the ZAP transport. Capability auth carries the API key in each request's Cap field, checked in constant time (crypto/subtle) — an upgrade over the deleted gRPC path, which compared with ==, a timing oracle. - H-1 hardening: with no API key configured the surface is unauthenticated, so it binds loopback only (adminBindHost) and is unreachable off-box; a keyed surface binds all interfaces. Reachability and authentication are decided separately, not entangled. - server.go: the adminTransport/UnimplementedServer gRPC scaffolding drops out for a *transport.Server. Removed: - google.golang.org/grpc, the direct google.golang.org/protobuf dependency, pkg/adminpb (the generated .pb.go + grpc stub), the grpc_auth middleware, server_grpc.go / server_zap.go, and the dead `replace operator => ../`. Tests (all pass): adminwire round-trip over real TCP and Unix sockets with all seven Reasoner fields intact, unknown-ordinal rejection, the five authorize cases, and the loopback-bind decision.
90 lines
3.0 KiB
Go
90 lines
3.0 KiB
Go
// Code generated by zapgen; DO NOT EDIT.
|
|
// source: reasoner_admin.zap
|
|
|
|
package admin
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/zap-proto/go/rpc"
|
|
)
|
|
|
|
// Method ordinals for the AdminReasoner service (stable 1-based wire ids).
|
|
const (
|
|
AdminReasonerListReasonersOrdinal uint32 = 1
|
|
)
|
|
|
|
// AdminReasonerChannel ships one Call envelope and awaits its correlated Response.
|
|
type AdminReasonerChannel interface {
|
|
Call(envelope []byte) (rpc.Response, error)
|
|
}
|
|
|
|
// AdminReasonerClient is a typed RPC client for the AdminReasoner service over a ZAP call channel.
|
|
// Each call takes a fresh PromiseID from sess; the pipelined "On" form of a
|
|
// method sets Target to a prior call's Promise so the server chains them.
|
|
type AdminReasonerClient struct {
|
|
ch AdminReasonerChannel
|
|
cap []byte
|
|
sess *rpc.Session
|
|
}
|
|
|
|
// NewAdminReasonerClient returns a client that issues calls over ch, attaching cap
|
|
// (which may be nil) to every request.
|
|
func NewAdminReasonerClient(ch AdminReasonerChannel, capability []byte) *AdminReasonerClient {
|
|
return &AdminReasonerClient{ch: ch, cap: capability, sess: rpc.NewSession()}
|
|
}
|
|
|
|
func (c *AdminReasonerClient) ListReasoners() (rpc.Promise, []byte, error) {
|
|
return c.invokeListReasoners(rpc.NoTarget, nil)
|
|
}
|
|
|
|
// ListReasonersOn issues ListReasoners as a dependent call pipelined on the answer of on:
|
|
// the server substitutes on's resolved result for this call's payload
|
|
// before dispatch, so it ships without waiting for on to round-trip.
|
|
func (c *AdminReasonerClient) ListReasonersOn(on rpc.Promise) (rpc.Promise, []byte, error) {
|
|
return c.invokeListReasoners(on.ID, nil)
|
|
}
|
|
|
|
func (c *AdminReasonerClient) invokeListReasoners(target uint32, payload []byte) (rpc.Promise, []byte, error) {
|
|
p := c.sess.Next()
|
|
resp, err := c.ch.Call(rpc.BuildRequest(rpc.Call{
|
|
Method: AdminReasonerListReasonersOrdinal,
|
|
PromiseID: p.ID,
|
|
Target: target,
|
|
Cap: c.cap,
|
|
Payload: payload,
|
|
}))
|
|
if err != nil {
|
|
return p, nil, err
|
|
}
|
|
if resp.Status != rpc.StatusOK {
|
|
return p, nil, fmt.Errorf("AdminReasoner.ListReasoners: status %d", resp.Status)
|
|
}
|
|
return p, resp.Body, nil
|
|
}
|
|
|
|
// AdminReasonerHandler is the server contract for the AdminReasoner service. Implement each
|
|
// method, then route requests to it with DispatchAdminReasoner.
|
|
type AdminReasonerHandler interface {
|
|
ListReasoners() ([]byte, error)
|
|
}
|
|
|
|
// DispatchAdminReasoner decodes a Call envelope, routes it by method ordinal to h,
|
|
// and returns the response envelope. An unknown ordinal yields a
|
|
// StatusNotFound response; a handler error yields StatusInternal.
|
|
func DispatchAdminReasoner(h AdminReasonerHandler, envelope []byte) ([]byte, error) {
|
|
call, err := rpc.ParseRequest(envelope)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
switch call.Method {
|
|
case AdminReasonerListReasonersOrdinal:
|
|
body, err := h.ListReasoners()
|
|
if err != nil {
|
|
return rpc.BuildResponse(rpc.StatusInternal, call.PromiseID, nil), nil
|
|
}
|
|
return rpc.BuildResponse(rpc.StatusOK, call.PromiseID, body), nil
|
|
default:
|
|
return rpc.BuildResponse(rpc.StatusNotFound, call.PromiseID, nil), nil
|
|
}
|
|
}
|