|
32 | 32 | if TYPE_CHECKING: |
33 | 33 | from openarmature.llm.messages import ToolCall |
34 | 34 | from openarmature.llm.response import Usage |
| 35 | + from openarmature.retrieval.response import EmbeddingUsage |
35 | 36 |
|
36 | 37 | # Sentinel empty metadata mapping for events constructed without a |
37 | 38 | # live caller-metadata snapshot (test helpers, synthetic events). |
@@ -749,6 +750,125 @@ class LlmRetryAttemptEvent: |
749 | 750 | output_tool_calls: list["ToolCall"] = field(default_factory=list["ToolCall"]) |
750 | 751 |
|
751 | 752 |
|
| 753 | +# Spec: realizes graph-engine §6 + observability §5.5.9 -- the typed |
| 754 | +# EmbeddingEvent / EmbeddingFailedEvent pair (proposal 0059, |
| 755 | +# retrieval-provider capability). Dispatched on the observer delivery |
| 756 | +# queue per EmbeddingProvider.embed() call: the success variant after the |
| 757 | +# response is parsed + validated, the failure variant alongside a raised |
| 758 | +# §7 category exception (mutually exclusive per call). Scalar |
| 759 | +# fan_out_index / branch_name only; the lineage chains arrive uniformly |
| 760 | +# across the provider events with proposal 0084 (v0.81.0). input_strings / |
| 761 | +# request_extras are payload-bearing, populated unconditionally; observer- |
| 762 | +# side privacy gates (OTel disable_provider_payload, Langfuse equivalents) |
| 763 | +# apply at rendering, symmetric with LlmCompletionEvent. |
| 764 | +@dataclass(frozen=True) |
| 765 | +class EmbeddingEvent: |
| 766 | + """A typed embedding provider call event delivered to observers. |
| 767 | +
|
| 768 | + Carries identity, scoping, and outcome data for a successful |
| 769 | + ``EmbeddingProvider.embed()`` call. Observer code filters by type |
| 770 | + discrimination (``isinstance(event, EmbeddingEvent)``). |
| 771 | +
|
| 772 | + The identity / scoping / request-side fields mirror |
| 773 | + ``LlmCompletionEvent``'s convention; the outcome fields are |
| 774 | + embedding-specific: |
| 775 | +
|
| 776 | + - ``input_strings``: the input strings the call was made with; |
| 777 | + non-nullable, populated unconditionally (privacy gating is |
| 778 | + observer-side at rendering). |
| 779 | + - ``input_count``: ``len(input_strings)``; a convenience field. |
| 780 | + - ``dimensions``: the output vector dimensionality from the response; |
| 781 | + ``None`` when the response surfaced no determinate dimensionality. |
| 782 | + - ``response_model`` / ``response_id``: the provider-returned model |
| 783 | + and response identifiers; ``None`` when the provider returned none. |
| 784 | + - ``usage``: the embedding token record; ``None`` when the call |
| 785 | + returned no usage. |
| 786 | + - ``request_params``: the embedding request parameters the caller |
| 787 | + supplied (e.g. ``dimensions``). Absence-is-meaningful: only supplied |
| 788 | + keys appear; an empty mapping when none. |
| 789 | + - ``request_extras``: the runtime-config extras pass-through bag. |
| 790 | + - ``active_prompt`` / ``active_prompt_group``: prompt-context |
| 791 | + snapshots at embed-call time; ``None`` outside a binding. |
| 792 | + - ``call_id``: a per-call disambiguator, always present, freshly |
| 793 | + minted per ``embed()`` call. |
| 794 | + """ |
| 795 | + |
| 796 | + invocation_id: str |
| 797 | + correlation_id: str | None |
| 798 | + node_name: str |
| 799 | + namespace: tuple[str, ...] |
| 800 | + attempt_index: int |
| 801 | + fan_out_index: int | None |
| 802 | + branch_name: str | None |
| 803 | + provider: str |
| 804 | + model: str |
| 805 | + response_id: str | None |
| 806 | + response_model: str | None |
| 807 | + # EmbeddingUsage is a string-typed forward reference per the |
| 808 | + # TYPE_CHECKING import -- keeps the runtime import direction |
| 809 | + # graph -> retrieval off the module-load path. |
| 810 | + usage: "EmbeddingUsage | None" |
| 811 | + latency_ms: float | None |
| 812 | + input_strings: list[str] |
| 813 | + input_count: int |
| 814 | + dimensions: int | None |
| 815 | + request_params: Mapping[str, Any] |
| 816 | + request_extras: Mapping[str, Any] |
| 817 | + active_prompt: Any |
| 818 | + active_prompt_group: Any |
| 819 | + call_id: str |
| 820 | + caller_invocation_metadata: Mapping[str, AttributeValue] | None = None |
| 821 | + |
| 822 | + |
| 823 | +# Spec: the failure sibling of EmbeddingEvent (proposal 0059). Dispatched |
| 824 | +# whenever EmbeddingProvider.embed() raises a §7 category exception -- |
| 825 | +# covers both the provider-caught path and the pre-send validation raise |
| 826 | +# (provider_invalid_request on an empty input list). Dispatched ALONGSIDE |
| 827 | +# the exception, not in place of it; mutually exclusive with EmbeddingEvent |
| 828 | +# on the same call. The response-side fields are absent (no response). |
| 829 | +@dataclass(frozen=True) |
| 830 | +class EmbeddingFailedEvent: |
| 831 | + """A typed embedding provider call failure event delivered to observers. |
| 832 | +
|
| 833 | + Carries identity, scoping, and failure-context data for an ``embed()`` |
| 834 | + call that raised a retrieval-provider category exception. Observer code |
| 835 | + filters by type discrimination |
| 836 | + (``isinstance(event, EmbeddingFailedEvent)``). |
| 837 | +
|
| 838 | + The identity / scoping / request-side field set mirrors |
| 839 | + ``EmbeddingEvent``; the response-side fields are absent. Failure- |
| 840 | + specific fields: |
| 841 | +
|
| 842 | + - ``error_category``: the error category the call raised (one of the |
| 843 | + embedding-applicable provider categories). Always present. |
| 844 | + - ``error_type``: an optional impl-level / vendor-specific type or |
| 845 | + code; ``None`` when unavailable. |
| 846 | + - ``error_message``: a human-readable message; always present (the |
| 847 | + empty string when the exception carried no message). |
| 848 | + """ |
| 849 | + |
| 850 | + invocation_id: str |
| 851 | + correlation_id: str | None |
| 852 | + node_name: str |
| 853 | + namespace: tuple[str, ...] |
| 854 | + attempt_index: int |
| 855 | + fan_out_index: int | None |
| 856 | + branch_name: str | None |
| 857 | + provider: str |
| 858 | + model: str |
| 859 | + latency_ms: float | None |
| 860 | + input_strings: list[str] |
| 861 | + request_params: Mapping[str, Any] |
| 862 | + request_extras: Mapping[str, Any] |
| 863 | + active_prompt: Any |
| 864 | + active_prompt_group: Any |
| 865 | + call_id: str |
| 866 | + error_category: str |
| 867 | + error_message: str |
| 868 | + error_type: str | None = None |
| 869 | + caller_invocation_metadata: Mapping[str, AttributeValue] | None = None |
| 870 | + |
| 871 | + |
752 | 872 | # Spec: realizes pipeline-utilities §6.3 failure-isolation middleware |
753 | 873 | # (proposal 0050). Emitted by FailureIsolationMiddleware when it |
754 | 874 | # catches an exception escaping the inner chain and substitutes a |
@@ -905,6 +1025,8 @@ class ToolCallFailedEvent: |
905 | 1025 |
|
906 | 1026 |
|
907 | 1027 | __all__ = [ |
| 1028 | + "EmbeddingEvent", |
| 1029 | + "EmbeddingFailedEvent", |
908 | 1030 | "FailureIsolatedEvent", |
909 | 1031 | "FanOutEventConfig", |
910 | 1032 | "InvocationCompletedEvent", |
|
0 commit comments