@@ -183,12 +183,25 @@ func NewSessionAgent(
183183 }
184184}
185185
186−func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (result *fantasy.AgentResult, retErr error) {
186+// ValidateCall performs the cheap structural validation that
187+// sessionAgent.Run requires before a call can be dispatched: a call must
188+// carry either a non-empty prompt or a text attachment, and it must name a
189+// session. It is exported so callers that accept a run before dispatching it
190+// (e.g. backend.SendMessage) can apply the same checks and keep the error
191+// contract consistent.
192+func ValidateCall(call SessionAgentCall) error {
187193 if call.Prompt == "" && !message.ContainsTextAttachment(call.Attachments) {
188− return nil, ErrEmptyPrompt
194+ return ErrEmptyPrompt
189195 }
190196 if call.SessionID == "" {
191− return nil, ErrSessionMissing
197+ return ErrSessionMissing
198+ }
199+ return nil
200+}
201+
202+func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (result *fantasy.AgentResult, retErr error) {
203+ if err := ValidateCall(call); err != nil {
204+ return nil, err
192205 }
193206
194207 // Queue the message if busy. Strip OnComplete: the caller that