(ctx context.Context, line string)
| 346 | var _ idtui.ShellHandler = (*shellCallHandler)(nil) |
| 347 | |
| 348 | func (h *shellCallHandler) Handle(ctx context.Context, line string) (rerr error) { |
| 349 | // Quick sanitization |
| 350 | line = strings.TrimSpace(line) |
| 351 | |
| 352 | // If in exit command |
| 353 | if line == "exit" || line == "/exit" { |
| 354 | h.cancel() |
| 355 | return nil |
| 356 | } |
| 357 | |
| 358 | // Empty input |
| 359 | if line == "" { |
| 360 | // add an immediately-canceled blank span, to emulate submitting blank shell |
| 361 | // commands to space things apart |
| 362 | _, span := Tracer().Start(ctx, "", |
| 363 | telemetry.Reveal(), |
| 364 | trace.WithAttributes(attribute.Bool(telemetry.CanceledAttr, true))) |
| 365 | span.End() |
| 366 | return nil |
| 367 | } |
| 368 | |
| 369 | // Handle based on mode |
| 370 | if h.mode == modePrompt { |
| 371 | // NB: no span in this case, just let the LLM APIs create the user/assistant |
| 372 | // message spans |
| 373 | |
| 374 | llm, err := h.llm(ctx) |
| 375 | if err != nil { |
| 376 | return err |
| 377 | } |
| 378 | newLLM, err := llm.WithPrompt(ctx, line) |
| 379 | if err != nil { |
| 380 | return err |
| 381 | } |
| 382 | h.llmSession = newLLM |
| 383 | h.llmModel = newLLM.model |
| 384 | return nil |
| 385 | } |
| 386 | |
| 387 | // Ensure we always see new telemetry for shell commands, rather than |
| 388 | // "resurrecting" the same telemetry from previous commands |
| 389 | if bag, err := baggage.Parse("repeat-telemetry=true"); err == nil { |
| 390 | ctx = baggage.ContextWithBaggage(ctx, bag) |
| 391 | } |
| 392 | |
| 393 | // Create a new span for this command |
| 394 | var span trace.Span |
| 395 | ctx, span = Tracer().Start(ctx, line, |
| 396 | telemetry.Reveal(), |
| 397 | trace.WithAttributes( |
| 398 | attribute.String(telemetry.ContentTypeAttr, h.mode.ContentType()), |
| 399 | )) |
| 400 | var telemetryErr error |
| 401 | defer telemetry.EndWithCause(span, &telemetryErr) |
| 402 | defer func() { |
| 403 | if errors.Is(rerr, context.Canceled) { |
| 404 | span.SetAttributes(attribute.Bool(telemetry.CanceledAttr, true)) |
| 405 | } else { |
nothing calls this directly
no test coverage detected