diff --git a/docs/plan/closure-dtos.txt b/docs/plan/closure-dtos.txt new file mode 100644 index 000000000..43ecc40ee --- /dev/null +++ b/docs/plan/closure-dtos.txt @@ -0,0 +1,211 @@ +# Unit 2.1 acceptance list (PHASES 2.1): every `#[ts(export)]` type. +# Generated by scripts/gen_closure_inventory.py; do not edit by hand. +# Format: . The [exported] section must equal +# the manifest coverage report (tools/aimux-codegen/generated/coverage.txt). + +[exported] 193 +AiMuxError error aimux-core/src/error.rs +ApiCallError error aimux-core/src/error.rs +AspectRatio core aimux-core/src/shared.rs +AssistantPart user aimux-core/src/language_model_message.rs +AudioChunk multimodal aimux-core/src/transcription_model.rs +AudioData multimodal aimux-core/src/speech_model.rs +AudioInput multimodal aimux-core/src/transcription_model.rs +BooleanCriteria core aimux-core/src/evaluation_model.rs +BreakKind recording aimux-core/src/trace/store.rs +CallOptions user aimux-core/src/options.rs +CatalogueSource provider aimux-core/src/model_catalogue.rs +ChatCompletion core aimux-core/src/openai_output.rs +ChatCompletionChoice core aimux-core/src/openai_output.rs +ChatCompletionChunk core aimux-core/src/openai_output.rs +ChatCompletionChunkChoice core aimux-core/src/openai_output.rs +ChatCompletionChunkFunction core aimux-core/src/openai_output.rs +ChatCompletionChunkToolCall core aimux-core/src/openai_output.rs +ChatCompletionDelta core aimux-core/src/openai_output.rs +ChatCompletionFunction core aimux-core/src/openai_output.rs +ChatCompletionMessage core aimux-core/src/openai_output.rs +ChatCompletionToolCall core aimux-core/src/openai_output.rs +ChatCompletionUsage core aimux-core/src/openai_output.rs +CompletionTokensDetails core aimux-core/src/openai_output.rs +ContentPart multimodal aimux-core/src/content.rs +CustomPart user aimux-core/src/language_model_message.rs +DecisionAnswer core aimux-core/src/decision_model.rs +DecisionBooleanCriteria core aimux-core/src/decision_model.rs +DecisionCallOptions core aimux-core/src/decision_model.rs +DecisionCapabilities core aimux-core/src/decision_model.rs +DecisionDescription core aimux-core/src/decision_model.rs +DecisionImage core aimux-core/src/decision_model.rs +DecisionOption core aimux-core/src/decision_model.rs +DecisionProbabilitySource core aimux-core/src/decision_model.rs +DecisionQuestion core aimux-core/src/decision_model.rs +DecisionResponse core aimux-core/src/decision_model.rs +DecisionResult core aimux-core/src/decision_model.rs +DecisionRounding core aimux-core/src/decision_model.rs +DecisionScoreLevel core aimux-core/src/decision_model.rs +DecisionValue core aimux-core/src/decision_model.rs +EmbeddingCallOptions multimodal aimux-core/src/embedding_model.rs +EmbeddingResponse multimodal aimux-core/src/embedding_model.rs +EmbeddingResult multimodal aimux-core/src/embedding_model.rs +EmbeddingUsage multimodal aimux-core/src/embedding_model.rs +EvaluationAnswer core aimux-core/src/evaluation_model.rs +EvaluationCallOptions core aimux-core/src/evaluation_model.rs +EvaluationInput core aimux-core/src/evaluation_model.rs +EvaluationQuestion core aimux-core/src/evaluation_model.rs +EvaluationQuestionType core aimux-core/src/evaluation_model.rs +EvaluationResult core aimux-core/src/evaluation_model.rs +EvaluationRounding core aimux-core/src/evaluation_model.rs +EvaluationUsage core aimux-core/src/evaluation_model.rs +FileBytes core aimux-core/src/shared.rs +FileData core aimux-core/src/shared.rs +FilePart user aimux-core/src/language_model_message.rs +Fingerprint recording aimux-core/src/trace/fingerprint.rs +FinishReason core aimux-core/src/types.rs +FinishReasonUnified core aimux-core/src/types.rs +FunctionTool tool aimux-core/src/tool.rs +FunctionToolInputExample tool aimux-core/src/tool.rs +GenerateContent core aimux-core/src/result.rs +GenerateObjectResult core aimux-core/src/generate.rs +GenerateResult core aimux-core/src/result.rs +GenerateTextOptions core aimux-core/src/generate.rs +GenerateTextResult core aimux-core/src/generate.rs +GeneratedFile core aimux-core/src/result.rs +GeneratedFileData core aimux-core/src/shared.rs +HttpExchange recording aimux-core/src/recording.rs +HttpRecord recording aimux-core/src/recording.rs +ImageCallOptions multimodal aimux-core/src/image_model.rs +ImageFile multimodal aimux-core/src/image_model.rs +ImageFileData multimodal aimux-core/src/image_model.rs +ImageOutputs multimodal aimux-core/src/image_model.rs +ImageResponse multimodal aimux-core/src/image_model.rs +ImageResult multimodal aimux-core/src/image_model.rs +ImageUsage multimodal aimux-core/src/image_model.rs +InputAudioFormat multimodal aimux-core/src/transcription_model.rs +InputRecord recording aimux-core/src/recording.rs +InputTokenUsage core aimux-core/src/types.rs +LanguageModelMessage user aimux-core/src/language_model_message.rs +MessageContent user aimux-core/src/message.rs +Modality provider aimux-core/src/model_catalogue.rs +ModelCapabilities provider aimux-core/src/model_catalogue.rs +ModelCost provider aimux-core/src/model_catalogue.rs +ModelId provider aimux-core/src/model_id.rs +ModelLimits provider aimux-core/src/model_catalogue.rs +ModelMessage user aimux-core/src/message.rs +ModelModalities provider aimux-core/src/model_catalogue.rs +ModelPrompt user aimux-core/src/message.rs +ModelSpec provider aimux-core/src/model_catalogue.rs +ModelType provider aimux-core/src/model_catalogue.rs +OutcomeRecord recording aimux-core/src/recording.rs +OutcomeStatus recording aimux-core/src/recording.rs +OutputTokenUsage core aimux-core/src/types.rs +PrefixBreak recording aimux-core/src/trace/store.rs +PromptTokensDetails core aimux-core/src/openai_output.rs +ProviderAuditSpec recording aimux-core/src/trace/verdict.rs +ProviderFamily recording aimux-core/src/trace/verdict.rs +ProviderRecord recording aimux-core/src/recording.rs +ProviderTool tool aimux-core/src/tool.rs +RawToolApprovalRequest core aimux-core/src/result.rs +RawToolCall tool aimux-core/src/tool.rs +ReasoningEffort core aimux-core/src/types.rs +ReasoningFileOutput core aimux-core/src/result.rs +ReasoningFilePart user aimux-core/src/language_model_message.rs +ReasoningMode provider aimux-core/src/model_catalogue.rs +ReasoningOutput core aimux-core/src/result.rs +ReasoningPart core aimux-core/src/result.rs +ReasoningPart user aimux-core/src/language_model_message.rs +ReasoningSpec provider aimux-core/src/model_catalogue.rs +ReasoningVisibility provider aimux-core/src/model_catalogue.rs +Recording recording aimux-core/src/recording.rs +RecordingOperation recording aimux-core/src/recording.rs +RequestCacheHints recording aimux-core/src/trace/record.rs +RequestInfo core aimux-core/src/shared.rs +RerankingCallOptions core aimux-core/src/reranking_model.rs +RerankingDocuments core aimux-core/src/reranking_model.rs +RerankingRank core aimux-core/src/reranking_model.rs +RerankingResponse core aimux-core/src/reranking_model.rs +RerankingResult core aimux-core/src/reranking_model.rs +ResponseFormat user aimux-core/src/options.rs +ResponseInfo core aimux-core/src/shared.rs +ResponseMetadata core aimux-core/src/types.rs +ResponseRecord recording aimux-core/src/recording.rs +RetryError error aimux-core/src/error.rs +RetryErrorReason error aimux-core/src/error.rs +Role user aimux-core/src/message.rs +RuntimeModel provider aimux-core/src/model_catalogue.rs +SearchCallOptions core aimux-core/src/search_model.rs +SearchResponse core aimux-core/src/search_model.rs +SearchResult core aimux-core/src/search_model.rs +SearchResultItem core aimux-core/src/search_model.rs +SessionCall core aimux-core/src/session.rs +SessionChainView recording aimux-core/src/trace/store.rs +SessionSource core aimux-core/src/session.rs +SessionStepStat recording aimux-core/src/trace/store.rs +SessionView core aimux-core/src/session.rs +Size core aimux-core/src/shared.rs +SkillFile core aimux-core/src/skills_model.rs +Source core aimux-core/src/result.rs +SpeechCallOptions multimodal aimux-core/src/speech_model.rs +SpeechRequest multimodal aimux-core/src/speech_model.rs +SpeechResponse multimodal aimux-core/src/speech_model.rs +SpeechResult multimodal aimux-core/src/speech_model.rs +StreamPart core aimux-core/src/stream_part.rs +StreamResponseInfo core aimux-core/src/shared.rs +StreamTextResultAggregated core aimux-core/src/result.rs +TextContentBinding core aimux-core/src/result.rs +TextPart user aimux-core/src/language_model_message.rs +TextStreamPart core aimux-core/src/stream_part.rs +TimeoutConfiguration user aimux-core/src/options.rs +TimingRecord recording aimux-core/src/recording.rs +Tool tool aimux-core/src/tool.rs +ToolApprovalRequestOutput core aimux-core/src/result.rs +ToolApprovalResponsePart user aimux-core/src/language_model_message.rs +ToolCall tool aimux-core/src/tool.rs +ToolCallPart user aimux-core/src/language_model_message.rs +ToolCallRepairReply tool aimux-core/src/parse_tool_call.rs +ToolChoice tool aimux-core/src/tool.rs +ToolPart user aimux-core/src/language_model_message.rs +ToolResult tool aimux-core/src/tool.rs +ToolResultContent user aimux-core/src/language_model_message.rs +ToolResultOutput user aimux-core/src/language_model_message.rs +ToolResultPart user aimux-core/src/language_model_message.rs +TraceFilter recording aimux-core/src/trace/store.rs +TraceRecord recording aimux-core/src/trace/record.rs +TraceStats recording aimux-core/src/trace/store.rs +TranscriptionCallOptions multimodal aimux-core/src/transcription_model.rs +TranscriptionRequest multimodal aimux-core/src/transcription_model.rs +TranscriptionResponse multimodal aimux-core/src/transcription_model.rs +TranscriptionResult multimodal aimux-core/src/transcription_model.rs +TranscriptionSegment multimodal aimux-core/src/transcription_model.rs +TranscriptionStreamPart multimodal aimux-core/src/transcription_model.rs +UploadFileCallOptions multimodal aimux-core/src/files_model.rs +UploadFileData multimodal aimux-core/src/files_model.rs +UploadFileResult multimodal aimux-core/src/files_model.rs +UploadSkillCallOptions core aimux-core/src/skills_model.rs +UploadSkillResult core aimux-core/src/skills_model.rs +Usage core aimux-core/src/types.rs +UsageSnapshot recording aimux-core/src/trace/record.rs +UserPart user aimux-core/src/language_model_message.rs +Verdict recording aimux-core/src/trace/verdict.rs +VerdictConfidence recording aimux-core/src/trace/verdict.rs +VerdictKind recording aimux-core/src/trace/verdict.rs +VideoCallOptions multimodal aimux-core/src/video_model.rs +VideoData multimodal aimux-core/src/video_model.rs +VideoFile multimodal aimux-core/src/video_model.rs +VideoFileData multimodal aimux-core/src/video_model.rs +VideoFrameImage multimodal aimux-core/src/video_model.rs +VideoFrameType multimodal aimux-core/src/video_model.rs +VideoPollOptions multimodal aimux-core/src/video_model.rs +VideoResponse multimodal aimux-core/src/video_model.rs +VideoResult multimodal aimux-core/src/video_model.rs +Warning core aimux-core/src/types.rs + +[derive-ts-without-export] 1 +AiMuxErrorWire aimux-core/src/error.rs + +[excluded] 7 (web-tool wire, not a binding DTO) +WireCallRequest tools/aimux-web/src/wire.rs +WireCallResponse tools/aimux-web/src/wire.rs +WireContentPart tools/aimux-web/src/wire.rs +WireMessage tools/aimux-web/src/wire.rs +WireMeta tools/aimux-web/src/wire.rs +WireOptions tools/aimux-web/src/wire.rs +WireTool tools/aimux-web/src/wire.rs diff --git a/docs/plan/closure.md b/docs/plan/closure.md new file mode 100644 index 000000000..52e4e09d1 --- /dev/null +++ b/docs/plan/closure.md @@ -0,0 +1,174 @@ +# Consumer-closure inventory (PHASES 1.5) + +Generated by `scripts/gen_closure_inventory.py`; do not edit by hand. +Counts cover tracked files only. Phase-3 acceptance: every list below reaches zero +except the file-size table (split scope is D10). + +## Summary + +| item | count | +|---|---| +| FFI `aimux_*_new` (name ends in `_new`) | 29 | +| FFI `aimux_*_new*` (incl. `_new_with_base` etc.) | 51 | +| .rs files > 1000 lines (all tracked) | 36 | +| .rs files > 1000 lines (excluding `*/tests/*`) | 24 | +| ts-rs `#[derive(TS)]` sites | 201 | +| `from_resolved` occurrences | 0 | +| closure-typed `Box/Arc` (non-test) | 3 | +| hand-written binding type files | 6 | + +## FFI constructors `aimux_*_new` + +- `aimux_abort_signal_new` +- `aimux_anthropic_aws_new` +- `aimux_anthropic_aws_new_with_base` (suffixed) +- `aimux_anthropic_new` +- `aimux_anthropic_new_with_base` (suffixed) +- `aimux_azure_new` +- `aimux_azure_new_with_base` (suffixed) +- `aimux_bedrock_new` +- `aimux_bedrock_new_with_base` (suffixed) +- `aimux_cohere_embedding_new` +- `aimux_cohere_embedding_new_with_base` (suffixed) +- `aimux_cohere_new` +- `aimux_cohere_new_with_base` (suffixed) +- `aimux_cohere_reranking_new` +- `aimux_cohere_reranking_new_with_base` (suffixed) +- `aimux_google_embedding_new` +- `aimux_google_embedding_new_with_base` (suffixed) +- `aimux_google_image_new` +- `aimux_google_image_new_with_base` (suffixed) +- `aimux_google_video_new` +- `aimux_google_video_new_with_base` (suffixed) +- `aimux_jev_decision_new` +- `aimux_jev_decision_new_with_probability_source` (suffixed) +- `aimux_mistral_new` +- `aimux_mistral_new_with_base` (suffixed) +- `aimux_moa_new` +- `aimux_mock_replay_new` +- `aimux_openai_embedding_new` +- `aimux_openai_embedding_new_with_base` (suffixed) +- `aimux_openai_files_new` +- `aimux_openai_files_new_with_base` (suffixed) +- `aimux_openai_image_new` +- `aimux_openai_image_new_with_base` (suffixed) +- `aimux_openai_new` +- `aimux_openai_new_with_base` (suffixed) +- `aimux_openai_speech_new` +- `aimux_openai_speech_new_with_base` (suffixed) +- `aimux_openai_transcription_new` +- `aimux_openai_transcription_new_with_base` (suffixed) +- `aimux_provider_handle_new` +- `aimux_provider_new` +- `aimux_router_new` +- `aimux_tavily_search_new` +- `aimux_tavily_search_new_with_base` (suffixed) +- `aimux_trace_new` +- `aimux_trace_new_audited` (suffixed) +- `aimux_transcription_session_new` +- `aimux_vertex_new` +- `aimux_vertex_new_with_base` (suffixed) +- `aimux_xai_new` +- `aimux_xai_new_with_base` (suffixed) + +## Hand-written binding types + +| file | lines | +|---|---| +| bindings/kotlin/src/main/kotlin/ai/arcships/aimux/Types.kt | 1248 | +| bindings/java/src/main/java/ai/arcships/aimux/Types.java | 5354 | +| bindings/swift/Sources/Aimux/Types.swift | 1734 | +| bindings/flutter/lib/types.dart | 2251 | +| bindings/python/python/aimux/wrapper.py | 1214 | +| bindings/go/types.go | 687 | + +## ts-rs derives + +| file | `derive(TS)` | +|---|---| +| aimux-core/src/content.rs | 1 | +| aimux-core/src/decision_model.rs | 14 | +| aimux-core/src/embedding_model.rs | 4 | +| aimux-core/src/error.rs | 5 | +| aimux-core/src/evaluation_model.rs | 9 | +| aimux-core/src/files_model.rs | 3 | +| aimux-core/src/generate.rs | 3 | +| aimux-core/src/image_model.rs | 7 | +| aimux-core/src/language_model_message.rs | 14 | +| aimux-core/src/message.rs | 4 | +| aimux-core/src/model_catalogue.rs | 12 | +| aimux-core/src/model_id.rs | 1 | +| aimux-core/src/openai_output.rs | 13 | +| aimux-core/src/options.rs | 3 | +| aimux-core/src/parse_tool_call.rs | 1 | +| aimux-core/src/recording.rs | 10 | +| aimux-core/src/reranking_model.rs | 5 | +| aimux-core/src/result.rs | 11 | +| aimux-core/src/search_model.rs | 4 | +| aimux-core/src/session.rs | 3 | +| aimux-core/src/shared.rs | 8 | +| aimux-core/src/skills_model.rs | 3 | +| aimux-core/src/speech_model.rs | 5 | +| aimux-core/src/stream_part.rs | 2 | +| aimux-core/src/tool.rs | 8 | +| aimux-core/src/trace/fingerprint.rs | 1 | +| aimux-core/src/trace/record.rs | 3 | +| aimux-core/src/trace/store.rs | 6 | +| aimux-core/src/trace/verdict.rs | 5 | +| aimux-core/src/transcription_model.rs | 9 | +| aimux-core/src/types.rs | 8 | +| aimux-core/src/video_model.rs | 9 | +| tools/aimux-web/src/wire.rs | 7 | + +## `from_resolved` + +| file | occurrences | +|---|---| + +## Closure-typed fields and parameters (non-test) + +| file | `Box/Arc` | +|---|---| +| aimux-core/src/parse_tool_call.rs | 1 | +| aimux-provider-utils/src/resolvable.rs | 2 | + +## .rs files over 1000 lines + +| file | lines | kind | +|---|---|---| +| aimux-ffi/src/lib.rs | 4729 | src | +| aimux-providers/src/anthropic/convert.rs | 3207 | src | +| aimux-core/src/recording.rs | 3067 | src | +| aimux-providers/tests/deepseek_chat_test.rs | 2562 | test | +| aimux-providers/tests/groq_test.rs | 2342 | test | +| aimux-providers/src/openai/responses/convert.rs | 2274 | src | +| aimux-providers/tests/open_responses_test.rs | 2235 | test | +| aimux-providers/tests/huggingface_responses_test.rs | 1959 | test | +| aimux-providers/src/google/convert.rs | 1893 | src | +| aimux-core/src/replay.rs | 1830 | src | +| aimux-providers/src/anthropic/stream.rs | 1785 | src | +| aimux-providers/src/openai/responses/responses_convert.rs | 1742 | src | +| aimux-providers/src/bedrock/convert.rs | 1699 | src | +| bindings/node/src/lib.rs | 1694 | src | +| aimux-providers/tests/data_loss_regression_test.rs | 1631 | test | +| aimux-core/src/generate.rs | 1490 | src | +| aimux-providers/src/open_responses.rs | 1424 | src | +| aimux-providers/tests/conformance_test.rs | 1400 | test | +| bindings/python/src/lib.rs | 1340 | src | +| aimux-providers/src/xai/responses/mod.rs | 1277 | src | +| aimux-ffi/tests/exports_smoke_test.rs | 1269 | test | +| aimux-providers/src/openai/convert.rs | 1262 | src | +| aimux-providers/src/vertex/model.rs | 1227 | src | +| aimux-providers/tests/bedrock_remaining_test.rs | 1215 | test | +| aimux-providers/tests/e2e_test.rs | 1185 | test | +| aimux-providers/src/elevenlabs.rs | 1184 | src | +| aimux-providers/src/huggingface/responses.rs | 1172 | src | +| aimux-providers/tests/bedrock_convert_test.rs | 1170 | test | +| aimux-providers/tests/openai_compatible_test.rs | 1152 | test | +| tools/aimux-codegen/src/extract.rs | 1134 | src | +| aimux-provider-utils/tests/streaming_tool_call_tracker_test.rs | 1105 | test | +| aimux-providers/src/vertex/auth.rs | 1090 | src | +| aimux-core/src/openai_output.rs | 1065 | src | +| aimux-providers/src/google/model.rs | 1045 | src | +| bindings/node/src/multimodal.rs | 1017 | src | +| aimux-providers/src/xai/responses/convert.rs | 1013 | src | diff --git a/scripts/gen_closure_inventory.py b/scripts/gen_closure_inventory.py new file mode 100644 index 000000000..a491d398e --- /dev/null +++ b/scripts/gen_closure_inventory.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python3 +"""Generate docs/plan/closure.md, the consumer-closure inventory (PHASES 1.5). + +Lists everything the atomic switch must replace (#200:1509, RFC-0039 §0.2): +the FFI `aimux_*_new` constructors, hand-written binding type files, ts-rs +derives, `from_resolved`, closure-typed fields (`Box/Arc`) and .rs +files over 1000 lines. Every count is computed from tracked files +(`git ls-files`), so the report is reproducible from a commit. + +Usage: + python3 scripts/gen_closure_inventory.py # write docs/plan/closure.md + python3 scripts/gen_closure_inventory.py --check # exit 1 if it is stale +""" + +from __future__ import annotations + +import re +import subprocess +import sys +from collections import Counter +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +OUT = ROOT / "docs/plan/closure.md" +DTO_OUT = ROOT / "docs/plan/closure-dtos.txt" + +# Unit 2.1 acceptance list: every `#[ts(export)]` type, with a category. The +# category is assigned per source file (planner Q2); the table is mirrored in +# tools/aimux-codegen/src/extract.rs and the two are compared by the +# coverage report, so a disagreement turns red. +DTO_EXCLUDED = ["tools/aimux-web/src/wire.rs"] +# The generator itself quotes `#[derive(.., TS)]` / `#[ts(export)]` in docs +# and test fixtures; those are text, not types. +TS_SCAN_EXCLUDED_PREFIX = "tools/aimux-codegen/" +CATEGORY_BY_FILE = { + "aimux-core/src/error.rs": "error", + "aimux-core/src/recording.rs": "recording", + "aimux-core/src/trace/fingerprint.rs": "recording", + "aimux-core/src/trace/record.rs": "recording", + "aimux-core/src/trace/store.rs": "recording", + "aimux-core/src/trace/verdict.rs": "recording", + "aimux-core/src/tool.rs": "tool", + "aimux-core/src/parse_tool_call.rs": "tool", + "aimux-core/src/content.rs": "multimodal", + "aimux-core/src/embedding_model.rs": "multimodal", + "aimux-core/src/files_model.rs": "multimodal", + "aimux-core/src/image_model.rs": "multimodal", + "aimux-core/src/speech_model.rs": "multimodal", + "aimux-core/src/transcription_model.rs": "multimodal", + "aimux-core/src/video_model.rs": "multimodal", + "aimux-core/src/model_catalogue.rs": "provider", + "aimux-core/src/model_id.rs": "provider", + "aimux-core/src/message.rs": "user", + "aimux-core/src/language_model_message.rs": "user", + "aimux-core/src/options.rs": "user", +} +DEFAULT_CATEGORY = "core" +# `#[ts(export` also when the attribute is split over lines (`#[ts(\n export,`). +TS_EXPORT = re.compile(r"#\[ts\(\s*export\b") +ITEM_ANY = re.compile(r"(?m)^\s*(?:pub(?:\([^)]*\))?\s+)?(struct|enum)\s+(\w+)") + +HANDWRITTEN_TYPES = [ + "bindings/kotlin/src/main/kotlin/ai/arcships/aimux/Types.kt", + "bindings/java/src/main/java/ai/arcships/aimux/Types.java", + "bindings/swift/Sources/Aimux/Types.swift", + "bindings/flutter/lib/types.dart", + "bindings/python/python/aimux/wrapper.py", + "bindings/go/types.go", +] + +FFI_NEW_EXACT = re.compile(r'extern\s+"C"\s+fn\s+(aimux_\w*_new)\s*\(') +FFI_NEW_PREFIX = re.compile(r'extern\s+"C"\s+fn\s+(aimux_\w*_new\w*)\s*\(') +TS_DERIVE = re.compile(r"#\[derive\([^\]]*\bTS\b[^\]]*\)\]") +FROM_RESOLVED = re.compile(r"\bfrom_resolved\b") +CLOSURE_FIELD = re.compile(r"\b(?:Box|Arc)<\s*dyn\s+(?:Fn|FnMut|FnOnce)\b") + + +def tracked(pattern: str) -> list[str]: + out = subprocess.run( + ["git", "ls-files", "-z", "--", pattern], + cwd=ROOT, check=True, capture_output=True, text=True, + ).stdout + return sorted(p for p in out.split("\0") if p) + + +def read(path: str) -> str: + return (ROOT / path).read_text(encoding="utf-8", errors="replace") + + +def per_file(paths: list[str], regex: re.Pattern[str]) -> Counter[str]: + counts: Counter[str] = Counter() + for path in paths: + n = len(regex.findall(read(path))) + if n: + counts[path] = n + return counts + + +def table(rows: list[tuple], header: tuple) -> list[str]: + lines = ["| " + " | ".join(header) + " |", "|" + "---|" * len(header)] + lines += ["| " + " | ".join(str(c) for c in row) + " |" for row in rows] + return lines + + +def render() -> str: + rs = tracked("*.rs") + ffi_src = [p for p in rs if p.startswith("aimux-ffi/src/")] + ffi_text = "\n".join(read(p) for p in ffi_src) + exact = sorted(set(FFI_NEW_EXACT.findall(ffi_text))) + prefixed = sorted(set(FFI_NEW_PREFIX.findall(ffi_text))) + ts = per_file([p for p in rs if not p.startswith(TS_SCAN_EXCLUDED_PREFIX)], TS_DERIVE) + resolved = per_file(rs, FROM_RESOLVED) + closures = per_file([p for p in rs if "/tests/" not in p], CLOSURE_FIELD) + lengths = {p: read(p).count("\n") for p in rs} + big = sorted(((n, p) for p, n in lengths.items() if n > 1000), reverse=True) + big_src = [(n, p) for n, p in big if "/tests/" not in p] + types = [(p, read(p).count("\n")) for p in HANDWRITTEN_TYPES if (ROOT / p).exists()] + + md = [ + "# Consumer-closure inventory (PHASES 1.5)", + "", + "Generated by `scripts/gen_closure_inventory.py`; do not edit by hand.", + "Counts cover tracked files only. Phase-3 acceptance: every list below reaches zero", + "except the file-size table (split scope is D10).", + "", + "## Summary", + "", + *table( + [ + ("FFI `aimux_*_new` (name ends in `_new`)", len(exact)), + ("FFI `aimux_*_new*` (incl. `_new_with_base` etc.)", len(prefixed)), + (".rs files > 1000 lines (all tracked)", len(big)), + (".rs files > 1000 lines (excluding `*/tests/*`)", len(big_src)), + ("ts-rs `#[derive(TS)]` sites", sum(ts.values())), + ("`from_resolved` occurrences", sum(resolved.values())), + ("closure-typed `Box/Arc` (non-test)", sum(closures.values())), + ("hand-written binding type files", len(types)), + ], + ("item", "count"), + ), + "", + "## FFI constructors `aimux_*_new`", + "", + *[f"- `{name}`" + ("" if name in exact else " (suffixed)") for name in prefixed], + "", + "## Hand-written binding types", + "", + *table(types, ("file", "lines")), + "", + "## ts-rs derives", + "", + *table(sorted(ts.items()), ("file", "`derive(TS)`")), + "", + "## `from_resolved`", + "", + *table(sorted(resolved.items()), ("file", "occurrences")), + "", + "## Closure-typed fields and parameters (non-test)", + "", + *table(sorted(closures.items()), ("file", "`Box/Arc`")), + "", + "## .rs files over 1000 lines", + "", + *table([(p, n, "test" if "/tests/" in p else "src") for n, p in big], ("file", "lines", "kind")), + "", + ] + return "\n".join(md) + + +def ts_items(path: str) -> list[tuple[str, bool]]: + """(type name, exported) for every `derive(TS)` struct/enum in `path`. + + From each `derive(..TS..)` the next struct/enum item is the type; a + `#[ts(export` between the derive and the item (or in the attribute lines + directly above the derive) makes it exported. + """ + text = read(path) + out = [] + for m in TS_DERIVE.finditer(text): + rest = text[m.end():] + item = ITEM_ANY.search(rest) + if not item: + continue + before = text[:m.start()].split("\n") + attrs = [] + for line in reversed(before[:-1] if before[-1].strip() == "" else before): + t = line.strip() + if not (t.startswith("#[") or t.startswith("///")): + break + attrs.append(t) + span = rest[: item.start()] + " ".join(attrs) + out.append((item.group(2), TS_EXPORT.search(span) is not None)) + return out + + +def render_dtos() -> str: + exported, unexported, excluded = [], [], [] + for path in tracked("*.rs"): + if "/tests/" in path or path.startswith(TS_SCAN_EXCLUDED_PREFIX) or not TS_DERIVE.search(read(path)): + continue + for name, exp in ts_items(path): + if path in DTO_EXCLUDED: + excluded.append((name, path)) + elif exp: + exported.append((name, CATEGORY_BY_FILE.get(path, DEFAULT_CATEGORY), path)) + else: + unexported.append((name, path)) + exported.sort() + unexported.sort() + excluded.sort() + lines = [ + "# Unit 2.1 acceptance list (PHASES 2.1): every `#[ts(export)]` type.", + "# Generated by scripts/gen_closure_inventory.py; do not edit by hand.", + "# Format: . The [exported] section must equal", + "# the manifest coverage report (tools/aimux-codegen/generated/coverage.txt).", + "", + f"[exported] {len(exported)}", + *[f"{n} {c} {p}" for n, c, p in exported], + "", + f"[derive-ts-without-export] {len(unexported)}", + *[f"{n} {p}" for n, p in unexported], + "", + f"[excluded] {len(excluded)} (web-tool wire, not a binding DTO)", + *[f"{n} {p}" for n, p in excluded], + "", + ] + return "\n".join(lines) + + +def main() -> int: + stale = False + for out, text in ((OUT, render()), (DTO_OUT, render_dtos())): + if "--check" in sys.argv[1:]: + if not out.exists() or out.read_text(encoding="utf-8") != text: + print(f"STALE: {out.relative_to(ROOT)} — run scripts/gen_closure_inventory.py") + stale = True + else: + print(f"{out.relative_to(ROOT)} up to date") + continue + out.parent.mkdir(parents=True, exist_ok=True) + out.write_text(text, encoding="utf-8") + print(f"wrote {out.relative_to(ROOT)}") + return 1 if stale else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/aimux-codegen/Cargo.toml b/tools/aimux-codegen/Cargo.toml index 178e18919..a1ff7af31 100644 --- a/tools/aimux-codegen/Cargo.toml +++ b/tools/aimux-codegen/Cargo.toml @@ -13,6 +13,11 @@ path = "src/main.rs" [dependencies] serde = { workspace = true } serde_json = { workspace = true } +# Unit 2.1: Rust-source extraction (syn) and the manifest input hash. +syn = { version = "2", features = ["full", "parsing", "printing", "extra-traits"] } +quote = "1" +proc-macro2 = { version = "1", features = ["span-locations"] } +sha2 = "0.10" [lints] workspace = true diff --git a/tools/aimux-codegen/generated/coverage.txt b/tools/aimux-codegen/generated/coverage.txt new file mode 100644 index 000000000..c846db94e --- /dev/null +++ b/tools/aimux-codegen/generated/coverage.txt @@ -0,0 +1,195 @@ +# Manifest coverage (unit 2.1). Generated by aimux-codegen; must equal the +# [exported] section of docs/plan/closure-dtos.txt. +AiMuxError error aimux-core/src/error.rs +ApiCallError error aimux-core/src/error.rs +AspectRatio core aimux-core/src/shared.rs +AssistantPart user aimux-core/src/language_model_message.rs +AudioChunk multimodal aimux-core/src/transcription_model.rs +AudioData multimodal aimux-core/src/speech_model.rs +AudioInput multimodal aimux-core/src/transcription_model.rs +BooleanCriteria core aimux-core/src/evaluation_model.rs +BreakKind recording aimux-core/src/trace/store.rs +CallOptions user aimux-core/src/options.rs +CatalogueSource provider aimux-core/src/model_catalogue.rs +ChatCompletion core aimux-core/src/openai_output.rs +ChatCompletionChoice core aimux-core/src/openai_output.rs +ChatCompletionChunk core aimux-core/src/openai_output.rs +ChatCompletionChunkChoice core aimux-core/src/openai_output.rs +ChatCompletionChunkFunction core aimux-core/src/openai_output.rs +ChatCompletionChunkToolCall core aimux-core/src/openai_output.rs +ChatCompletionDelta core aimux-core/src/openai_output.rs +ChatCompletionFunction core aimux-core/src/openai_output.rs +ChatCompletionMessage core aimux-core/src/openai_output.rs +ChatCompletionToolCall core aimux-core/src/openai_output.rs +ChatCompletionUsage core aimux-core/src/openai_output.rs +CompletionTokensDetails core aimux-core/src/openai_output.rs +ContentPart multimodal aimux-core/src/content.rs +CustomPart user aimux-core/src/language_model_message.rs +DecisionAnswer core aimux-core/src/decision_model.rs +DecisionBooleanCriteria core aimux-core/src/decision_model.rs +DecisionCallOptions core aimux-core/src/decision_model.rs +DecisionCapabilities core aimux-core/src/decision_model.rs +DecisionDescription core aimux-core/src/decision_model.rs +DecisionImage core aimux-core/src/decision_model.rs +DecisionOption core aimux-core/src/decision_model.rs +DecisionProbabilitySource core aimux-core/src/decision_model.rs +DecisionQuestion core aimux-core/src/decision_model.rs +DecisionResponse core aimux-core/src/decision_model.rs +DecisionResult core aimux-core/src/decision_model.rs +DecisionRounding core aimux-core/src/decision_model.rs +DecisionScoreLevel core aimux-core/src/decision_model.rs +DecisionValue core aimux-core/src/decision_model.rs +EmbeddingCallOptions multimodal aimux-core/src/embedding_model.rs +EmbeddingResponse multimodal aimux-core/src/embedding_model.rs +EmbeddingResult multimodal aimux-core/src/embedding_model.rs +EmbeddingUsage multimodal aimux-core/src/embedding_model.rs +EvaluationAnswer core aimux-core/src/evaluation_model.rs +EvaluationCallOptions core aimux-core/src/evaluation_model.rs +EvaluationInput core aimux-core/src/evaluation_model.rs +EvaluationQuestion core aimux-core/src/evaluation_model.rs +EvaluationQuestionType core aimux-core/src/evaluation_model.rs +EvaluationResult core aimux-core/src/evaluation_model.rs +EvaluationRounding core aimux-core/src/evaluation_model.rs +EvaluationUsage core aimux-core/src/evaluation_model.rs +FileBytes core aimux-core/src/shared.rs +FileData core aimux-core/src/shared.rs +FilePart user aimux-core/src/language_model_message.rs +Fingerprint recording aimux-core/src/trace/fingerprint.rs +FinishReason core aimux-core/src/types.rs +FinishReasonUnified core aimux-core/src/types.rs +FunctionTool tool aimux-core/src/tool.rs +FunctionToolInputExample tool aimux-core/src/tool.rs +GenerateContent core aimux-core/src/result.rs +GenerateObjectResult core aimux-core/src/generate.rs +GenerateResult core aimux-core/src/result.rs +GenerateTextOptions core aimux-core/src/generate.rs +GenerateTextResult core aimux-core/src/generate.rs +GeneratedFile core aimux-core/src/result.rs +GeneratedFileData core aimux-core/src/shared.rs +HttpExchange recording aimux-core/src/recording.rs +HttpRecord recording aimux-core/src/recording.rs +ImageCallOptions multimodal aimux-core/src/image_model.rs +ImageFile multimodal aimux-core/src/image_model.rs +ImageFileData multimodal aimux-core/src/image_model.rs +ImageOutputs multimodal aimux-core/src/image_model.rs +ImageResponse multimodal aimux-core/src/image_model.rs +ImageResult multimodal aimux-core/src/image_model.rs +ImageUsage multimodal aimux-core/src/image_model.rs +InputAudioFormat multimodal aimux-core/src/transcription_model.rs +InputRecord recording aimux-core/src/recording.rs +InputTokenUsage core aimux-core/src/types.rs +LanguageModelMessage user aimux-core/src/language_model_message.rs +MessageContent user aimux-core/src/message.rs +Modality provider aimux-core/src/model_catalogue.rs +ModelCapabilities provider aimux-core/src/model_catalogue.rs +ModelCost provider aimux-core/src/model_catalogue.rs +ModelId provider aimux-core/src/model_id.rs +ModelLimits provider aimux-core/src/model_catalogue.rs +ModelMessage user aimux-core/src/message.rs +ModelModalities provider aimux-core/src/model_catalogue.rs +ModelPrompt user aimux-core/src/message.rs +ModelSpec provider aimux-core/src/model_catalogue.rs +ModelType provider aimux-core/src/model_catalogue.rs +OutcomeRecord recording aimux-core/src/recording.rs +OutcomeStatus recording aimux-core/src/recording.rs +OutputTokenUsage core aimux-core/src/types.rs +PrefixBreak recording aimux-core/src/trace/store.rs +PromptTokensDetails core aimux-core/src/openai_output.rs +ProviderAuditSpec recording aimux-core/src/trace/verdict.rs +ProviderFamily recording aimux-core/src/trace/verdict.rs +ProviderRecord recording aimux-core/src/recording.rs +ProviderTool tool aimux-core/src/tool.rs +RawToolApprovalRequest core aimux-core/src/result.rs +RawToolCall tool aimux-core/src/tool.rs +ReasoningEffort core aimux-core/src/types.rs +ReasoningFileOutput core aimux-core/src/result.rs +ReasoningFilePart user aimux-core/src/language_model_message.rs +ReasoningMode provider aimux-core/src/model_catalogue.rs +ReasoningOutput core aimux-core/src/result.rs +ReasoningPart core aimux-core/src/result.rs +ReasoningPart user aimux-core/src/language_model_message.rs +ReasoningSpec provider aimux-core/src/model_catalogue.rs +ReasoningVisibility provider aimux-core/src/model_catalogue.rs +Recording recording aimux-core/src/recording.rs +RecordingOperation recording aimux-core/src/recording.rs +RequestCacheHints recording aimux-core/src/trace/record.rs +RequestInfo core aimux-core/src/shared.rs +RerankingCallOptions core aimux-core/src/reranking_model.rs +RerankingDocuments core aimux-core/src/reranking_model.rs +RerankingRank core aimux-core/src/reranking_model.rs +RerankingResponse core aimux-core/src/reranking_model.rs +RerankingResult core aimux-core/src/reranking_model.rs +ResponseFormat user aimux-core/src/options.rs +ResponseInfo core aimux-core/src/shared.rs +ResponseMetadata core aimux-core/src/types.rs +ResponseRecord recording aimux-core/src/recording.rs +RetryError error aimux-core/src/error.rs +RetryErrorReason error aimux-core/src/error.rs +Role user aimux-core/src/message.rs +RuntimeModel provider aimux-core/src/model_catalogue.rs +SearchCallOptions core aimux-core/src/search_model.rs +SearchResponse core aimux-core/src/search_model.rs +SearchResult core aimux-core/src/search_model.rs +SearchResultItem core aimux-core/src/search_model.rs +SessionCall core aimux-core/src/session.rs +SessionChainView recording aimux-core/src/trace/store.rs +SessionSource core aimux-core/src/session.rs +SessionStepStat recording aimux-core/src/trace/store.rs +SessionView core aimux-core/src/session.rs +Size core aimux-core/src/shared.rs +SkillFile core aimux-core/src/skills_model.rs +Source core aimux-core/src/result.rs +SpeechCallOptions multimodal aimux-core/src/speech_model.rs +SpeechRequest multimodal aimux-core/src/speech_model.rs +SpeechResponse multimodal aimux-core/src/speech_model.rs +SpeechResult multimodal aimux-core/src/speech_model.rs +StreamPart core aimux-core/src/stream_part.rs +StreamResponseInfo core aimux-core/src/shared.rs +StreamTextResultAggregated core aimux-core/src/result.rs +TextContentBinding core aimux-core/src/result.rs +TextPart user aimux-core/src/language_model_message.rs +TextStreamPart core aimux-core/src/stream_part.rs +TimeoutConfiguration user aimux-core/src/options.rs +TimingRecord recording aimux-core/src/recording.rs +Tool tool aimux-core/src/tool.rs +ToolApprovalRequestOutput core aimux-core/src/result.rs +ToolApprovalResponsePart user aimux-core/src/language_model_message.rs +ToolCall tool aimux-core/src/tool.rs +ToolCallPart user aimux-core/src/language_model_message.rs +ToolCallRepairReply tool aimux-core/src/parse_tool_call.rs +ToolChoice tool aimux-core/src/tool.rs +ToolPart user aimux-core/src/language_model_message.rs +ToolResult tool aimux-core/src/tool.rs +ToolResultContent user aimux-core/src/language_model_message.rs +ToolResultOutput user aimux-core/src/language_model_message.rs +ToolResultPart user aimux-core/src/language_model_message.rs +TraceFilter recording aimux-core/src/trace/store.rs +TraceRecord recording aimux-core/src/trace/record.rs +TraceStats recording aimux-core/src/trace/store.rs +TranscriptionCallOptions multimodal aimux-core/src/transcription_model.rs +TranscriptionRequest multimodal aimux-core/src/transcription_model.rs +TranscriptionResponse multimodal aimux-core/src/transcription_model.rs +TranscriptionResult multimodal aimux-core/src/transcription_model.rs +TranscriptionSegment multimodal aimux-core/src/transcription_model.rs +TranscriptionStreamPart multimodal aimux-core/src/transcription_model.rs +UploadFileCallOptions multimodal aimux-core/src/files_model.rs +UploadFileData multimodal aimux-core/src/files_model.rs +UploadFileResult multimodal aimux-core/src/files_model.rs +UploadSkillCallOptions core aimux-core/src/skills_model.rs +UploadSkillResult core aimux-core/src/skills_model.rs +Usage core aimux-core/src/types.rs +UsageSnapshot recording aimux-core/src/trace/record.rs +UserPart user aimux-core/src/language_model_message.rs +Verdict recording aimux-core/src/trace/verdict.rs +VerdictConfidence recording aimux-core/src/trace/verdict.rs +VerdictKind recording aimux-core/src/trace/verdict.rs +VideoCallOptions multimodal aimux-core/src/video_model.rs +VideoData multimodal aimux-core/src/video_model.rs +VideoFile multimodal aimux-core/src/video_model.rs +VideoFileData multimodal aimux-core/src/video_model.rs +VideoFrameImage multimodal aimux-core/src/video_model.rs +VideoFrameType multimodal aimux-core/src/video_model.rs +VideoPollOptions multimodal aimux-core/src/video_model.rs +VideoResponse multimodal aimux-core/src/video_model.rs +VideoResult multimodal aimux-core/src/video_model.rs +Warning core aimux-core/src/types.rs diff --git a/tools/aimux-codegen/generated/manifest.json b/tools/aimux-codegen/generated/manifest.json new file mode 100644 index 000000000..df25a1949 --- /dev/null +++ b/tools/aimux-codegen/generated/manifest.json @@ -0,0 +1,14653 @@ +{ + "schemaRevision": 1, + "generator": { + "name": "aimux-codegen", + "version": "0.5.0" + }, + "sdk": { + "@ai-sdk/anthropic": "4.0.71", + "@ai-sdk/google": "4.0.87", + "@ai-sdk/openai": "4.0.83", + "@ai-sdk/openai-compatible": "3.0.62", + "@ai-sdk/provider": "4.0.21", + "@ai-sdk/provider-utils": "5.0.53", + "ai": "7.0.127" + }, + "inputHash": "sha256:bce4b4955cf3331f39dff7299340c5cced60b0fe7048d265015e18f10e104396", + "types": [ + { + "name": "AiMuxError", + "category": "error", + "source": "aimux-core/src/error.rs", + "proxy": { + "from": { + "ref": { + "name": "AiMuxErrorWire", + "args": [] + } + }, + "into": { + "ref": { + "name": "AiMuxErrorWire", + "args": [] + } + } + }, + "tsOverride": "AiMuxErrorWire", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "ApiCall", + "wire": "ApiCall", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ApiCallError", + "args": [] + } + } + } + }, + { + "rust": "Retry", + "wire": "Retry", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "RetryError", + "args": [] + } + } + } + }, + { + "rust": "JsonParse", + "wire": "JsonParse", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "NoOutputGenerated", + "wire": "NoOutputGenerated", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "InvalidResponseData", + "wire": "InvalidResponseData", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "ToolCallNotFoundForApproval", + "wire": "ToolCallNotFoundForApproval", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "tool_call_id", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "approval_id", + "rust": "approval_id", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "NoSuchTool", + "wire": "NoSuchTool", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "tool_name", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "available_tools", + "rust": "available_tools", + "type": { + "option": { + "array": { + "prim": "String" + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "tool_input", + "rust": "tool_input", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "InvalidToolInput", + "wire": "InvalidToolInput", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "tool_name", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "tool_input", + "rust": "tool_input", + "type": { + "prim": "String" + } + }, + { + "wire": "cause", + "rust": "cause", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "ToolCallRepair", + "wire": "ToolCallRepair", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "original_error", + "rust": "original_error", + "type": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + }, + { + "wire": "cause", + "rust": "cause", + "type": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + } + ] + } + }, + { + "rust": "InvalidArgument", + "wire": "InvalidArgument", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "InvalidPrompt", + "wire": "InvalidPrompt", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "LoadApiKey", + "wire": "LoadApiKey", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "env_var", + "rust": "env_var", + "type": { + "prim": "String" + } + }, + { + "wire": "description", + "rust": "description", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "LoadSetting", + "wire": "LoadSetting", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "env_var", + "rust": "env_var", + "type": { + "prim": "String" + } + }, + { + "wire": "name", + "rust": "name", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "TokenExpired", + "wire": "TokenExpired", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "UnsupportedFunctionality", + "wire": "UnsupportedFunctionality", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "NoSuchModel", + "wire": "NoSuchModel", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "model_id", + "rust": "model_id", + "type": { + "prim": "String" + } + }, + { + "wire": "model_type", + "rust": "model_type", + "type": { + "prim": "String" + }, + "default": true + } + ] + } + }, + { + "rust": "NoSuchProvider", + "wire": "NoSuchProvider", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "provider_id", + "rust": "provider_id", + "type": { + "prim": "String" + } + }, + { + "wire": "model_id", + "rust": "model_id", + "type": { + "prim": "String" + } + }, + { + "wire": "model_type", + "rust": "model_type", + "type": { + "prim": "String" + } + }, + { + "wire": "available_providers", + "rust": "available_providers", + "type": { + "array": { + "prim": "String" + } + } + } + ] + } + }, + { + "rust": "Timeout", + "wire": "Timeout", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Aborted", + "wire": "Aborted", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Other", + "wire": "Other", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + } + ] + } + }, + { + "name": "ApiCallError", + "category": "error", + "source": "aimux-core/src/error.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "requestBodyValues", + "rust": "request_body_values", + "type": "json" + }, + { + "wire": "statusCode", + "rust": "status_code", + "type": { + "option": { + "prim": "u16" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerCode", + "rust": "provider_code", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + }, + { + "wire": "responseBody", + "rust": "response_body", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "responseHeaders", + "rust": "response_headers", + "type": { + "option": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "String" + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "data", + "rust": "data", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "isRetryable", + "rust": "is_retryable", + "type": { + "prim": "bool" + }, + "default": true + } + ] + } + }, + { + "name": "AspectRatio", + "category": "core", + "source": "aimux-core/src/shared.rs", + "proxy": { + "into": { + "prim": "String" + }, + "try_from": { + "prim": "String" + } + }, + "tsOverride": "`${number}:${number}`", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "width", + "rust": "width", + "type": { + "prim": "u32" + } + }, + { + "wire": "height", + "rust": "height", + "type": { + "prim": "u32" + } + } + ] + } + }, + { + "name": "AssistantPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "TextPart", + "args": [] + } + } + } + }, + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "FilePart", + "args": [] + } + } + } + }, + { + "rust": "Reasoning", + "wire": "reasoning", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ReasoningPart", + "args": [] + } + } + } + }, + { + "rust": "ReasoningFile", + "wire": "reasoning-file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ReasoningFilePart", + "args": [] + } + } + } + }, + { + "rust": "Custom", + "wire": "custom", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "CustomPart", + "args": [] + } + } + } + }, + { + "rust": "ToolCall", + "wire": "tool-call", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolCallPart", + "args": [] + } + } + } + }, + { + "rust": "ToolResult", + "wire": "tool-result", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolResultPart", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "AudioChunk", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Binary", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "prim": "u8" + } + } + } + }, + { + "rust": "Base64", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + } + ] + } + }, + { + "name": "AudioData", + "category": "multimodal", + "source": "aimux-core/src/speech_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Base64", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Binary", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "prim": "u8" + } + } + } + } + ] + } + }, + { + "name": "AudioInput", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Binary", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "prim": "u8" + } + } + } + }, + { + "rust": "Base64", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + } + ] + } + }, + { + "name": "BooleanCriteria", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "true", + "rust": "true_", + "type": { + "triState": { + "ref": { + "name": "EvaluationInput", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true, + "serdeWith": "deserialize_with=present", + "codec": { + "name": "presence", + "wire": "absent | null | value: an absent key and an explicit null are distinct" + } + }, + { + "wire": "false", + "rust": "false_", + "type": { + "triState": { + "ref": { + "name": "EvaluationInput", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true, + "serdeWith": "deserialize_with=present", + "codec": { + "name": "presence", + "wire": "absent | null | value: an absent key and an explicit null are distinct" + } + } + ] + } + }, + { + "name": "BreakKind", + "category": "recording", + "source": "aimux-core/src/trace/store.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "SystemChanged", + "wire": "SystemChanged", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ToolsChanged", + "wire": "ToolsChanged", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ConversationReset", + "wire": "ConversationReset", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Unknown", + "wire": "Unknown", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "CallOptions", + "category": "user", + "source": "aimux-core/src/options.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "prompt", + "rust": "prompt", + "type": { + "ref": { + "name": "LanguageModelPrompt", + "args": [] + } + } + }, + { + "wire": "maxOutputTokens", + "rust": "max_output_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "temperature", + "rust": "temperature", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "stopSequences", + "rust": "stop_sequences", + "type": { + "option": { + "array": { + "prim": "String" + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "topP", + "rust": "top_p", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "topK", + "rust": "top_k", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "presencePenalty", + "rust": "presence_penalty", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "frequencyPenalty", + "rust": "frequency_penalty", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "responseFormat", + "rust": "response_format", + "type": { + "option": { + "ref": { + "name": "ResponseFormat", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "seed", + "rust": "seed", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "tools", + "rust": "tools", + "type": { + "option": { + "array": { + "ref": { + "name": "Tool", + "args": [] + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "toolChoice", + "rust": "tool_choice", + "type": { + "option": { + "ref": { + "name": "ToolChoice", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "String" + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "reasoning", + "rust": "reasoning", + "type": { + "option": { + "ref": { + "name": "ReasoningEffort", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "sessionId", + "rust": "session_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "includeRawChunks", + "rust": "include_raw_chunks", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "CatalogueSource", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Anya2a", + "wire": "Anya2a", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ModelsDev", + "wire": "ModelsDev", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Manual", + "wire": "Manual", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "ChatCompletion", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "object", + "rust": "object", + "type": { + "prim": "String" + } + }, + { + "wire": "created", + "rust": "created", + "type": { + "prim": "u64" + } + }, + { + "wire": "model", + "rust": "model", + "type": { + "prim": "String" + } + }, + { + "wire": "choices", + "rust": "choices", + "type": { + "array": { + "ref": { + "name": "ChatCompletionChoice", + "args": [] + } + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "ChatCompletionUsage", + "args": [] + } + } + }, + { + "wire": "system_fingerprint", + "rust": "system_fingerprint", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ChatCompletionChoice", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "index", + "rust": "index", + "type": { + "prim": "u32" + } + }, + { + "wire": "message", + "rust": "message", + "type": { + "ref": { + "name": "ChatCompletionMessage", + "args": [] + } + } + }, + { + "wire": "finish_reason", + "rust": "finish_reason", + "type": { + "option": { + "prim": "String" + } + } + }, + { + "wire": "logprobs", + "rust": "logprobs", + "type": { + "option": "json" + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ChatCompletionChunk", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "object", + "rust": "object", + "type": { + "prim": "String" + } + }, + { + "wire": "created", + "rust": "created", + "type": { + "prim": "u64" + } + }, + { + "wire": "model", + "rust": "model", + "type": { + "prim": "String" + } + }, + { + "wire": "choices", + "rust": "choices", + "type": { + "array": { + "ref": { + "name": "ChatCompletionChunkChoice", + "args": [] + } + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "option": { + "ref": { + "name": "ChatCompletionUsage", + "args": [] + } + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ChatCompletionChunkChoice", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "index", + "rust": "index", + "type": { + "prim": "u32" + } + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "ref": { + "name": "ChatCompletionDelta", + "args": [] + } + } + }, + { + "wire": "finish_reason", + "rust": "finish_reason", + "type": { + "option": { + "prim": "String" + } + } + }, + { + "wire": "logprobs", + "rust": "logprobs", + "type": { + "option": "json" + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ChatCompletionChunkFunction", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "name", + "rust": "name", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + }, + { + "wire": "arguments", + "rust": "arguments", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ChatCompletionChunkToolCall", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "index", + "rust": "index", + "type": { + "prim": "u32" + } + }, + { + "wire": "id", + "rust": "id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + }, + { + "wire": "type", + "rust": "tool_type", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + }, + { + "wire": "function", + "rust": "function", + "type": { + "ref": { + "name": "ChatCompletionChunkFunction", + "args": [] + } + } + } + ] + } + }, + { + "name": "ChatCompletionDelta", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "role", + "rust": "role", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + }, + { + "wire": "content", + "rust": "content", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + }, + { + "wire": "reasoning_content", + "rust": "reasoning_content", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + }, + { + "wire": "tool_calls", + "rust": "tool_calls", + "type": { + "option": { + "array": { + "ref": { + "name": "ChatCompletionChunkToolCall", + "args": [] + } + } + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ChatCompletionFunction", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "name", + "rust": "name", + "type": { + "prim": "String" + } + }, + { + "wire": "arguments", + "rust": "arguments", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "name": "ChatCompletionMessage", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "role", + "rust": "role", + "type": { + "prim": "String" + } + }, + { + "wire": "content", + "rust": "content", + "type": { + "option": { + "prim": "String" + } + } + }, + { + "wire": "reasoning_content", + "rust": "reasoning_content", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true + }, + { + "wire": "tool_calls", + "rust": "tool_calls", + "type": { + "option": { + "array": { + "ref": { + "name": "ChatCompletionToolCall", + "args": [] + } + } + } + }, + "omitWhenEmpty": true + }, + { + "wire": "annotations", + "rust": "annotations", + "type": { + "option": { + "array": "json" + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ChatCompletionToolCall", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "type", + "rust": "tool_type", + "type": { + "prim": "String" + } + }, + { + "wire": "function", + "rust": "function", + "type": { + "ref": { + "name": "ChatCompletionFunction", + "args": [] + } + } + } + ] + } + }, + { + "name": "ChatCompletionUsage", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "prompt_tokens", + "rust": "prompt_tokens", + "type": { + "prim": "u32" + } + }, + { + "wire": "completion_tokens", + "rust": "completion_tokens", + "type": { + "prim": "u32" + } + }, + { + "wire": "total_tokens", + "rust": "total_tokens", + "type": { + "prim": "u32" + } + }, + { + "wire": "prompt_tokens_details", + "rust": "prompt_tokens_details", + "type": { + "option": { + "ref": { + "name": "PromptTokensDetails", + "args": [] + } + } + }, + "omitWhenEmpty": true + }, + { + "wire": "completion_tokens_details", + "rust": "completion_tokens_details", + "type": { + "option": { + "ref": { + "name": "CompletionTokensDetails", + "args": [] + } + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "CompletionTokensDetails", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "reasoning_tokens", + "rust": "reasoning_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ContentPart", + "category": "multimodal", + "source": "aimux-core/src/content.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Custom", + "wire": "custom", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "kind", + "rust": "kind", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ReasoningFile", + "wire": "reasoning-file", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "GeneratedFileData", + "args": [] + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolApprovalRequest", + "wire": "tool-approval-request", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "approvalId", + "rust": "approval_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "reason", + "rust": "reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "isAutomatic", + "rust": "is_automatic", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "signature", + "rust": "signature", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "inputSchemaInput", + "rust": "input_schema_input", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Image", + "wire": "image", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "image", + "rust": "image", + "type": { + "array": { + "prim": "u8" + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "array": { + "prim": "u8" + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "filename", + "rust": "filename", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "FileBase64", + "wire": "file-base64", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "prim": "String" + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "filename", + "rust": "filename", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "FileUrl", + "wire": "file-url", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "FileReference", + "wire": "file-reference", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "reference", + "rust": "reference", + "type": "json" + }, + { + "wire": "filename", + "rust": "filename", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Reasoning", + "wire": "reasoning", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "signature", + "rust": "signature", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolCall", + "wire": "tool-call", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "input", + "rust": "input", + "type": "json" + }, + { + "wire": "providerExecuted", + "rust": "provider_executed", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolResult", + "wire": "tool-result", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "output", + "rust": "output", + "type": { + "ref": { + "name": "ToolResultOutput", + "args": [] + } + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "CustomPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "kind", + "rust": "kind", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "DecisionAnswer", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Refusal", + "wire": "refusal", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Skipped", + "wire": "skipped", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Abstention", + "wire": "abstention", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Boolean", + "wire": "boolean", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "probability_true", + "rust": "probability_true", + "type": { + "prim": "f64" + } + } + ] + } + }, + { + "rust": "Choice", + "wire": "choice", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "selected", + "rust": "selected", + "type": { + "prim": "String" + } + }, + { + "wire": "value", + "rust": "value", + "type": { + "option": { + "ref": { + "name": "DecisionValue", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "probabilities", + "rust": "probabilities", + "type": { + "option": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "f64" + } + } + } + } + }, + { + "wire": "confidence", + "rust": "confidence", + "type": { + "option": { + "prim": "f64" + } + } + } + ] + } + }, + { + "rust": "Score", + "wire": "score", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "expected_value", + "rust": "expected_value", + "type": { + "prim": "f64" + } + }, + { + "wire": "levels", + "rust": "levels", + "type": { + "array": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + } + }, + { + "wire": "probabilities", + "rust": "probabilities", + "type": { + "option": { + "array": { + "prim": "f64" + } + } + } + }, + { + "wire": "confidence", + "rust": "confidence", + "type": { + "option": { + "prim": "f64" + } + } + } + ] + } + } + ] + } + }, + { + "name": "DecisionBooleanCriteria", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "true", + "rust": "true_description", + "type": { + "option": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "false", + "rust": "false_description", + "type": { + "option": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ], + "denyUnknownFields": true + } + }, + { + "name": "DecisionCallOptions", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "state", + "rust": "state", + "type": { + "ref": { + "name": "DecisionState", + "args": [] + } + } + }, + { + "wire": "images", + "rust": "images", + "type": { + "array": { + "ref": { + "name": "DecisionImage", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "questions", + "rust": "questions", + "type": { + "array": { + "ref": { + "name": "DecisionQuestion", + "args": [] + } + } + } + }, + { + "wire": "max_retries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "provider_options", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "DecisionCapabilities", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "supports_images", + "rust": "supports_images", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "max_images", + "rust": "max_images", + "type": { + "option": { + "prim": "usize" + } + }, + "default": true + }, + { + "wire": "supports_typed_choices", + "rust": "supports_typed_choices", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "rounding", + "rust": "rounding", + "type": { + "ref": { + "name": "DecisionRounding", + "args": [] + } + }, + "default": true + }, + { + "wire": "probability_source", + "rust": "probability_source", + "type": { + "ref": { + "name": "DecisionProbabilitySource", + "args": [] + } + } + }, + { + "wire": "supports_boolean", + "rust": "supports_boolean", + "type": { + "prim": "bool" + } + }, + { + "wire": "supports_choice", + "rust": "supports_choice", + "type": { + "prim": "bool" + } + }, + { + "wire": "supports_score", + "rust": "supports_score", + "type": { + "prim": "bool" + } + }, + { + "wire": "returns_distributions", + "rust": "returns_distributions", + "type": { + "prim": "bool" + } + }, + { + "wire": "max_questions", + "rust": "max_questions", + "type": { + "option": { + "prim": "usize" + } + } + }, + { + "wire": "min_choices", + "rust": "min_choices", + "type": { + "option": { + "prim": "usize" + } + } + }, + { + "wire": "max_choices", + "rust": "max_choices", + "type": { + "option": { + "prim": "usize" + } + } + }, + { + "wire": "max_score_levels", + "rust": "max_score_levels", + "type": { + "option": { + "prim": "usize" + } + } + } + ] + } + }, + { + "name": "DecisionDescription", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Text", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Object", + "shape": { + "kind": "newtype", + "inner": { + "codec": { + "rust": "serde_json::Map", + "wire": "Record" + } + } + } + }, + { + "rust": "Array", + "shape": { + "kind": "newtype", + "inner": { + "codec": { + "rust": "Vec", + "wire": "unknown[]" + } + } + } + } + ] + } + }, + { + "name": "DecisionImage", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "codec": { + "rust": "crate::shared::FileBytes", + "wire": "{ \"Base64\": string } | { \"Binary\": Array }" + } + }, + "serdeWith": "with=tagged_file_bytes" + }, + { + "wire": "media_type", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "detail", + "rust": "detail", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "DecisionOption", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "label", + "rust": "label", + "type": { + "prim": "String" + } + }, + { + "wire": "value", + "rust": "value", + "type": { + "option": { + "ref": { + "name": "DecisionValue", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "description", + "rust": "description", + "type": { + "option": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "DecisionProbabilitySource", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Native", + "wire": "native", + "shape": { + "kind": "unit" + } + }, + { + "rust": "LogitScoring", + "wire": "logit_scoring", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ModelEstimate", + "wire": "model_estimate", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "DecisionQuestion", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Boolean", + "wire": "boolean", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "instructions", + "rust": "instructions", + "type": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + }, + { + "wire": "criteria", + "rust": "criteria", + "type": { + "option": { + "ref": { + "name": "DecisionBooleanCriteria", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Choice", + "wire": "choice", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "instructions", + "rust": "instructions", + "type": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + }, + { + "wire": "options", + "rust": "options", + "type": { + "array": { + "ref": { + "name": "DecisionOption", + "args": [] + } + } + } + } + ] + } + }, + { + "rust": "Score", + "wire": "score", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "instructions", + "rust": "instructions", + "type": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + }, + { + "wire": "levels", + "rust": "levels", + "type": { + "array": { + "ref": { + "name": "DecisionDescription", + "args": [] + } + } + } + } + ] + } + } + ] + } + }, + { + "name": "DecisionResponse", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + } + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + } + } + ] + } + }, + { + "name": "DecisionResult", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "rounding", + "rust": "rounding", + "type": { + "ref": { + "name": "DecisionRounding", + "args": [] + } + }, + "default": true + }, + { + "wire": "answers", + "rust": "answers", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "ref": { + "name": "DecisionAnswer", + "args": [] + } + } + } + } + }, + { + "wire": "provider", + "rust": "provider", + "type": { + "prim": "String" + } + }, + { + "wire": "model", + "rust": "model", + "type": { + "prim": "String" + } + }, + { + "wire": "model_version", + "rust": "model_version", + "type": { + "option": { + "prim": "String" + } + } + }, + { + "wire": "probability_source", + "rust": "probability_source", + "type": { + "ref": { + "name": "DecisionProbabilitySource", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "option": { + "ref": { + "name": "Usage", + "args": [] + } + } + } + }, + { + "wire": "latency_ms", + "rust": "latency_ms", + "type": { + "option": { + "prim": "f64" + } + } + }, + { + "wire": "provider_metadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + } + }, + { + "wire": "response", + "rust": "response", + "type": { + "option": { + "ref": { + "name": "DecisionResponse", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "DecisionRounding", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "probability_decimals", + "rust": "probability_decimals", + "type": { + "option": { + "prim": "u8" + } + } + }, + { + "wire": "score_decimals", + "rust": "score_decimals", + "type": { + "option": { + "prim": "u8" + } + } + } + ] + } + }, + { + "name": "DecisionScoreLevel", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "label", + "rust": "label", + "type": { + "prim": "String" + } + }, + { + "wire": "description", + "rust": "description", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ], + "denyUnknownFields": true + } + }, + { + "name": "DecisionValue", + "category": "core", + "source": "aimux-core/src/decision_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Text", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Boolean", + "shape": { + "kind": "newtype", + "inner": { + "prim": "bool" + } + } + } + ] + } + }, + { + "name": "EmbeddingCallOptions", + "category": "multimodal", + "source": "aimux-core/src/embedding_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "values", + "rust": "values", + "type": { + "array": { + "prim": "String" + } + } + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "EmbeddingResponse", + "category": "multimodal", + "source": "aimux-core/src/embedding_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "EmbeddingResult", + "category": "multimodal", + "source": "aimux-core/src/embedding_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "embeddings", + "rust": "embeddings", + "type": { + "array": { + "ref": { + "name": "Embedding", + "args": [] + } + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "option": { + "ref": { + "name": "EmbeddingUsage", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "option": { + "ref": { + "name": "EmbeddingResponse", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "EmbeddingUsage", + "category": "multimodal", + "source": "aimux-core/src/embedding_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "tokens", + "rust": "tokens", + "type": { + "prim": "u32" + } + } + ] + } + }, + { + "name": "EvaluationAnswer", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Choice", + "wire": "choice", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "choice", + "rust": "choice", + "type": { + "prim": "String" + } + }, + { + "wire": "probabilities", + "rust": "probabilities", + "type": { + "option": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "f64" + } + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Score", + "wire": "score", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "score", + "rust": "score", + "type": { + "prim": "f64" + } + }, + { + "wire": "probabilities", + "rust": "probabilities", + "type": { + "option": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "f64" + } + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Boolean", + "wire": "boolean", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "probability", + "rust": "probability", + "type": { + "prim": "f64" + } + } + ] + } + } + ] + } + }, + { + "name": "EvaluationCallOptions", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "state", + "rust": "state", + "type": { + "ref": { + "name": "EvaluationInput", + "args": [] + } + } + }, + { + "wire": "questions", + "rust": "questions", + "type": { + "codec": { + "rust": "IndexMap", + "wire": "std::collections::HashMap" + } + } + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "EvaluationInput", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Text", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Object", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "JsonObject", + "args": [] + } + } + } + }, + { + "rust": "Array", + "shape": { + "kind": "newtype", + "inner": { + "array": "json" + } + } + } + ] + } + }, + { + "name": "EvaluationQuestion", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Choice", + "wire": "choice", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "instructions", + "rust": "instructions", + "type": { + "ref": { + "name": "EvaluationInput", + "args": [] + } + } + }, + { + "wire": "criteria", + "rust": "criteria", + "type": { + "codec": { + "rust": "IndexMap>", + "wire": "std::collections::HashMap>" + } + } + } + ] + } + }, + { + "rust": "Score", + "wire": "score", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "instructions", + "rust": "instructions", + "type": { + "ref": { + "name": "EvaluationInput", + "args": [] + } + } + }, + { + "wire": "criteria", + "rust": "criteria", + "type": { + "array": { + "option": { + "ref": { + "name": "EvaluationInput", + "args": [] + } + } + } + } + } + ] + } + }, + { + "rust": "Boolean", + "wire": "boolean", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "instructions", + "rust": "instructions", + "type": { + "ref": { + "name": "EvaluationInput", + "args": [] + } + } + }, + { + "wire": "criteria", + "rust": "criteria", + "type": { + "option": { + "ref": { + "name": "BooleanCriteria", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "EvaluationQuestionType", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Choice", + "wire": "choice", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Score", + "wire": "score", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Boolean", + "wire": "boolean", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "EvaluationResult", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "answers", + "rust": "answers", + "type": { + "codec": { + "rust": "IndexMap", + "wire": "std::collections::HashMap" + } + } + }, + { + "wire": "rounding", + "rust": "rounding", + "type": { + "option": { + "ref": { + "name": "EvaluationRounding", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "option": { + "ref": { + "name": "EvaluationUsage", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "option": { + "ref": { + "name": "ResponseInfo", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "EvaluationRounding", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "probabilityDecimals", + "rust": "probability_decimals", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "scoreDecimals", + "rust": "score_decimals", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "EvaluationUsage", + "category": "core", + "source": "aimux-core/src/evaluation_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "inputTokens", + "rust": "input_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "outputTokens", + "rust": "output_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "FileBytes", + "category": "core", + "source": "aimux-core/src/shared.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Binary", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "prim": "u8" + } + } + } + }, + { + "rust": "Base64", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + } + ] + } + }, + { + "name": "FileData", + "category": "core", + "source": "aimux-core/src/shared.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Data", + "wire": "data", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "FileBytes", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Url", + "wire": "url", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "originalUrl", + "rust": "original_url", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Reference", + "wire": "reference", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "reference", + "rust": "reference", + "type": { + "ref": { + "name": "SharedProviderReference", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + } + ] + } + } + ] + } + }, + { + "name": "FilePart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "FileData", + "args": [] + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "filename", + "rust": "filename", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "Fingerprint", + "category": "recording", + "source": "aimux-core/src/trace/fingerprint.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "bodyHash", + "rust": "body_hash", + "type": { + "prim": "String" + } + }, + { + "wire": "lenBytes", + "rust": "len_bytes", + "type": { + "prim": "u64" + } + }, + { + "wire": "blockSize", + "rust": "block_size", + "type": { + "prim": "u64" + } + }, + { + "wire": "blockHashes", + "rust": "block_hashes", + "type": { + "array": { + "prim": "String" + } + } + }, + { + "wire": "tokenEstimate", + "rust": "token_estimate", + "type": { + "prim": "u64" + } + } + ] + } + }, + { + "name": "FinishReason", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "unified", + "rust": "unified", + "type": { + "ref": { + "name": "FinishReasonUnified", + "args": [] + } + } + }, + { + "wire": "raw", + "rust": "raw", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "FinishReasonUnified", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Stop", + "wire": "stop", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Length", + "wire": "length", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ContentFilter", + "wire": "content-filter", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ToolCalls", + "wire": "tool-calls", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Error", + "wire": "error", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Other", + "wire": "other", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "FunctionTool", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "name", + "rust": "name", + "type": { + "prim": "String" + } + }, + { + "wire": "description", + "rust": "description", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "inputSchema", + "rust": "input_schema", + "type": "json" + }, + { + "wire": "strict", + "rust": "strict", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "inputExamples", + "rust": "input_examples", + "type": { + "option": { + "array": { + "ref": { + "name": "FunctionToolInputExample", + "args": [] + } + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "FunctionToolInputExample", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "input", + "rust": "input", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": "json" + } + } + } + ] + } + }, + { + "name": "GenerateContent", + "category": "core", + "source": "aimux-core/src/result.rs", + "generics": [ + "C", + "A", + "R" + ], + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolCall", + "wire": "tool-call", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "C", + "args": [] + } + } + } + }, + { + "rust": "Source", + "wire": "source", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "Source", + "args": [] + } + } + } + }, + { + "rust": "Reasoning", + "wire": "reasoning", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ReasoningOutput", + "args": [] + } + } + } + }, + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "GeneratedFile", + "args": [] + } + } + } + }, + { + "rust": "ReasoningFile", + "wire": "reasoning-file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "R", + "args": [] + } + } + } + }, + { + "rust": "Custom", + "wire": "custom", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "kind", + "rust": "kind", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolApprovalRequest", + "wire": "tool-approval-request", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "A", + "args": [] + } + } + } + }, + { + "rust": "ToolResult", + "wire": "tool-result", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolResult", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "GenerateObjectResult", + "category": "core", + "source": "aimux-core/src/generate.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "object", + "rust": "object", + "type": "json" + }, + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "ref": { + "name": "FinishReason", + "args": [] + } + } + }, + { + "wire": "rawFinishReason", + "rust": "raw_finish_reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + } + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "reasoning", + "rust": "reasoning", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "ResponseMetadata", + "args": [] + } + }, + "default": true + }, + { + "wire": "raw", + "rust": "raw", + "type": { + "ref": { + "name": "GenerateTextResult", + "args": [] + } + } + } + ] + } + }, + { + "name": "GenerateResult", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "content", + "rust": "content", + "type": { + "array": { + "ref": { + "name": "GenerateContent", + "args": [] + } + } + } + }, + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "ref": { + "name": "FinishReason", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + } + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "request", + "rust": "request", + "type": { + "option": { + "ref": { + "name": "RequestInfo", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "option": { + "ref": { + "name": "ResponseInfo", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "GenerateTextOptions", + "category": "core", + "source": "aimux-core/src/generate.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "maxOutputTokens", + "rust": "max_output_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "temperature", + "rust": "temperature", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "stopSequences", + "rust": "stop_sequences", + "type": { + "option": { + "array": { + "prim": "String" + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "topP", + "rust": "top_p", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "topK", + "rust": "top_k", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "presencePenalty", + "rust": "presence_penalty", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "frequencyPenalty", + "rust": "frequency_penalty", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "responseFormat", + "rust": "response_format", + "type": { + "option": { + "ref": { + "name": "ResponseFormat", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "seed", + "rust": "seed", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "tools", + "rust": "tools", + "type": { + "option": { + "array": { + "ref": { + "name": "Tool", + "args": [] + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "toolChoice", + "rust": "tool_choice", + "type": { + "option": { + "ref": { + "name": "ToolChoice", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "String" + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "reasoning", + "rust": "reasoning", + "type": { + "option": { + "ref": { + "name": "ReasoningEffort", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "instructions", + "rust": "instructions", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "sessionId", + "rust": "session_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "includeRawChunks", + "rust": "include_raw_chunks", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "GenerateTextResult", + "category": "core", + "source": "aimux-core/src/generate.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "content", + "rust": "content", + "type": { + "array": { + "ref": { + "name": "TextContent", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "toolCalls", + "rust": "tool_calls", + "type": { + "array": { + "ref": { + "name": "ToolCall", + "args": [] + } + } + } + }, + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "ref": { + "name": "FinishReason", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + } + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "raw", + "rust": "raw", + "type": { + "ref": { + "name": "GenerateResult", + "args": [] + } + } + }, + { + "wire": "reasoning", + "rust": "reasoning", + "type": { + "array": { + "ref": { + "name": "ReasoningPart", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "reasoningText", + "rust": "reasoning_text", + "type": { + "prim": "String" + }, + "default": true + }, + { + "wire": "sources", + "rust": "sources", + "type": { + "array": { + "ref": { + "name": "Source", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "files", + "rust": "files", + "type": { + "array": { + "ref": { + "name": "GeneratedFile", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "responseMessages", + "rust": "response_messages", + "type": { + "array": { + "ref": { + "name": "ModelMessage", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "rawFinishReason", + "rust": "raw_finish_reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "request", + "rust": "request", + "type": { + "ref": { + "name": "RequestInfo", + "args": [] + } + }, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "ResponseInfo", + "args": [] + } + }, + "default": true + }, + { + "wire": "totalUsage", + "rust": "total_usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + }, + "default": true + } + ] + } + }, + { + "name": "GeneratedFile", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "GeneratedFileData", + "args": [] + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "GeneratedFileData", + "category": "core", + "source": "aimux-core/src/shared.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Data", + "wire": "data", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "FileBytes", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Url", + "wire": "url", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "originalUrl", + "rust": "original_url", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "HttpExchange", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "step", + "rust": "step", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "attempt", + "rust": "attempt", + "type": { + "prim": "u32" + } + }, + { + "wire": "exchangeIndex", + "rust": "exchange_index", + "type": { + "prim": "u32" + }, + "default": true + }, + { + "wire": "request", + "rust": "request", + "type": { + "ref": { + "name": "HttpRecord", + "args": [] + } + } + }, + { + "wire": "response", + "rust": "response", + "type": { + "option": { + "ref": { + "name": "ResponseRecord", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timing", + "rust": "timing", + "type": { + "ref": { + "name": "TimingRecord", + "args": [] + } + } + }, + { + "wire": "error", + "rust": "error", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "finalized", + "rust": "finalized", + "type": { + "prim": "bool" + }, + "default": true + } + ] + } + }, + { + "name": "HttpRecord", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "method", + "rust": "method", + "type": { + "prim": "String" + } + }, + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "array": { + "tuple": [ + { + "prim": "String" + }, + { + "prim": "String" + } + ] + } + } + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ImageCallOptions", + "category": "multimodal", + "source": "aimux-core/src/image_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "prompt", + "rust": "prompt", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "n", + "rust": "n", + "type": { + "prim": "u32" + } + }, + { + "wire": "size", + "rust": "size", + "type": { + "option": { + "ref": { + "name": "Size", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "aspectRatio", + "rust": "aspect_ratio", + "type": { + "option": { + "ref": { + "name": "AspectRatio", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "seed", + "rust": "seed", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "files", + "rust": "files", + "type": { + "option": { + "array": { + "ref": { + "name": "ImageFile", + "args": [] + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "mask", + "rust": "mask", + "type": { + "option": { + "ref": { + "name": "ImageFile", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ImageFile", + "category": "multimodal", + "source": "aimux-core/src/image_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "ImageFileData", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Url", + "wire": "url", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + } + ] + } + } + ] + } + }, + { + "name": "ImageFileData", + "category": "multimodal", + "source": "aimux-core/src/image_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Base64", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Binary", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "prim": "u8" + } + } + } + } + ] + } + }, + { + "name": "ImageOutputs", + "category": "multimodal", + "source": "aimux-core/src/image_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Base64", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "prim": "String" + } + } + } + }, + { + "rust": "Binary", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "array": { + "prim": "u8" + } + } + } + } + } + ] + } + }, + { + "name": "ImageResponse", + "category": "multimodal", + "source": "aimux-core/src/image_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ImageResult", + "category": "multimodal", + "source": "aimux-core/src/image_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "images", + "rust": "images", + "type": { + "ref": { + "name": "ImageOutputs", + "args": [] + } + } + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "ImageResponse", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "option": { + "ref": { + "name": "ImageUsage", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ImageUsage", + "category": "multimodal", + "source": "aimux-core/src/image_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "inputTokens", + "rust": "input_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "outputTokens", + "rust": "output_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "totalTokens", + "rust": "total_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "InputAudioFormat", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "formatType", + "rust": "format_type", + "type": { + "prim": "String" + } + }, + { + "wire": "rate", + "rust": "rate", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "InputRecord", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "decisionCapabilities", + "rust": "decision_capabilities", + "type": { + "option": { + "ref": { + "name": "DecisionCapabilities", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "operation", + "rust": "operation", + "type": { + "ref": { + "name": "RecordingOperation", + "args": [] + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "prompt", + "rust": "prompt", + "type": { + "ref": { + "name": "LanguageModelPrompt", + "args": [] + } + } + }, + { + "wire": "options", + "rust": "options", + "type": "json" + } + ] + } + }, + { + "name": "InputTokenUsage", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "total", + "rust": "total", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "noCache", + "rust": "no_cache", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "cacheRead", + "rust": "cache_read", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "cacheWrite", + "rust": "cache_write", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "LanguageModelMessage", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "role" + }, + "variants": [ + { + "rust": "System", + "wire": "system", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "content", + "rust": "content", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "User", + "wire": "user", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "content", + "rust": "content", + "type": { + "array": { + "ref": { + "name": "UserPart", + "args": [] + } + } + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Assistant", + "wire": "assistant", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "content", + "rust": "content", + "type": { + "array": { + "ref": { + "name": "AssistantPart", + "args": [] + } + } + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Tool", + "wire": "tool", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "content", + "rust": "content", + "type": { + "array": { + "ref": { + "name": "ToolPart", + "args": [] + } + } + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "MessageContent", + "category": "user", + "source": "aimux-core/src/message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Text", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Parts", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "ref": { + "name": "ContentPart", + "args": [] + } + } + } + } + } + ] + } + }, + { + "name": "Modality", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Text", + "wire": "Text", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Image", + "wire": "Image", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Audio", + "wire": "Audio", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Video", + "wire": "Video", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Pdf", + "wire": "Pdf", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Embedding", + "wire": "Embedding", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Score", + "wire": "Score", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Other", + "wire": "Other", + "other": true, + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "ModelCapabilities", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCall", + "rust": "tool_call", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "structuredOutput", + "rust": "structured_output", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "temperature", + "rust": "temperature", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "attachment", + "rust": "attachment", + "type": { + "prim": "bool" + }, + "default": true + } + ] + } + }, + { + "name": "ModelCost", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "input", + "rust": "input", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "output", + "rust": "output", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "cacheRead", + "rust": "cache_read", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "cacheWrite", + "rust": "cache_write", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ModelId", + "category": "provider", + "source": "aimux-core/src/model_id.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "provider", + "rust": "provider", + "type": { + "prim": "String" + } + }, + { + "wire": "model", + "rust": "model", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "name": "ModelLimits", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "context", + "rust": "context", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "output", + "rust": "output", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "input", + "rust": "input", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ModelMessage", + "category": "user", + "source": "aimux-core/src/message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "role", + "rust": "role", + "type": { + "ref": { + "name": "Role", + "args": [] + } + } + }, + { + "wire": "content", + "rust": "content", + "type": { + "ref": { + "name": "MessageContent", + "args": [] + } + } + } + ] + } + }, + { + "name": "ModelModalities", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "input", + "rust": "input", + "type": { + "array": { + "ref": { + "name": "Modality", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "output", + "rust": "output", + "type": { + "array": { + "ref": { + "name": "Modality", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ModelPrompt", + "category": "user", + "source": "aimux-core/src/message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Text", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Messages", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "ref": { + "name": "ModelMessage", + "args": [] + } + } + } + } + } + ] + } + }, + { + "name": "ModelSpec", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "displayName", + "rust": "display_name", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "type", + "rust": "type", + "type": { + "ref": { + "name": "ModelType", + "args": [] + } + }, + "default": true + }, + { + "wire": "limits", + "rust": "limits", + "type": { + "ref": { + "name": "ModelLimits", + "args": [] + } + }, + "default": true + }, + { + "wire": "modalities", + "rust": "modalities", + "type": { + "ref": { + "name": "ModelModalities", + "args": [] + } + }, + "default": true + }, + { + "wire": "capabilities", + "rust": "capabilities", + "type": { + "ref": { + "name": "ModelCapabilities", + "args": [] + } + }, + "default": true + }, + { + "wire": "reasoning", + "rust": "reasoning", + "type": { + "option": { + "ref": { + "name": "ReasoningSpec", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "cost", + "rust": "cost", + "type": { + "option": { + "ref": { + "name": "ModelCost", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "source", + "rust": "source", + "type": { + "ref": { + "name": "CatalogueSource", + "args": [] + } + }, + "default": true + }, + { + "wire": "provider", + "rust": "provider", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "raw", + "rust": "raw", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ModelType", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Chat", + "wire": "Chat", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Completion", + "wire": "Completion", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Embedding", + "wire": "Embedding", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Rerank", + "wire": "Rerank", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ImageGen", + "wire": "ImageGen", + "aliases": [ + "image-generation", + "imageGeneration" + ], + "shape": { + "kind": "unit" + } + }, + { + "rust": "ImageEdit", + "wire": "ImageEdit", + "aliases": [ + "image-edit" + ], + "shape": { + "kind": "unit" + } + }, + { + "rust": "Video", + "wire": "Video", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Audio", + "wire": "Audio", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Other", + "wire": "Other", + "other": true, + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "OutcomeRecord", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "decisionResult", + "rust": "decision_result", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "status", + "rust": "status", + "type": { + "ref": { + "name": "OutcomeStatus", + "args": [] + } + } + }, + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "error", + "rust": "error", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "errorValue", + "rust": "error_value", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "OutcomeStatus", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Pending", + "wire": "pending", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Success", + "wire": "success", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Error", + "wire": "error", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Incomplete", + "wire": "incomplete", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Cancelled", + "wire": "cancelled", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "OutputTokenUsage", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "total", + "rust": "total", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "text", + "rust": "text", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "reasoning", + "rust": "reasoning", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "PrefixBreak", + "category": "recording", + "source": "aimux-core/src/trace/store.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "atRecordId", + "rust": "at_record_id", + "type": { + "prim": "String" + } + }, + { + "wire": "prevRecordId", + "rust": "prev_record_id", + "type": { + "prim": "String" + } + }, + { + "wire": "lcpBytes", + "rust": "lcp_bytes", + "type": { + "prim": "u64" + } + }, + { + "wire": "expectedBreak", + "rust": "expected_break", + "type": { + "prim": "bool" + } + }, + { + "wire": "kind", + "rust": "kind", + "type": { + "ref": { + "name": "BreakKind", + "args": [] + } + } + } + ] + } + }, + { + "name": "PromptTokensDetails", + "category": "core", + "source": "aimux-core/src/openai_output.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "cached_tokens", + "rust": "cached_tokens", + "type": { + "prim": "u32" + } + }, + { + "wire": "cache_write_tokens", + "rust": "cache_write_tokens", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true + } + ] + } + }, + { + "name": "ProviderAuditSpec", + "category": "recording", + "source": "aimux-core/src/trace/verdict.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "family", + "rust": "family", + "type": { + "ref": { + "name": "ProviderFamily", + "args": [] + } + } + }, + { + "wire": "gran", + "rust": "gran", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "threshold", + "rust": "threshold", + "type": { + "prim": "u64" + } + }, + { + "wire": "ttlMs", + "rust": "ttl_ms", + "type": { + "prim": "u64" + } + }, + { + "wire": "model56plus", + "rust": "model56plus", + "type": { + "prim": "bool" + } + }, + { + "wire": "sharedCeilingMult", + "rust": "shared_ceiling_mult", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ProviderFamily", + "category": "recording", + "source": "aimux-core/src/trace/verdict.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "OpenAi", + "wire": "OpenAi", + "shape": { + "kind": "unit" + } + }, + { + "rust": "DeepSeek", + "wire": "DeepSeek", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Anthropic", + "wire": "Anthropic", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Bedrock", + "wire": "Bedrock", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Gemini", + "wire": "Gemini", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Vllm", + "wire": "Vllm", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Generic", + "wire": "Generic", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "ProviderRecord", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "providerId", + "rust": "provider_id", + "type": { + "prim": "String" + } + }, + { + "wire": "provider", + "rust": "provider", + "type": { + "prim": "String" + } + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "prim": "String" + } + }, + { + "wire": "baseUrl", + "rust": "base_url", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "apiKeySource", + "rust": "api_key_source", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "profile", + "rust": "profile", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ProviderTool", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "name", + "rust": "name", + "type": { + "prim": "String" + } + }, + { + "wire": "args", + "rust": "args", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": "json" + } + } + } + ] + } + }, + { + "name": "RawToolApprovalRequest", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "approvalId", + "rust": "approval_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "RawToolCall", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "input", + "rust": "input", + "type": { + "prim": "String" + } + }, + { + "wire": "providerExecuted", + "rust": "provider_executed", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "dynamic", + "rust": "dynamic", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ReasoningEffort", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "ProviderDefault", + "wire": "provider-default", + "shape": { + "kind": "unit" + } + }, + { + "rust": "None", + "wire": "none", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Minimal", + "wire": "minimal", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Low", + "wire": "low", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Medium", + "wire": "medium", + "shape": { + "kind": "unit" + } + }, + { + "rust": "High", + "wire": "high", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Xhigh", + "wire": "xhigh", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "ReasoningFileOutput", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "file", + "rust": "file", + "type": { + "ref": { + "name": "GeneratedFile", + "args": [] + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ReasoningFilePart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "GeneratedFileData", + "args": [] + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ReasoningMode", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Budget", + "wire": "Budget", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Effort", + "wire": "Effort", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Level", + "wire": "Level", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Fixed", + "wire": "Fixed", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Mixed", + "wire": "Mixed", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Toggle", + "wire": "Toggle", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Other", + "wire": "Other", + "other": true, + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "ReasoningOutput", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ReasoningPart", + "tsName": "LanguageModelReasoningPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ReasoningPart", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "reasoning", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ReasoningOutput", + "args": [] + } + } + } + }, + { + "rust": "File", + "wire": "reasoning-file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ReasoningFileOutput", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "ReasoningSpec", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "supported", + "rust": "supported", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "defaultEnabled", + "rust": "default_enabled", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "mode", + "rust": "mode", + "type": { + "option": { + "ref": { + "name": "ReasoningMode", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "effortDefault", + "rust": "effort_default", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "effortOptions", + "rust": "effort_options", + "type": { + "array": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "budgetMin", + "rust": "budget_min", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "interleaved", + "rust": "interleaved", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "visibility", + "rust": "visibility", + "type": { + "option": { + "ref": { + "name": "ReasoningVisibility", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ReasoningVisibility", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Hidden", + "wire": "Hidden", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Summary", + "wire": "Summary", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Full", + "wire": "Full", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Mixed", + "wire": "Mixed", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Omitted", + "wire": "Omitted", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Other", + "wire": "Other", + "other": true, + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "Recording", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "schema", + "rust": "schema", + "type": { + "prim": "u32" + }, + "serdeWith": "deserialize_with=deserialize_current_schema", + "codec": { + "name": "currentRecordingSchema", + "wire": "u32; decode accepts only RECORDING_SCHEMA and rejects any other value" + } + }, + { + "wire": "callId", + "rust": "call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "recordedAt", + "rust": "recorded_at", + "type": { + "prim": "String" + } + }, + { + "wire": "input", + "rust": "input", + "type": { + "ref": { + "name": "InputRecord", + "args": [] + } + } + }, + { + "wire": "provider", + "rust": "provider", + "type": { + "ref": { + "name": "ProviderRecord", + "args": [] + } + } + }, + { + "wire": "exchanges", + "rust": "exchanges", + "type": { + "array": { + "ref": { + "name": "HttpExchange", + "args": [] + } + } + } + }, + { + "wire": "outcome", + "rust": "outcome", + "type": { + "ref": { + "name": "OutcomeRecord", + "args": [] + } + } + }, + { + "wire": "complete", + "rust": "complete", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "transportClosed", + "rust": "transport_closed", + "type": { + "prim": "bool" + }, + "default": true + }, + { + "wire": "sessionId", + "rust": "session_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "step", + "rust": "step", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "RecordingOperation", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "LanguageModel", + "wire": "language_model", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Decision", + "wire": "decision", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "RequestCacheHints", + "category": "recording", + "source": "aimux-core/src/trace/record.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "requestedWrite", + "rust": "requested_write", + "type": { + "prim": "bool" + } + } + ] + } + }, + { + "name": "RequestInfo", + "category": "core", + "source": "aimux-core/src/shared.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "RerankingCallOptions", + "category": "core", + "source": "aimux-core/src/reranking_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "documents", + "rust": "documents", + "type": { + "ref": { + "name": "RerankingDocuments", + "args": [] + } + } + }, + { + "wire": "query", + "rust": "query", + "type": { + "prim": "String" + } + }, + { + "wire": "topN", + "rust": "top_n", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "RerankingDocuments", + "category": "core", + "source": "aimux-core/src/reranking_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "values", + "rust": "values", + "type": { + "array": { + "prim": "String" + } + } + } + ] + } + }, + { + "rust": "Object", + "wire": "object", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "values", + "rust": "values", + "type": { + "array": "json" + } + } + ] + } + } + ] + } + }, + { + "name": "RerankingRank", + "category": "core", + "source": "aimux-core/src/reranking_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "index", + "rust": "index", + "type": { + "prim": "u32" + } + }, + { + "wire": "relevanceScore", + "rust": "relevance_score", + "type": { + "prim": "f64" + } + } + ] + } + }, + { + "name": "RerankingResponse", + "category": "core", + "source": "aimux-core/src/reranking_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "RerankingResult", + "category": "core", + "source": "aimux-core/src/reranking_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "ranking", + "rust": "ranking", + "type": { + "array": { + "ref": { + "name": "RerankingRank", + "args": [] + } + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "option": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "option": { + "ref": { + "name": "RerankingResponse", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ResponseFormat", + "category": "user", + "source": "aimux-core/src/options.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Json", + "wire": "json", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "schema", + "rust": "schema", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "name", + "rust": "name", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "description", + "rust": "description", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "ResponseInfo", + "category": "core", + "source": "aimux-core/src/shared.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ResponseMetadata", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ResponseRecord", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "status", + "rust": "status", + "type": { + "prim": "u16" + } + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "array": { + "tuple": [ + { + "prim": "String" + }, + { + "prim": "String" + } + ] + } + } + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "streamChunks", + "rust": "stream_chunks", + "type": { + "option": { + "prim": "usize" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "ttfbMs", + "rust": "ttfb_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "RetryError", + "category": "error", + "source": "aimux-core/src/error.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "reason", + "rust": "reason", + "type": { + "ref": { + "name": "RetryErrorReason", + "args": [] + } + } + }, + { + "wire": "errors", + "rust": "errors", + "type": { + "array": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "RetryErrorReason", + "category": "error", + "source": "aimux-core/src/error.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "MaxRetriesExceeded", + "wire": "maxRetriesExceeded", + "shape": { + "kind": "unit" + } + }, + { + "rust": "ErrorNotRetryable", + "wire": "errorNotRetryable", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "Role", + "category": "user", + "source": "aimux-core/src/message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "System", + "wire": "system", + "shape": { + "kind": "unit" + } + }, + { + "rust": "User", + "wire": "user", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Assistant", + "wire": "assistant", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Tool", + "wire": "tool", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "RuntimeModel", + "category": "provider", + "source": "aimux-core/src/model_catalogue.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "ownedBy", + "rust": "owned_by", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "created", + "rust": "created", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SearchCallOptions", + "category": "core", + "source": "aimux-core/src/search_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "query", + "rust": "query", + "type": { + "prim": "String" + } + }, + { + "wire": "maxResults", + "rust": "max_results", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "includeRawContent", + "rust": "include_raw_content", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeRange", + "rust": "time_range", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "includeDomains", + "rust": "include_domains", + "type": { + "option": { + "array": { + "prim": "String" + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "excludeDomains", + "rust": "exclude_domains", + "type": { + "option": { + "array": { + "prim": "String" + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SearchResponse", + "category": "core", + "source": "aimux-core/src/search_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SearchResult", + "category": "core", + "source": "aimux-core/src/search_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "results", + "rust": "results", + "type": { + "array": { + "ref": { + "name": "SearchResultItem", + "args": [] + } + } + } + }, + { + "wire": "answer", + "rust": "answer", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "response", + "rust": "response", + "type": { + "option": { + "ref": { + "name": "SearchResponse", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SearchResultItem", + "category": "core", + "source": "aimux-core/src/search_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "title", + "rust": "title", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "url", + "rust": "url", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "content", + "rust": "content", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "rawContent", + "rust": "raw_content", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "score", + "rust": "score", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SessionCall", + "category": "core", + "source": "aimux-core/src/session.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "callId", + "rust": "call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "step", + "rust": "step", + "type": { + "prim": "u32" + } + }, + { + "wire": "recordedAt", + "rust": "recorded_at", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "name": "SessionChainView", + "category": "recording", + "source": "aimux-core/src/trace/store.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "sessionId", + "rust": "session_id", + "type": { + "prim": "String" + } + }, + { + "wire": "recordIds", + "rust": "record_ids", + "type": { + "array": { + "prim": "String" + } + } + }, + { + "wire": "prefixStability", + "rust": "prefix_stability", + "type": { + "prim": "f64" + } + }, + { + "wire": "breaks", + "rust": "breaks", + "type": { + "array": { + "ref": { + "name": "PrefixBreak", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "SessionSource", + "category": "core", + "source": "aimux-core/src/session.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Explicit", + "wire": "Explicit", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Inferred", + "wire": "Inferred", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "SessionStepStat", + "category": "recording", + "source": "aimux-core/src/trace/store.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "step", + "rust": "step", + "type": { + "prim": "u32" + } + }, + { + "wire": "callId", + "rust": "call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "hitRate", + "rust": "hit_rate", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "verdict", + "rust": "verdict", + "type": { + "option": { + "ref": { + "name": "Verdict", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "error", + "rust": "error", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SessionView", + "category": "core", + "source": "aimux-core/src/session.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "sessionId", + "rust": "session_id", + "type": { + "prim": "String" + } + }, + { + "wire": "source", + "rust": "source", + "type": { + "ref": { + "name": "SessionSource", + "args": [] + } + } + }, + { + "wire": "calls", + "rust": "calls", + "type": { + "array": { + "ref": { + "name": "SessionCall", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "Size", + "category": "core", + "source": "aimux-core/src/shared.rs", + "proxy": { + "into": { + "prim": "String" + }, + "try_from": { + "prim": "String" + } + }, + "tsOverride": "`${number}x${number}`", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "width", + "rust": "width", + "type": { + "prim": "u32" + } + }, + { + "wire": "height", + "rust": "height", + "type": { + "prim": "u32" + } + } + ] + } + }, + { + "name": "SkillFile", + "category": "core", + "source": "aimux-core/src/skills_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "path", + "rust": "path", + "type": { + "prim": "String" + } + }, + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "UploadFileData", + "args": [] + } + } + } + ] + } + }, + { + "name": "Source", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "sourceType" + }, + "variants": [ + { + "rust": "Url", + "wire": "url", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "title", + "rust": "title", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Document", + "wire": "document", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "title", + "rust": "title", + "type": { + "prim": "String" + } + }, + { + "wire": "filename", + "rust": "filename", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "SpeechCallOptions", + "category": "multimodal", + "source": "aimux-core/src/speech_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "voice", + "rust": "voice", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "outputFormat", + "rust": "output_format", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "instructions", + "rust": "instructions", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "speed", + "rust": "speed", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "language", + "rust": "language", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SpeechRequest", + "category": "multimodal", + "source": "aimux-core/src/speech_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SpeechResponse", + "category": "multimodal", + "source": "aimux-core/src/speech_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "SpeechResult", + "category": "multimodal", + "source": "aimux-core/src/speech_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "audio", + "rust": "audio", + "type": { + "ref": { + "name": "AudioData", + "args": [] + } + } + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "request", + "rust": "request", + "type": { + "option": { + "ref": { + "name": "SpeechRequest", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "SpeechResponse", + "args": [] + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "StreamPart", + "category": "core", + "source": "aimux-core/src/stream_part.rs", + "generics": [ + "C", + "A", + "R" + ], + "concrete": { + "A": "RawToolApprovalRequest", + "C": "RawToolCall", + "R": "GeneratedFile" + }, + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "TextStart", + "wire": "text-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "TextDelta", + "wire": "text-delta", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "TextEnd", + "wire": "text-end", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "StreamStart", + "wire": "stream-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + } + ] + } + }, + { + "rust": "Finish", + "wire": "finish", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "ref": { + "name": "FinishReason", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Error", + "wire": "error", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "error", + "rust": "error", + "type": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + } + ] + } + }, + { + "rust": "ToolInputStart", + "wire": "tool-input-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "providerExecuted", + "rust": "provider_executed", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "dynamic", + "rust": "dynamic", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "title", + "rust": "title", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolInputDelta", + "wire": "tool-input-delta", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolInputEnd", + "wire": "tool-input-end", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolCall", + "wire": "tool-call", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "C", + "args": [] + } + } + } + }, + { + "rust": "ToolResult", + "wire": "tool-result", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolResult", + "args": [] + } + } + } + }, + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "GeneratedFile", + "args": [] + } + } + } + }, + { + "rust": "ReasoningFile", + "wire": "reasoning-file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "R", + "args": [] + } + } + } + }, + { + "rust": "Custom", + "wire": "custom", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "kind", + "rust": "kind", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolApprovalRequest", + "wire": "tool-approval-request", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "A", + "args": [] + } + } + } + }, + { + "rust": "ReasoningStart", + "wire": "reasoning-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ReasoningDelta", + "wire": "reasoning-delta", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ReasoningEnd", + "wire": "reasoning-end", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ResponseMetadata", + "wire": "response-metadata", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ResponseMetadata", + "args": [] + } + } + } + }, + { + "rust": "Source", + "wire": "source", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "Source", + "args": [] + } + } + } + }, + { + "rust": "Raw", + "wire": "raw", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "rawValue", + "rust": "raw_value", + "type": "json" + } + ] + } + } + ] + } + }, + { + "name": "StreamResponseInfo", + "category": "core", + "source": "aimux-core/src/shared.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "StreamTextResultAggregated", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "content", + "rust": "content", + "type": { + "array": { + "ref": { + "name": "TextContent", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "reasoning", + "rust": "reasoning", + "type": { + "array": { + "ref": { + "name": "ReasoningPart", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "reasoningText", + "rust": "reasoning_text", + "type": { + "prim": "String" + }, + "default": true + }, + { + "wire": "toolCalls", + "rust": "tool_calls", + "type": { + "array": { + "ref": { + "name": "ToolCall", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "sources", + "rust": "sources", + "type": { + "array": { + "ref": { + "name": "Source", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "files", + "rust": "files", + "type": { + "array": { + "ref": { + "name": "GeneratedFile", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "ref": { + "name": "FinishReason", + "args": [] + } + } + }, + { + "wire": "rawFinishReason", + "rust": "raw_finish_reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + }, + "default": true + }, + { + "wire": "totalUsage", + "rust": "total_usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + }, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + }, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "request", + "rust": "request", + "type": { + "ref": { + "name": "RequestInfo", + "args": [] + } + }, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "ResponseInfo", + "args": [] + } + }, + "default": true + }, + { + "wire": "responseMessages", + "rust": "response_messages", + "type": { + "array": { + "ref": { + "name": "ModelMessage", + "args": [] + } + } + }, + "default": true + } + ] + } + }, + { + "name": "TextContentBinding", + "tsName": "TextContent", + "category": "core", + "source": "aimux-core/src/result.rs", + "tsOverride": "TextContent", + "shape": { + "kind": "handWritten", + "wire": "TextContent" + } + }, + { + "name": "TextPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TextStreamPart", + "category": "core", + "source": "aimux-core/src/stream_part.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "TextStart", + "wire": "text-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "TextDelta", + "wire": "text-delta", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "TextEnd", + "wire": "text-end", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "StreamStart", + "wire": "stream-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + } + ] + } + }, + { + "rust": "Finish", + "wire": "finish", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "ref": { + "name": "FinishReason", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "FinishStep", + "wire": "finish-step", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "finishReason", + "rust": "finish_reason", + "type": { + "ref": { + "name": "FinishReason", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "Usage", + "args": [] + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "ResponseInfo", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Error", + "wire": "error", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "error", + "rust": "error", + "type": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + } + ] + } + }, + { + "rust": "ToolInputStart", + "wire": "tool-input-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "providerExecuted", + "rust": "provider_executed", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "dynamic", + "rust": "dynamic", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "title", + "rust": "title", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolInputDelta", + "wire": "tool-input-delta", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolInputEnd", + "wire": "tool-input-end", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolCall", + "wire": "tool-call", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolCall", + "args": [] + } + } + } + }, + { + "rust": "ToolResult", + "wire": "tool-result", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolResult", + "args": [] + } + } + } + }, + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "GeneratedFile", + "args": [] + } + } + } + }, + { + "rust": "ReasoningFile", + "wire": "reasoning-file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ReasoningFileOutput", + "args": [] + } + } + } + }, + { + "rust": "Custom", + "wire": "custom", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "kind", + "rust": "kind", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ToolApprovalRequest", + "wire": "tool-approval-request", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolApprovalRequestOutput", + "args": [] + } + } + } + }, + { + "rust": "ReasoningStart", + "wire": "reasoning-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ReasoningDelta", + "wire": "reasoning-delta", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ReasoningEnd", + "wire": "reasoning-end", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Source", + "wire": "source", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "Source", + "args": [] + } + } + } + }, + { + "rust": "Raw", + "wire": "raw", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "rawValue", + "rust": "raw_value", + "type": "json" + } + ] + } + } + ] + } + }, + { + "name": "TimeoutConfiguration", + "category": "user", + "source": "aimux-core/src/options.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "totalMs", + "rust": "total_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "stepMs", + "rust": "step_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "firstChunkMs", + "rust": "first_chunk_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "chunkMs", + "rust": "chunk_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TimingRecord", + "category": "recording", + "source": "aimux-core/src/recording.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "latencyMs", + "rust": "latency_ms", + "type": { + "codec": { + "rust": "u64", + "wire": "number" + } + } + }, + { + "wire": "ttfbMs", + "rust": "ttfb_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "Tool", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Function", + "wire": "function", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "FunctionTool", + "args": [] + } + } + } + }, + { + "rust": "Provider", + "wire": "provider", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ProviderTool", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "ToolApprovalRequestOutput", + "category": "core", + "source": "aimux-core/src/result.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "approvalId", + "rust": "approval_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolCall", + "rust": "tool_call", + "type": { + "ref": { + "name": "ToolCall", + "args": [] + } + } + }, + { + "wire": "reason", + "rust": "reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "isAutomatic", + "rust": "is_automatic", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "signature", + "rust": "signature", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ToolApprovalResponsePart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "approvalId", + "rust": "approval_id", + "type": { + "prim": "String" + } + }, + { + "wire": "approved", + "rust": "approved", + "type": { + "prim": "bool" + } + }, + { + "wire": "reason", + "rust": "reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ToolCall", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "input", + "rust": "input", + "type": "json" + }, + { + "wire": "providerExecuted", + "rust": "provider_executed", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "dynamic", + "rust": "dynamic", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "invalid", + "rust": "invalid", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "error", + "rust": "error", + "type": { + "option": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ToolCallPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "input", + "rust": "input", + "type": "json" + }, + { + "wire": "providerExecuted", + "rust": "provider_executed", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ToolCallRepairReply", + "category": "tool", + "source": "aimux-core/src/parse_tool_call.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Repaired", + "wire": "repaired", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCall", + "rust": "tool_call", + "type": { + "ref": { + "name": "RawToolCall", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Unchanged", + "wire": "unchanged", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Failed", + "wire": "failed", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + } + ] + } + }, + { + "name": "ToolChoice", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "tsOverride": "\"auto\" | \"none\" | \"required\" | { type: \"tool\"; toolName: string }", + "shape": { + "kind": "handWritten", + "wire": "\"auto\" | \"none\" | \"required\" | { type: \"tool\"; toolName: string }" + } + }, + { + "name": "ToolPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "ToolResult", + "wire": "tool-result", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolResultPart", + "args": [] + } + } + } + }, + { + "rust": "ToolApprovalResponse", + "wire": "tool-approval-response", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ToolApprovalResponsePart", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "ToolResult", + "category": "tool", + "source": "aimux-core/src/tool.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "result", + "rust": "result", + "type": "json" + }, + { + "wire": "isError", + "rust": "is_error", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "preliminary", + "rust": "preliminary", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "dynamic", + "rust": "dynamic", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "ProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "ToolResultContent", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "TextPart", + "args": [] + } + } + } + }, + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "FilePart", + "args": [] + } + } + } + }, + { + "rust": "Custom", + "wire": "custom", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "ToolResultOutput", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "value", + "rust": "value", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Json", + "wire": "json", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "value", + "rust": "value", + "type": "json" + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ExecutionDenied", + "wire": "execution-denied", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "reason", + "rust": "reason", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ErrorText", + "wire": "error-text", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "value", + "rust": "value", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ErrorJson", + "wire": "error-json", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "value", + "rust": "value", + "type": "json" + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Content", + "wire": "content", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "value", + "rust": "value", + "type": { + "array": { + "ref": { + "name": "ToolResultContent", + "args": [] + } + } + } + } + ] + } + } + ] + } + }, + { + "name": "ToolResultPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "output", + "rust": "output", + "type": { + "ref": { + "name": "ToolResultOutput", + "args": [] + } + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TraceFilter", + "category": "recording", + "source": "aimux-core/src/trace/store.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "provider", + "rust": "provider", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "model", + "rust": "model", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "sessionId", + "rust": "session_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "sinceUnixMs", + "rust": "since_unix_ms", + "type": { + "option": { + "prim": "i64" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TraceRecord", + "category": "recording", + "source": "aimux-core/src/trace/record.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "provider", + "rust": "provider", + "type": { + "prim": "String" + } + }, + { + "wire": "model", + "rust": "model", + "type": { + "prim": "String" + } + }, + { + "wire": "requestId", + "rust": "request_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "sessionId", + "rust": "session_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "callId", + "rust": "call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "sentAtUnixMs", + "rust": "sent_at_unix_ms", + "type": { + "codec": { + "rust": "i64", + "wire": "number" + } + } + }, + { + "wire": "lcpTokenUpper", + "rust": "lcp_token_upper", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "ttftMs", + "rust": "ttft_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "fingerprint", + "rust": "fingerprint", + "type": { + "ref": { + "name": "Fingerprint", + "args": [] + } + } + }, + { + "wire": "usage", + "rust": "usage", + "type": { + "ref": { + "name": "UsageSnapshot", + "args": [] + } + } + }, + { + "wire": "responseCacheHeaders", + "rust": "response_cache_headers", + "type": { + "option": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "String" + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "requestCacheHints", + "rust": "request_cache_hints", + "type": { + "option": { + "ref": { + "name": "RequestCacheHints", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "verdict", + "rust": "verdict", + "type": { + "option": { + "ref": { + "name": "Verdict", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "error", + "rust": "error", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TraceStats", + "category": "recording", + "source": "aimux-core/src/trace/store.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "provider", + "rust": "provider", + "type": { + "prim": "String" + } + }, + { + "wire": "model", + "rust": "model", + "type": { + "prim": "String" + } + }, + { + "wire": "requests", + "rust": "requests", + "type": { + "prim": "u64" + } + }, + { + "wire": "inputTokensTotal", + "rust": "input_tokens_total", + "type": { + "prim": "u64" + } + }, + { + "wire": "claimedCacheReadTotal", + "rust": "claimed_cache_read_total", + "type": { + "prim": "u64" + } + }, + { + "wire": "claimedCacheWriteTotal", + "rust": "claimed_cache_write_total", + "type": { + "prim": "u64" + } + }, + { + "wire": "reportedHitRate", + "rust": "reported_hit_rate", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "clientUpperBoundHitRate", + "rust": "client_upper_bound_hit_rate", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "verdictCounts", + "rust": "verdict_counts", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "u64" + } + } + } + }, + { + "wire": "ttftP50Ms", + "rust": "ttft_p50_ms", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "ttftP95Ms", + "rust": "ttft_p95_ms", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "errors", + "rust": "errors", + "type": { + "prim": "u64" + } + } + ] + } + }, + { + "name": "TranscriptionCallOptions", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "audio", + "rust": "audio", + "type": { + "ref": { + "name": "AudioInput", + "args": [] + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TranscriptionRequest", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "body", + "rust": "body", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TranscriptionResponse", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TranscriptionResult", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "segments", + "rust": "segments", + "type": { + "array": { + "ref": { + "name": "TranscriptionSegment", + "args": [] + } + } + } + }, + { + "wire": "language", + "rust": "language", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "durationInSeconds", + "rust": "duration_in_seconds", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "request", + "rust": "request", + "type": { + "option": { + "ref": { + "name": "TranscriptionRequest", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "TranscriptionResponse", + "args": [] + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "TranscriptionSegment", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "startSecond", + "rust": "start_second", + "type": { + "prim": "f64" + } + }, + { + "wire": "endSecond", + "rust": "end_second", + "type": { + "prim": "f64" + } + } + ] + } + }, + { + "name": "TranscriptionStreamPart", + "category": "multimodal", + "source": "aimux-core/src/transcription_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "StreamStart", + "wire": "stream-start", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + } + ] + } + }, + { + "rust": "TranscriptDelta", + "wire": "transcript-delta", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "delta", + "rust": "delta", + "type": { + "prim": "String" + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "TranscriptPartial", + "wire": "transcript-partial", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "startSecond", + "rust": "start_second", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "durationInSeconds", + "rust": "duration_in_seconds", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "channelIndex", + "rust": "channel_index", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "TranscriptFinal", + "wire": "transcript-final", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "id", + "rust": "id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "startSecond", + "rust": "start_second", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "endSecond", + "rust": "end_second", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "channelIndex", + "rust": "channel_index", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "ResponseMetadata", + "wire": "response-metadata", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "body", + "rust": "body", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Finish", + "wire": "finish", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + }, + { + "wire": "segments", + "rust": "segments", + "type": { + "array": { + "ref": { + "name": "TranscriptionSegment", + "args": [] + } + } + } + }, + { + "wire": "language", + "rust": "language", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "durationInSeconds", + "rust": "duration_in_seconds", + "type": { + "option": { + "prim": "f64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Raw", + "wire": "raw", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "rawValue", + "rust": "raw_value", + "type": "json" + } + ] + } + }, + { + "rust": "Error", + "wire": "error", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "error", + "rust": "error", + "type": "json" + } + ] + } + } + ] + } + }, + { + "name": "UploadFileCallOptions", + "category": "multimodal", + "source": "aimux-core/src/files_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "UploadFileData", + "args": [] + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "filename", + "rust": "filename", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "UploadFileData", + "category": "multimodal", + "source": "aimux-core/src/files_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Data", + "wire": "data", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "FileBytes", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "text", + "rust": "text", + "type": { + "prim": "String" + } + } + ] + } + } + ] + } + }, + { + "name": "UploadFileResult", + "category": "multimodal", + "source": "aimux-core/src/files_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "providerReference", + "rust": "provider_reference", + "type": { + "ref": { + "name": "SharedProviderReference", + "args": [] + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "filename", + "rust": "filename", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "UploadSkillCallOptions", + "category": "core", + "source": "aimux-core/src/skills_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "files", + "rust": "files", + "type": { + "array": { + "ref": { + "name": "SkillFile", + "args": [] + } + } + } + }, + { + "wire": "displayTitle", + "rust": "display_title", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "option": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "UploadSkillResult", + "category": "core", + "source": "aimux-core/src/skills_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "providerReference", + "rust": "provider_reference", + "type": { + "ref": { + "name": "SharedProviderReference", + "args": [] + } + } + }, + { + "wire": "displayTitle", + "rust": "display_title", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "name", + "rust": "name", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "description", + "rust": "description", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "latestVersion", + "rust": "latest_version", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "Usage", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "inputTokens", + "rust": "input_tokens", + "type": { + "ref": { + "name": "InputTokenUsage", + "args": [] + } + } + }, + { + "wire": "outputTokens", + "rust": "output_tokens", + "type": { + "ref": { + "name": "OutputTokenUsage", + "args": [] + } + } + }, + { + "wire": "raw", + "rust": "raw", + "type": { + "codec": { + "rust": "Option>", + "wire": "Record" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "UsageSnapshot", + "category": "recording", + "source": "aimux-core/src/trace/record.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "inputTotal", + "rust": "input_total", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "inputNoCache", + "rust": "input_no_cache", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "cacheRead", + "rust": "cache_read", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "cacheWrite", + "rust": "cache_write", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "outputTotal", + "rust": "output_total", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "outputText", + "rust": "output_text", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "outputReasoning", + "rust": "output_reasoning", + "type": { + "option": { + "prim": "u64" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "raw", + "rust": "raw", + "type": { + "option": "json" + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "UserPart", + "category": "user", + "source": "aimux-core/src/language_model_message.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Text", + "wire": "text", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "TextPart", + "args": [] + } + } + } + }, + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "FilePart", + "args": [] + } + } + } + } + ] + } + }, + { + "name": "Verdict", + "category": "recording", + "source": "aimux-core/src/trace/verdict.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "kind", + "rust": "kind", + "type": { + "ref": { + "name": "VerdictKind", + "args": [] + } + } + }, + { + "wire": "confidence", + "rust": "confidence", + "type": { + "ref": { + "name": "VerdictConfidence", + "args": [] + } + } + }, + { + "wire": "violated", + "rust": "violated", + "type": { + "array": { + "prim": "String" + } + } + }, + { + "wire": "expectedMax", + "rust": "expected_max", + "type": { + "prim": "u64" + } + }, + { + "wire": "claimed", + "rust": "claimed", + "type": { + "prim": "u64" + } + }, + { + "wire": "lcpBytes", + "rust": "lcp_bytes", + "type": { + "prim": "u64" + } + }, + { + "wire": "notes", + "rust": "notes", + "type": { + "array": { + "prim": "String" + } + } + } + ] + } + }, + { + "name": "VerdictConfidence", + "category": "recording", + "source": "aimux-core/src/trace/verdict.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "High", + "wire": "High", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Medium", + "wire": "Medium", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Low", + "wire": "Low", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "VerdictKind", + "category": "recording", + "source": "aimux-core/src/trace/verdict.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "Trusted", + "wire": "Trusted", + "shape": { + "kind": "unit" + } + }, + { + "rust": "SuspectOverclaim", + "wire": "SuspectOverclaim", + "shape": { + "kind": "unit" + } + }, + { + "rust": "SuspectUnderclaim", + "wire": "SuspectUnderclaim", + "shape": { + "kind": "unit" + } + }, + { + "rust": "Unknown", + "wire": "Unknown", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "VideoCallOptions", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "prompt", + "rust": "prompt", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "n", + "rust": "n", + "type": { + "prim": "u32" + }, + "default": true + }, + { + "wire": "aspectRatio", + "rust": "aspect_ratio", + "type": { + "option": { + "ref": { + "name": "AspectRatio", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "resolution", + "rust": "resolution", + "type": { + "option": { + "ref": { + "name": "Size", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "duration", + "rust": "duration", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "fps", + "rust": "fps", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "seed", + "rust": "seed", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "image", + "rust": "image", + "type": { + "option": { + "ref": { + "name": "VideoFile", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "frameImages", + "rust": "frame_images", + "type": { + "option": { + "array": { + "ref": { + "name": "VideoFrameImage", + "args": [] + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "inputReferences", + "rust": "input_references", + "type": { + "option": { + "array": { + "ref": { + "name": "VideoFile", + "args": [] + } + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "generateAudio", + "rust": "generate_audio", + "type": { + "option": { + "prim": "bool" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "providerOptions", + "rust": "provider_options", + "type": { + "ref": { + "name": "SharedProviderOptions", + "args": [] + } + }, + "default": true + }, + { + "wire": "maxRetries", + "rust": "max_retries", + "type": { + "option": { + "prim": "u32" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "poll", + "rust": "poll", + "type": { + "option": { + "ref": { + "name": "VideoPollOptions", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeout", + "rust": "timeout", + "type": { + "option": { + "ref": { + "name": "TimeoutConfiguration", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "VideoData", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Url", + "wire": "url", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "Base64", + "wire": "base64", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "prim": "String" + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "Binary", + "wire": "binary", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "data", + "rust": "data", + "type": { + "array": { + "prim": "u8" + } + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + } + ] + } + } + ] + } + }, + { + "name": "VideoFile", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "File", + "wire": "file", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "prim": "String" + } + }, + { + "wire": "data", + "rust": "data", + "type": { + "ref": { + "name": "VideoFileData", + "args": [] + } + } + } + ] + } + }, + { + "rust": "Url", + "wire": "url", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "url", + "rust": "url", + "type": { + "prim": "String" + } + }, + { + "wire": "mediaType", + "rust": "media_type", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + } + ] + } + }, + { + "name": "VideoFileData", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "untagged" + }, + "variants": [ + { + "rust": "Base64", + "shape": { + "kind": "newtype", + "inner": { + "prim": "String" + } + } + }, + { + "rust": "Binary", + "shape": { + "kind": "newtype", + "inner": { + "array": { + "prim": "u8" + } + } + } + } + ] + } + }, + { + "name": "VideoFrameImage", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "image", + "rust": "image", + "type": { + "ref": { + "name": "VideoFile", + "args": [] + } + } + }, + { + "wire": "frameType", + "rust": "frame_type", + "type": { + "ref": { + "name": "VideoFrameType", + "args": [] + } + } + } + ] + } + }, + { + "name": "VideoFrameType", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "external" + }, + "variants": [ + { + "rust": "FirstFrame", + "wire": "first_frame", + "shape": { + "kind": "unit" + } + }, + { + "rust": "LastFrame", + "wire": "last_frame", + "shape": { + "kind": "unit" + } + } + ] + } + }, + { + "name": "VideoPollOptions", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "intervalMs", + "rust": "interval_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "timeoutMs", + "rust": "timeout_ms", + "type": { + "codec": { + "rust": "Option", + "wire": "number" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "VideoResponse", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "timestamp", + "rust": "timestamp", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "headers", + "rust": "headers", + "type": { + "option": { + "ref": { + "name": "SharedHeaders", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "name": "VideoResult", + "category": "multimodal", + "source": "aimux-core/src/video_model.rs", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "videos", + "rust": "videos", + "type": { + "array": { + "ref": { + "name": "VideoData", + "args": [] + } + } + } + }, + { + "wire": "warnings", + "rust": "warnings", + "type": { + "array": { + "ref": { + "name": "Warning", + "args": [] + } + } + } + }, + { + "wire": "providerMetadata", + "rust": "provider_metadata", + "type": { + "option": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "response", + "rust": "response", + "type": { + "ref": { + "name": "VideoResponse", + "args": [] + } + } + } + ] + } + }, + { + "name": "Warning", + "category": "core", + "source": "aimux-core/src/types.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "type" + }, + "variants": [ + { + "rust": "Unsupported", + "wire": "unsupported", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "feature", + "rust": "feature", + "type": { + "prim": "String" + } + }, + { + "wire": "details", + "rust": "details", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Compatibility", + "wire": "compatibility", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "feature", + "rust": "feature", + "type": { + "prim": "String" + } + }, + { + "wire": "details", + "rust": "details", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "Deprecated", + "wire": "deprecated", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "setting", + "rust": "setting", + "type": { + "prim": "String" + } + }, + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "Other", + "wire": "other", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + } + ] + } + } + ], + "auxiliaryTypes": [ + { + "name": "AiMuxErrorWire", + "category": "error", + "source": "aimux-core/src/error.rs", + "shape": { + "kind": "enum", + "representation": { + "style": "internal", + "tag": "name" + }, + "variants": [ + { + "rust": "ApiCall", + "wire": "AI_APICallError", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "ApiCallError", + "args": [] + } + } + } + }, + { + "rust": "Retry", + "wire": "AI_RetryError", + "shape": { + "kind": "newtype", + "inner": { + "ref": { + "name": "RetryError", + "args": [] + } + } + } + }, + { + "rust": "JsonParse", + "wire": "AI_JSONParseError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "NoOutputGenerated", + "wire": "AI_NoOutputGeneratedError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "InvalidResponseData", + "wire": "AI_InvalidResponseDataError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "ToolCallNotFoundForApproval", + "wire": "AI_ToolCallNotFoundForApprovalError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolCallId", + "rust": "tool_call_id", + "type": { + "prim": "String" + } + }, + { + "wire": "approvalId", + "rust": "approval_id", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "NoSuchTool", + "wire": "AI_NoSuchToolError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "availableTools", + "rust": "available_tools", + "type": { + "option": { + "array": { + "prim": "String" + } + } + }, + "omitWhenEmpty": true, + "default": true + }, + { + "wire": "toolInput", + "rust": "tool_input", + "type": { + "option": { + "prim": "String" + } + }, + "omitWhenEmpty": true, + "default": true + } + ] + } + }, + { + "rust": "InvalidToolInput", + "wire": "AI_InvalidToolInputError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "toolName", + "rust": "tool_name", + "type": { + "prim": "String" + } + }, + { + "wire": "toolInput", + "rust": "tool_input", + "type": { + "prim": "String" + } + }, + { + "wire": "cause", + "rust": "cause", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "ToolCallRepair", + "wire": "AI_ToolCallRepairError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "originalError", + "rust": "original_error", + "type": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + }, + { + "wire": "cause", + "rust": "cause", + "type": { + "ref": { + "name": "AiMuxError", + "args": [] + } + } + } + ] + } + }, + { + "rust": "InvalidArgument", + "wire": "AI_InvalidArgumentError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "InvalidPrompt", + "wire": "AI_InvalidPromptError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "LoadApiKey", + "wire": "AI_LoadAPIKeyError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "envVar", + "rust": "env_var", + "type": { + "prim": "String" + } + }, + { + "wire": "description", + "rust": "description", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "LoadSetting", + "wire": "AI_LoadSettingError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "envVar", + "rust": "env_var", + "type": { + "prim": "String" + } + }, + { + "wire": "settingName", + "rust": "name", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "TokenExpired", + "wire": "AI_TokenExpiredError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "UnsupportedFunctionality", + "wire": "AI_UnsupportedFunctionalityError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "NoSuchModel", + "wire": "AI_NoSuchModelError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "modelId", + "rust": "model_id", + "type": { + "prim": "String" + } + }, + { + "wire": "modelType", + "rust": "model_type", + "type": { + "prim": "String" + }, + "default": true + } + ] + } + }, + { + "rust": "NoSuchProvider", + "wire": "AI_NoSuchProviderError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "providerId", + "rust": "provider_id", + "type": { + "prim": "String" + } + }, + { + "wire": "modelId", + "rust": "model_id", + "type": { + "prim": "String" + } + }, + { + "wire": "modelType", + "rust": "model_type", + "type": { + "prim": "String" + } + }, + { + "wire": "availableProviders", + "rust": "available_providers", + "type": { + "array": { + "prim": "String" + } + } + } + ] + } + }, + { + "rust": "Timeout", + "wire": "TimeoutError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "Aborted", + "wire": "AbortError", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + }, + { + "rust": "Other", + "wire": "AI_Error", + "shape": { + "kind": "struct", + "fields": [ + { + "wire": "message", + "rust": "message", + "type": { + "prim": "String" + } + } + ] + } + } + ] + } + } + ], + "aliases": { + "DecisionState": { + "source": "aimux-core/src/decision_model.rs", + "type": "json" + }, + "Embedding": { + "source": "aimux-core/src/embedding_model.rs", + "type": { + "array": { + "prim": "f32" + } + } + }, + "JsonObject": { + "source": "aimux-core/src/shared.rs", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": "json" + } + } + }, + "LanguageModelPrompt": { + "source": "aimux-core/src/language_model_message.rs", + "type": { + "array": { + "ref": { + "name": "LanguageModelMessage", + "args": [] + } + } + } + }, + "ProviderMetadata": { + "source": "aimux-core/src/types.rs", + "type": { + "ref": { + "name": "SharedProviderMetadata", + "args": [] + } + } + }, + "SharedHeaders": { + "source": "aimux-core/src/shared.rs", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "String" + } + } + } + }, + "SharedProviderMetadata": { + "source": "aimux-core/src/shared.rs", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "ref": { + "name": "JsonObject", + "args": [] + } + } + } + } + }, + "SharedProviderOptions": { + "source": "aimux-core/src/shared.rs", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "ref": { + "name": "JsonObject", + "args": [] + } + } + } + } + }, + "SharedProviderReference": { + "source": "aimux-core/src/shared.rs", + "type": { + "map": { + "key": { + "prim": "String" + }, + "value": { + "prim": "String" + } + } + } + }, + "TextContent": { + "source": "aimux-core/src/result.rs", + "type": { + "ref": { + "name": "GenerateContent", + "args": [ + { + "ref": { + "name": "ToolCall", + "args": [] + } + }, + { + "ref": { + "name": "ToolApprovalRequestOutput", + "args": [] + } + }, + { + "ref": { + "name": "ReasoningFileOutput", + "args": [] + } + } + ] + } + } + } + } +} diff --git a/tools/aimux-codegen/src/extract.rs b/tools/aimux-codegen/src/extract.rs new file mode 100644 index 000000000..ad7174798 --- /dev/null +++ b/tools/aimux-codegen/src/extract.rs @@ -0,0 +1,1134 @@ +//! Type model extracted from the Rust sources (unit 2.1; RFC-0042:200 "Rust +//! types are the protocol source"). Every `#[derive(.., TS, ..)]` item that +//! also carries `#[ts(export ..)]` becomes one [`TypeDef`]. The serde +//! attributes decide the wire shape: field/variant renames, `rename_all`, +//! enum representation (external / `tag` / `tag`+`content` / `untagged`), +//! `skip`, `default`, `skip_serializing_if`, `flatten`, proxies +//! (`from`/`into`/`try_from`). +//! +//! A field type is accepted only when it is a primitive, a known container, +//! opaque JSON, a generic parameter, another exported type, or a registered +//! codec (an explicit `#[ts(type|as = ..)]`, or an entry in [`CODECS`]). +//! Anything else fails generation with `file:line`; it never degrades to +//! `any` (RFC-0042:200). + +use std::collections::{BTreeMap, BTreeSet}; +use std::path::{Path, PathBuf}; + +use quote::ToTokens; +use serde::Serialize; +use syn::spanned::Spanned; +use syn::{Attribute, Fields, GenericArgument, Item, PathArguments, Type}; + +/// Category per source file (planner Q2). Mirrors `CATEGORY_BY_FILE` in +/// `scripts/gen_closure_inventory.py`; the coverage report compares +/// ` ` lines, so the two tables cannot drift apart. +pub const CATEGORY_BY_FILE: &[(&str, &str)] = &[ + ("aimux-core/src/error.rs", "error"), + ("aimux-core/src/recording.rs", "recording"), + ("aimux-core/src/trace/fingerprint.rs", "recording"), + ("aimux-core/src/trace/record.rs", "recording"), + ("aimux-core/src/trace/store.rs", "recording"), + ("aimux-core/src/trace/verdict.rs", "recording"), + ("aimux-core/src/tool.rs", "tool"), + ("aimux-core/src/parse_tool_call.rs", "tool"), + ("aimux-core/src/content.rs", "multimodal"), + ("aimux-core/src/embedding_model.rs", "multimodal"), + ("aimux-core/src/files_model.rs", "multimodal"), + ("aimux-core/src/image_model.rs", "multimodal"), + ("aimux-core/src/speech_model.rs", "multimodal"), + ("aimux-core/src/transcription_model.rs", "multimodal"), + ("aimux-core/src/video_model.rs", "multimodal"), + ("aimux-core/src/model_catalogue.rs", "provider"), + ("aimux-core/src/model_id.rs", "provider"), + ("aimux-core/src/message.rs", "user"), + ("aimux-core/src/language_model_message.rs", "user"), + ("aimux-core/src/options.rs", "user"), +]; + +/// Category for files not in [`CATEGORY_BY_FILE`]. +pub const DEFAULT_CATEGORY: &str = "core"; + +/// Registered codecs for Rust types that are not exported DTOs, by the last +/// path segment. Each one names its wire form; adding a type here is the +/// explicit registration RFC-0042:200 asks for. +pub const CODECS: &[(&str, &str)] = &[]; + +/// A registered codec for a field that uses serde `with` / +/// `deserialize_with` / `serialize_with` without a `#[ts(type)]`. Such a +/// field is accepted only when `(owner, field, serde)` matches an entry here; +/// otherwise generation fails with `file:line`. +#[derive(Debug, Clone, Copy)] +pub struct FieldCodec { + /// Containing type. + pub owner: &'static str, + /// Rust field name (without `r#`). + pub field: &'static str, + /// The serde attribute as `=`. + pub serde: &'static str, + /// Codec id written into the manifest. + pub name: &'static str, + /// Wire contract. + pub wire: &'static str, + /// The field's manifest type becomes [`TypeRef::TriState`] + /// (`Option>` → absent | null | T). + pub tri_state: bool, +} + +/// Field codec registrations (unit 2.1). +pub const FIELD_CODECS: &[FieldCodec] = &[ + // aimux-core/src/recording.rs:73 + FieldCodec { + owner: "Recording", + field: "schema", + serde: "deserialize_with=deserialize_current_schema", + name: "currentRecordingSchema", + wire: "u32; decode accepts only RECORDING_SCHEMA and rejects any other value", + tri_state: false, + }, + // aimux-core/src/evaluation_model.rs:62-73 + FieldCodec { + owner: "BooleanCriteria", + field: "true_", + serde: "deserialize_with=present", + name: "presence", + wire: "absent | null | value: an absent key and an explicit null are distinct", + tri_state: true, + }, + FieldCodec { + owner: "BooleanCriteria", + field: "false_", + serde: "deserialize_with=present", + name: "presence", + wire: "absent | null | value: an absent key and an explicit null are distinct", + tri_state: true, + }, +]; + +/// One exported type. +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct TypeDef { + pub name: String, + /// Name in the current TypeScript export (`#[ts(rename)]`), when it differs. + #[serde(skip_serializing_if = "Option::is_none")] + pub ts_name: Option, + pub category: String, + pub source: String, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub generics: Vec, + /// `#[ts(concrete(..))]` substitutions used by the current export. + #[serde(skip_serializing_if = "BTreeMap::is_empty")] + pub concrete: BTreeMap, + /// `#[serde(from|into|try_from = ..)]`: the wire goes through this type. + #[serde(skip_serializing_if = "BTreeMap::is_empty")] + pub proxy: BTreeMap, + /// `#[ts(as|type = ..)]` on the container. + #[serde(skip_serializing_if = "Option::is_none")] + pub ts_override: Option, + pub shape: Shape, +} + +/// Wire shape of a type. +#[derive(Debug, Clone, Serialize)] +#[serde(tag = "kind", rename_all = "camelCase")] +pub enum Shape { + #[serde(rename_all = "camelCase")] + Struct { + fields: Vec, + #[serde(skip_serializing_if = "std::ops::Not::not")] + deny_unknown_fields: bool, + }, + /// Tuple struct with one field: the wire is the inner value. + Newtype { + inner: TypeRef, + }, + Tuple { + items: Vec, + }, + Unit, + /// serde is implemented by hand (no `derive(Serialize/Deserialize)`): + /// the wire is the declared `#[ts(type|as)]` codec only. + HandWritten { + wire: String, + }, + /// Discriminated or untagged union. + #[serde(rename_all = "camelCase")] + Enum { + representation: Representation, + variants: Vec, + }, +} + +/// serde enum representation. +#[derive(Debug, Clone, Serialize)] +#[serde(tag = "style", rename_all = "camelCase")] +pub enum Representation { + External, + Internal { tag: String }, + Adjacent { tag: String, content: String }, + Untagged, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct VariantDef { + pub rust: String, + /// Discriminator value on the wire (absent for untagged). + #[serde(skip_serializing_if = "Option::is_none")] + pub wire: Option, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub aliases: Vec, + /// `#[serde(other)]` catch-all. + #[serde(skip_serializing_if = "std::ops::Not::not")] + pub other: bool, + pub shape: Shape, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct FieldDef { + pub wire: String, + pub rust: String, + #[serde(rename = "type")] + pub ty: TypeRef, + /// May be absent on the wire when serialized (`skip_serializing_if`). + #[serde(skip_serializing_if = "std::ops::Not::not")] + pub omit_when_empty: bool, + /// Absent on input is accepted (`default`). + #[serde(skip_serializing_if = "std::ops::Not::not")] + pub default: bool, + #[serde(skip_serializing_if = "std::ops::Not::not")] + pub flatten: bool, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub aliases: Vec, + /// `#[serde(with|deserialize_with|serialize_with = ..)]` custom codec. + #[serde(skip_serializing_if = "Option::is_none")] + pub serde_with: Option, + /// Registered [`FieldCodec`] for a `serde_with` field. + #[serde(skip_serializing_if = "Option::is_none")] + pub codec: Option, +} + +/// The registered codec used by a field. +#[derive(Debug, Clone, Serialize)] +pub struct FieldCodecRef { + pub name: String, + pub wire: String, +} + +/// A field type. +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum TypeRef { + Prim(String), + Json, + Option(Box), + Array(Box), + Map { + key: Box, + value: Box, + }, + Tuple(Vec), + Ref { + name: String, + args: Vec, + }, + Generic(String), + /// Explicit codec: Rust type text plus its declared wire form. + Codec { + rust: String, + wire: String, + }, + /// Three wire states: key absent, explicit `null`, or a value of the + /// inner type (Rust `Option>` with a presence codec). + TriState(Box), +} + +const PRIMS: &[&str] = &[ + "String", "str", "bool", "char", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", + "i32", "i64", "i128", "isize", "f32", "f64", +]; + +/// Raw item before reference resolution. +struct Found { + def: TypeDef, + line: usize, + exported: bool, +} + +/// A non-generic `type X = ..;` alias referenced by DTO fields. +#[derive(Debug, Clone, Serialize)] +pub struct AliasDef { + pub source: String, + #[serde(rename = "type")] + pub ty: TypeRef, +} + +/// Everything extracted from the sources. +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Model { + /// `#[ts(export)]` types: the coverage set. + pub types: Vec, + /// `derive(TS)` types without export that an exported type reaches + /// (e.g. the `AiMuxError` wire proxy). Listed in the + /// `[derive-ts-without-export]` section of closure-dtos.txt. + pub auxiliary_types: Vec, + pub aliases: BTreeMap, +} + +/// Every exported type under `src_root` (an `aimux-core/src` directory), +/// sorted by `(name, source)`. `rel_prefix` is the path prefix written into +/// `source` (e.g. `aimux-core/src`). +/// +/// # Errors +/// +/// One message per unreadable file, parse error, unsupported construct or +/// unregistered field type, each with `file:line`. +pub fn extract(src_root: &Path, rel_prefix: &str) -> Result> { + let mut files = Vec::new(); + collect_rs(src_root, &mut files).map_err(|e| vec![e])?; + files.sort(); + let mut found = Vec::new(); + let mut errors = Vec::new(); + let mut aliases: BTreeMap = BTreeMap::new(); + for path in &files { + let rel = format!( + "{rel_prefix}/{}", + path.strip_prefix(src_root) + .unwrap_or(path) + .to_string_lossy() + .replace('\\', "/") + ); + let text = match std::fs::read_to_string(path) { + Ok(t) => t, + Err(e) => { + errors.push(format!("{rel}: {e}")); + continue; + } + }; + let file = match syn::parse_file(&text) { + Ok(f) => f, + Err(e) => { + errors.push(format!("{rel}:{}: {e}", e.span().start().line)); + continue; + } + }; + walk_items(&file.items, &rel, &mut found, &mut aliases, &mut errors); + } + let exported: BTreeSet = found + .iter() + .filter(|f| f.exported) + .map(|f| f.def.name.clone()) + .collect(); + let unexported_ts: BTreeSet = found + .iter() + .filter(|f| !f.exported) + .map(|f| f.def.name.clone()) + .collect(); + let alias_names: BTreeSet = aliases.keys().cloned().collect(); + // Auxiliary types are kept only when an exported type reaches them. + let mut reached = BTreeSet::new(); + for f in found.iter().filter(|f| f.exported) { + refs_in_shape(&f.def.shape, &mut reached); + f.def.proxy.values().for_each(|t| refs_in(t, &mut reached)); + } + // Aliases (and aliases of aliases) reached from DTOs; others are ignored. + loop { + let before = reached.len(); + for (name, (a, _)) in &aliases { + if reached.contains(name) { + let mut more = BTreeSet::new(); + refs_in(&a.ty, &mut more); + reached.extend(more); + } + } + if reached.len() == before { + break; + } + } + aliases.retain(|name, _| reached.contains(name)); + for (name, (a, line)) in &aliases { + let mut ctx = Resolve { + exported: &exported, + unexported_ts: &unexported_ts, + aliases: &alias_names, + allow_aux: true, + generics: BTreeSet::new(), + at: format!("{}:{line} (alias {name})", a.source), + errors: &mut errors, + }; + ctx.check(&a.ty); + } + for f in found + .iter() + .filter(|f| f.exported || reached.contains(&f.def.name)) + { + let mut ctx = Resolve { + exported: &exported, + unexported_ts: &unexported_ts, + aliases: &alias_names, + allow_aux: true, + generics: f.def.generics.iter().cloned().collect(), + at: format!("{}:{}", f.def.source, f.line), + errors: &mut errors, + }; + ctx.check_shape(&f.def.shape); + for t in f.def.proxy.values() { + ctx.check(t); + } + } + if !errors.is_empty() { + return Err(errors); + } + let key = |a: &TypeDef, b: &TypeDef| (&a.name, &a.source).cmp(&(&b.name, &b.source)); + let mut types = Vec::new(); + let mut auxiliary_types = Vec::new(); + for f in found { + if f.exported { + types.push(f.def); + } else if reached.contains(&f.def.name) { + auxiliary_types.push(f.def); + } + } + types.sort_by(key); + auxiliary_types.sort_by(key); + let aliases = aliases.into_iter().map(|(k, (a, _))| (k, a)).collect(); + Ok(Model { + types, + auxiliary_types, + aliases, + }) +} + +fn refs_in_shape(shape: &Shape, out: &mut BTreeSet) { + match shape { + Shape::Struct { fields, .. } => fields.iter().for_each(|f| refs_in(&f.ty, out)), + Shape::Newtype { inner } => refs_in(inner, out), + Shape::Tuple { items } => items.iter().for_each(|t| refs_in(t, out)), + Shape::Unit | Shape::HandWritten { .. } => {} + Shape::Enum { variants, .. } => variants.iter().for_each(|v| refs_in_shape(&v.shape, out)), + } +} + +fn refs_in(t: &TypeRef, out: &mut BTreeSet) { + match t { + TypeRef::Option(i) | TypeRef::Array(i) | TypeRef::TriState(i) => refs_in(i, out), + TypeRef::Map { key, value } => { + refs_in(key, out); + refs_in(value, out); + } + TypeRef::Tuple(items) => items.iter().for_each(|i| refs_in(i, out)), + TypeRef::Ref { name, args } => { + out.insert(name.clone()); + args.iter().for_each(|i| refs_in(i, out)); + } + _ => {} + } +} + +fn collect_rs(dir: &Path, out: &mut Vec) -> Result<(), String> { + let entries = std::fs::read_dir(dir).map_err(|e| format!("{}: {e}", dir.display()))?; + for entry in entries { + let entry = entry.map_err(|e| format!("{}: {e}", dir.display()))?; + let path = entry.path(); + if path.is_dir() { + if path.file_name().is_some_and(|n| n == "tests") { + continue; + } + collect_rs(&path, out)?; + } else if path.extension().is_some_and(|x| x == "rs") { + out.push(path); + } + } + Ok(()) +} + +fn is_cfg_test(attrs: &[Attribute]) -> bool { + attrs + .iter() + .any(|a| a.path().is_ident("cfg") && a.meta.to_token_stream().to_string().contains("test")) +} + +fn walk_items( + items: &[Item], + rel: &str, + found: &mut Vec, + aliases: &mut BTreeMap, + errors: &mut Vec, +) { + for item in items { + match item { + Item::Mod(m) if !is_cfg_test(&m.attrs) => { + if let Some((_, inner)) = &m.content { + walk_items(inner, rel, found, aliases, errors); + } + } + Item::Type(t) if t.generics.params.is_empty() && !is_cfg_test(&t.attrs) => { + aliases.insert( + t.ident.to_string(), + ( + AliasDef { + source: rel.to_string(), + ty: type_ref(&t.ty, None), + }, + t.ident.span().start().line, + ), + ); + } + Item::Struct(s) => { + consider(&s.attrs, &s.ident, &s.generics, rel, found, errors, |c| { + struct_shape(&s.ident.to_string(), &s.fields, c) + }); + } + Item::Enum(e) => { + consider(&e.attrs, &e.ident, &e.generics, rel, found, errors, |c| { + enum_shape(&e.ident.to_string(), e, c) + }); + } + _ => {} + } + } +} + +/// Container-level serde/ts attributes. +#[derive(Default)] +struct Container { + rename_all: Option, + rename_all_fields: Option, + tag: Option, + content: Option, + untagged: bool, + deny_unknown_fields: bool, + proxy: BTreeMap, + ts_export: bool, + ts_rename: Option, + ts_override: Option, + concrete: BTreeMap, +} + +#[allow(clippy::too_many_arguments)] +fn consider( + attrs: &[Attribute], + ident: &syn::Ident, + generics: &syn::Generics, + rel: &str, + found: &mut Vec, + errors: &mut Vec, + shape: impl FnOnce(&Container) -> Result, +) { + if !derives_ts(attrs) { + return; + } + let line = ident.span().start().line; + let c = match container(attrs) { + Ok(c) => c, + Err(e) => { + errors.push(format!("{rel}:{line}: {e}")); + return; + } + }; + let shape = if derives(attrs, "Serialize") || derives(attrs, "Deserialize") { + shape(&c) + } else if let Some(wire) = &c.ts_override { + Ok(Shape::HandWritten { wire: wire.clone() }) + } else { + Err("has hand-written serde and no `#[ts(type|as)]` codec".to_string()) + }; + let shape = match shape { + Ok(s) => s, + Err(e) => { + match e.strip_prefix('@').and_then(|r| r.split_once('@')) { + Some((l, msg)) => errors.push(format!("{rel}:{l}: {msg}")), + None => errors.push(format!("{rel}:{line}: {ident} {e}")), + } + return; + } + }; + let category = CATEGORY_BY_FILE + .iter() + .find(|(f, _)| *f == rel) + .map_or(DEFAULT_CATEGORY, |(_, c)| c) + .to_string(); + let proxy = c + .proxy + .iter() + .map(|(k, v)| { + let ty: Type = syn::parse_str(v).unwrap_or_else(|_| syn::parse_quote!(Unparsed)); + (k.clone(), type_ref(&ty, None)) + }) + .collect(); + found.push(Found { + def: TypeDef { + name: ident.to_string(), + ts_name: c.ts_rename.clone(), + category, + source: rel.to_string(), + generics: generics + .type_params() + .map(|p| p.ident.to_string()) + .collect(), + concrete: c.concrete.clone(), + proxy, + ts_override: c.ts_override.clone(), + shape, + }, + line, + exported: c.ts_export, + }); +} + +fn derives_ts(attrs: &[Attribute]) -> bool { + derives(attrs, "TS") +} + +fn derives(attrs: &[Attribute], name: &str) -> bool { + attrs.iter().any(|a| { + a.path().is_ident("derive") + && a.parse_args_with( + syn::punctuated::Punctuated::::parse_terminated, + ) + .is_ok_and(|ps| { + ps.iter() + .any(|p| p.segments.last().is_some_and(|s| s.ident == name)) + }) + }) +} + +fn lit_str(meta: &syn::meta::ParseNestedMeta<'_>) -> syn::Result { + Ok(meta.value()?.parse::()?.value()) +} + +/// Skip whatever follows a nested meta key (`= expr` or `(..)`). +fn skip_rest(meta: &syn::meta::ParseNestedMeta<'_>) -> syn::Result<()> { + if meta.input.peek(syn::Token![=]) { + let _: syn::Expr = meta.value()?.parse()?; + } else if meta.input.peek(syn::token::Paren) { + let _g: proc_macro2::Group = meta.input.parse()?; + } + Ok(()) +} + +fn container(attrs: &[Attribute]) -> Result { + let mut c = Container::default(); + for a in attrs { + if a.path().is_ident("serde") { + a.parse_nested_meta(|m| { + let key = m + .path + .get_ident() + .map(ToString::to_string) + .unwrap_or_default(); + match key.as_str() { + "rename_all" => c.rename_all = Some(lit_str(&m)?), + "rename_all_fields" => c.rename_all_fields = Some(lit_str(&m)?), + "tag" => c.tag = Some(lit_str(&m)?), + "content" => c.content = Some(lit_str(&m)?), + "untagged" => c.untagged = true, + "deny_unknown_fields" => c.deny_unknown_fields = true, + "from" | "into" | "try_from" => { + let v = lit_str(&m)?; + c.proxy.insert(key, v); + } + other => { + return Err( + m.error(format!("unsupported serde container attribute `{other}`")) + ); + } + } + Ok(()) + }) + .map_err(|e| e.to_string())?; + } else if a.path().is_ident("ts") { + a.parse_nested_meta(|m| { + let key = m + .path + .get_ident() + .map(ToString::to_string) + .unwrap_or_default(); + match key.as_str() { + "export" => c.ts_export = true, + "rename" => c.ts_rename = Some(lit_str(&m)?), + "as" | "type" => c.ts_override = Some(lit_str(&m)?), + "concrete" => { + let g: proc_macro2::Group = m.input.parse()?; + let text = g.stream().to_string(); + for pair in text.split(',') { + if let Some((k, v)) = pair.split_once('=') { + c.concrete + .insert(k.trim().to_string(), v.trim().to_string()); + } + } + } + _ => skip_rest(&m)?, + } + Ok(()) + }) + .map_err(|e| e.to_string())?; + } + } + Ok(c) +} + +/// Field/variant-level attributes. +#[derive(Default)] +struct Member { + rename: Option, + aliases: Vec, + skip: bool, + default: bool, + skip_serializing_if: bool, + flatten: bool, + other: bool, + with: Option, + ts_type: Option, + ts_optional: bool, +} + +fn member(attrs: &[Attribute]) -> Result { + let mut m = Member::default(); + for a in attrs { + if a.path().is_ident("serde") { + a.parse_nested_meta(|n| { + let key = n + .path + .get_ident() + .map(ToString::to_string) + .unwrap_or_default(); + match key.as_str() { + "rename" => m.rename = Some(lit_str(&n)?), + "alias" => m.aliases.push(lit_str(&n)?), + "skip" => m.skip = true, + "default" => { + m.default = true; + skip_rest(&n)?; + } + "skip_serializing_if" => { + m.skip_serializing_if = true; + skip_rest(&n)?; + } + "flatten" => m.flatten = true, + "other" => m.other = true, + "with" | "deserialize_with" | "serialize_with" => { + m.with = Some(format!("{key}={}", lit_str(&n)?)); + } + other => { + return Err(n.error(format!("unsupported serde field attribute `{other}`"))); + } + } + Ok(()) + }) + .map_err(|e| e.to_string())?; + } else if a.path().is_ident("ts") { + a.parse_nested_meta(|n| { + let key = n + .path + .get_ident() + .map(ToString::to_string) + .unwrap_or_default(); + match key.as_str() { + "type" | "as" => m.ts_type = Some(lit_str(&n)?), + "optional" => { + m.ts_optional = true; + skip_rest(&n)?; + } + _ => skip_rest(&n)?, + } + Ok(()) + }) + .map_err(|e| e.to_string())?; + } + } + Ok(m) +} + +/// Error text carrying the field's own line: `@@`; `consider` +/// turns it into `file:: ..`. +fn at_line(line: usize, msg: &str) -> String { + format!("@{line}@{msg}") +} + +/// Check a `with`-style field: `#[ts(type)]` or a [`FIELD_CODECS`] entry. +fn field_codec( + owner: &str, + field: &str, + m: &Member, + line: usize, +) -> Result, String> { + let Some(with) = &m.with else { + return Ok(None); + }; + if m.ts_type.is_some() { + return Ok(None); + } + FIELD_CODECS + .iter() + .find(|c| c.owner == owner && c.field == field && c.serde == with) + .map(Some) + .ok_or_else(|| { + at_line( + line, + &format!("{owner}.{field} uses serde `{with}` but has no `#[ts(type)]` and no FIELD_CODECS registration"), + ) + }) +} + +fn fields_of(owner: &str, fields: &Fields, rename_all: Option<&str>) -> Result { + match fields { + Fields::Unit => Ok(Shape::Unit), + Fields::Unnamed(u) => { + let mut items = Vec::new(); + for (i, f) in u.unnamed.iter().enumerate() { + let m = member(&f.attrs)?; + field_codec(owner, &i.to_string(), &m, f.ty.span().start().line)?; + items.push(type_ref(&f.ty, m.ts_type.as_deref())); + } + if items.len() == 1 { + Ok(Shape::Newtype { + inner: items.remove(0), + }) + } else { + Ok(Shape::Tuple { items }) + } + } + Fields::Named(n) => { + let mut out = Vec::new(); + for f in &n.named { + let m = member(&f.attrs)?; + if m.skip { + continue; + } + let rust = f + .ident + .as_ref() + .map(ToString::to_string) + .unwrap_or_default(); + let rust = rust.strip_prefix("r#").unwrap_or(&rust).to_string(); + let wire = m + .rename + .clone() + .unwrap_or_else(|| rename(&rust, rename_all, false)); + let line = f.ident.as_ref().map_or(0, |i| i.span().start().line); + let codec = field_codec(owner, &rust, &m, line)?; + let mut ty = type_ref(&f.ty, m.ts_type.as_deref()); + if codec.is_some_and(|c| c.tri_state) { + let bad = || { + at_line( + line, + &format!("{owner}.{rust}: tri-state codec needs Option>"), + ) + }; + ty = match ty { + TypeRef::Option(outer) => match *outer { + TypeRef::Option(inner) => TypeRef::TriState(inner), + _ => return Err(bad()), + }, + _ => return Err(bad()), + }; + } + out.push(FieldDef { + wire, + rust, + ty, + codec: codec.map(|c| FieldCodecRef { + name: c.name.into(), + wire: c.wire.into(), + }), + omit_when_empty: m.skip_serializing_if, + default: m.default, + flatten: m.flatten, + aliases: m.aliases, + serde_with: m.with, + }); + } + Ok(Shape::Struct { + fields: out, + deny_unknown_fields: false, + }) + } + } +} + +fn struct_shape(owner: &str, fields: &Fields, c: &Container) -> Result { + let mut shape = fields_of(owner, fields, c.rename_all.as_deref())?; + if let Shape::Struct { + deny_unknown_fields, + .. + } = &mut shape + { + *deny_unknown_fields = c.deny_unknown_fields; + } + Ok(shape) +} + +fn enum_shape(owner: &str, e: &syn::ItemEnum, c: &Container) -> Result { + let representation = match (&c.tag, &c.content, c.untagged) { + (_, _, true) => Representation::Untagged, + (Some(tag), Some(content), false) => Representation::Adjacent { + tag: tag.clone(), + content: content.clone(), + }, + (Some(tag), None, false) => Representation::Internal { tag: tag.clone() }, + (None, None, false) => Representation::External, + (None, Some(_), false) => return Err("`content` without `tag`".into()), + }; + let mut variants = Vec::new(); + for v in &e.variants { + let m = member(&v.attrs)?; + if m.skip { + continue; + } + let rust = v.ident.to_string(); + let untagged = matches!(representation, Representation::Untagged) || { + v.attrs.iter().any(|a| { + a.path().is_ident("serde") + && a.meta.to_token_stream().to_string().contains("untagged") + }) + }; + let wire = if untagged { + None + } else { + Some( + m.rename + .clone() + .unwrap_or_else(|| rename(&rust, c.rename_all.as_deref(), true)), + ) + }; + let vc = container_fields_rule(&v.attrs, c)?; + variants.push(VariantDef { + rust, + wire, + aliases: m.aliases, + other: m.other, + shape: fields_of(owner, &v.fields, vc.as_deref())?, + }); + } + Ok(Shape::Enum { + representation, + variants, + }) +} + +/// `rename_all` that applies to a variant's own fields: a variant-level +/// `#[serde(rename_all)]`, else the container's `rename_all_fields`. +fn container_fields_rule(attrs: &[Attribute], c: &Container) -> Result, String> { + let mut rule = c.rename_all_fields.clone(); + for a in attrs { + if a.path().is_ident("serde") && a.meta.to_token_stream().to_string().contains("rename_all") + { + a.parse_nested_meta(|n| { + if n.path.is_ident("rename_all") { + rule = Some(lit_str(&n)?); + } else { + skip_rest(&n)?; + } + Ok(()) + }) + .map_err(|e| e.to_string())?; + } + } + Ok(rule) +} + +/// serde's `rename_all` rules. `variant` inputs are PascalCase, field inputs +/// snake_case. +#[must_use] +pub fn rename(name: &str, rule: Option<&str>, variant: bool) -> String { + let Some(rule) = rule else { + return name.to_string(); + }; + let words: Vec = if variant { + let mut words = Vec::new(); + let mut cur = String::new(); + for ch in name.chars() { + if ch.is_uppercase() && !cur.is_empty() { + words.push(std::mem::take(&mut cur)); + } + cur.push(ch); + } + if !cur.is_empty() { + words.push(cur); + } + words.into_iter().map(|w| w.to_lowercase()).collect() + } else { + name.split('_').map(str::to_string).collect() + }; + let cap = |w: &str| { + let mut c = w.chars(); + c.next().map_or(String::new(), |f| { + f.to_uppercase().collect::() + c.as_str() + }) + }; + match rule { + "lowercase" => { + if variant { + name.to_lowercase() + } else { + name.to_string() + } + } + "UPPERCASE" => name.to_uppercase(), + "PascalCase" => words.iter().map(|w| cap(w)).collect(), + "camelCase" => words + .iter() + .enumerate() + .map(|(i, w)| if i == 0 { w.clone() } else { cap(w) }) + .collect(), + "snake_case" => words.join("_"), + "SCREAMING_SNAKE_CASE" => words.join("_").to_uppercase(), + "kebab-case" => words.join("-"), + "SCREAMING-KEBAB-CASE" => words.join("-").to_uppercase(), + _ => name.to_string(), + } +} + +fn last_ident(path: &syn::Path) -> String { + path.segments + .last() + .map(|s| s.ident.to_string()) + .unwrap_or_default() +} + +fn args(seg: &syn::PathSegment) -> Vec<&Type> { + match &seg.arguments { + PathArguments::AngleBracketed(a) => a + .args + .iter() + .filter_map(|g| { + if let GenericArgument::Type(t) = g { + Some(t) + } else { + None + } + }) + .collect(), + _ => Vec::new(), + } +} + +fn type_ref(ty: &Type, ts_override: Option<&str>) -> TypeRef { + let text = ty.to_token_stream().to_string().replace(' ', ""); + if let Some(wire) = ts_override { + return TypeRef::Codec { + rust: text, + wire: wire.to_string(), + }; + } + match ty { + Type::Reference(r) => type_ref(&r.elem, None), + Type::Tuple(t) => TypeRef::Tuple(t.elems.iter().map(|e| type_ref(e, None)).collect()), + Type::Slice(s) => TypeRef::Array(Box::new(type_ref(&s.elem, None))), + Type::Array(a) => TypeRef::Array(Box::new(type_ref(&a.elem, None))), + Type::Path(p) if p.qself.is_none() => { + let Some(seg) = p.path.segments.last() else { + return TypeRef::Ref { + name: text, + args: vec![], + }; + }; + let name = seg.ident.to_string(); + let a = args(seg); + let joined = p + .path + .segments + .iter() + .map(|s| s.ident.to_string()) + .collect::>() + .join("::"); + match (name.as_str(), a.as_slice()) { + (n, []) if PRIMS.contains(&n) => TypeRef::Prim(if n == "str" { + "String".into() + } else { + n.into() + }), + ("Value", []) if joined.contains("serde_json") || joined == "Value" => { + TypeRef::Json + } + ("JsonValue", []) => TypeRef::Json, + ("Map", [k, v]) => TypeRef::Map { + key: Box::new(type_ref(k, None)), + value: Box::new(type_ref(v, None)), + }, + ("Option", [t]) => TypeRef::Option(Box::new(type_ref(t, None))), + ("Vec" | "VecDeque" | "BTreeSet" | "HashSet" | "IndexSet", [t]) => { + TypeRef::Array(Box::new(type_ref(t, None))) + } + ("HashMap" | "BTreeMap" | "IndexMap", [k, v]) => TypeRef::Map { + key: Box::new(type_ref(k, None)), + value: Box::new(type_ref(v, None)), + }, + ("Box" | "Arc" | "Rc" | "Cow", [t]) => type_ref(t, None), + ("Cow", [_, t]) => type_ref(t, None), + _ => TypeRef::Ref { + name: last_ident(&p.path), + args: a.iter().map(|t| type_ref(t, None)).collect(), + }, + } + } + _ => TypeRef::Ref { + name: text, + args: vec![], + }, + } +} + +struct Resolve<'a> { + exported: &'a BTreeSet, + unexported_ts: &'a BTreeSet, + aliases: &'a BTreeSet, + allow_aux: bool, + generics: BTreeSet, + at: String, + errors: &'a mut Vec, +} + +impl Resolve<'_> { + fn check_shape(&mut self, shape: &Shape) { + match shape { + Shape::Struct { fields, .. } => { + for f in fields { + self.check(&f.ty); + } + } + Shape::Newtype { inner } => self.check(inner), + Shape::Tuple { items } => items.iter().for_each(|t| self.check(t)), + Shape::Unit | Shape::HandWritten { .. } => {} + Shape::Enum { variants, .. } => { + for v in variants { + self.check_shape(&v.shape); + } + } + } + } + + fn check(&mut self, t: &TypeRef) { + match t { + TypeRef::Prim(_) | TypeRef::Json | TypeRef::Codec { .. } | TypeRef::Generic(_) => {} + TypeRef::Option(i) | TypeRef::Array(i) | TypeRef::TriState(i) => self.check(i), + TypeRef::Map { key, value } => { + self.check(key); + self.check(value); + } + TypeRef::Tuple(items) => items.iter().for_each(|i| self.check(i)), + TypeRef::Ref { name, args } => { + args.iter().for_each(|i| self.check(i)); + if self.generics.contains(name) + || self.exported.contains(name) + || self.aliases.contains(name) + || (self.allow_aux && self.unexported_ts.contains(name)) + || CODECS.iter().any(|(n, _)| n == name) + { + return; + } + let why = if self.unexported_ts.contains(name) { + "derives TS but is not `#[ts(export)]`" + } else { + "is not an exported type and has no registered codec" + }; + self.errors + .push(format!("{}: unregistered type `{name}` ({why})", self.at)); + } + } + } +} diff --git a/tools/aimux-codegen/src/lib.rs b/tools/aimux-codegen/src/lib.rs index f60fc346f..b54e5ec72 100644 --- a/tools/aimux-codegen/src/lib.rs +++ b/tools/aimux-codegen/src/lib.rs @@ -11,6 +11,9 @@ use std::path::{Path, PathBuf}; use serde::Deserialize; +pub mod extract; +pub mod manifest; + /// A type spec. #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] diff --git a/tools/aimux-codegen/src/main.rs b/tools/aimux-codegen/src/main.rs index ad13f1ca9..d52f49e6a 100644 --- a/tools/aimux-codegen/src/main.rs +++ b/tools/aimux-codegen/src/main.rs @@ -1,48 +1,69 @@ -//! `aimux-codegen [--check]`: regenerate (or verify) `generated/` from `spec/`. +//! `aimux-codegen [--check] [--spec DIR] [--out DIR] [--src DIR] [--versions FILE] [--list FILE]`: +//! regenerate (or verify) `generated/` — the 1.8 PoC outputs from `spec/` +//! and the 2.1 `manifest.json` + `coverage.txt` from `aimux-core/src`. use std::path::PathBuf; use std::process::ExitCode; +use aimux_codegen::manifest::{self, Inputs}; + +const USAGE: &str = "usage: aimux-codegen [--check] [--spec DIR] [--out DIR] [--src DIR] [--versions FILE] [--list FILE]"; + fn main() -> ExitCode { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut spec = root.join("spec"); let mut out = root.join("generated"); + let mut inputs = Inputs::from_workspace(&root.join("../..")); let mut check = false; let mut args = std::env::args().skip(1); while let Some(arg) = args.next() { + let mut path = |current: PathBuf| args.next().map_or(current, PathBuf::from); match arg.as_str() { "--check" => check = true, - "--spec" => spec = args.next().map_or(spec, PathBuf::from), - "--out" => out = args.next().map_or(out, PathBuf::from), + "--spec" => spec = path(spec), + "--out" => out = path(out), + "--src" => inputs.src_root = path(inputs.src_root), + "--versions" => inputs.versions = path(inputs.versions), + "--list" => inputs.list = path(inputs.list), other => { - eprintln!( - "unknown argument {other}; usage: aimux-codegen [--check] [--spec DIR] [--out DIR]" - ); + eprintln!("unknown argument {other}; {USAGE}"); return ExitCode::from(2); } } } + let mut problems = Vec::new(); if check { - match aimux_codegen::check(&spec, &out) { - Ok(()) => { - println!("{}: up to date", out.display()); - ExitCode::SUCCESS - } - Err(problems) => { - for p in problems { - eprintln!("{p}"); - } - eprintln!("run `cargo run -p aimux-codegen` to regenerate"); - ExitCode::FAILURE - } + if let Err(p) = aimux_codegen::check(&spec, &out) { + problems.extend(p); + } + if let Err(p) = manifest::check(&inputs, &out) { + problems.extend(p); } } else { - match aimux_codegen::write(&spec, &out) { - Ok(()) => ExitCode::SUCCESS, - Err(e) => { - eprintln!("{e}"); - ExitCode::FAILURE + // Manifest first: a coverage or extraction failure writes nothing. + match manifest::generate(&inputs) { + Err(p) => problems.extend(p), + Ok(_) => { + if let Err(e) = aimux_codegen::write(&spec, &out) { + problems.push(e); + } + if let Err(p) = manifest::write(&inputs, &out) { + problems.extend(p); + } } } } + if problems.is_empty() { + if check { + println!("{}: up to date", out.display()); + } + return ExitCode::SUCCESS; + } + for p in problems { + eprintln!("{p}"); + } + if check { + eprintln!("run `cargo run -p aimux-codegen` to regenerate"); + } + ExitCode::FAILURE } diff --git a/tools/aimux-codegen/src/manifest.rs b/tools/aimux-codegen/src/manifest.rs new file mode 100644 index 000000000..ab57f616a --- /dev/null +++ b/tools/aimux-codegen/src/manifest.rs @@ -0,0 +1,262 @@ +//! `manifest.json` and the coverage report (phase 2 unit 2.1; #200 §6.5, +//! RFC-0042 §7.2–7.3). +//! +//! The manifest records the AI SDK baseline read from +//! `fixtures/aisdk/VERSIONS.json` at generation time (D11 default a), the +//! generator version, a hash of every input, a schema revision and the type +//! model extracted from `aimux-core/src` ([`crate::extract`]). +//! +//! The coverage report lists ` ` for every manifest +//! type; it must equal the `[exported]` section of +//! `docs/plan/closure-dtos.txt` (the 1.5 closure DTO list). Any missing or +//! extra line fails generation and `--check`. + +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; + +use serde::Serialize; +use sha2::{Digest, Sha256}; + +use crate::Output; +use crate::extract::{AliasDef, TypeDef, extract}; + +/// Bumped when the manifest layout changes. +pub const SCHEMA_REVISION: u32 = 1; + +/// Where the manifest inputs live. +#[derive(Debug, Clone)] +pub struct Inputs { + /// `aimux-core/src`. + pub src_root: PathBuf, + /// `fixtures/aisdk/VERSIONS.json`. + pub versions: PathBuf, + /// `docs/plan/closure-dtos.txt`. + pub list: PathBuf, +} + +impl Inputs { + /// Default inputs relative to the workspace root. + #[must_use] + pub fn from_workspace(root: &Path) -> Self { + Self { + src_root: root.join("aimux-core/src"), + versions: root.join("fixtures/aisdk/VERSIONS.json"), + list: root.join("docs/plan/closure-dtos.txt"), + } + } +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct Manifest<'a> { + schema_revision: u32, + generator: Generator, + sdk: BTreeMap, + input_hash: String, + types: &'a [TypeDef], + auxiliary_types: &'a [TypeDef], + aliases: &'a BTreeMap, +} + +#[derive(Serialize)] +struct Generator { + name: &'static str, + version: &'static str, +} + +const SRC_PREFIX: &str = "aimux-core/src"; + +/// Manifest and coverage outputs (`manifest.json`, `coverage.txt`). +/// +/// # Errors +/// +/// Extraction errors, an unreadable/invalid VERSIONS.json or list, and one +/// message per coverage difference (`missing from manifest: ..` / +/// `not in closure-dtos.txt: ..`). +pub fn generate(inputs: &Inputs) -> Result, Vec> { + let model = extract(&inputs.src_root, SRC_PREFIX)?; + let types = &model.types; + let versions_text = std::fs::read_to_string(&inputs.versions) + .map_err(|e| vec![format!("{}: {e}", inputs.versions.display())])?; + let sdk: BTreeMap = serde_json::from_str(&versions_text) + .map_err(|e| vec![format!("{}: {e}", inputs.versions.display())])?; + let coverage = coverage_lines(types); + let list_text = std::fs::read_to_string(&inputs.list) + .map_err(|e| vec![format!("{}: {e}", inputs.list.display())])?; + compare(&coverage, &exported_section(&list_text))?; + + let manifest = Manifest { + schema_revision: SCHEMA_REVISION, + generator: Generator { + name: env!("CARGO_PKG_NAME"), + version: env!("CARGO_PKG_VERSION"), + }, + sdk, + input_hash: input_hash(inputs, &versions_text)?, + types, + auxiliary_types: &model.auxiliary_types, + aliases: &model.aliases, + }; + let mut json = serde_json::to_string_pretty(&manifest).map_err(|e| vec![e.to_string()])?; + json.push('\n'); + let mut report = String::from( + "# Manifest coverage (unit 2.1). Generated by aimux-codegen; must equal the\n# [exported] section of docs/plan/closure-dtos.txt.\n", + ); + for line in &coverage { + report.push_str(line); + report.push('\n'); + } + Ok(vec![ + Output { + path: PathBuf::from("manifest.json"), + content: json, + }, + Output { + path: PathBuf::from("coverage.txt"), + content: report, + }, + ]) +} + +/// ` ` per type, sorted. +#[must_use] +pub fn coverage_lines(types: &[TypeDef]) -> Vec { + let mut lines: Vec = types + .iter() + .map(|t| format!("{} {} {}", t.name, t.category, t.source)) + .collect(); + lines.sort(); + lines +} + +/// Lines of the `[exported]` section of closure-dtos.txt. +#[must_use] +pub fn exported_section(text: &str) -> Vec { + let mut lines = Vec::new(); + let mut inside = false; + for line in text.lines() { + if line.starts_with('[') { + inside = line.starts_with("[exported]"); + continue; + } + if inside && !line.trim().is_empty() && !line.starts_with('#') { + lines.push(line.trim().to_string()); + } + } + lines.sort(); + lines +} + +/// Equal sets, or one message per difference. +/// +/// # Errors +/// +/// `missing from manifest: ` for list lines the manifest lacks and +/// `not in closure-dtos.txt: ` for extra manifest types. +pub fn compare(coverage: &[String], list: &[String]) -> Result<(), Vec> { + let mut problems = Vec::new(); + for l in list { + if !coverage.contains(l) { + problems.push(format!("coverage: missing from manifest: {l}")); + } + } + for c in coverage { + if !list.contains(c) { + problems.push(format!("coverage: not in closure-dtos.txt: {c}")); + } + } + if problems.is_empty() { + Ok(()) + } else { + Err(problems) + } +} + +fn input_hash(inputs: &Inputs, versions_text: &str) -> Result> { + let mut files = Vec::new(); + collect(&inputs.src_root, &mut files).map_err(|e| vec![e])?; + files.sort(); + let mut h = Sha256::new(); + for f in files { + let rel = f + .strip_prefix(&inputs.src_root) + .unwrap_or(&f) + .to_string_lossy() + .replace('\\', "/"); + let bytes = lf(&std::fs::read(&f).map_err(|e| vec![format!("{}: {e}", f.display())])?); + h.update(format!("{SRC_PREFIX}/{rel}\0{}\0", bytes.len())); + h.update(bytes); + } + h.update("fixtures/aisdk/VERSIONS.json\0"); + h.update(lf(versions_text.as_bytes())); + Ok(format!("sha256:{:x}", h.finalize())) +} + +/// CRLF → LF, so the hash (and the manifest) is the same whatever line +/// endings the checkout produced (e.g. `core.autocrlf=true` on Windows). +/// Done here rather than via `.gitattributes`, which only applies to +/// checkouts that honour it. +#[must_use] +pub fn lf(bytes: &[u8]) -> Vec { + let mut out = Vec::with_capacity(bytes.len()); + let mut i = 0; + while i < bytes.len() { + if bytes[i] == b'\r' && bytes.get(i + 1) == Some(&b'\n') { + i += 1; + continue; + } + out.push(bytes[i]); + i += 1; + } + out +} + +fn collect(dir: &Path, out: &mut Vec) -> Result<(), String> { + for entry in std::fs::read_dir(dir).map_err(|e| format!("{}: {e}", dir.display()))? { + let p = entry.map_err(|e| e.to_string())?.path(); + if p.is_dir() { + collect(&p, out)?; + } else if p.extension().is_some_and(|x| x == "rs") { + out.push(p); + } + } + Ok(()) +} + +/// Write `manifest.json` and `coverage.txt` under `out_dir`. Nothing is +/// written when generation fails. +/// +/// # Errors +/// +/// See [`generate`]; plus I/O errors. +pub fn write(inputs: &Inputs, out_dir: &Path) -> Result<(), Vec> { + for o in generate(inputs)? { + let path = out_dir.join(&o.path); + std::fs::write(&path, o.content).map_err(|e| vec![format!("{}: {e}", path.display())])?; + } + Ok(()) +} + +/// Compare committed `manifest.json` / `coverage.txt` under `out_dir` with a +/// fresh generation (D8 `--check`). +/// +/// # Errors +/// +/// Generation/coverage errors, or one ` is out of date` per stale or +/// missing file. +pub fn check(inputs: &Inputs, out_dir: &Path) -> Result<(), Vec> { + let mut problems = Vec::new(); + for o in generate(inputs)? { + let path = out_dir.join(&o.path); + match std::fs::read_to_string(&path) { + Ok(t) if t == o.content => {} + Ok(_) => problems.push(format!("{} is out of date", path.display())), + Err(e) => problems.push(format!("{}: {e}", path.display())), + } + } + if problems.is_empty() { + Ok(()) + } else { + Err(problems) + } +} diff --git a/tools/aimux-codegen/tests/manifest_test.rs b/tools/aimux-codegen/tests/manifest_test.rs new file mode 100644 index 000000000..daf8827da --- /dev/null +++ b/tools/aimux-codegen/tests/manifest_test.rs @@ -0,0 +1,576 @@ +//! Phase 2 unit 2.1 acceptance: the manifest covers every `#[ts(export)]` +//! type, its coverage report equals the 1.5 closure DTO list +//! (`docs/plan/closure-dtos.txt`), and each mutation below turns red. + +use std::path::{Path, PathBuf}; +use std::process::Command; + +use aimux_codegen::manifest::{self, Inputs, exported_section}; + +fn root() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) +} + +fn workspace() -> PathBuf { + root().join("../..") +} + +fn inputs() -> Inputs { + Inputs::from_workspace(&workspace()) +} + +fn tmp(label: &str) -> PathBuf { + let dir = std::env::temp_dir().join(format!( + "aimux-manifest-{label}-{}-{:?}", + std::process::id(), + std::thread::current().id() + )); + let _ = std::fs::remove_dir_all(&dir); + std::fs::create_dir_all(&dir).unwrap(); + dir +} + +fn copy_tree(from: &Path, to: &Path) { + std::fs::create_dir_all(to).unwrap(); + for entry in std::fs::read_dir(from).unwrap() { + let entry = entry.unwrap(); + let target = to.join(entry.file_name()); + if entry.file_type().unwrap().is_dir() { + copy_tree(&entry.path(), &target); + } else { + std::fs::copy(entry.path(), target).unwrap(); + } + } +} + +/// Inputs whose `aimux-core/src` is a scratch copy. +fn scratch_src(label: &str) -> (PathBuf, Inputs) { + let dir = tmp(label); + let src = dir.join("src"); + copy_tree(&inputs().src_root, &src); + let mut i = inputs(); + i.src_root = src; + (dir, i) +} + +fn errors(i: &Inputs) -> Vec { + manifest::generate(i).expect_err("generation should fail") +} + +#[test] +fn committed_manifest_is_up_to_date() { + manifest::check(&inputs(), &root().join("generated")).unwrap(); +} + +#[test] +fn coverage_report_equals_the_closure_dto_list() { + let list = std::fs::read_to_string(&inputs().list).unwrap(); + let expected = exported_section(&list); + let header = list.lines().find(|l| l.starts_with("[exported]")).unwrap(); + assert_eq!(header, format!("[exported] {}", expected.len())); + let report = std::fs::read_to_string(root().join("generated/coverage.txt")).unwrap(); + let got: Vec = report + .lines() + .filter(|l| !l.starts_with('#')) + .map(str::to_string) + .collect(); + assert_eq!(got, expected); + for category in [ + "user", + "provider", + "core", + "error", + "recording", + "multimodal", + "tool", + ] { + assert!( + got.iter().any(|l| l.split(' ').nth(1) == Some(category)), + "no {category} type in the manifest" + ); + } +} + +#[test] +fn manifest_records_versions_json_verbatim() { + let manifest: serde_json::Value = serde_json::from_str( + &std::fs::read_to_string(root().join("generated/manifest.json")).unwrap(), + ) + .unwrap(); + let versions: serde_json::Value = + serde_json::from_str(&std::fs::read_to_string(&inputs().versions).unwrap()).unwrap(); + assert_eq!(manifest["sdk"], versions); + assert_eq!(versions.as_object().unwrap().len(), 7); + assert_eq!(manifest["generator"]["name"], "aimux-codegen"); + assert!( + manifest["inputHash"] + .as_str() + .unwrap() + .starts_with("sha256:") + ); +} + +/// Mutation 1: a type loses `#[ts(export)]` (it leaves the manifest) → +/// red, naming exactly that list line. +#[test] +fn removed_type_is_named() { + let (dir, i) = scratch_src("removed"); + let file = i.src_root.join("recording.rs"); + let text = std::fs::read_to_string(&file).unwrap(); + let item = text + .find("pub struct HttpExchange") + .expect("HttpExchange in recording.rs"); + let attr = text[..item].rfind("#[ts(export)]").unwrap(); + let mutated = format!("{}{}", &text[..attr], &text[attr + "#[ts(export)]".len()..]); + std::fs::write(&file, mutated).unwrap(); + let errs = errors(&i); + assert_eq!( + errs, + vec!["coverage: missing from manifest: HttpExchange recording aimux-core/src/recording.rs"] + ); + let _ = std::fs::remove_dir_all(dir); +} + +/// Mutation 2: a fake line in the list → red, naming it. +#[test] +fn fake_list_line_is_named() { + let dir = tmp("fake"); + let list = std::fs::read_to_string(&inputs().list).unwrap(); + let mutated = list.replacen( + "\n[exported] ", + "\n[exported] \nFakeDto core aimux-core/src/fake.rs\n# count: ", + 1, + ); + let mut i = inputs(); + i.list = dir.join("closure-dtos.txt"); + std::fs::write(&i.list, mutated).unwrap(); + assert_eq!( + errors(&i), + vec!["coverage: missing from manifest: FakeDto core aimux-core/src/fake.rs"] + ); + let _ = std::fs::remove_dir_all(dir); +} + +/// Mutation 3: an extra exported type not in the list → red, naming it. +#[test] +fn extra_manifest_type_is_named() { + let (dir, i) = scratch_src("extra"); + std::fs::write( + i.src_root.join("extra_dto.rs"), + "#[derive(Serialize, Deserialize, TS)]\n#[ts(export)]\npub struct ExtraDto {\n pub a: String,\n}\n", + ) + .unwrap(); + assert_eq!( + errors(&i), + vec!["coverage: not in closure-dtos.txt: ExtraDto core aimux-core/src/extra_dto.rs"] + ); + let _ = std::fs::remove_dir_all(dir); +} + +/// Mutation 4: VERSIONS.json changes → committed manifest is stale (lib and +/// CLI), and the new version lands in a regenerated manifest. +#[test] +fn versions_change_makes_manifest_stale() { + let dir = tmp("versions"); + let text = std::fs::read_to_string(&inputs().versions).unwrap(); + assert!(text.contains("\"ai\": \"7.0.127\"")); + let versions = dir.join("VERSIONS.json"); + std::fs::write( + &versions, + text.replace("\"ai\": \"7.0.127\"", "\"ai\": \"7.0.999\""), + ) + .unwrap(); + let mut i = inputs(); + i.versions = versions.clone(); + let problems = manifest::check(&i, &root().join("generated")).unwrap_err(); + assert_eq!(problems.len(), 1, "{problems:?}"); + assert!( + problems[0].ends_with("manifest.json is out of date"), + "{problems:?}" + ); + let fresh = manifest::generate(&i).unwrap(); + assert!(fresh[0].content.contains("\"ai\": \"7.0.999\"")); + + let out = Command::new(env!("CARGO_BIN_EXE_aimux-codegen")) + .args(["--check", "--versions"]) + .arg(&versions) + .output() + .unwrap(); + assert!(!out.status.success()); + assert!(String::from_utf8_lossy(&out.stderr).contains("manifest.json is out of date")); + let _ = std::fs::remove_dir_all(dir); +} + +/// Mutation 5: an exported type with a field type that is neither a DTO, +/// alias, primitive/container nor registered codec → generation error with +/// file:line; nothing is written. +#[test] +fn unregistered_field_type_fails_generation() { + let (dir, i) = scratch_src("unregistered"); + std::fs::write( + i.src_root.join("extra_dto.rs"), + "#[derive(Serialize, Deserialize, TS)]\n#[ts(export)]\npub struct ExtraDto {\n pub at: std::time::Instant,\n}\n", + ) + .unwrap(); + let errs = errors(&i); + assert!( + errs.iter().any(|e| e + == "aimux-core/src/extra_dto.rs:3: unregistered type `Instant` (is not an exported type and has no registered codec)"), + "{errs:?}" + ); + + let out_dir = dir.join("out"); + std::fs::create_dir_all(&out_dir).unwrap(); + let out = Command::new(env!("CARGO_BIN_EXE_aimux-codegen")) + .args(["--src"]) + .arg(&i.src_root) + .arg("--out") + .arg(&out_dir) + .output() + .unwrap(); + assert!(!out.status.success()); + assert!(String::from_utf8_lossy(&out.stderr).contains("unregistered type `Instant`")); + assert_eq!( + std::fs::read_dir(&out_dir).unwrap().count(), + 0, + "failed generation wrote files" + ); + let _ = std::fs::remove_dir_all(dir); +} + +/// Hand-written serde without a declared codec is rejected too. +#[test] +fn hand_written_serde_without_codec_fails() { + let (dir, i) = scratch_src("handwritten"); + std::fs::write( + i.src_root.join("extra_dto.rs"), + "#[derive(TS)]\n#[ts(export)]\npub enum ExtraDto { A }\n", + ) + .unwrap(); + let errs = errors(&i); + assert!( + errs.iter() + .any(|e| e.contains("extra_dto.rs:3: ExtraDto has hand-written serde")), + "{errs:?}" + ); + let _ = std::fs::remove_dir_all(dir); +} + +/// Every struct field wire name and every tagged variant value in the +/// manifest appears in the current ts-rs export for that type, so the +/// extracted serde rules (rename / rename_all / tag) match what serde emits. +#[test] +fn wire_names_match_the_current_ts_exports() { + let manifest: serde_json::Value = serde_json::from_str( + &std::fs::read_to_string(root().join("generated/manifest.json")).unwrap(), + ) + .unwrap(); + let mut checked = 0; + let mut problems = Vec::new(); + for t in manifest["types"].as_array().unwrap() { + if t.get("tsOverride").is_some() { + continue; + } + let name = t.get("tsName").unwrap_or(&t["name"]).as_str().unwrap(); + let path = workspace().join(format!("bindings/node/src/types/{name}.ts")); + let ts = std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("{name}: {e}")); + let shape = &t["shape"]; + let mut names = Vec::new(); + match shape["kind"].as_str().unwrap() { + "struct" => { + for f in shape["fields"].as_array().unwrap() { + if f.get("flatten").is_none() { + names.push(f["wire"].as_str().unwrap().to_string()); + } + } + } + "enum" => { + for v in shape["variants"].as_array().unwrap() { + if let Some(w) = v.get("wire") { + names.push(format!("\"{}\"", w.as_str().unwrap())); + } + } + } + _ => {} + } + for n in names { + checked += 1; + let found = if n.starts_with('"') { + ts.contains(&n) + } else { + ts.contains(&format!("{n}:")) + || ts.contains(&format!("{n}?:")) + || ts.contains(&format!("\"{n}\":")) + || ts.contains(&format!("\"{n}\"?:")) + }; + if !found { + problems.push(format!("{name}: {n}")); + } + } + } + assert!(checked > 800, "only {checked} names checked"); + assert!(problems.is_empty(), "{problems:?}"); +} + +/// A CRLF checkout (Windows `core.autocrlf=true`) of the same sources and +/// VERSIONS.json gives the same input hash and a byte-identical manifest. +#[test] +fn crlf_checkout_gives_identical_manifest() { + fn to_crlf(dir: &Path) { + for entry in std::fs::read_dir(dir).unwrap() { + let p = entry.unwrap().path(); + if p.is_dir() { + to_crlf(&p); + } else { + let text = std::fs::read_to_string(&p).unwrap(); + std::fs::write(&p, text.replace("\r\n", "\n").replace('\n', "\r\n")).unwrap(); + } + } + } + let (dir, mut i) = scratch_src("crlf"); + to_crlf(&i.src_root); + let versions = dir.join("VERSIONS.json"); + let text = std::fs::read_to_string(&inputs().versions).unwrap(); + std::fs::write(&versions, text.replace('\n', "\r\n")).unwrap(); + i.versions = versions; + assert!( + std::fs::read_to_string(i.src_root.join("lib.rs")) + .unwrap() + .contains("\r\n") + ); + + let lf_out = manifest::generate(&inputs()).unwrap(); + let crlf_out = manifest::generate(&i).unwrap(); + let hash = |o: &[aimux_codegen::Output]| { + let v: serde_json::Value = serde_json::from_str(&o[0].content).unwrap(); + v["inputHash"].as_str().unwrap().to_string() + }; + assert_eq!(hash(&crlf_out), hash(&lf_out)); + assert_eq!(crlf_out, lf_out); + manifest::check(&i, &root().join("generated")).unwrap(); + let _ = std::fs::remove_dir_all(dir); +} + +/// Manifest of `i` as JSON, without `inputHash` (which changes on any edit). +fn manifest_json(i: &Inputs) -> serde_json::Value { + let out = manifest::generate(i).unwrap(); + let mut v: serde_json::Value = serde_json::from_str(&out[0].content).unwrap(); + v.as_object_mut().unwrap().remove("inputHash"); + v +} + +fn find_type<'a>(m: &'a serde_json::Value, name: &str) -> &'a serde_json::Value { + m["types"] + .as_array() + .unwrap() + .iter() + .find(|t| t["name"] == name) + .unwrap() +} + +fn find_field<'a>(t: &'a serde_json::Value, rust: &str) -> &'a serde_json::Value { + t["shape"]["fields"] + .as_array() + .unwrap() + .iter() + .find(|f| f["rust"] == rust) + .unwrap() +} + +/// Each serde rule the extractor models changes the specific manifest field +/// it drives (manifests compared without `inputHash`), and the committed +/// manifest goes stale. +#[test] +fn serde_attribute_mutations_change_the_modelled_field() { + type Probe = fn(&serde_json::Value) -> serde_json::Value; + let cases: &[( + &str, + &str, + &str, + &str, + Probe, + serde_json::Value, + serde_json::Value, + )] = &[ + ( + "skip_serializing_if", + "tool.rs", + "#[serde(default, skip_serializing_if = \"Option::is_none\")]", + "#[serde(default)]", + |m| find_field(find_type(m, "FunctionTool"), "description")["omitWhenEmpty"].clone(), + serde_json::json!(true), + serde_json::Value::Null, + ), + ( + "flatten", + "tool.rs", + "#[serde(default, skip_serializing_if = \"Option::is_none\")]", + "#[serde(flatten, default, skip_serializing_if = \"Option::is_none\")]", + |m| find_field(find_type(m, "FunctionTool"), "description")["flatten"].clone(), + serde_json::Value::Null, + serde_json::json!(true), + ), + ( + "untagged", + "transcription_model.rs", + "#[serde(untagged)]", + "", + |m| find_type(m, "AudioInput")["shape"]["representation"]["style"].clone(), + serde_json::json!("untagged"), + serde_json::json!("external"), + ), + ( + "rename_all", + "tool.rs", + "#[serde(rename_all = \"camelCase\")]", + "#[serde(rename_all = \"snake_case\")]", + |m| find_field(find_type(m, "FunctionTool"), "input_schema")["wire"].clone(), + serde_json::json!("inputSchema"), + serde_json::json!("input_schema"), + ), + ( + "field rename", + "decision_model.rs", + "#[serde(rename = \"true\",", + "#[serde(rename = \"yes\",", + |m| { + find_field(find_type(m, "DecisionBooleanCriteria"), "true_description")["wire"] + .clone() + }, + serde_json::json!("true"), + serde_json::json!("yes"), + ), + ]; + let base = manifest_json(&inputs()); + for (label, file, from, to, probe, before, after) in cases { + let (dir, i) = scratch_src(&label.replace(' ', "_")); + let path = i.src_root.join(file); + let text = std::fs::read_to_string(&path).unwrap(); + assert!(text.contains(from), "{label}: `{from}` not in {file}"); + std::fs::write(&path, text.replacen(from, to, 1)).unwrap(); + let mutated = manifest_json(&i); + assert_eq!(&probe(&base), before, "{label}: baseline"); + assert_eq!(&probe(&mutated), after, "{label}: mutated"); + let problems = manifest::check(&i, &root().join("generated")) + .expect_err(&format!("{label}: mutation not detected")); + assert!( + problems + .iter() + .any(|p| p.ends_with("manifest.json is out of date")), + "{label}: {problems:?}" + ); + let _ = std::fs::remove_dir_all(dir); + } +} + +/// Control: a comment-only edit changes `inputHash` but nothing else. +#[test] +fn comment_only_edit_leaves_manifest_identical_except_input_hash() { + let (dir, i) = scratch_src("comment"); + let path = i.src_root.join("tool.rs"); + let text = std::fs::read_to_string(&path).unwrap(); + std::fs::write(&path, format!("// control comment\n{text}")).unwrap(); + let hash = |i: &Inputs| { + let v: serde_json::Value = + serde_json::from_str(&manifest::generate(i).unwrap()[0].content).unwrap(); + v["inputHash"].clone() + }; + assert_ne!(hash(&i), hash(&inputs())); + assert_eq!( + serde_json::to_string_pretty(&manifest_json(&i)).unwrap(), + serde_json::to_string_pretty(&manifest_json(&inputs())).unwrap() + ); + let _ = std::fs::remove_dir_all(dir); +} + +/// The acceptance list is computed from source by the script (not edited by +/// hand): regenerating it reproduces the committed file, including the +/// 193rd type `ToolChoice`, whose `#[ts(\n export, ..)]` spans lines +/// (aimux-core/src/tool.rs:210-213). +#[test] +fn closure_dto_list_is_reproducible_from_source() { + let out = Command::new("python3") + .arg(workspace().join("scripts/gen_closure_inventory.py")) + .arg("--check") + .output() + .expect("python3 is required to verify docs/plan/closure-dtos.txt"); + assert!( + out.status.success(), + "{}{}", + String::from_utf8_lossy(&out.stdout), + String::from_utf8_lossy(&out.stderr) + ); + let list = std::fs::read_to_string(&inputs().list).unwrap(); + assert!(list.contains("\n[exported] 193\n")); + let tool = std::fs::read_to_string(workspace().join("aimux-core/src/tool.rs")).unwrap(); + assert!( + tool.contains("#[ts(\n export,"), + "multi-line export fixture moved" + ); + assert!( + exported_section(&list).contains(&"ToolChoice tool aimux-core/src/tool.rs".to_string()) + ); +} + +/// `BooleanCriteria.true/false` (evaluation_model.rs:62-73) keep three wire +/// states: absent key, explicit null, value. The manifest says so with +/// `triState` and the `presence` codec instead of `Option>`. +#[test] +fn boolean_criteria_manifest_entry_is_tri_state() { + let manifest: serde_json::Value = serde_json::from_str( + &std::fs::read_to_string(root().join("generated/manifest.json")).unwrap(), + ) + .unwrap(); + let t = manifest["types"] + .as_array() + .unwrap() + .iter() + .find(|t| t["name"] == "BooleanCriteria") + .unwrap(); + let fields = t["shape"]["fields"].as_array().unwrap(); + assert_eq!(fields.len(), 2); + for (f, wire) in fields.iter().zip(["true", "false"]) { + assert_eq!(f["wire"], wire); + assert_eq!( + f["type"], + serde_json::json!({ "triState": { "ref": { "name": "EvaluationInput", "args": [] } } }) + ); + assert!(!f["type"].to_string().contains("\"option\""), "{f}"); + assert_eq!(f["codec"]["name"], "presence"); + assert_eq!(f["omitWhenEmpty"], true); + assert_eq!(f["default"], true); + } + let recording = manifest["types"] + .as_array() + .unwrap() + .iter() + .find(|t| t["name"] == "Recording") + .unwrap(); + let schema = recording["shape"]["fields"] + .as_array() + .unwrap() + .iter() + .find(|f| f["wire"] == "schema") + .unwrap(); + assert_eq!(schema["codec"]["name"], "currentRecordingSchema"); + assert_eq!(schema["type"], serde_json::json!({ "prim": "u32" })); +} + +/// A serde `with`-style field with neither `#[ts(type)]` nor a FIELD_CODECS +/// registration fails generation at the field's file:line. +#[test] +fn unregistered_serde_with_field_fails_generation() { + let (dir, i) = scratch_src("serde_with"); + std::fs::write( + i.src_root.join("extra_dto.rs"), + "#[derive(Serialize, Deserialize, TS)]\n#[ts(export)]\npub struct ExtraDto {\n #[serde(deserialize_with = \"custom\")]\n pub a: u32,\n}\n", + ) + .unwrap(); + let errs = errors(&i); + assert!( + errs.iter().any(|e| e + == "aimux-core/src/extra_dto.rs:5: ExtraDto.a uses serde `deserialize_with=custom` but has no `#[ts(type)]` and no FIELD_CODECS registration"), + "{errs:?}" + ); + let _ = std::fs::remove_dir_all(dir); +}