package ocaml-ai-sdk
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
OCaml AI SDK - Provider abstraction for AI models
Install
dune-project
Dependency
Authors
Maintainers
Sources
ocaml-ai-sdk-0.2.tbz
sha256=17063971a74ccd72619a43ecfcb29d28cdf08f90d406a960bd475f65fee1a0d9
sha512=1f3f2d1d7fa4f53843cc1b303cbf9d6dcc85780e7c768ced723f3de83ea897748fa231b48e729216abcc069dee818edc6751a45271541e8a007369bf6e9d23e3
doc/src/ocaml-ai-sdk.ai_provider_anthropic/anthropic_model.ml.html
Source file anthropic_model.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106(** Check for unsupported features and emit warnings. *) let check_unsupported ~anthropic_opts (opts : Ai_provider.Call_options.t) = List.concat [ (match opts.frequency_penalty with | Some _ -> [ Ai_provider.Warning.Unsupported_feature { feature = "frequency_penalty"; details = None } ] | None -> []); (match opts.presence_penalty with | Some _ -> [ Ai_provider.Warning.Unsupported_feature { feature = "presence_penalty"; details = None } ] | None -> []); (match opts.seed with | Some _ -> [ Ai_provider.Warning.Unsupported_feature { feature = "seed"; details = None } ] | None -> []); (* Warn if thinking is enabled with temperature *) (match anthropic_opts.Anthropic_options.thinking with | Some t when t.Thinking.enabled && Option.is_some opts.temperature -> [ Ai_provider.Warning.Unsupported_feature { feature = "temperature with thinking"; details = Some "Anthropic does not support temperature when thinking is enabled"; }; ] | _ -> []); ] (** Prepare the request body and warnings — shared by generate and stream. *) let prepare_request ~model ~stream (opts : Ai_provider.Call_options.t) = let anthropic_opts = Anthropic_options.of_provider_options opts.provider_options |> Stdlib.Option.value ~default:Anthropic_options.default in let warnings = check_unsupported ~anthropic_opts opts in let system, remaining = Convert_prompt.extract_system opts.prompt in let messages = Convert_prompt.convert_messages remaining in (* Handle structured output mode by injecting JSON instructions into system prompt *) let system = let append_instruction instruction = match system with | Some s -> Some (s ^ "\n\n" ^ instruction) | None -> Some instruction in match opts.mode with | Object_json (Some { name; schema }) -> Printf.sprintf "Respond ONLY with a JSON object matching this schema (name: %s):\n\ %s\n\n\ Do not include any other text, markdown formatting, or code blocks. Output raw JSON only." name (Yojson.Basic.pretty_to_string schema) |> append_instruction | Object_json None -> append_instruction "Respond ONLY with valid JSON. Do not include any other text, markdown formatting, or code blocks. Output raw \ JSON only." | Regular | Object_tool _ -> system in let tools, tool_choice = Convert_tools.convert_tools ~tools:opts.tools ~tool_choice:opts.tool_choice in (* Use model-aware default for max_tokens *) let max_tokens = Some (match opts.max_output_tokens with | Some n -> n | None -> Model_catalog.default_max_tokens (Model_catalog.of_model_id model)) in let thinking_enabled = match anthropic_opts.thinking with | Some t when t.Thinking.enabled -> true | Some _ | None -> false in let body = Anthropic_api.make_request_body ~model ~messages ?system ~tools ?tool_choice ?max_tokens ?temperature:opts.temperature ?top_p:opts.top_p ?top_k:opts.top_k ~stop_sequences:opts.stop_sequences ?thinking:anthropic_opts.thinking ~stream () in (* Merge user headers with required beta headers — the result includes all of opts.headers plus a merged anthropic-beta header, so it replaces opts.headers entirely *) let required_betas = Beta_headers.required_betas ~thinking:thinking_enabled ~has_pdf:false ~tool_streaming:anthropic_opts.tool_streaming in let extra_headers = Beta_headers.merge_beta_headers ~user_headers:opts.headers ~required:required_betas in body, warnings, extra_headers let create ~config ~model = let module M = struct let specification_version = "V3" let provider = "anthropic" let model_id = model let generate opts = let body, warnings, extra_headers = prepare_request ~model ~stream:false opts in match%lwt Anthropic_api.messages ~config ~body ~extra_headers ~stream:false with | `Json json -> let result = Convert_response.parse_response json in Lwt.return { result with warnings = warnings @ result.warnings } | `Stream _ -> Lwt.fail_with "unexpected streaming response for non-streaming request" let stream opts = let body, warnings, extra_headers = prepare_request ~model ~stream:true opts in match%lwt Anthropic_api.messages ~config ~body ~extra_headers ~stream:true with | `Stream line_stream -> let sse_events = Sse.parse_events line_stream in let parts = Convert_stream.transform sse_events ~warnings in Lwt.return { Ai_provider.Stream_result.stream = parts; warnings; raw_response = None } | `Json _ -> Lwt.fail_with "unexpected non-streaming response for streaming request" end in (module M : Ai_provider.Language_model.S)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>