Merge the internal/ipc sweep (#216)
V-575. dispatch held 13 arms of one shape: nil check, unmarshal, call, marshal, and a hand-written unknown-method error repeated eight times. callDirect, callDirectNoParams, callDirectVoid and unknownMethod give the switch one line per method naming the Server field behind it. The nil-field-means-unconfigured contract is unchanged. withParamsSlice holds the nil-slice normalisation the method table repeated 14 times. MethodTurnDecisions and MethodMorningStatus keep their own, because one normalises on error and the other must still emit null. mapRows replaces the same three lines in 11 store methods. RevertFact sent a map[string]string against a server marshalling map[string]int64, so both sides now share revertReq and revertResp. Wire bytes are identical throughout. The 45 client shims stay. They mirror CoreAPI one to one on purpose. 156 insertions, 362 deletions. go test -race passes.
This commit is contained in:
+6
-9
@@ -594,7 +594,7 @@ type setTaskFieldsReq struct {
|
||||
BlockedOn string `json:"blocked_on,omitempty"`
|
||||
}
|
||||
|
||||
// idReq — methods keyed by a single id.
|
||||
// idReq — methods keyed by a single id, which is every routine transition.
|
||||
type idReq struct {
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
@@ -652,6 +652,11 @@ type calendarEventsReq struct {
|
||||
type revertReq struct {
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// revertResp — the id of the voiding fact the revert wrote.
|
||||
type revertResp struct {
|
||||
NewID int64 `json:"new_id"`
|
||||
}
|
||||
type writeNoteReq struct {
|
||||
Ts time.Time `json:"ts"`
|
||||
Text string `json:"text"`
|
||||
@@ -780,14 +785,6 @@ type listProposedRoutinesResp struct {
|
||||
Routines []ProposedRoutine `json:"routines"`
|
||||
}
|
||||
|
||||
type dismissProposedRoutineReq struct {
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
type acceptProposedRoutineReq struct {
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
// IntakeEvent — one entry of the unified intake journal on the wire. Mirrors
|
||||
// event.Event field for field; the ipc package does not import internal/event
|
||||
// so the wire shape stays independent of the in-process type.
|
||||
|
||||
@@ -649,11 +649,11 @@ func (c *Client) ModelStatus(ctx context.Context) (ModelStatusResp, error) {
|
||||
}
|
||||
|
||||
func (c *Client) DismissProposedRoutine(ctx context.Context, id int64) error {
|
||||
return c.call(ctx, MethodDismissProposedRoutine, dismissProposedRoutineReq{ID: id}, nil)
|
||||
return c.call(ctx, MethodDismissProposedRoutine, idReq{ID: id}, nil)
|
||||
}
|
||||
|
||||
func (c *Client) AcceptProposedRoutine(ctx context.Context, id int64) error {
|
||||
return c.call(ctx, MethodAcceptProposedRoutine, acceptProposedRoutineReq{ID: id}, nil)
|
||||
return c.call(ctx, MethodAcceptProposedRoutine, idReq{ID: id}, nil)
|
||||
}
|
||||
|
||||
func (c *Client) Chat(ctx context.Context, conversation, text string) (ChatReply, error) {
|
||||
@@ -713,13 +713,11 @@ func (c *Client) DayPlan(ctx context.Context) (DayPlan, error) {
|
||||
}
|
||||
|
||||
func (c *Client) RevertFact(ctx context.Context, key string) (int64, error) {
|
||||
var result struct {
|
||||
NewID int64 `json:"new_id"`
|
||||
}
|
||||
if err := c.call(ctx, MethodRevertFact, map[string]string{"key": key}, &result); err != nil {
|
||||
var r revertResp
|
||||
if err := c.call(ctx, MethodRevertFact, revertReq{Key: key}, &r); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.NewID, nil
|
||||
return r.NewID, nil
|
||||
}
|
||||
|
||||
// Ping asks whether the daemon is there, and whether it is locked. It is not a
|
||||
|
||||
+126
-264
@@ -335,6 +335,22 @@ func withoutParams[R any](fn func(ctx context.Context, api CoreAPI) (R, error))
|
||||
}
|
||||
}
|
||||
|
||||
// withParamsSlice is withParams for a list read. It replaces a nil slice with
|
||||
// an empty one so the wire carries [] rather than null, which every reader of
|
||||
// these methods relies on.
|
||||
func withParamsSlice[P any, E any](fn func(ctx context.Context, api CoreAPI, p P) ([]E, error)) handlerFunc {
|
||||
return withParams(func(ctx context.Context, api CoreAPI, p P) ([]E, error) {
|
||||
out, err := fn(ctx, api, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []E{}
|
||||
}
|
||||
return out, nil
|
||||
})
|
||||
}
|
||||
|
||||
// methodTable — one entry per CoreAPI-backed method. Built once at package
|
||||
// init, not per-Server and not per-dispatch: entries close over nothing but
|
||||
// the CoreAPI method being called, and dispatch passes in the *current*
|
||||
@@ -373,15 +389,8 @@ var methodTable = map[Method]handlerFunc{
|
||||
MethodMarkReminder: withParamsVoid(func(ctx context.Context, api CoreAPI, p markReminderReq) error {
|
||||
return api.MarkReminder(ctx, p.ID, p.Status)
|
||||
}),
|
||||
MethodListReminders: withParams(func(ctx context.Context, api CoreAPI, p nReq) ([]Reminder, error) {
|
||||
out, err := api.ListReminders(ctx, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Reminder{}
|
||||
}
|
||||
return out, nil
|
||||
MethodListReminders: withParamsSlice(func(ctx context.Context, api CoreAPI, p nReq) ([]Reminder, error) {
|
||||
return api.ListReminders(ctx, p.N)
|
||||
}),
|
||||
MethodRecordNudge: withParams(func(ctx context.Context, api CoreAPI, p recordNudgeReq) (idResp, error) {
|
||||
id, err := api.RecordNudge(ctx, p.Rule, p.Channel, p.Message, p.Ts)
|
||||
@@ -390,109 +399,39 @@ var methodTable = map[Method]handlerFunc{
|
||||
MethodResolveNudge: withParamsVoid(func(ctx context.Context, api CoreAPI, p resolveNudgeReq) error {
|
||||
return api.ResolveNudge(ctx, p.ID, p.Outcome, p.Ts)
|
||||
}),
|
||||
MethodRecentOutcomes: withParams(func(ctx context.Context, api CoreAPI, p outcomesReq) ([]string, error) {
|
||||
out, err := api.RecentOutcomes(ctx, p.Rule, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []string{} // stable non-null on the wire
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentOutcomes: withParamsSlice(func(ctx context.Context, api CoreAPI, p outcomesReq) ([]string, error) {
|
||||
return api.RecentOutcomes(ctx, p.Rule, p.N)
|
||||
}),
|
||||
MethodRecentFacts: withParams(func(ctx context.Context, api CoreAPI, p nReq) ([]Fact, error) {
|
||||
out, err := api.RecentFacts(ctx, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Fact{}
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentFacts: withParamsSlice(func(ctx context.Context, api CoreAPI, p nReq) ([]Fact, error) {
|
||||
return api.RecentFacts(ctx, p.N)
|
||||
}),
|
||||
MethodRecentActiveFacts: withParams(func(ctx context.Context, api CoreAPI, p kindNReq) ([]Fact, error) {
|
||||
out, err := api.RecentActiveFactsByKind(ctx, p.Kind, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Fact{}
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentActiveFacts: withParamsSlice(func(ctx context.Context, api CoreAPI, p kindNReq) ([]Fact, error) {
|
||||
return api.RecentActiveFactsByKind(ctx, p.Kind, p.N)
|
||||
}),
|
||||
MethodCalendarEvents: withParams(func(ctx context.Context, api CoreAPI, p calendarEventsReq) ([]Fact, error) {
|
||||
out, err := api.CalendarEvents(ctx, p.From, p.To)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Fact{}
|
||||
}
|
||||
return out, nil
|
||||
MethodCalendarEvents: withParamsSlice(func(ctx context.Context, api CoreAPI, p calendarEventsReq) ([]Fact, error) {
|
||||
return api.CalendarEvents(ctx, p.From, p.To)
|
||||
}),
|
||||
MethodRecentEcoTraces: withParams(func(ctx context.Context, api CoreAPI, p nReq) ([]EcosystemTrace, error) {
|
||||
out, err := api.RecentEcosystemTraces(ctx, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []EcosystemTrace{}
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentEcoTraces: withParamsSlice(func(ctx context.Context, api CoreAPI, p nReq) ([]EcosystemTrace, error) {
|
||||
return api.RecentEcosystemTraces(ctx, p.N)
|
||||
}),
|
||||
MethodDeliveryAttempts: withParams(func(ctx context.Context, api CoreAPI, p deliveryAttemptsReq) ([]DeliveryAttempt, error) {
|
||||
out, err := api.DeliveryAttempts(ctx, p.Status, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []DeliveryAttempt{}
|
||||
}
|
||||
return out, nil
|
||||
MethodDeliveryAttempts: withParamsSlice(func(ctx context.Context, api CoreAPI, p deliveryAttemptsReq) ([]DeliveryAttempt, error) {
|
||||
return api.DeliveryAttempts(ctx, p.Status, p.N)
|
||||
}),
|
||||
MethodRecentNudges: withParams(func(ctx context.Context, api CoreAPI, p nReq) ([]Nudge, error) {
|
||||
out, err := api.RecentNudges(ctx, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Nudge{}
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentNudges: withParamsSlice(func(ctx context.Context, api CoreAPI, p nReq) ([]Nudge, error) {
|
||||
return api.RecentNudges(ctx, p.N)
|
||||
}),
|
||||
MethodWriteNote: withParams(func(ctx context.Context, api CoreAPI, p writeNoteReq) (idResp, error) {
|
||||
id, err := api.WriteNote(ctx, p.Ts, p.Text, p.Embedding, p.Source)
|
||||
return idResp{ID: id}, err
|
||||
}),
|
||||
MethodQueryNotes: withParams(func(ctx context.Context, api CoreAPI, p queryNotesReq) ([]Note, error) {
|
||||
out, err := api.QueryNotes(ctx, p.Embedding, p.K)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Note{}
|
||||
}
|
||||
return out, nil
|
||||
MethodQueryNotes: withParamsSlice(func(ctx context.Context, api CoreAPI, p queryNotesReq) ([]Note, error) {
|
||||
return api.QueryNotes(ctx, p.Embedding, p.K)
|
||||
}),
|
||||
MethodRecentNotesFromSource: withParams(func(ctx context.Context, api CoreAPI, p sourceNReq) ([]Note, error) {
|
||||
out, err := api.RecentNotesFromSource(ctx, p.Prefix, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Note{}
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentNotesFromSource: withParamsSlice(func(ctx context.Context, api CoreAPI, p sourceNReq) ([]Note, error) {
|
||||
return api.RecentNotesFromSource(ctx, p.Prefix, p.N)
|
||||
}),
|
||||
MethodRecentNotes: withParams(func(ctx context.Context, api CoreAPI, p nReq) ([]Note, error) {
|
||||
out, err := api.RecentNotes(ctx, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []Note{}
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentNotes: withParamsSlice(func(ctx context.Context, api CoreAPI, p nReq) ([]Note, error) {
|
||||
return api.RecentNotes(ctx, p.N)
|
||||
}),
|
||||
MethodProposeTool: withParams(func(ctx context.Context, api CoreAPI, p proposeToolReq) (proposeToolResp, error) {
|
||||
ok, err := api.ProposeTool(ctx, p.Name, p.Utterance, p.Scope, p.Ts)
|
||||
@@ -563,18 +502,15 @@ var methodTable = map[Method]handlerFunc{
|
||||
}
|
||||
return listProposedRoutinesResp{Routines: out}, nil
|
||||
}),
|
||||
MethodDismissProposedRoutine: withParamsVoid(func(ctx context.Context, api CoreAPI, p dismissProposedRoutineReq) error {
|
||||
MethodDismissProposedRoutine: withParamsVoid(func(ctx context.Context, api CoreAPI, p idReq) error {
|
||||
return api.DismissProposedRoutine(ctx, p.ID)
|
||||
}),
|
||||
MethodAcceptProposedRoutine: withParamsVoid(func(ctx context.Context, api CoreAPI, p acceptProposedRoutineReq) error {
|
||||
MethodAcceptProposedRoutine: withParamsVoid(func(ctx context.Context, api CoreAPI, p idReq) error {
|
||||
return api.AcceptProposedRoutine(ctx, p.ID)
|
||||
}),
|
||||
MethodRevertFact: withParams(func(ctx context.Context, api CoreAPI, p revertReq) (map[string]int64, error) {
|
||||
MethodRevertFact: withParams(func(ctx context.Context, api CoreAPI, p revertReq) (revertResp, error) {
|
||||
newID, err := api.RevertFact(ctx, p.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]int64{"new_id": newID}, nil
|
||||
return revertResp{NewID: newID}, err
|
||||
}),
|
||||
MethodChat: withParams(func(ctx context.Context, api CoreAPI, p chatReq) (chatResp, error) {
|
||||
reply, err := api.Chat(ctx, p.Conversation, p.Text)
|
||||
@@ -599,15 +535,8 @@ var methodTable = map[Method]handlerFunc{
|
||||
MethodMorningStatus: withoutParams(func(ctx context.Context, api CoreAPI) ([]MorningRoutineStatus, error) {
|
||||
return api.MorningStatus(ctx)
|
||||
}),
|
||||
MethodRecentEvents: withParams(func(ctx context.Context, api CoreAPI, p nReq) ([]IntakeEvent, error) {
|
||||
out, err := api.RecentEvents(ctx, p.N)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
out = []IntakeEvent{}
|
||||
}
|
||||
return out, nil
|
||||
MethodRecentEvents: withParamsSlice(func(ctx context.Context, api CoreAPI, p nReq) ([]IntakeEvent, error) {
|
||||
return api.RecentEvents(ctx, p.N)
|
||||
}),
|
||||
MethodMCPServers: withoutParams(func(ctx context.Context, api CoreAPI) ([]MCPServerStatus, error) {
|
||||
out, err := api.MCPServers(ctx)
|
||||
@@ -654,180 +583,113 @@ func (s *Server) dispatch(ctx context.Context, req Request) (json.RawMessage, er
|
||||
return marshalResult(PingResp{Alive: true, Locked: locked}), nil
|
||||
|
||||
case MethodAssertStepUp:
|
||||
if s.StepUp != nil {
|
||||
return marshalResult(nil), s.StepUp(ctx)
|
||||
if s.StepUp == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
return marshalResult(nil), s.StepUp(ctx)
|
||||
|
||||
case MethodStoreEncryptionKey:
|
||||
if s.WrapKeyFn != nil {
|
||||
var p storeEncryptionKeyReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.WrapKeyFn(ctx, p.Secret, p.Explicit)
|
||||
if s.WrapKeyFn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
var p storeEncryptionKeyReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.WrapKeyFn(ctx, p.Secret, p.Explicit)
|
||||
|
||||
case MethodUnlock:
|
||||
if s.UnlockFn != nil {
|
||||
var p unlockReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.UnlockFn(ctx, p.Secret)
|
||||
if s.UnlockFn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
var p unlockReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), s.UnlockFn(ctx, p.Secret)
|
||||
|
||||
case MethodIngestMail:
|
||||
if s.IngestMailFn != nil {
|
||||
var p IngestMailReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.IngestMailFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.IngestMailFn)
|
||||
case MethodSwapModel:
|
||||
if s.SwapModelFn != nil {
|
||||
var p SwapModelReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.SwapModelFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.SwapModelFn)
|
||||
case MethodDescribeImage:
|
||||
if s.DescribeImageFn != nil {
|
||||
var p DescribeImageReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.DescribeImageFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.DescribeImageFn)
|
||||
case MethodCaptureStart:
|
||||
if s.CaptureStartFn != nil {
|
||||
var p CaptureStartReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.CaptureStartFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.CaptureStartFn)
|
||||
case MethodCaptureAppend:
|
||||
if s.CaptureAppendFn != nil {
|
||||
var p CaptureAppendReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.CaptureAppendFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.CaptureAppendFn)
|
||||
case MethodCaptureStop:
|
||||
if s.CaptureStopFn != nil {
|
||||
var p CaptureStopReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.CaptureStopFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
case MethodCaptureStatus:
|
||||
if s.CaptureStatusFn != nil {
|
||||
resp, err := s.CaptureStatusFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.CaptureStopFn)
|
||||
case MethodEnrollSpeaker:
|
||||
if s.EnrollSpeakerFn != nil {
|
||||
var p EnrollSpeakerReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.EnrollSpeakerFn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirect(ctx, req, s.EnrollSpeakerFn)
|
||||
case MethodCaptureStatus:
|
||||
return callDirectNoParams(ctx, req, s.CaptureStatusFn)
|
||||
case MethodListSpeakers:
|
||||
if s.ListSpeakersFn != nil {
|
||||
resp, err := s.ListSpeakersFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
case MethodForgetSpeaker:
|
||||
if s.ForgetSpeakerFn != nil {
|
||||
var p ForgetSpeakerReq
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.ForgetSpeakerFn(ctx, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
|
||||
return callDirectNoParams(ctx, req, s.ListSpeakersFn)
|
||||
case MethodModelStatus:
|
||||
if s.ModelStatusFn != nil {
|
||||
resp, err := s.ModelStatusFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(resp), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
return callDirectNoParams(ctx, req, s.ModelStatusFn)
|
||||
case MethodForgetSpeaker:
|
||||
return callDirectVoid(ctx, req, s.ForgetSpeakerFn)
|
||||
}
|
||||
|
||||
h, ok := methodTable[req.Method]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnknownMethod, req.Method)
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
return h(ctx, api, req.Params)
|
||||
}
|
||||
|
||||
// callDirect runs a daemon-supplied handler that bypasses CoreAPI: unmarshal
|
||||
// the params, call it, marshal the reply. A nil handler is the capability being
|
||||
// unconfigured on this box, and the wire says so as an unknown method.
|
||||
func callDirect[P any, R any](ctx context.Context, req Request, fn func(context.Context, P) (R, error)) (json.RawMessage, error) {
|
||||
if fn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
var p P
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err := fn(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(r), nil
|
||||
}
|
||||
|
||||
// callDirectNoParams is callDirect for a handler that reads no params. Like
|
||||
// withoutParams it never touches req.Params.
|
||||
func callDirectNoParams[R any](ctx context.Context, req Request, fn func(context.Context) (R, error)) (json.RawMessage, error) {
|
||||
if fn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
r, err := fn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(r), nil
|
||||
}
|
||||
|
||||
// callDirectVoid is callDirect for a handler with nothing to report back. The
|
||||
// wire reply is always null.
|
||||
func callDirectVoid[P any](ctx context.Context, req Request, fn func(context.Context, P) error) (json.RawMessage, error) {
|
||||
if fn == nil {
|
||||
return nil, unknownMethod(req.Method)
|
||||
}
|
||||
var p P
|
||||
if err := unmarshalParams(req.Params, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := fn(ctx, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return marshalResult(nil), nil
|
||||
}
|
||||
|
||||
func unknownMethod(m Method) error {
|
||||
return fmt.Errorf("%w: %s", ErrUnknownMethod, m)
|
||||
}
|
||||
|
||||
func unmarshalParams(raw json.RawMessage, v any) error {
|
||||
if len(raw) == 0 {
|
||||
raw = []byte("null")
|
||||
|
||||
+34
-105
@@ -77,18 +77,24 @@ func (a *storeAPI) MarkReminder(ctx context.Context, id int64, status string) er
|
||||
return mapErr(a.s.MarkReminder(ctx, id, status))
|
||||
}
|
||||
|
||||
func (a *storeAPI) ListReminders(ctx context.Context, n int) ([]Reminder, error) {
|
||||
rs, err := a.s.ListReminders(ctx, n)
|
||||
// mapRows carries a store read's error through mapErr and converts the rows to
|
||||
// their wire shape. Every list method here is that one shape.
|
||||
func mapRows[S any, W any](rows []S, err error, conv func(S) W) ([]W, error) {
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Reminder, len(rs))
|
||||
for i, r := range rs {
|
||||
out[i] = toReminder(r)
|
||||
out := make([]W, len(rows))
|
||||
for i, r := range rows {
|
||||
out[i] = conv(r)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *storeAPI) ListReminders(ctx context.Context, n int) ([]Reminder, error) {
|
||||
rs, err := a.s.ListReminders(ctx, n)
|
||||
return mapRows(rs, err, toReminder)
|
||||
}
|
||||
|
||||
func (a *storeAPI) RescheduleReminder(ctx context.Context, id int64, now time.Time) error {
|
||||
return mapErr(a.s.RescheduleReminder(ctx, id, now))
|
||||
}
|
||||
@@ -109,85 +115,48 @@ func (a *storeAPI) RecentOutcomes(ctx context.Context, rule string, n int) ([]st
|
||||
|
||||
func (a *storeAPI) RecentFacts(ctx context.Context, n int) ([]Fact, error) {
|
||||
fs, err := a.s.RecentFacts(ctx, n)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Fact, len(fs))
|
||||
for i, f := range fs {
|
||||
out[i] = toFact(f)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(fs, err, toFact)
|
||||
}
|
||||
|
||||
func (a *storeAPI) RecentActiveFactsByKind(ctx context.Context, kind string, n int) ([]Fact, error) {
|
||||
fs, err := a.s.RecentActiveFactsByKind(ctx, store.FactKind(kind), n)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Fact, len(fs))
|
||||
for i, f := range fs {
|
||||
out[i] = toFact(f)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(fs, err, toFact)
|
||||
}
|
||||
|
||||
func (a *storeAPI) CalendarEvents(ctx context.Context, from, to time.Time) ([]Fact, error) {
|
||||
fs, err := a.s.CalendarEvents(ctx, from, to)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Fact, len(fs))
|
||||
for i, f := range fs {
|
||||
out[i] = toFact(f)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(fs, err, toFact)
|
||||
}
|
||||
|
||||
func (a *storeAPI) RecentEcosystemTraces(ctx context.Context, n int) ([]EcosystemTrace, error) {
|
||||
trs, err := a.s.RecentEcosystemTraces(ctx, n)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]EcosystemTrace, len(trs))
|
||||
for i, tr := range trs {
|
||||
out[i] = EcosystemTrace{
|
||||
return mapRows(trs, err, func(tr store.EcosystemTrace) EcosystemTrace {
|
||||
return EcosystemTrace{
|
||||
ID: tr.ID, Ts: tr.Ts, Service: tr.Service, Operation: tr.Operation,
|
||||
Status: tr.Status, DurationMs: tr.DurationMs, CorrelationID: tr.CorrelationID,
|
||||
CausationID: tr.CausationID, HTTPStatus: tr.HTTPStatus, Fields: tr.Fields,
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (a *storeAPI) RecentNudges(ctx context.Context, n int) ([]Nudge, error) {
|
||||
ns, err := a.s.RecentNudges(ctx, n)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Nudge, len(ns))
|
||||
for i, ng := range ns {
|
||||
out[i] = toNudge(ng)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(ns, err, toNudge)
|
||||
}
|
||||
|
||||
func (a *storeAPI) DeliveryAttempts(ctx context.Context, status string, n int) ([]DeliveryAttempt, error) {
|
||||
as, err := a.s.ListDeliveryAttempts(ctx, status, n)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]DeliveryAttempt, len(as))
|
||||
for i, at := range as {
|
||||
out[i] = DeliveryAttempt{
|
||||
return mapRows(as, err, func(at store.DeliveryAttempt) DeliveryAttempt {
|
||||
out := DeliveryAttempt{
|
||||
ID: at.ID, Kind: at.Kind, Rule: at.Rule, ReminderID: at.ReminderID,
|
||||
Channel: at.Channel, Status: at.Status, Created: at.Created,
|
||||
}
|
||||
if at.HasComplete {
|
||||
t := at.Completed
|
||||
out[i].Completed = &t
|
||||
out.Completed = &t
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
return out
|
||||
})
|
||||
}
|
||||
|
||||
func (a *storeAPI) WriteNote(ctx context.Context, ts time.Time, text string, embedding []float32, source string) (int64, error) {
|
||||
@@ -197,38 +166,17 @@ func (a *storeAPI) WriteNote(ctx context.Context, ts time.Time, text string, emb
|
||||
|
||||
func (a *storeAPI) QueryNotes(ctx context.Context, embedding []float32, k int) ([]Note, error) {
|
||||
ns, err := a.s.QueryNotes(ctx, embedding, k)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Note, len(ns))
|
||||
for i, n := range ns {
|
||||
out[i] = toNote(n)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(ns, err, toNote)
|
||||
}
|
||||
|
||||
func (a *storeAPI) RecentNotesFromSource(ctx context.Context, prefix string, n int) ([]Note, error) {
|
||||
ns, err := a.s.RecentNotesFromSource(ctx, prefix, n)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Note, len(ns))
|
||||
for i, note := range ns {
|
||||
out[i] = toNote(note)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(ns, err, toNote)
|
||||
}
|
||||
|
||||
func (a *storeAPI) RecentNotes(ctx context.Context, n int) ([]Note, error) {
|
||||
ns, err := a.s.RecentNotes(ctx, n)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Note, len(ns))
|
||||
for i, note := range ns {
|
||||
out[i] = toNote(note)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(ns, err, toNote)
|
||||
}
|
||||
|
||||
func (a *storeAPI) ProposeTool(ctx context.Context, name, utterance, scope string, ts time.Time) (bool, error) {
|
||||
@@ -299,14 +247,7 @@ func (a *storeAPI) DayPlan(ctx context.Context) (DayPlan, error) {
|
||||
|
||||
func (a *storeAPI) ListTools(ctx context.Context, status string) ([]Tool, error) {
|
||||
ts, err := a.s.ListTools(ctx, status)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Tool, len(ts))
|
||||
for i, t := range ts {
|
||||
out[i] = toTool(t)
|
||||
}
|
||||
return out, nil
|
||||
return mapRows(ts, err, toTool)
|
||||
}
|
||||
|
||||
func (a *storeAPI) DeleteTool(ctx context.Context, name string) error {
|
||||
@@ -334,12 +275,8 @@ func (a *storeAPI) CaptureTask(ctx context.Context, req CaptureTaskReq) (Capture
|
||||
|
||||
func (a *storeAPI) ListTasks(ctx context.Context, status string) ([]Task, error) {
|
||||
ts, err := a.s.ListTasks(ctx, status)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]Task, len(ts))
|
||||
for i, t := range ts {
|
||||
out[i] = Task{
|
||||
return mapRows(ts, err, func(t store.Task) Task {
|
||||
return Task{
|
||||
ID: t.ID,
|
||||
CreatedTs: t.CreatedTs,
|
||||
Text: t.Text,
|
||||
@@ -354,8 +291,7 @@ func (a *storeAPI) ListTasks(ctx context.Context, status string) ([]Task, error)
|
||||
DoneWhen: t.DoneWhen,
|
||||
BlockedOn: t.BlockedOn,
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (a *storeAPI) SetTaskStatus(ctx context.Context, id int64, status string, ts time.Time, by string) error {
|
||||
@@ -379,24 +315,17 @@ func (a *storeAPI) SetTaskFields(ctx context.Context, id int64, doneWhen, blocke
|
||||
|
||||
func (a *storeAPI) ListProposedRoutines(ctx context.Context) ([]ProposedRoutine, error) {
|
||||
rs, err := a.s.ListProposedRoutines(ctx)
|
||||
if err != nil {
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
out := make([]ProposedRoutine, len(rs))
|
||||
for i, r := range rs {
|
||||
out[i] = ProposedRoutine{
|
||||
return mapRows(rs, err, func(r store.ProposedRoutine) ProposedRoutine {
|
||||
return ProposedRoutine{
|
||||
ID: r.ID,
|
||||
Action: r.Action,
|
||||
Object: r.Object,
|
||||
IntervalDays: r.IntervalDays,
|
||||
Status: string(r.Status),
|
||||
CreatedTs: r.CreatedTs.UnixMilli(),
|
||||
ReminderID: r.ReminderID,
|
||||
}
|
||||
if r.ReminderID != nil {
|
||||
out[i].ReminderID = r.ReminderID
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (a *storeAPI) DismissProposedRoutine(ctx context.Context, id int64) error {
|
||||
|
||||
Reference in New Issue
Block a user