@codefionn/llmleaf-client 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -31,6 +31,7 @@ export { cachedTokens } from "./types.js";
31
31
  export type {
32
32
  Usage,
33
33
  PromptTokensDetails,
34
+ ErrorBody,
34
35
  TextPart,
35
36
  ImageUrlPart,
36
37
  ContentPart,
@@ -51,6 +52,29 @@ export type {
51
52
  Delta,
52
53
  ChunkChoice,
53
54
  ChatCompletionChunk,
55
+ // Responses dialect (POST /v1/responses)
56
+ ResponseInputTextPart,
57
+ ResponseInputImagePart,
58
+ ResponseOutputTextPart,
59
+ ResponseContentPart,
60
+ ResponseMessageContent,
61
+ ResponseMessageItem,
62
+ ResponseFunctionCallItem,
63
+ ResponseFunctionCallOutputItem,
64
+ ResponseReasoningText,
65
+ ResponseReasoningItem,
66
+ ResponseItem,
67
+ ResponsesInput,
68
+ ResponsesToolDef,
69
+ ResponsesToolChoice,
70
+ ResponsesReasoning,
71
+ ResponsesRequest,
72
+ ResponsesInputTokensDetails,
73
+ ResponsesOutputTokensDetails,
74
+ ResponsesUsage,
75
+ ResponsesIncompleteDetails,
76
+ ResponsesResponse,
77
+ ResponsesStreamEvent,
54
78
  EmbeddingRequest,
55
79
  Embedding,
56
80
  EmbeddingResponse,
package/src/types.ts CHANGED
@@ -55,6 +55,18 @@ export function cachedTokens(usage: Usage): number {
55
55
  return usage.promptTokensDetails?.cachedTokens ?? 0;
56
56
  }
57
57
 
58
+ /**
59
+ * The canonical error envelope body (`{"error":{"message":...}}`). Any non-2xx HTTP
60
+ * response is raised as an {@link "./error".ApiError}; this typed shape is the `error`
61
+ * carried *inside* a `failed` {@link ResponsesResponse} snapshot.
62
+ */
63
+ export interface ErrorBody {
64
+ message: string;
65
+ /** present on some dialects; absent on the llmleaf core envelope. */
66
+ type?: string;
67
+ code?: string;
68
+ }
69
+
58
70
  // ---------------------------------------------------------------------------
59
71
  // Chat
60
72
  // ---------------------------------------------------------------------------
@@ -456,3 +468,248 @@ export interface BatchResultLine {
456
468
  response?: BatchResponse;
457
469
  error?: BatchError;
458
470
  }
471
+
472
+ // ---------------------------------------------------------------------------
473
+ // Responses (POST /v1/responses) — the OpenAI Responses dialect
474
+ // ---------------------------------------------------------------------------
475
+ //
476
+ // llmleaf serves this dialect statelessly: `store` is accepted but always answered
477
+ // `false`, `previousResponseId`/`background:true` are rejected (400), and there is no
478
+ // retrieval call (`GET /v1/responses/{id}` is an explained 404). Dialect vocabulary
479
+ // that would collide with the chat enums (statuses "completed"/"in_progress"/…, roles
480
+ // incl. "developer") stays a plain wire string here rather than an enum.
481
+
482
+ /** `{"type":"input_text","text":...}` */
483
+ export interface ResponseInputTextPart {
484
+ type: "input_text";
485
+ text: string;
486
+ }
487
+
488
+ /**
489
+ * `{"type":"input_image","image_url":"<url>","detail":...}`. Unlike the chat dialect's
490
+ * nested `{url}` object, {@link imageUrl} is a plain string here.
491
+ */
492
+ export interface ResponseInputImagePart {
493
+ type: "input_image";
494
+ imageUrl: string;
495
+ /** "auto" | "low" | "high" */
496
+ detail?: string;
497
+ }
498
+
499
+ /** `{"type":"output_text","text":...,"annotations":[]}` (annotations emitted as `[]`). */
500
+ export interface ResponseOutputTextPart {
501
+ type: "output_text";
502
+ text: string;
503
+ }
504
+
505
+ export type ResponseContentPart =
506
+ | ResponseInputTextPart
507
+ | ResponseInputImagePart
508
+ | ResponseOutputTextPart;
509
+
510
+ /** A message item's `content`: a bare string or an array of content parts. */
511
+ export type ResponseMessageContent = string | ResponseContentPart[];
512
+
513
+ /**
514
+ * A conversation message item. On input, {@link role} is "user" | "system" |
515
+ * "developer" | "assistant" and serialises as a bare role-keyed object (no `"type"`);
516
+ * on output, role is "assistant" with `output_text` parts and {@link status}/{@link id}.
517
+ */
518
+ export interface ResponseMessageItem {
519
+ type: "message";
520
+ id?: string;
521
+ /** "user" | "system" | "developer" | "assistant" */
522
+ role: string;
523
+ content?: ResponseMessageContent;
524
+ /** output only: "in_progress" | "completed" */
525
+ status?: string;
526
+ }
527
+
528
+ /**
529
+ * A function call the model made. {@link callId} pairs it with its
530
+ * {@link ResponseFunctionCallOutputItem}; {@link arguments} is the raw JSON string.
531
+ */
532
+ export interface ResponseFunctionCallItem {
533
+ type: "function_call";
534
+ id?: string;
535
+ callId: string;
536
+ name: string;
537
+ arguments: string;
538
+ status?: string;
539
+ }
540
+
541
+ /** The caller's answer to a function call, replayed on the next turn. */
542
+ export interface ResponseFunctionCallOutputItem {
543
+ type: "function_call_output";
544
+ id?: string;
545
+ callId: string;
546
+ output: string;
547
+ }
548
+
549
+ /** One entry of a reasoning item's `summary[]` or `content[]` list. */
550
+ export interface ResponseReasoningText {
551
+ text: string;
552
+ }
553
+
554
+ /**
555
+ * A reasoning ("thinking") item. {@link summary} entries serialise as
556
+ * `{"type":"summary_text","text"}`, {@link content} entries as
557
+ * `{"type":"reasoning_text","text"}` — the list decides the wire token.
558
+ * {@link encryptedContent} is opaque and MUST be echoed back verbatim in the next
559
+ * request's input to continue an encrypted reasoning turn.
560
+ */
561
+ export interface ResponseReasoningItem {
562
+ type: "reasoning";
563
+ id?: string;
564
+ summary?: ResponseReasoningText[];
565
+ content?: ResponseReasoningText[];
566
+ encryptedContent?: string;
567
+ }
568
+
569
+ /**
570
+ * One item of the request `input` array or the response `output` array. The `type`
571
+ * field is the discriminator (a message item serialises without one — see
572
+ * {@link ResponseMessageItem}).
573
+ */
574
+ export type ResponseItem =
575
+ | ResponseMessageItem
576
+ | ResponseFunctionCallItem
577
+ | ResponseFunctionCallOutputItem
578
+ | ResponseReasoningItem;
579
+
580
+ /** `input`: a bare string (one user message) or an array of items. */
581
+ export type ResponsesInput = string | ResponseItem[];
582
+
583
+ /**
584
+ * A tool the model MAY call — FLAT in this dialect (`type`/`name`/`parameters` at the
585
+ * top level, no nested `function` object).
586
+ */
587
+ export interface ResponsesToolDef {
588
+ /** "function" */
589
+ type: string;
590
+ name: string;
591
+ description?: string;
592
+ /** raw JSON Schema object, as a JSON string. */
593
+ parameters?: string;
594
+ /** defaults TRUE upstream; llmleaf's own edge pins false. */
595
+ strict?: boolean;
596
+ }
597
+
598
+ /**
599
+ * "auto" | "none" | "required", or the FLAT named object `{type:"function",name}`
600
+ * (no nested `function`, unlike the chat dialect).
601
+ */
602
+ export type ResponsesToolChoice =
603
+ | string
604
+ | {
605
+ type: "function";
606
+ name: string;
607
+ };
608
+
609
+ /** `reasoning`: `{"effort":...,"summary":...}`. */
610
+ export interface ResponsesReasoning {
611
+ /** "minimal" | "low" | "medium" | "high" | ... */
612
+ effort?: string;
613
+ summary?: string;
614
+ }
615
+
616
+ export interface ResponsesRequest {
617
+ model: string;
618
+ input: ResponsesInput;
619
+ /** becomes a leading system message */
620
+ instructions?: string;
621
+ stream?: boolean;
622
+ temperature?: number;
623
+ topP?: number;
624
+ maxOutputTokens?: number;
625
+ tools?: ResponsesToolDef[];
626
+ toolChoice?: ResponsesToolChoice;
627
+ reasoning?: ResponsesReasoning;
628
+ /** accepted, but llmleaf stores nothing and always answers `false`. */
629
+ store?: boolean;
630
+ /** dialect-specific passthrough, raw JSON object as a JSON string, merged at the top level. */
631
+ extra?: string;
632
+ }
633
+
634
+ export interface ResponsesInputTokensDetails {
635
+ cachedTokens?: number;
636
+ }
637
+
638
+ export interface ResponsesOutputTokensDetails {
639
+ reasoningTokens?: number;
640
+ }
641
+
642
+ /**
643
+ * Token accounting in the Responses dialect's own names (`input_tokens`/`output_tokens`,
644
+ * not the chat dialect's `prompt_tokens`/`completion_tokens`).
645
+ */
646
+ export interface ResponsesUsage {
647
+ inputTokens: number;
648
+ inputTokensDetails?: ResponsesInputTokensDetails;
649
+ outputTokens: number;
650
+ outputTokensDetails?: ResponsesOutputTokensDetails;
651
+ totalTokens: number;
652
+ }
653
+
654
+ /** `status:"incomplete"` refinement: "max_output_tokens" | "content_filter". */
655
+ export interface ResponsesIncompleteDetails {
656
+ reason: string;
657
+ }
658
+
659
+ /**
660
+ * The response object (`"object":"response"`), also the snapshot carried by the
661
+ * `response.created` / `response.in_progress` / `response.completed` stream events.
662
+ */
663
+ export interface ResponsesResponse {
664
+ id: string;
665
+ /** "response" */
666
+ object: string;
667
+ /** unix seconds */
668
+ createdAt: number;
669
+ /** "completed" | "in_progress" | "incomplete" | "failed" */
670
+ status: string;
671
+ incompleteDetails?: ResponsesIncompleteDetails;
672
+ /** carried by a `failed` snapshot */
673
+ error?: ErrorBody;
674
+ model: string;
675
+ output: ResponseItem[];
676
+ /** null on in-flight snapshots */
677
+ usage?: ResponsesUsage;
678
+ /** llmleaf always answers `false`. */
679
+ store?: boolean;
680
+ instructions?: string;
681
+ maxOutputTokens?: number;
682
+ temperature?: number;
683
+ topP?: number;
684
+ reasoning?: ResponsesReasoning;
685
+ }
686
+
687
+ /**
688
+ * One streaming SSE event. Unlike chat streaming there is NO `data: [DONE]` sentinel —
689
+ * the stream ends after the terminal `response.completed` / `response.incomplete` /
690
+ * `response.failed` event. This is a flat superset of every event's fields; {@link type}
691
+ * says which are meaningful. {@link "./client".LlmleafClient.responsesStream} skips event
692
+ * types it doesn't recognise (the dialect grows by adding types).
693
+ */
694
+ export interface ResponsesStreamEvent {
695
+ /** "response.created", "response.output_text.delta", "error", ... */
696
+ type: string;
697
+ sequenceNumber: number;
698
+ /** response.created / in_progress / completed / incomplete / failed */
699
+ response?: ResponsesResponse;
700
+ outputIndex?: number;
701
+ itemId?: string;
702
+ contentIndex?: number;
703
+ /** response.output_item.added / done */
704
+ item?: ResponseItem;
705
+ /** response.content_part.added / done */
706
+ part?: ResponseContentPart;
707
+ /** *.delta events (text / reasoning / arguments) */
708
+ delta?: string;
709
+ /** response.output_text.done / reasoning_text.done */
710
+ text?: string;
711
+ /** response.function_call_arguments.done */
712
+ arguments?: string;
713
+ /** "error" event */
714
+ message?: string;
715
+ }