返回 DeepSeek-Reasonix
form_instances.go
根目录 / internal / extension / uihub / form_instances.go
1 package uihub
2
3 import (
4 "context"
5 "strings"
6
7 "reasonix/internal/extension/protocol"
8 )
9
10 type activeForm struct {
11 pluginID string
12 surfaceID string
13 sessionID string
14 generation uint64
15 instanceID string
16 submitting bool
17 }
18
19 func formKey(pluginID, surfaceID string) string { return pluginID + "\x00" + surfaceID }
20
21 // SubmitExact pins the form instance and sidecar client while holding the hub
22 // lock. The sidecar call runs after unlock, so replacements keep their identity.
23 func (h *Hub) SubmitExact(ctx context.Context, pluginID, surfaceID, sessionID string, generation uint64, instanceID string, values map[string]any) (protocol.UISubmitResult, error) {
24 if strings.TrimSpace(surfaceID) == "" || strings.TrimSpace(instanceID) == "" {
25 return protocol.UISubmitResult{}, &protocol.ProtocolError{Reason: protocol.ErrInvalidParams, Message: "exact form identity is required"}
26 }
27 h.mu.Lock()
28 form, ok := h.activeForms[formKey(pluginID, surfaceID)]
29 if !ok || form.sessionID != sessionID || form.generation != generation || form.instanceID != instanceID {
30 h.mu.Unlock()
31 return protocol.UISubmitResult{}, &protocol.ProtocolError{Reason: protocol.ErrInvalidParams, Message: "extension form is stale"}
32 }
33 if form.submitting {
34 h.mu.Unlock()
35 return protocol.UISubmitResult{}, &protocol.ProtocolError{Reason: protocol.ErrInvalidParams, Message: "extension form submission is already in progress"}
36 }
37 if !h.known[pluginID] {
38 h.mu.Unlock()
39 return protocol.UISubmitResult{}, unknownClientError(pluginID)
40 }
41 if h.crashed[pluginID] || h.resolve == nil {
42 h.mu.Unlock()
43 return protocol.UISubmitResult{}, &protocol.ProtocolError{Reason: protocol.ErrProviderInterrupted, Message: "extension sidecar is unavailable"}
44 }
45 client := h.resolve(pluginID)
46 if client == nil {
47 h.mu.Unlock()
48 return protocol.UISubmitResult{}, &protocol.ProtocolError{Reason: protocol.ErrProviderInterrupted, Message: "extension " + pluginID + " has no live sidecar"}
49 }
50 form.submitting = true
51 h.activeForms[formKey(pluginID, surfaceID)] = form
52 h.mu.Unlock()
53 result, err := client.UISubmit(ctx, protocol.UISubmitParams{SurfaceID: surfaceID, SessionID: sessionID, Generation: generation, Values: values})
54 h.mu.Lock()
55 current, currentOK := h.activeForms[formKey(pluginID, surfaceID)]
56 if currentOK && current.instanceID == instanceID {
57 if err != nil || result.Accepted {
58 delete(h.activeForms, formKey(pluginID, surfaceID))
59 } else {
60 current.submitting = false
61 h.activeForms[formKey(pluginID, surfaceID)] = current
62 }
63 }
64 h.mu.Unlock()
65 return result, err
66 }
67
67 lines GO