| 269 | } |
| 270 | |
| 271 | func (d *debugModel) GenerateObject( |
| 272 | ctx context.Context, |
| 273 | call fantasy.ObjectCall, |
| 274 | ) (*fantasy.ObjectResponse, error) { |
| 275 | if d.svc == nil { |
| 276 | return d.inner.GenerateObject(ctx, call) |
| 277 | } |
| 278 | if _, ok := RunFromContext(ctx); !ok { |
| 279 | return d.inner.GenerateObject(ctx, call) |
| 280 | } |
| 281 | |
| 282 | handle, enrichedCtx := beginStep(ctx, d.svc, d.opts, OperationGenerate, |
| 283 | normalizeObjectCall(call)) |
| 284 | if handle == nil { |
| 285 | return d.inner.GenerateObject(ctx, call) |
| 286 | } |
| 287 | |
| 288 | // Keep the step alive during the blocking provider call so the |
| 289 | // stale finalizer does not mark it as interrupted. |
| 290 | heartbeatDone := make(chan struct{}) |
| 291 | launchHeartbeat(ctx, handle.svc, handle.stepCtx.StepID, handle.stepCtx.RunID, handle.stepCtx.ChatID, heartbeatDone) |
| 292 | |
| 293 | resp, err := d.inner.GenerateObject(enrichedCtx, call) |
| 294 | close(heartbeatDone) |
| 295 | if err != nil { |
| 296 | handle.finish(ctx, stepStatusForError(err), nil, nil, normalizeError(ctx, err), |
| 297 | map[string]any{"structured_output": true}) |
| 298 | return nil, err |
| 299 | } |
| 300 | if resp == nil { |
| 301 | err = xerrors.Errorf("GenerateObject: %w", ErrNilModelResult) |
| 302 | handle.finish(ctx, StatusError, nil, nil, normalizeError(ctx, err), |
| 303 | map[string]any{"structured_output": true}) |
| 304 | return nil, err |
| 305 | } |
| 306 | |
| 307 | handle.finish(ctx, StatusCompleted, normalizeObjectResponse(resp), &resp.Usage, |
| 308 | nil, map[string]any{"structured_output": true}) |
| 309 | return resp, nil |
| 310 | } |
| 311 | |
| 312 | func (d *debugModel) StreamObject( |
| 313 | ctx context.Context, |